+
Teamspen's Hammer Addons
@@ -23,7 +23,9 @@ Below are short explanations, see the "Help" display on the entity properties in
| Entity | Description |
|----------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `comp_adv_output` | Adds a single output to another entity, while allowing instance renaming or `$fixups` to apply to only certain parts. |
| `comp_flicker` | Fires on/off and skin inputs repeatedly to simulate a flicker-on effect. |
+| `comp_case` | Version of `logic_case` which is optimised away by the compiler. |
| `comp_choreo_sceneset` | Chains a set of choreographed scenes together. |
| `comp_entity_finder` | Finds the closest entity of a given type, then applies various transformations. Outputs from this entity will be moved to the found entity. |
| `comp_entity_mover` | Shift an entity by a given amount. This is useful to place entities into the void, for example. |
diff --git a/examples/hadd_comp_case.vmf b/examples/hadd_comp_case.vmf
new file mode 100644
index 000000000..b8a6e16cc
--- /dev/null
+++ b/examples/hadd_comp_case.vmf
@@ -0,0 +1,7553 @@
+versioninfo
+{
+ "editorversion" "400"
+ "editorbuild" "9520"
+ "mapversion" "59"
+ "formatversion" "100"
+ "prefab" "0"
+}
+visgroups
+{
+}
+viewsettings
+{
+ "bSnapToGrid" "1"
+ "bShowGrid" "1"
+ "bShowLogicalGrid" "0"
+ "nGridSpacing" "32"
+ "bShow3DGrid" "1"
+}
+world
+{
+ "id" "1"
+ "mapversion" "59"
+ "classname" "worldspawn"
+ "detailmaterial" "detail/detailsprites"
+ "detailvbsp" "detail.vbsp"
+ "maxpropscreenwidth" "-1"
+ "skyname" "sky_day01_01"
+ solid
+ {
+ "id" "4"
+ side
+ {
+ "id" "18"
+ "plane" "(-64 320 128) (0 320 128) (0 0 128)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "17"
+ "plane" "(-64 0 0) (0 0 0) (0 320 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "16"
+ "plane" "(-64 320 128) (-64 0 128) (-64 0 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "15"
+ "plane" "(0 320 0) (0 0 0) (0 0 128)"
+ "material" "DEV/DEV_MEASUREGENERIC01"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "14"
+ "plane" "(0 320 128) (-64 320 128) (-64 320 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "13"
+ "plane" "(0 0 0) (-64 0 0) (-64 0 128)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "7"
+ side
+ {
+ "id" "30"
+ "plane" "(448 320 128) (448 0 128) (384 0 128)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "29"
+ "plane" "(448 0 0) (448 320 0) (384 320 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "28"
+ "plane" "(384 320 128) (384 0 128) (384 0 0)"
+ "material" "DEV/DEV_MEASUREGENERIC01"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "27"
+ "plane" "(448 0 128) (448 320 128) (448 320 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "26"
+ "plane" "(448 320 128) (384 320 128) (384 320 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "25"
+ "plane" "(384 0 128) (448 0 128) (448 0 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "24"
+ side
+ {
+ "id" "42"
+ "plane" "(0 320 128) (0 384 128) (384 384 128)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "41"
+ "plane" "(0 384 0) (0 320 0) (384 320 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "40"
+ "plane" "(0 320 0) (0 384 0) (0 384 128)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "39"
+ "plane" "(384 384 0) (384 320 0) (384 320 128)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "38"
+ "plane" "(0 384 0) (384 384 0) (384 384 128)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "37"
+ "plane" "(384 320 0) (0 320 0) (0 320 128)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "27"
+ side
+ {
+ "id" "54"
+ "plane" "(0 -64 192) (0 0 192) (384 0 192)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "53"
+ "plane" "(0 0 0) (0 -64 0) (384 -64 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "52"
+ "plane" "(0 -64 0) (0 0 0) (0 0 192)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "51"
+ "plane" "(384 0 0) (384 -64 0) (384 -64 192)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "50"
+ "plane" "(0 0 0) (384 0 0) (384 0 192)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "49"
+ "plane" "(384 -64 0) (0 -64 0) (0 -64 192)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "33"
+ side
+ {
+ "id" "84"
+ "plane" "(384 384 256) (384 320 256) (0 320 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "83"
+ "plane" "(384 320 128) (384 384 128) (0 384 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "82"
+ "plane" "(0 384 256) (0 320 256) (0 320 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "81"
+ "plane" "(384 320 256) (384 384 256) (384 384 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "80"
+ "plane" "(384 384 256) (0 384 256) (0 384 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "79"
+ "plane" "(0 320 256) (384 320 256) (384 320 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "34"
+ side
+ {
+ "id" "90"
+ "plane" "(-64 320 256) (0 320 256) (0 0 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "89"
+ "plane" "(-64 0 128) (0 0 128) (0 320 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "88"
+ "plane" "(-64 320 256) (-64 0 256) (-64 0 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "87"
+ "plane" "(0 320 128) (0 0 128) (0 0 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "86"
+ "plane" "(0 320 256) (-64 320 256) (-64 320 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "85"
+ "plane" "(0 0 128) (-64 0 128) (-64 0 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "35"
+ side
+ {
+ "id" "96"
+ "plane" "(0 -64 256) (0 0 256) (384 0 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "95"
+ "plane" "(0 0 192) (0 -64 192) (384 -64 192)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "94"
+ "plane" "(0 -64 192) (0 0 192) (0 0 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "93"
+ "plane" "(384 0 192) (384 -64 192) (384 -64 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "92"
+ "plane" "(0 0 192) (384 0 192) (384 0 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "91"
+ "plane" "(384 -64 192) (0 -64 192) (0 -64 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "36"
+ side
+ {
+ "id" "102"
+ "plane" "(448 320 256) (448 0 256) (384 0 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "101"
+ "plane" "(448 0 128) (448 320 128) (384 320 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "100"
+ "plane" "(384 320 256) (384 0 256) (384 0 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "99"
+ "plane" "(448 0 256) (448 320 256) (448 320 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "98"
+ "plane" "(448 320 256) (384 320 256) (384 320 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "97"
+ "plane" "(384 0 256) (448 0 256) (448 0 128)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "53"
+ side
+ {
+ "id" "114"
+ "plane" "(384 320 320) (384 0 320) (0 0 320)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "113"
+ "plane" "(384 0 256) (384 320 256) (0 320 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "112"
+ "plane" "(0 320 320) (0 0 320) (0 0 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "111"
+ "plane" "(384 0 320) (384 320 320) (384 320 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "110"
+ "plane" "(384 320 320) (0 320 320) (0 320 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "109"
+ "plane" "(0 0 320) (384 0 320) (384 0 256)"
+ "material" "TOOLS/TOOLSSKYBOX"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "5279"
+ side
+ {
+ "id" "1191"
+ "plane" "(0 0 0) (0 96 0) (384 96 0)"
+ "material" "DEV/DEV_MEASUREGENERIC01B"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1190"
+ "plane" "(0 96 -64) (0 0 -64) (384 0 -64)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1189"
+ "plane" "(0 0 -64) (0 96 -64) (0 96 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1188"
+ "plane" "(384 96 -64) (384 0 -64) (384 0 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1187"
+ "plane" "(384 0 -64) (0 0 -64) (0 0 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1186"
+ "plane" "(0 96 -64) (384 96 -64) (384 96 0)"
+ "material" "DEV/DEV_MEASUREGENERIC01B"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "5280"
+ side
+ {
+ "id" "1197"
+ "plane" "(0 96 0) (0 208 0) (384 208 0)"
+ "material" "DEV/DEV_MEASUREGENERIC01B"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1196"
+ "plane" "(0 208 -64) (0 96 -64) (384 96 -64)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1195"
+ "plane" "(0 96 -64) (0 208 -64) (0 208 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1194"
+ "plane" "(384 208 -64) (384 96 -64) (384 96 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1193"
+ "plane" "(384 96 -64) (0 96 -64) (0 96 0)"
+ "material" "DEV/DEV_MEASUREGENERIC01B"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1192"
+ "plane" "(0 208 -64) (384 208 -64) (384 208 0)"
+ "material" "DEV/DEV_MEASUREGENERIC01B"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "5281"
+ side
+ {
+ "id" "1203"
+ "plane" "(0 208 0) (0 320 0) (384 320 0)"
+ "material" "DEV/DEV_MEASUREGENERIC01B"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1202"
+ "plane" "(0 320 -64) (0 208 -64) (384 208 -64)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1201"
+ "plane" "(0 208 -64) (0 320 -64) (0 320 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1200"
+ "plane" "(384 320 -64) (384 208 -64) (384 208 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1199"
+ "plane" "(0 320 -64) (384 320 -64) (384 320 0)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1198"
+ "plane" "(384 208 -64) (0 208 -64) (0 208 0)"
+ "material" "DEV/DEV_MEASUREGENERIC01B"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 148 189"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+}
+entity
+{
+ "id" "109"
+ "classname" "info_player_start"
+ "angles" "0 45 0"
+ "origin" "32 32 0"
+ editor
+ {
+ "color" "0 255 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 5000]"
+ }
+}
+entity
+{
+ "id" "117"
+ "classname" "light_environment"
+ "_ambient" "255 255 255 20"
+ "_ambienthdr" "-1 -1 -1 1"
+ "_ambientscalehdr" "1"
+ "_light" "254 252 216 200"
+ "_lighthdr" "-1 -1 -1 1"
+ "_lightscalehdr" "1"
+ "angles" "-75 18.5 0"
+ "pitch" "-65"
+ "style" "0"
+ "sunspreadangle" "2"
+ "origin" "32 32 96"
+ editor
+ {
+ "color" "255 255 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 5500]"
+ }
+}
+entity
+{
+ "id" "157"
+ "classname" "func_detail"
+ solid
+ {
+ "id" "145"
+ side
+ {
+ "id" "150"
+ "plane" "(192 304 64) (192 320 64) (224 320 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 -256] 0.25"
+ "vaxis" "[0 -1 0 128] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "149"
+ "plane" "(192 320 0) (192 304 0) (224 304 0)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 -256] 0.25"
+ "vaxis" "[0 -1 0 128] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "148"
+ "plane" "(192 304 0) (192 320 0) (192 320 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[0 1 0 -128] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "147"
+ "plane" "(224 320 0) (224 304 0) (224 304 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[0 1 0 -128] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "146"
+ "plane" "(192 320 0) (224 320 0) (224 320 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 -256] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "145"
+ "plane" "(224 304 0) (192 304 0) (192 304 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 -256] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 500]"
+ }
+}
+entity
+{
+ "id" "164"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 0 0"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_eq_5"
+ "origin" "208 312 72"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "360"
+ "classname" "func_detail"
+ solid
+ {
+ "id" "352"
+ side
+ {
+ "id" "351"
+ "plane" "(202 302 26) (202 302 20) (196 302 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 0 -1 -96] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "350"
+ "plane" "(196 304 26) (196 304 20) (202 304 20)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -32] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "349"
+ "plane" "(196 302 26) (196 302 20) (196 304 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 96] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "348"
+ "plane" "(202 304 26) (202 304 20) (202 302 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 96] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "347"
+ "plane" "(202 302 26) (196 302 26) (196 304 26)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ side
+ {
+ "id" "346"
+ "plane" "(202 304 20) (196 304 20) (196 302 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "313"
+ side
+ {
+ "id" "357"
+ "plane" "(202 304 26) (202 304 20) (212 304 24)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "356"
+ "plane" "(202 302 20) (202 302 26) (208 302 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "355"
+ "plane" "(202 302 26) (202 302 20) (202 304 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "354"
+ "plane" "(208 304 28) (212 304 24) (212 302 24)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "353"
+ "plane" "(212 304 24) (202 304 20) (202 302 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ side
+ {
+ "id" "352"
+ "plane" "(208 302 28) (202 302 26) (202 304 26)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "314"
+ side
+ {
+ "id" "363"
+ "plane" "(208 304 28) (212 304 24) (216 304 34)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "362"
+ "plane" "(212 302 24) (208 302 28) (210 302 34)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "361"
+ "plane" "(208 302 28) (212 302 24) (212 304 24)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "360"
+ "plane" "(216 302 34) (210 302 34) (210 304 34)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "359"
+ "plane" "(216 304 34) (212 304 24) (212 302 24)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ side
+ {
+ "id" "358"
+ "plane" "(210 302 34) (208 302 28) (208 304 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "307"
+ side
+ {
+ "id" "369"
+ "plane" "(210 304 34) (216 304 34) (212 304 44)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "368"
+ "plane" "(216 302 34) (210 302 34) (208 302 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "367"
+ "plane" "(216 304 34) (210 304 34) (210 302 34)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "366"
+ "plane" "(212 302 44) (208 302 40) (208 304 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "365"
+ "plane" "(212 304 44) (216 304 34) (216 302 34)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ side
+ {
+ "id" "364"
+ "plane" "(208 302 40) (210 302 34) (210 304 34)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "308"
+ side
+ {
+ "id" "375"
+ "plane" "(202 304 48) (202 304 42) (208 304 40)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "374"
+ "plane" "(212 302 44) (208 302 40) (202 302 42)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "373"
+ "plane" "(212 304 44) (208 304 40) (208 302 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "372"
+ "plane" "(202 302 48) (202 302 42) (202 304 42)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "371"
+ "plane" "(212 302 44) (202 302 48) (202 304 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ side
+ {
+ "id" "370"
+ "plane" "(208 304 40) (202 304 42) (202 302 42)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "350"
+ side
+ {
+ "id" "381"
+ "plane" "(202 302 54) (202 302 42) (196 302 42)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "380"
+ "plane" "(196 304 54) (196 304 42) (202 304 42)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "379"
+ "plane" "(196 302 54) (196 302 42) (196 304 42)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -316] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "378"
+ "plane" "(202 304 54) (202 304 42) (202 302 42)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -316] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "377"
+ "plane" "(202 302 54) (196 302 54) (196 304 54)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -316] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "376"
+ "plane" "(202 304 42) (196 304 42) (196 302 42)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -316] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "351"
+ side
+ {
+ "id" "387"
+ "plane" "(216 302 60) (216 302 54) (196 302 54)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 0 -1 40] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "386"
+ "plane" "(196 304 60) (196 304 54) (216 304 54)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 40] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "385"
+ "plane" "(196 302 60) (196 302 54) (196 304 54)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -40] 0.25"
+ "vaxis" "[0 1 0 -352] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "384"
+ "plane" "(216 304 60) (216 304 54) (216 302 54)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -40] 0.25"
+ "vaxis" "[0 1 0 -352] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "383"
+ "plane" "(216 302 60) (196 302 60) (196 304 60)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -352] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "382"
+ "plane" "(216 304 54) (196 304 54) (196 302 54)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -128] 0.25"
+ "vaxis" "[0 1 0 -352] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 6000]"
+ }
+}
+entity
+{
+ "id" "523"
+ "classname" "func_detail"
+ solid
+ {
+ "id" "524"
+ side
+ {
+ "id" "413"
+ "plane" "(96 304 64) (96 320 64) (160 320 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 128] 0.25"
+ "vaxis" "[0 -1 0 128] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "412"
+ "plane" "(96 320 0) (96 304 0) (160 304 0)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 128] 0.25"
+ "vaxis" "[0 -1 0 128] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "411"
+ "plane" "(96 304 0) (96 320 0) (96 320 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[0 1 0 -128] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "410"
+ "plane" "(160 320 0) (160 304 0) (160 304 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[0 1 0 -128] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "409"
+ "plane" "(96 320 0) (160 320 0) (160 320 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 128] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "408"
+ "plane" "(160 304 0) (96 304 0) (96 304 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 -384] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 500]"
+ }
+}
+entity
+{
+ "id" "547"
+ "classname" "func_detail"
+ solid
+ {
+ "id" "548"
+ side
+ {
+ "id" "434"
+ "plane" "(132 302 44) (132 302 40) (108 302 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 0 -1 -48] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "433"
+ "plane" "(108 304 36) (108 304 28) (132 304 40)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 0 -1 -48] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "432"
+ "plane" "(132 304 44) (132 304 40) (132 302 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 48] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "431"
+ "plane" "(108 302 36) (108 302 28) (108 304 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 48] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "430"
+ "plane" "(124 302 44) (108 302 36) (108 304 36)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "429"
+ "plane" "(132 304 40) (108 304 28) (108 302 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "428"
+ "plane" "(132 302 44) (124 302 44) (124 304 44)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 -1 0 -4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "549"
+ side
+ {
+ "id" "441"
+ "plane" "(132 302 48) (132 302 44) (124 302 44)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 0 1 -400] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "440"
+ "plane" "(108 304 60) (108 304 52) (124 304 44)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 0 1 -16] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "439"
+ "plane" "(132 304 48) (132 304 44) (132 302 44)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 400] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "438"
+ "plane" "(108 302 60) (108 302 52) (108 304 52)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 400] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "437"
+ "plane" "(124 304 44) (108 304 52) (108 302 52)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "436"
+ "plane" "(132 302 48) (108 302 60) (108 304 60)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "435"
+ "plane" "(132 304 44) (124 304 44) (124 302 44)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 -1 0 -4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 6500]"
+ }
+}
+entity
+{
+ "id" "852"
+ "classname" "func_detail"
+ solid
+ {
+ "id" "821"
+ side
+ {
+ "id" "591"
+ "plane" "(150.402 304 42.8594) (146.803 304 45.7152) (141.398 304 44.2853)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 48] 0.25"
+ "vaxis" "[0 0 1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "590"
+ "plane" "(141.398 302 40) (141.398 302 44.2853) (146.802 302 45.7149)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 0 1 -436] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "589"
+ "plane" "(150.402 302 42.8594) (146.803 302 45.7152) (146.802 304 45.7147)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 436] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "588"
+ "plane" "(141.4 302 44.2857) (141.4 302 40) (141.4 304 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 436] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "587"
+ "plane" "(150.402 304 42.8574) (141.4 304 40) (141.398 302 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ side
+ {
+ "id" "586"
+ "plane" "(146.801 302 45.7148) (141.4 302 44.286) (141.398 304 44.2852)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "822"
+ side
+ {
+ "id" "597"
+ "plane" "(154 304 50) (148.6 304 50) (146.8 304 45.7133)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 48] 0.25"
+ "vaxis" "[0 0 1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "596"
+ "plane" "(150.398 302 42.8555) (146.799 302 45.7126) (148.6 302 50)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 0 1 -436] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "595"
+ "plane" "(154 302 50) (148.6 302 50) (148.6 304 50)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "594"
+ "plane" "(150.398 304 42.8594) (146.8 304 45.7153) (146.801 302 45.7156)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 436] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "593"
+ "plane" "(154 304 50) (150.4 304 42.8571) (150.4 302 42.8594)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 436] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "1"
+ }
+ side
+ {
+ "id" "592"
+ "plane" "(148.6 302 50) (146.8 302 45.7145) (146.801 304 45.7148)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 436] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "823"
+ side
+ {
+ "id" "603"
+ "plane" "(141.398 304 60) (141.398 304 55.7147) (146.802 304 54.2851)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 48] 0.25"
+ "vaxis" "[0 0 1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "602"
+ "plane" "(150.398 302 57.1445) (146.798 302 54.2863) (141.398 302 55.7147)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 0 1 -436] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "601"
+ "plane" "(141.4 302 60) (141.4 302 55.7143) (141.4 304 55.7143)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 436] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "600"
+ "plane" "(150.398 304 57.1406) (146.8 304 54.2857) (146.799 302 54.286)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 436] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "599"
+ "plane" "(150.398 302 57.1426) (141.398 302 60) (141.398 304 60)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "1"
+ }
+ side
+ {
+ "id" "598"
+ "plane" "(146.801 304 54.2871) (141.398 304 55.7158) (141.395 302 55.7158)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "824"
+ side
+ {
+ "id" "609"
+ "plane" "(141.399 302 60) (141.399 302 55.7148) (136 302 55.7148)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 0 1 -480] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "608"
+ "plane" "(136 304 60) (136 304 55.7148) (141.399 304 55.7148)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 48] 0.25"
+ "vaxis" "[0 0 1 -32] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "607"
+ "plane" "(136 302 60) (136 302 55.7148) (136 304 55.7148)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 480] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "606"
+ "plane" "(141.4 304 60) (141.4 304 55.7148) (141.4 302 55.7148)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 480] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "605"
+ "plane" "(141.398 304 55.7143) (136 304 55.7143) (136 302 55.7143)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ side
+ {
+ "id" "604"
+ "plane" "(141.398 302 60) (136 302 60) (136 304 60)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "825"
+ side
+ {
+ "id" "615"
+ "plane" "(150.402 304 57.1445) (146.8 304 54.2851) (148.6 304 50)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 48] 0.25"
+ "vaxis" "[0 0 1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "614"
+ "plane" "(154 302 50) (148.598 302 50) (146.8 302 54.285)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 0 1 -436] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "613"
+ "plane" "(150.398 302 57.1445) (146.799 302 54.2874) (146.8 304 54.2867)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 436] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "612"
+ "plane" "(154 304 50) (148.6 304 50) (148.6 302 50)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "611"
+ "plane" "(150.402 304 57.1406) (154 304 50) (154 302 50)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 436] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "1"
+ }
+ side
+ {
+ "id" "610"
+ "plane" "(146.799 302 54.2891) (148.6 302 50) (148.604 304 50)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 436] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "598"
+ side
+ {
+ "id" "621"
+ "plane" "(141.399 302 44.2852) (141.399 302 35.7143) (136 302 35.7148)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "620"
+ "plane" "(136 304 44.2852) (136 304 35.7143) (141.399 304 35.7148)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 48] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "619"
+ "plane" "(136 302 44.2852) (136 302 35.7143) (136 304 35.7148)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -316] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "618"
+ "plane" "(141.4 304 44.2852) (141.4 304 35.7143) (141.4 302 35.7148)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -316] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "617"
+ "plane" "(141.398 302 44.2857) (136 302 44.2857) (136 304 44.2857)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -316] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ side
+ {
+ "id" "616"
+ "plane" "(141.398 304 35.7143) (136 304 35.7143) (136 302 35.7143)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -316] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "597"
+ side
+ {
+ "id" "627"
+ "plane" "(141.398 304 40) (141.398 304 35.7147) (146.799 304 34.286)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 48] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "626"
+ "plane" "(150.402 302 37.1406) (146.803 302 34.2848) (141.398 302 35.7147)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "625"
+ "plane" "(150.398 304 37.1445) (146.798 304 34.2863) (146.802 302 34.2851)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "624"
+ "plane" "(141.4 302 40) (141.4 302 35.7143) (141.4 304 35.7143)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "623"
+ "plane" "(150.406 302 37.1426) (141.4 302 40) (141.398 304 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "2"
+ }
+ side
+ {
+ "id" "622"
+ "plane" "(146.797 304 34.2861) (141.4 304 35.7139) (141.398 302 35.7148)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "595"
+ side
+ {
+ "id" "633"
+ "plane" "(146.8 304 25.7134) (150.4 304 22.8563) (154 304 30)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 48] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "632"
+ "plane" "(150.406 302 22.8555) (146.801 302 25.7173) (148.6 302 30)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "631"
+ "plane" "(150.398 304 22.8555) (146.799 304 25.7126) (146.799 302 25.711)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "630"
+ "plane" "(154 302 30) (148.6 302 30) (148.6 304 30)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "629"
+ "plane" "(154 304 30) (150.398 304 22.8555) (150.4 302 22.8594)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ side
+ {
+ "id" "628"
+ "plane" "(148.598 302 30) (146.799 302 25.7148) (146.797 304 25.7109)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "594"
+ side
+ {
+ "id" "639"
+ "plane" "(141.398 304 24.2853) (141.398 304 20) (150.398 304 22.8555)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 48] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "638"
+ "plane" "(141.398 302 20) (141.398 302 24.2853) (146.799 302 25.714)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "637"
+ "plane" "(141.4 302 24.2857) (141.4 302 20) (141.4 304 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "636"
+ "plane" "(150.398 302 22.8555) (146.798 302 25.7137) (146.795 304 25.713)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "635"
+ "plane" "(150.398 304 22.8574) (141.398 304 20) (141.398 302 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ side
+ {
+ "id" "634"
+ "plane" "(146.797 302 25.7139) (141.398 302 24.2852) (141.398 304 24.2852)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "596"
+ side
+ {
+ "id" "645"
+ "plane" "(148.6 304 30) (154 304 30) (150.398 304 37.1445)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 48] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "644"
+ "plane" "(154 302 30) (148.6 302 30) (146.8 302 34.2867)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 0 -1 -52] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "643"
+ "plane" "(154 304 30) (148.6 304 30) (148.6 302 30)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "642"
+ "plane" "(150.398 302 37.1445) (146.799 302 34.2874) (146.801 304 34.2844)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "641"
+ "plane" "(150.4 304 37.1406) (154 304 30) (154 302 30)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "2"
+ }
+ side
+ {
+ "id" "640"
+ "plane" "(146.799 302 34.2852) (148.6 302 30) (148.6 304 30)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 52] 0.25"
+ "vaxis" "[0 1 0 -276] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "593"
+ side
+ {
+ "id" "651"
+ "plane" "(141.399 302 24.2852) (141.399 302 20) (136 302 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 0 -1 -96] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "650"
+ "plane" "(136 304 24.2852) (136 304 20) (141.399 304 20)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 48] 0.25"
+ "vaxis" "[0 0 -1 -32] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "649"
+ "plane" "(136 302 24.2852) (136 302 20) (136 304 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 96] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "648"
+ "plane" "(141.4 304 24.2852) (141.4 304 20) (141.4 302 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 96] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "647"
+ "plane" "(141.398 302 24.2857) (136 302 24.2857) (136 304 24.2857)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ side
+ {
+ "id" "646"
+ "plane" "(141.398 304 20) (136 304 20) (136 302 20)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 112] 0.25"
+ "vaxis" "[0 1 0 -216] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 9500]"
+ }
+}
+entity
+{
+ "id" "913"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 0 0"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_gt_3"
+ "origin" "128 312 72"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "1017"
+ "classname" "comp_case"
+ "case01" ">= 3"
+ "case02" "5"
+ "case03" "< 8"
+ "ctrl_type" "0"
+ "ctrl_value" "1"
+ "mode" "numeric"
+ "multiplecasesallowed" "1"
+ "targetname" "case_numbers"
+ connections
+ {
+ "OnUsed" "spr_*,Color,255 0 0,1,-1"
+ "OnCase01" "spr_gt_3,Color,0 255 0,0,-1"
+ "OnCase02" "spr_eq_5,Color,0 255 0,0,-1"
+ "OnCase03" "spr_lt_8,Color,0 255 0,0,-1"
+ }
+ "origin" "208 280 40"
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "comments" "Demonstrates the numeric mode, allowing doing numeric comparisons in addition to just equality."
+ "logicalpos" "[0 10000]"
+ }
+}
+entity
+{
+ "id" "1163"
+ "classname" "func_detail"
+ solid
+ {
+ "id" "1164"
+ side
+ {
+ "id" "678"
+ "plane" "(284 302 32) (284 302 24) (260 302 36)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 16] 0.25"
+ "vaxis" "[0 0 -1 -64] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "677"
+ "plane" "(260 304 40) (260 304 36) (284 304 24)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 16] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "676"
+ "plane" "(260 302 40) (260 302 36) (260 304 36)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 64] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "675"
+ "plane" "(284 304 32) (284 304 24) (284 302 24)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 64] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "674"
+ "plane" "(284 302 32) (268 302 40) (268 304 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 16] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "673"
+ "plane" "(284 304 24) (260 304 36) (260 302 36)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 16] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "672"
+ "plane" "(268 302 40) (260 302 40) (260 304 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 16] 0.25"
+ "vaxis" "[0 -1 0 -4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1165"
+ side
+ {
+ "id" "685"
+ "plane" "(284 302 56) (284 302 48) (268 302 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 16] 0.25"
+ "vaxis" "[0 0 1 -384] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "684"
+ "plane" "(260 304 44) (260 304 40) (268 304 40)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 16] 0.25"
+ "vaxis" "[0 0 1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "683"
+ "plane" "(260 302 44) (260 302 40) (260 304 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 384] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "682"
+ "plane" "(284 304 56) (284 304 48) (284 302 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 -1 384] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "681"
+ "plane" "(284 304 48) (268 304 40) (268 302 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 16] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "680"
+ "plane" "(284 302 56) (260 302 44) (260 304 44)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 16] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "679"
+ "plane" "(268 304 40) (260 304 40) (260 302 40)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 16] 0.25"
+ "vaxis" "[0 -1 0 -4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 6500]"
+ }
+}
+entity
+{
+ "id" "1166"
+ "classname" "func_detail"
+ solid
+ {
+ "id" "1167"
+ side
+ {
+ "id" "691"
+ "plane" "(256 304 64) (256 320 64) (320 320 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 128] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "690"
+ "plane" "(256 320 0) (256 304 0) (320 304 0)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 128] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "689"
+ "plane" "(256 304 0) (256 320 0) (256 320 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[0 1 0 -128] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "688"
+ "plane" "(320 320 0) (320 304 0) (320 304 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[0 1 0 -128] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "687"
+ "plane" "(256 320 0) (320 320 0) (320 320 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "686"
+ "plane" "(320 304 0) (256 304 0) (256 304 64)"
+ "material" "DEV/REFLECTIVITY_20"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 500]"
+ }
+}
+entity
+{
+ "id" "1465"
+ "classname" "func_detail"
+ solid
+ {
+ "id" "1340"
+ side
+ {
+ "id" "841"
+ "plane" "(312 304 48) (309 304 55) (306 304 52)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "840"
+ "plane" "(308 302 48) (306 302 52) (309 302 55)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "839"
+ "plane" "(312 302 48) (312 304 48) (308 304 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "838"
+ "plane" "(309 304 55) (309 302 55) (306 302 52)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "837"
+ "plane" "(309 304 55) (312 304 48) (312 302 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ side
+ {
+ "id" "836"
+ "plane" "(308 304 48) (306 304 52) (306 302 52)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1341"
+ side
+ {
+ "id" "847"
+ "plane" "(309 304 55) (302 304 58) (302 304 54)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "846"
+ "plane" "(306 302 52) (302 302 54) (302 302 58)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "845"
+ "plane" "(309 302 55) (309 304 55) (306 304 52)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "844"
+ "plane" "(302 304 58) (302 302 58) (302 302 54)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "843"
+ "plane" "(302 304 58) (309 304 55) (309 302 55)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ side
+ {
+ "id" "842"
+ "plane" "(306 304 52) (302 304 54) (302 302 54)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1342"
+ side
+ {
+ "id" "853"
+ "plane" "(302 304 58) (295 304 55) (298 304 52)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "852"
+ "plane" "(302 302 54) (298 302 52) (295 302 55)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "851"
+ "plane" "(302 302 58) (302 304 58) (302 304 54)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "850"
+ "plane" "(295 304 55) (295 302 55) (298 302 52)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "849"
+ "plane" "(295 304 55) (302 304 58) (302 302 58)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ side
+ {
+ "id" "848"
+ "plane" "(302 304 54) (298 304 52) (298 302 52)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1343"
+ side
+ {
+ "id" "859"
+ "plane" "(295 304 55) (292 304 48) (296 304 48)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "858"
+ "plane" "(298 302 52) (296 302 48) (292 302 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "857"
+ "plane" "(295 302 55) (295 304 55) (298 304 52)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "856"
+ "plane" "(292 304 48) (292 302 48) (296 302 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "855"
+ "plane" "(292 304 48) (295 304 55) (295 302 55)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ side
+ {
+ "id" "854"
+ "plane" "(298 304 52) (296 304 48) (296 302 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1344"
+ side
+ {
+ "id" "865"
+ "plane" "(292 304 48) (295 304 41) (298 304 44)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "864"
+ "plane" "(296 302 48) (298 302 44) (295 302 41)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "863"
+ "plane" "(292 302 48) (292 304 48) (296 304 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "862"
+ "plane" "(295 304 41) (295 302 41) (298 302 44)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "861"
+ "plane" "(295 304 41) (292 304 48) (292 302 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ side
+ {
+ "id" "860"
+ "plane" "(296 304 48) (298 304 44) (298 302 44)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1347"
+ side
+ {
+ "id" "883"
+ "plane" "(309 304 41) (312 304 48) (308 304 48)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "882"
+ "plane" "(306 302 44) (308 302 48) (312 302 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "881"
+ "plane" "(309 302 41) (309 304 41) (306 304 44)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "880"
+ "plane" "(312 304 48) (312 302 48) (308 302 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "879"
+ "plane" "(312 304 48) (309 304 41) (309 302 41)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "8"
+ }
+ side
+ {
+ "id" "878"
+ "plane" "(306 304 44) (308 304 48) (308 302 48)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "1"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "5001"
+ side
+ {
+ "id" "1152"
+ "plane" "(298 304 44) (295 304 41) (306 304 36)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1151"
+ "plane" "(309 302 39) (306 302 36) (295 302 41)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 4] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1150"
+ "plane" "(295 304 41) (298 304 44) (298 302 44)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1149"
+ "plane" "(306 302 36) (309 302 39) (309 304 39)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 -4] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1148"
+ "plane" "(295 302 41) (306 302 36) (306 304 36)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "10"
+ }
+ side
+ {
+ "id" "1147"
+ "plane" "(298 304 44) (309 304 39) (309 302 39)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "5"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1349"
+ side
+ {
+ "id" "889"
+ "plane" "(312 304 32) (309 304 39) (306 304 36)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "888"
+ "plane" "(308 302 32) (306 302 36) (309 302 39)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "887"
+ "plane" "(312 302 32) (312 304 32) (308 304 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "886"
+ "plane" "(309 304 39) (309 302 39) (306 302 36)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "885"
+ "plane" "(309 304 39) (312 304 32) (312 302 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ side
+ {
+ "id" "884"
+ "plane" "(308 304 32) (306 304 36) (306 302 36)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1352"
+ side
+ {
+ "id" "907"
+ "plane" "(295 304 39) (292 304 32) (296 304 32)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "906"
+ "plane" "(298 302 36) (296 302 32) (292 302 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "905"
+ "plane" "(295 302 39) (295 304 39) (298 304 36)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "904"
+ "plane" "(292 304 32) (292 302 32) (296 302 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "903"
+ "plane" "(292 304 32) (295 304 39) (295 302 39)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ side
+ {
+ "id" "902"
+ "plane" "(298 304 36) (296 304 32) (296 302 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1353"
+ side
+ {
+ "id" "913"
+ "plane" "(292 304 32) (295 304 25) (298 304 28)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "912"
+ "plane" "(296 302 32) (298 302 28) (295 302 25)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "911"
+ "plane" "(292 302 32) (292 304 32) (296 304 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "910"
+ "plane" "(295 304 25) (295 302 25) (298 302 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "909"
+ "plane" "(295 304 25) (292 304 32) (292 302 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ side
+ {
+ "id" "908"
+ "plane" "(296 304 32) (298 304 28) (298 302 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1354"
+ side
+ {
+ "id" "919"
+ "plane" "(295 304 25) (302 304 22) (302 304 26)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "918"
+ "plane" "(298 302 28) (302 302 26) (302 302 22)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "917"
+ "plane" "(295 302 25) (295 304 25) (298 304 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "916"
+ "plane" "(302 304 22) (302 302 22) (302 302 26)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "915"
+ "plane" "(302 304 22) (295 304 25) (295 302 25)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ side
+ {
+ "id" "914"
+ "plane" "(298 304 28) (302 304 26) (302 302 26)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1355"
+ side
+ {
+ "id" "925"
+ "plane" "(302 304 22) (309 304 25) (306 304 28)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "924"
+ "plane" "(302 302 26) (306 302 28) (309 302 25)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "923"
+ "plane" "(302 302 22) (302 304 22) (302 304 26)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "922"
+ "plane" "(309 304 25) (309 302 25) (306 302 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "921"
+ "plane" "(309 304 25) (302 304 22) (302 302 22)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ side
+ {
+ "id" "920"
+ "plane" "(302 304 26) (306 304 28) (306 302 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "1356"
+ side
+ {
+ "id" "931"
+ "plane" "(309 304 25) (312 304 32) (308 304 32)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "930"
+ "plane" "(306 302 28) (308 302 32) (312 302 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "929"
+ "plane" "(309 302 25) (309 304 25) (306 304 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "928"
+ "plane" "(312 304 32) (312 302 32) (308 302 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "927"
+ "plane" "(312 304 32) (309 304 25) (309 302 25)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "4"
+ }
+ side
+ {
+ "id" "926"
+ "plane" "(306 304 28) (308 304 32) (308 302 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "2"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ solid
+ {
+ "id" "5031"
+ side
+ {
+ "id" "1173"
+ "plane" "(309 304 41) (306 304 44) (295 304 39)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1172"
+ "plane" "(298 302 36) (295 302 39) (306.003 302 44)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 -60] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1170"
+ "plane" "(298 304 36) (295 304 39) (295 302 39)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 60] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1169"
+ "plane" "(295 304 39) (306 304 44) (306.003 302 44)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "5"
+ }
+ side
+ {
+ "id" "1168"
+ "plane" "(298 302 36) (309 302 41) (309 304 41)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 1 0 -324] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "10"
+ }
+ side
+ {
+ "id" "1167"
+ "plane" "(306 304 44) (309 304 41) (309 302 41)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1000]"
+ }
+}
+entity
+{
+ "id" "1514"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 0 0"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_lt_8"
+ "origin" "289 312 72"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "1617"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "96 248 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "case_numbers,InValue,1,0,-1"
+ }
+ solid
+ {
+ "id" "1604"
+ side
+ {
+ "id" "943"
+ "plane" "(88 256 32) (104 256 32) (104 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 384] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "942"
+ "plane" "(88 240 -1.03315e-006) (104 240 -1.03315e-006) (104 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 384] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "941"
+ "plane" "(88 256 32) (88 240 32) (88 240 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "940"
+ "plane" "(104 256 -1.03315e-006) (104 240 -1.03315e-006) (104 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "939"
+ "plane" "(104 256 32) (88 256 32) (88 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 384] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "938"
+ "plane" "(104 240 -1.03315e-006) (88 240 -1.03315e-006) (88 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 384] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "1648"
+ "classname" "point_message"
+ "angles" "0 0 0"
+ "developeronly" "0"
+ "message" "1"
+ "radius" "128"
+ "origin" "96 248 36"
+ editor
+ {
+ "color" "200 200 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 3000]"
+ }
+}
+entity
+{
+ "id" "1678"
+ "classname" "point_message"
+ "angles" "0 0 0"
+ "developeronly" "0"
+ "message" "2"
+ "radius" "128"
+ "origin" "120 248 36"
+ editor
+ {
+ "color" "200 200 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 3000]"
+ }
+}
+entity
+{
+ "id" "1682"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "120 248 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "case_numbers,InValue,2,0,-1"
+ }
+ solid
+ {
+ "id" "1683"
+ side
+ {
+ "id" "955"
+ "plane" "(112 256 32) (128 256 32) (128 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 288] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "954"
+ "plane" "(112 240 -1.03315e-006) (128 240 -1.03315e-006) (128 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 288] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "953"
+ "plane" "(112 256 32) (112 240 32) (112 240 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "952"
+ "plane" "(128 256 -1.03315e-006) (128 240 -1.03315e-006) (128 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "951"
+ "plane" "(128 256 32) (112 256 32) (112 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 288] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "950"
+ "plane" "(128 240 -1.03315e-006) (112 240 -1.03315e-006) (112 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 288] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "1750"
+ "classname" "point_message"
+ "angles" "0 0 0"
+ "developeronly" "0"
+ "message" "3"
+ "radius" "128"
+ "origin" "144 248 36"
+ editor
+ {
+ "color" "200 200 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 3000]"
+ }
+}
+entity
+{
+ "id" "1754"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "144 248 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "case_numbers,InValue,3,0,-1"
+ }
+ solid
+ {
+ "id" "1755"
+ side
+ {
+ "id" "967"
+ "plane" "(136 256 32) (152 256 32) (152 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 192] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "966"
+ "plane" "(136 240 -1.03315e-006) (152 240 -1.03315e-006) (152 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 192] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "965"
+ "plane" "(136 256 32) (136 240 32) (136 240 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "964"
+ "plane" "(152 256 -1.03315e-006) (152 240 -1.03315e-006) (152 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "963"
+ "plane" "(152 256 32) (136 256 32) (136 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 192] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "962"
+ "plane" "(152 240 -1.03315e-006) (136 240 -1.03315e-006) (136 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 192] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "1813"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "168 248 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "case_numbers,InValue,4,0,-1"
+ }
+ solid
+ {
+ "id" "1814"
+ side
+ {
+ "id" "979"
+ "plane" "(160 256 32) (176 256 32) (176 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 96] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "978"
+ "plane" "(160 240 -1.03315e-006) (176 240 -1.03315e-006) (176 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 96] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "977"
+ "plane" "(160 256 32) (160 240 32) (160 240 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "976"
+ "plane" "(176 256 -1.03315e-006) (176 240 -1.03315e-006) (176 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "975"
+ "plane" "(176 256 32) (160 256 32) (160 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 96] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "974"
+ "plane" "(176 240 -1.03315e-006) (160 240 -1.03315e-006) (160 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 96] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "1818"
+ "classname" "point_message"
+ "angles" "0 0 0"
+ "developeronly" "0"
+ "message" "4"
+ "radius" "128"
+ "origin" "168 248 36"
+ editor
+ {
+ "color" "200 200 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 3000]"
+ }
+}
+entity
+{
+ "id" "1840"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "192 248 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "case_numbers,InValue,5,0,-1"
+ }
+ solid
+ {
+ "id" "1841"
+ side
+ {
+ "id" "991"
+ "plane" "(184 256 32) (200 256 32) (200 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "990"
+ "plane" "(184 240 -1.03315e-006) (200 240 -1.03315e-006) (200 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "989"
+ "plane" "(184 256 32) (184 240 32) (184 240 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "988"
+ "plane" "(200 256 -1.03315e-006) (200 240 -1.03315e-006) (200 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "987"
+ "plane" "(200 256 32) (184 256 32) (184 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "986"
+ "plane" "(200 240 -1.03315e-006) (184 240 -1.03315e-006) (184 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "1845"
+ "classname" "point_message"
+ "angles" "0 0 0"
+ "developeronly" "0"
+ "message" "5"
+ "radius" "128"
+ "origin" "192 248 36"
+ editor
+ {
+ "color" "200 200 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 3000]"
+ }
+}
+entity
+{
+ "id" "1867"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "216 248 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "case_numbers,InValue,6,0,-1"
+ }
+ solid
+ {
+ "id" "1868"
+ side
+ {
+ "id" "1003"
+ "plane" "(208 256 32) (224 256 32) (224 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -96] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1002"
+ "plane" "(208 240 -1.03315e-006) (224 240 -1.03315e-006) (224 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -96] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1001"
+ "plane" "(208 256 32) (208 240 32) (208 240 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1000"
+ "plane" "(224 256 -1.03315e-006) (224 240 -1.03315e-006) (224 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "999"
+ "plane" "(224 256 32) (208 256 32) (208 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -96] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "998"
+ "plane" "(224 240 -1.03315e-006) (208 240 -1.03315e-006) (208 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -96] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "1872"
+ "classname" "point_message"
+ "angles" "0 0 0"
+ "developeronly" "0"
+ "message" "6"
+ "radius" "128"
+ "origin" "216 248 36"
+ editor
+ {
+ "color" "200 200 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 3000]"
+ }
+}
+entity
+{
+ "id" "1894"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "240 248 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "case_numbers,InValue,7,0,-1"
+ }
+ solid
+ {
+ "id" "1895"
+ side
+ {
+ "id" "1015"
+ "plane" "(232 256 32) (248 256 32) (248 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -192] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1014"
+ "plane" "(232 240 -1.03315e-006) (248 240 -1.03315e-006) (248 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -192] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1013"
+ "plane" "(232 256 32) (232 240 32) (232 240 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1012"
+ "plane" "(248 256 -1.03315e-006) (248 240 -1.03315e-006) (248 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1011"
+ "plane" "(248 256 32) (232 256 32) (232 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -192] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1010"
+ "plane" "(248 240 -1.03315e-006) (232 240 -1.03315e-006) (232 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -192] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "1899"
+ "classname" "point_message"
+ "angles" "0 0 0"
+ "developeronly" "0"
+ "message" "7"
+ "radius" "128"
+ "origin" "240 248 36"
+ editor
+ {
+ "color" "200 200 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 3000]"
+ }
+}
+entity
+{
+ "id" "1921"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "264 248 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "case_numbers,InValue,8,0,-1"
+ }
+ solid
+ {
+ "id" "1922"
+ side
+ {
+ "id" "1027"
+ "plane" "(256 256 32) (272 256 32) (272 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -288] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1026"
+ "plane" "(256 240 -1.03315e-006) (272 240 -1.03315e-006) (272 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -288] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1025"
+ "plane" "(256 256 32) (256 240 32) (256 240 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1024"
+ "plane" "(272 256 -1.03315e-006) (272 240 -1.03315e-006) (272 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1023"
+ "plane" "(272 256 32) (256 256 32) (256 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -288] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1022"
+ "plane" "(272 240 -1.03315e-006) (256 240 -1.03315e-006) (256 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -288] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "1926"
+ "classname" "point_message"
+ "angles" "0 0 0"
+ "developeronly" "0"
+ "message" "8"
+ "radius" "128"
+ "origin" "264 248 36"
+ editor
+ {
+ "color" "200 200 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 3000]"
+ }
+}
+entity
+{
+ "id" "1948"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "288 248 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "case_numbers,InValue,9,0,-1"
+ }
+ solid
+ {
+ "id" "1949"
+ side
+ {
+ "id" "1039"
+ "plane" "(280 256 32) (296 256 32) (296 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -384] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1038"
+ "plane" "(280 240 -1.03315e-006) (296 240 -1.03315e-006) (296 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -384] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1037"
+ "plane" "(280 256 32) (280 240 32) (280 240 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1036"
+ "plane" "(296 256 -1.03315e-006) (296 240 -1.03315e-006) (296 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1035"
+ "plane" "(296 256 32) (280 256 32) (280 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -384] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1034"
+ "plane" "(296 240 -1.03315e-006) (280 240 -1.03315e-006) (280 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 -384] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "1953"
+ "classname" "point_message"
+ "angles" "0 0 0"
+ "developeronly" "0"
+ "message" "9"
+ "radius" "128"
+ "origin" "288 248 36"
+ editor
+ {
+ "color" "200 200 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 3000]"
+ }
+}
+entity
+{
+ "id" "1975"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "312 248 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "case_numbers,InValue,10,0,-1"
+ }
+ solid
+ {
+ "id" "1976"
+ side
+ {
+ "id" "1051"
+ "plane" "(304 256 32) (320 256 32) (320 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 32] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1050"
+ "plane" "(304 240 -1.03315e-006) (320 240 -1.03315e-006) (320 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 32] 0.25"
+ "vaxis" "[0 -1 0 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1049"
+ "plane" "(304 256 32) (304 240 32) (304 240 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1048"
+ "plane" "(320 256 -1.03315e-006) (320 240 -1.03315e-006) (320 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 0] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1047"
+ "plane" "(320 256 32) (304 256 32) (304 256 -1.03315e-006)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 32] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1046"
+ "plane" "(320 240 -1.03315e-006) (304 240 -1.03315e-006) (304 240 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 32] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "1980"
+ "classname" "point_message"
+ "angles" "0 0 0"
+ "developeronly" "0"
+ "message" "10"
+ "radius" "128"
+ "origin" "312 248 36"
+ editor
+ {
+ "color" "200 200 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 3000]"
+ }
+}
+entity
+{
+ "id" "2996"
+ "classname" "func_detail"
+ solid
+ {
+ "id" "2980"
+ side
+ {
+ "id" "1083"
+ "plane" "(132 302 28) (108 302 16) (108 302 24)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 0 -1 -96] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1082"
+ "plane" "(108 304 16) (132 304 28) (132 304 36)"
+ "material" "TOOLS/TOOLSNODRAW"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 0 -1 -32] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1081"
+ "plane" "(132 304 28) (132 302 28) (132 302 36)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 96] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "2"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1080"
+ "plane" "(108 302 16) (108 304 16) (108 304 24)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 0 1 96] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1079"
+ "plane" "(108 302 24) (108 304 24) (132 304 36)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1078"
+ "plane" "(108 304 16) (108 302 16) (132 302 28)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[-1 0 0 48] 0.25"
+ "vaxis" "[0 1 0 -300] 0.25"
+ "rotation" "0"
+ "lightmapscale" "4"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "0 180 0"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 4500]"
+ }
+}
+entity
+{
+ "id" "3623"
+ "classname" "comp_case"
+ "ctrl_type" "0"
+ "ctrl_value" "1"
+ "mode" "casefold"
+ "multiplecasesallowed" "0"
+ "targetname" "case_random_a"
+ connections
+ {
+ "OnCase01" "!self,Color,255 0 0,0,-1"
+ "OnCase02" "!self,Color,0 255 0,0,-1"
+ "OnCase03" "!self,Color,0 0 255,0,-1"
+ "OnCase06" "!self,Color,255 255 0,0,-1"
+ "OnCase05" "!self,Color,255 0 255,0,-1"
+ "OnCase04" "!self,Color,0 255 255,0,-1"
+ "OnCase07" "!self,Color,255 255 255,0,-1"
+ "OnCase08" "!self,Color,16 16 16,0,-1"
+ "OnCase10" "!self,Color,255 128 64,0,-1"
+ "OnCase09" "!self,Color,64 128 255,0,-1"
+ "OnCase11" "!self,Color,128 255 64,0,-1"
+ "OnCase12" "!self,Color,64 255 128,0,-1"
+ }
+ "origin" "184 72 8"
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "comments" "Each sprite fires PickRandom, so they get random colours added for the OnUserX outputs. The choice is consistent across compiles though."
+ "logicalpos" "[0 10000]"
+ }
+}
+entity
+{
+ "id" "3625"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_1"
+ connections
+ {
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ }
+ "origin" "96 16 48"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3696"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_2"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "128 16 48"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3701"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_3"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "160 16 48"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3706"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_4"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "192 16 48"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3711"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_5"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "224 16 48"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3716"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_6"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "256 16 48"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3721"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_7"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "288 16 48"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3726"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_8"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "320 16 48"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3731"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_9"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "352 16 48"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3736"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_10"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "96 16 80"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3741"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_11"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "128 16 80"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3746"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_12"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "160 16 80"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3751"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_13"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "192 16 80"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3756"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_14"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "224 16 80"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3761"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_15"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "256 16 80"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3766"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_16"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "288 16 80"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3771"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_17"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "320 16 80"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "3791"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "168 56 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "spr_rand_*,FireUser1,,0,-1"
+ }
+ solid
+ {
+ "id" "3792"
+ side
+ {
+ "id" "1107"
+ "plane" "(160 48 32) (160 64 32) (176 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 96] 0.25"
+ "vaxis" "[0 -1 0 -256] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1106"
+ "plane" "(160 64 0) (160 48 0) (176 48 0)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 96] 0.25"
+ "vaxis" "[0 -1 0 -256] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1105"
+ "plane" "(160 48 0) (160 64 0) (160 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 256] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1104"
+ "plane" "(176 64 0) (176 48 0) (176 48 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 256] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1103"
+ "plane" "(160 64 0) (176 64 0) (176 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 96] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1102"
+ "plane" "(176 48 0) (160 48 0) (160 48 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 96] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "3806"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "200 56 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "spr_rand_*,FireUser2,,0,-1"
+ }
+ solid
+ {
+ "id" "3807"
+ side
+ {
+ "id" "1119"
+ "plane" "(192 48 32) (192 64 32) (208 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 480] 0.25"
+ "vaxis" "[0 -1 0 -256] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1118"
+ "plane" "(192 64 0) (192 48 0) (208 48 0)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 480] 0.25"
+ "vaxis" "[0 -1 0 -256] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1117"
+ "plane" "(192 48 0) (192 64 0) (192 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 256] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1116"
+ "plane" "(208 64 0) (208 48 0) (208 48 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 256] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1115"
+ "plane" "(192 64 0) (208 64 0) (208 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 480] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1114"
+ "plane" "(208 48 0) (192 48 0) (192 48 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 480] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "3841"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "232 56 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "spr_rand_*,FireUser3,,0,-1"
+ }
+ solid
+ {
+ "id" "3842"
+ side
+ {
+ "id" "1131"
+ "plane" "(224 48 32) (224 64 32) (240 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 352] 0.25"
+ "vaxis" "[0 -1 0 -256] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1130"
+ "plane" "(224 64 0) (224 48 0) (240 48 0)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 352] 0.25"
+ "vaxis" "[0 -1 0 -256] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1129"
+ "plane" "(224 48 0) (224 64 0) (224 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 256] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1128"
+ "plane" "(240 64 0) (240 48 0) (240 48 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 256] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1127"
+ "plane" "(224 64 0) (240 64 0) (240 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 352] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1126"
+ "plane" "(240 48 0) (224 48 0) (224 48 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 352] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "4750"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_18"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "352 16 80"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "5497"
+ "classname" "comp_case"
+ "ctrl_type" "0"
+ "ctrl_value" "1"
+ "mode" "casefold"
+ "multiplecasesallowed" "0"
+ "targetname" "case_random_b"
+ connections
+ {
+ "OnCase01" "!self,Color,255 0 0,0,-1"
+ "OnCase02" "!self,Color,0 255 0,0,-1"
+ "OnCase03" "!self,Color,0 0 255,0,-1"
+ "OnCase06" "!self,Color,255 255 0,0,-1"
+ "OnCase05" "!self,Color,255 0 255,0,-1"
+ "OnCase04" "!self,Color,0 255 255,0,-1"
+ "OnCase07" "!self,Color,255 255 255,0,-1"
+ "OnCase08" "!self,Color,16 16 16,0,-1"
+ "OnCase10" "!self,Color,255 128 64,0,-1"
+ "OnCase09" "!self,Color,64 128 255,0,-1"
+ "OnCase11" "!self,Color,128 255 64,0,-1"
+ "OnCase12" "!self,Color,64 255 128,0,-1"
+ }
+ "origin" "216 72 8"
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "comments" "Each sprite fires PickRandom, so they get random colours added for the OnUserX outputs. The choice is consistent across compiles though. "
+ "logicalpos" "[0 10000]"
+ }
+}
+entity
+{
+ "id" "5672"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_19"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "352 16 112"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "5676"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_20"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "320 16 112"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "5680"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_21"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "288 16 112"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "5684"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_22"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "256 16 112"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "5688"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_23"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "224 16 112"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "5692"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_24"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "192 16 112"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "5696"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_25"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "160 16 112"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "5700"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_26"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "128 16 112"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "5704"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_27"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "96 16 112"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "5860"
+ "classname" "comp_case"
+ "case01" "5"
+ "case02" "5"
+ "case03" "5"
+ "case04" "1"
+ "case05" "1"
+ "case06" "1"
+ "case07" "0.1"
+ "ctrl_type" "0"
+ "ctrl_value" "1"
+ "mode" "randweight"
+ "multiplecasesallowed" "0"
+ "targetname" "case_random_c"
+ connections
+ {
+ "OnCase01" "!self,Color,255 0 0,0,-1"
+ "OnCase02" "!self,Color,0 255 0,0,-1"
+ "OnCase03" "!self,Color,0 0 255,0,-1"
+ "OnCase06" "!self,Color,255 255 0,0,-1"
+ "OnCase05" "!self,Color,255 0 255,0,-1"
+ "OnCase04" "!self,Color,0 255 255,0,-1"
+ "OnCase07" "!self,Color,255 255 255,0,-1"
+ }
+ "origin" "280 72 8"
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "comments" "This demonstrates weighted randomisation."
+ "logicalpos" "[0 10000]"
+ }
+}
+entity
+{
+ "id" "5910"
+ "classname" "func_button"
+ "_minlight" "0"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "health" "0"
+ "lip" "20"
+ "locked_sound" "0"
+ "movedir" "90 0 0"
+ "origin" "280 56 16"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "0"
+ "sounds" "0"
+ "spawnflags" "1024"
+ "speed" "20"
+ "unlocked_sound" "0"
+ "vrad_brush_cast_shadows" "1"
+ "wait" "0.5"
+ connections
+ {
+ "OnPressed" "spr_rand_*,FireUser4,,0,-1"
+ }
+ solid
+ {
+ "id" "5911"
+ side
+ {
+ "id" "1215"
+ "plane" "(272 48 32) (272 64 32) (288 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 160] 0.25"
+ "vaxis" "[0 -1 0 -256] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1214"
+ "plane" "(272 64 0) (272 48 0) (288 48 0)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 160] 0.25"
+ "vaxis" "[0 -1 0 -256] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1213"
+ "plane" "(272 48 0) (272 64 0) (272 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 256] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1212"
+ "plane" "(288 64 0) (288 48 0) (288 48 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[0 1 0 256] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1211"
+ "plane" "(272 64 0) (288 64 0) (288 64 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 160] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ side
+ {
+ "id" "1210"
+ "plane" "(288 48 0) (272 48 0) (272 48 32)"
+ "material" "DEV/DEV_MEASUREWALL01A"
+ "uaxis" "[1 0 0 160] 0.25"
+ "vaxis" "[0 0 -1 0] 0.25"
+ "rotation" "0"
+ "lightmapscale" "16"
+ "smoothing_groups" "0"
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ }
+ }
+ editor
+ {
+ "color" "220 30 220"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2500]"
+ }
+}
+entity
+{
+ "id" "6161"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_28"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "96 16 144"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6165"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_29"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "128 16 144"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6169"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_30"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "160 16 144"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6173"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_31"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "192 16 144"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6177"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_32"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "224 16 144"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6181"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_33"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "256 16 144"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6185"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_34"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "288 16 144"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6189"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_35"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "320 16 144"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6193"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_36"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "352 16 144"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6214"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_37"
+ connections
+ {
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ }
+ "origin" "32 16 48"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6218"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_38"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "32 16 80"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6222"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_39"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "32 16 112"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6226"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_40"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "32 16 144"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6231"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_41"
+ connections
+ {
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ }
+ "origin" "64 16 48"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6235"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_42"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "64 16 80"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6239"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_43"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "64 16 112"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+entity
+{
+ "id" "6243"
+ "classname" "env_sprite"
+ "angles" "0 0 0"
+ "disablereceiveshadows" "0"
+ "framerate" "10.0"
+ "glowproxysize" "20"
+ "hdrcolorscale" "0.7"
+ "model" "sprites/glow01.vmt"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "renderfx" "0"
+ "rendermode" "9"
+ "scale" "0.75"
+ "spawnflags" "1"
+ "targetname" "spr_rand_44"
+ connections
+ {
+ "OnUser1" "case_random_a,PickRandom,,0,-1"
+ "OnUser2" "case_random_b,PickRandom,,0,-1"
+ "OnUser4" "case_random_c,PickRandom,,0,-1"
+ "OnUser3" "case_random_a,PickRandom,,0,-1"
+ }
+ "origin" "64 16 144"
+ editor
+ {
+ "color" "20 140 20"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 1500]"
+ }
+}
+cameras
+{
+ "activecamera" "-1"
+}
+cordon
+{
+ "mins" "(-1024 -1024 -1024)"
+ "maxs" "(1024 1024 1024)"
+ "active" "0"
+}
diff --git a/examples/hadd_sequential_call.vmf b/examples/hadd_sequential_call.vmf
index 130310f3b..e70e14b96 100644
--- a/examples/hadd_sequential_call.vmf
+++ b/examples/hadd_sequential_call.vmf
@@ -2338,7 +2338,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -2535,7 +2535,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -2732,7 +2732,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -2929,7 +2929,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -3126,7 +3126,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -3323,7 +3323,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -3520,7 +3520,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -3717,7 +3717,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -3914,7 +3914,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -4111,7 +4111,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -4308,7 +4308,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -4505,7 +4505,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -4702,7 +4702,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -4899,7 +4899,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -5096,7 +5096,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -5293,7 +5293,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -5490,7 +5490,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -5687,7 +5687,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -5884,7 +5884,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -6081,7 +6081,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -6278,7 +6278,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -6475,7 +6475,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -6672,7 +6672,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -6869,7 +6869,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -7066,7 +7066,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -7263,7 +7263,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -7460,7 +7460,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -7657,7 +7657,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -7854,7 +7854,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -8051,7 +8051,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -8248,7 +8248,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -8445,7 +8445,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -8642,7 +8642,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -9331,7 +9331,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -9530,7 +9530,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -9729,7 +9729,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -9928,7 +9928,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -10127,7 +10127,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -10326,7 +10326,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -10525,7 +10525,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -10724,7 +10724,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -10923,7 +10923,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -11122,7 +11122,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -11321,7 +11321,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -11520,7 +11520,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -11719,7 +11719,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -11918,7 +11918,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -12117,7 +12117,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -12316,7 +12316,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -12515,7 +12515,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -12714,7 +12714,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -12913,7 +12913,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -13112,7 +13112,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -13311,7 +13311,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -13510,7 +13510,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -13709,7 +13709,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -13908,7 +13908,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -14107,7 +14107,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -14306,7 +14306,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -14505,7 +14505,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -14704,7 +14704,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -14903,7 +14903,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -15102,7 +15102,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -15301,7 +15301,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -15500,7 +15500,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -15699,7 +15699,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -15898,7 +15898,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -16097,7 +16097,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -16296,7 +16296,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -16495,7 +16495,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -16694,7 +16694,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -16893,7 +16893,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -17092,7 +17092,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -17291,7 +17291,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -17490,7 +17490,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -17689,7 +17689,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -17888,7 +17888,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -18087,7 +18087,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -18286,7 +18286,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -18485,7 +18485,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -18684,7 +18684,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -18883,7 +18883,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -19082,7 +19082,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -19281,7 +19281,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -19497,7 +19497,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -19696,7 +19696,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -19895,7 +19895,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -20094,7 +20094,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -20293,7 +20293,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -20492,7 +20492,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -20855,7 +20855,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -21054,7 +21054,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -21253,7 +21253,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -21452,7 +21452,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -21651,7 +21651,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -21850,7 +21850,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -21973,7 +21973,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -22096,7 +22096,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -22219,7 +22219,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -22342,7 +22342,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -22541,7 +22541,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -22740,7 +22740,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -22939,7 +22939,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -23138,7 +23138,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -23337,7 +23337,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -23536,7 +23536,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -23735,7 +23735,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -23934,7 +23934,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -24133,7 +24133,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -24332,7 +24332,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -24531,7 +24531,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -24730,7 +24730,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -24929,7 +24929,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -25128,7 +25128,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -25327,7 +25327,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -25526,7 +25526,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -25725,7 +25725,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -25924,7 +25924,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -26123,7 +26123,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -26246,7 +26246,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -26369,7 +26369,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -26568,7 +26568,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -26767,7 +26767,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -26890,7 +26890,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -27013,7 +27013,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -27212,7 +27212,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -27411,7 +27411,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -27610,7 +27610,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -27809,7 +27809,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
@@ -28008,7 +28008,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 0 0"
"renderfx" "0"
diff --git a/examples/instances/unique_state_btn.vmf b/examples/instances/unique_state_btn.vmf
index 660fa314e..85eed1391 100644
--- a/examples/instances/unique_state_btn.vmf
+++ b/examples/instances/unique_state_btn.vmf
@@ -326,7 +326,7 @@ entity
"mincpulevel" "0"
"mindxlevel" "0"
"mingpulevel" "0"
- "model" "sprites/glow01.spr"
+ "model" "sprites/glow01.vmt"
"renderamt" "255"
"rendercolor" "255 50 50"
"renderfx" "0"
diff --git a/fgd/base_entity.fgd b/fgd/base_entity.fgd
index 7192e2067..6f5f8e090 100644
--- a/fgd/base_entity.fgd
+++ b/fgd/base_entity.fgd
@@ -39,7 +39,7 @@
fadescale(float) : "Fade Scale": 0
parentname(target_destination) : "Parent"
- parent_attachment_point[srctools](string) : "Attachment Point"
+ parent_attachment_point[srctools](string) : "[HA] Attachment Point"
responseContext(string) : "Response Context" : ""
addon(string) : "AI Addon" : : "Broken ASW feature."
diff --git a/fgd/bases/BaseBeam.fgd b/fgd/bases/BaseBeam.fgd
index e19210d3c..9266706af 100644
--- a/fgd/bases/BaseBeam.fgd
+++ b/fgd/bases/BaseBeam.fgd
@@ -14,7 +14,7 @@
framerate(integer) : "Frames per 10 seconds" : 0 : "Framerate at which the beam texture should animate, if it has multiple frames."
framestart(integer) : "Starting Frame" : 0 : "The frame to start the beam texture on."
- texture(sprite) : "Sprite Name" : "sprites/laserbeam.spr" : "The material used to draw the beam."
+ texture(sprite) : "Sprite Name" : "sprites/laserbeam.vmt" : "The material used to draw the beam."
texturescroll(integer) : "Texture Scroll Rate (0-100)" : 35 : "Rate at which the beam texture should scroll along the beam."
damage(string) : "Damage / second" : "0" : "How much damage this beam does per second to things while active. For continuous damage, the value should be greater than 10 or it may not work."
diff --git a/fgd/bases/BaseEntity.fgd b/fgd/bases/BaseEntity.fgd
index 85260c0d7..8e5171af2 100644
--- a/fgd/bases/BaseEntity.fgd
+++ b/fgd/bases/BaseEntity.fgd
@@ -1,5 +1,5 @@
// Special case - entities that aren't quite brushes or point ents.
-@BaseClass base(BaseEntityIO) = BaseEntity
+@BaseClass base(BaseEntityInputs, BaseEntityOutputs) = BaseEntity
[
targetname(target_source) : "Name" : : "The name that other entities refer to this entity by."
globalname(string) : "Global Entity Name" : : "Name by which this entity is linked to another entity in a different map. " +
@@ -9,8 +9,8 @@
vscripts[VSCRIPT](scriptlist) : "Entity Scripts" : : "Name(s) of script files that are executed after all entities have spawned."
thinkfunction[VSCRIPT](string) : "Script think function" : : "Name of a function in this entity's script scope which will be called automatically."
- vscript_init_code[+VSCRIPT, +srctools](string) : "Init Code" : : "This code will be executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings."
- vscript_init_code2[+VSCRIPT, +srctools](string) : "Init Code 2" : : "This code will be the second line executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings. " +
+ vscript_init_code[+VSCRIPT, +srctools](string) : "[HA] Init Code" : : "This code will be executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings."
+ vscript_init_code2[+VSCRIPT, +srctools](string) : "[HA] Init Code 2" : : "This code will be the second line executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings. " +
"Additional Init Code keyvalues can be added with SmartEdit off."
// etc
diff --git a/fgd/bases/BaseEntityAnimating.fgd b/fgd/bases/BaseEntityAnimating.fgd
index ac3ccc884..aec3785c5 100644
--- a/fgd/bases/BaseEntityAnimating.fgd
+++ b/fgd/bases/BaseEntityAnimating.fgd
@@ -63,9 +63,13 @@
fadescale(float) : "Fade Scale" : : "If specified in the worldspawn, or if the engine is running below DirectX 8, entities will fade out even if the fade distances above aren't specified. This value gives more control over when this happens: numbers smaller than 1 cause the entity to fade out at further distances, and greater than 1 cause it to fade out at closer distances. Using 0 turns off the forced fade altogether."
shadowcastdist[complete](integer) : "Shadow Cast Distance" : 0 : "Sets how far the entity casts dynamic shadows, in units. 0 means default distance from the shadow_control entity."
- disableshadows(boolean) : "Disable Shadows?" : 0 : "Prevent the entity from creating cheap render-to-texture/dynamic shadows."
- disablereceiveshadows(boolean) : "Disable Receiving Shadows?" : 0 : "Prevents dynamic shadows (e.g. player and prop shadows) from appearing on this entity."
- disableshadowdepth[since_L4D, +complete](boolean) : "Disable ShadowDepth" : 0 : "Used to disable rendering into shadow depth (for flashlight) for this entity."
+
+ // Disambiguate from projected textures if present.
+ disableshadows[until_L4D](boolean) : "Disable Producing Shadows?" : 0 : "Prevent the entity from creating cheap render-to-texture/dynamic shadows."
+ disableshadows[since_L4D](boolean) : "Disable Producing Cheap Shadows?" : 0 : "Prevent the entity from creating cheap render-to-texture/dynamic shadows."
+
+ disablereceiveshadows(boolean) : "Disable Receiving Shadows?" : 0 : "Prevents shadows (cheap & projected texture) from appearing on this entity."
+ disableshadowdepth[since_L4D](boolean) : "No Affecting Proj Texs" : 0 : "Prevent this entity from affecting projected texture shadows."
shadowdepthnocache[since_L4D, +complete](choices) : "Projected Texture Cache" : "0" : "Used to hint projected texture system whether it is sufficient to cache shadow volume of this entity or to force render it every frame instead." =
[
0: "Default"
@@ -73,7 +77,7 @@
2: "Cache it = render only once"
]
shadowdepthnocache[engine](integer): "Projected Texture Cache": 0
- disableflashlight[since_L4D, MBase](boolean) : "Disable flashlight" : 0 : "Used to disable flashlight (env_projectedtexture) lighting and shadows on this entity."
+ disableflashlight[since_L4D, MBase](boolean) : "No Recieving Proj Texs" : 0 : "Used to disable flashlight (env_projectedtexture) lighting and shadows on this entity."
linedivider_anim[!engine](string) readonly : "----------------------------------------------------------------------------------------------------------" : ""
@@ -93,8 +97,8 @@
input DisableShadow(void) : "Allows the entity to draw a render target (dynamic) shadow."
input EnableShadow(void) : "Prevents the entity from drawing a render target (dynamic) shadow."
- input DisableReceivingFlashlight[since_L4D, MBase](void) : "This object will not recieve light or shadows from projected textures (flashlights)."
- input EnableReceivingFlashlight[since_L4D, MBase](void) : "This object may recieve light or shadows from projected textures (flashlights)."
+ input DisableReceivingFlashlight[since_L4D, MBase, GMod](void) : "This object will not recieve light or shadows from projected textures (flashlights)."
+ input EnableReceivingFlashlight[since_L4D, MBase, GMod](void) : "This object may recieve light or shadows from projected textures (flashlights)."
input AlternativeSorting[SINCE_EP1](boolean) : "Used to attempt to fix sorting problems when rendering. True activates, false deactivates"
input SetModelScale[EP1, EP2, MESA, !GMod](vector) : "Takes two values separated by a space. The first is the target model scale. " +
diff --git a/fgd/bases/BaseEntityBrush.fgd b/fgd/bases/BaseEntityBrush.fgd
index 5ef9c2523..16b8ad3fd 100644
--- a/fgd/bases/BaseEntityBrush.fgd
+++ b/fgd/bases/BaseEntityBrush.fgd
@@ -1,4 +1,4 @@
-@BaseClass base(BaseEntityIO) = BaseEntityBrush
+@BaseClass base(BaseEntityInputs, BaseEntityOutputs) = BaseEntityBrush
[
targetname(target_source) : "Name" : : "The name that other entities refer to this entity by."
globalname(string) : "Global Entity Name" : : "Name by which this entity is linked to another entity in a different map. " +
@@ -9,15 +9,15 @@
parentname[!srctools](target_destination) : "Parent" : : "The name of this entity's parent in the movement hierarchy. Entities with parents move with their parent. Set an attachment point via 'parentname,attachment'."
parentname[srctools](target_destination) : "Parent" : : "The name of this entity's parent in the movement hierarchy. Entities with parents move with their parent."
- parent_attachment_point[srctools](string) : "Attachment Point" : : "If set, attach to this attachment point on the parent during spawn."
+ parent_attachment_point[srctools](string) : "[HA] Attachment Point" : : "If set, attach to this attachment point on the parent during spawn."
linedivider_vscript[+VSCRIPT, -engine](string) readonly : "-------------------------------------------------------------------------------------------------------" : ""
vscripts[VSCRIPT](scriptlist) : "Entity Scripts" : : "Name(s) of script files that are executed after all entities have spawned."
thinkfunction[VSCRIPT](string) : "Script think function" : : "Name of a function in this entity's script scope which will be called automatically."
- vscript_init_code[+VSCRIPT, +srctools](string) : "Init Code" : : "This code will be executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings."
- vscript_init_code2[+VSCRIPT, +srctools](string) : "Init Code 2" : : "This code will be the second line executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings. " +
+ vscript_init_code[+VSCRIPT, +srctools](string) : "[HA] Init Code" : : "This code will be executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings."
+ vscript_init_code2[+VSCRIPT, +srctools](string) : "[HA] Init Code 2" : : "This code will be the second line executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings. " +
"Additional Init Code keyvalues can be added with SmartEdit off."
// etc
@@ -60,8 +60,8 @@
input SetParentAttachment(string) : "Change this entity to attach to a specific attachment point on its parent. Entities must be parented before being sent this input. The parameter passed in should be the name of the attachment."
input SetParentAttachmentMaintainOffset(string) : "Change this entity to attach to a specific attachment point on it's parent. Entities must be parented before being sent this input. The parameter passed in should be the name of the attachment. The entity will maintain it's position relative to the parent at the time it is attached."
input ClearParent(void) : "Removes this entity from the the movement hierarchy, leaving it free to move independently."
- input SetLocalAngles[since_ASW, MBase](vector) : "Sets the rotation of the entity relative to the parent's rotation."
- input SetLocalOrigin[since_ASW, MBase](vector) : "Sets the position of the entity relative to its parent if one exists. Otherwise relative to the world."
+ input SetLocalAngles[since_ASW, MBase, GMod](vector) : "Sets the rotation of the entity relative to the parent's rotation."
+ input SetLocalOrigin[since_ASW, MBase, GMod](vector) : "Sets the position of the entity relative to its parent if one exists. Otherwise relative to the world."
input SetAbsAngles[MBase](vector) : "Set this entity's angles, always relative to the world origin."
input FreeChildren[MBase](void) : "Unparents all direct children of this entity."
diff --git a/fgd/bases/BaseEntityIO.fgd b/fgd/bases/BaseEntityInputs.fgd
similarity index 76%
rename from fgd/bases/BaseEntityIO.fgd
rename to fgd/bases/BaseEntityInputs.fgd
index ecb58e4cb..669013188 100644
--- a/fgd/bases/BaseEntityIO.fgd
+++ b/fgd/bases/BaseEntityInputs.fgd
@@ -1,7 +1,6 @@
-// IO available on all entities.
-@BaseClass = BaseEntityIO
- [
- // Inputs
+@BaseClass = BaseEntityInputs
+[
+ // Inputs
input Kill(void) : "Removes this entity from the world."
input KillHierarchy(void) : "Removes this entity and all its children from the world."
@@ -17,23 +16,16 @@
input DispatchEffect[until_L4D](string) : "Dispatch an effect from the entity's origin. See https://developer.valvesoftware.com/wiki/List_of_Client_Effects"
input RunScriptFile[VSCRIPT](string) : "Execute a game script file from disk."
- input RunScriptCode[+VSCRIPT, -srctools, -TF2](script) : "Execute a string of script source code."
- input RunScriptCode[+VSCRIPT, +srctools, -TF2](script) : "Execute a string of script source code. Backtick ( ` ) characters will be converted to quotes in-game for strings."
+ input RunScriptCode[+VSCRIPT, -srctools, -TF2](script) : "Execute a string of script source code. Using double quote characters will corrupt the VMF, so strings cannot be passed in."
+ input RunScriptCode[+VSCRIPT, +srctools, -TF2](script) : "Execute a string of script source code. Using double quote characters will corrupt the VMF, use backticks ( ` ) instead if you need to pass in a string."
// TF2 does this in game code.
- input RunScriptCode[+TF2, +VSCRIPT](script) : "Execute a string of script source code. Backtick ( ` ) characters will be converted to quotes in-game for strings."
+ input RunScriptCode[+TF2, +VSCRIPT](script) : "Execute a string of script source code. Using double quote characters will corrupt the VMF, use backticks ( ` ) instead if you need to pass in a string."
input RunScriptCodeQuotable[+MBase, +VSCRIPT](string) : "Execute a string of script source code which converts double apostrophes ('') to quotation marks for strings."
input CallScriptFunction[VSCRIPT](string) : "Execute the given function name."
input ClearScriptScope[+MBase, +VSCRIPT](void) : "Clears this entity's script scope"
input TerminateScriptScope[+TF2, +VSCRIPT](void) : "Terminates the script scope of the entity."
- // Outputs
- output OnUser1(void) : "Fired in response to FireUser1 input."
- output OnUser2(void) : "Fired in response to FireUser2 input."
- output OnUser3(void) : "Fired in response to FireUser3 input."
- output OnUser4(void) : "Fired in response to FireUser4 input."
- output OnKilled[MBase, L4D](void) : "Fired when the entity is killed and removed from the game."
-
- // Mapbase BaseEntity changes:
+ // Mapbase Inputs:
input PassUser1[MBase](string) : "Causes this entity's OutUser1 output to be fired, passing along the parameter unchanged."
input PassUser2[MBase](string) : "Causes this entity's OutUser2 output to be fired, passing along the parameter unchanged."
input PassUser3[MBase](string) : "Causes this entity's OutUser3 output to be fired, passing along the parameter unchanged."
@@ -50,8 +42,8 @@
input AcceptInput[MBase](string) : "Fires the named input on this entity. Format: '
:
:::' (SetTarget:cheese). Everything beyond the input name is optional. Mind the fact this is arranged differently from FireOutput, having the parameter right after the input name."
input CancelPending[MBase](void) : "Cancels any events fired by this entity that are currently pending in the I/O event queue."
- input AddSpawnFlags[MBase](integer) : "Adds spawnflag(s) to this entity. Many spawnflags have their respective numbers suffixed in this FGD."
- input RemoveSpawnFlags[MBase](integer) : "Removes spawnflag(s) to this entity. Many spawnflags have their respective numbers suffixed in this FGD."
+ input AddSpawnFlags[MBase](integer) : "Adds spawnflag(s) to this entity. Spawnflags have their respective numbers prefixed in this FGD."
+ input RemoveSpawnFlags[MBase](integer) : "Removes spawnflag(s) to this entity. Spawnflags have their respective numbers prefixed in this FGD."
input AddSolidFlags[MBase](integer) : "Adds solid flags to this entity."
input RemoveSolidFlags[MBase](integer) : "Removes solid flags from this entity."
@@ -62,12 +54,7 @@
input SetTarget[MBase](target_destination) : "Sets this entity's target. This is specific to certain entities, particularly logic entities that involve a target."
input SetOwnerEntity[MBase](target_destination) : "Sets this entity's owner entity. This has nothing to do with parenting and has more to do with collision and kill credits."
- input SetThinkNull[MBase](void) : "Sets this entity's general think function to null. Behavior varies from entity to entity.."
+ input SetThinkNull[MBase](void) : "Sets this entity's general think function to null. Behavior varies from entity to entity."
input Use[MBase](void) : "More or less replicates the player interacting with an entity. (+USE)"
-
- output OutUser1[MBase](string) : "Fires in response to PassUser1 input, with the parameter passed through unchanged."
- output OutUser2[MBase](string) : "Fires in response to PassUser2 input, with the parameter passed through unchanged."
- output OutUser3[MBase](string) : "Fires in response to PassUser3 input, with the parameter passed through unchanged."
- output OutUser4[MBase](string) : "Fires in response to PassUser4 input, with the parameter passed through unchanged."
- ]
+]
\ No newline at end of file
diff --git a/fgd/bases/BaseEntityOutputs.fgd b/fgd/bases/BaseEntityOutputs.fgd
new file mode 100644
index 000000000..4fd8eb1c6
--- /dev/null
+++ b/fgd/bases/BaseEntityOutputs.fgd
@@ -0,0 +1,15 @@
+@BaseClass = BaseEntityOutputs
+[
+ // Outputs
+ output OnUser1(void) : "Fired in response to FireUser1 input."
+ output OnUser2(void) : "Fired in response to FireUser2 input."
+ output OnUser3(void) : "Fired in response to FireUser3 input."
+ output OnUser4(void) : "Fired in response to FireUser4 input."
+ output OnKilled[MBase, L4D](void) : "Fired when the entity is killed and removed from the game."
+
+ // Mapbase Outputs
+ output OutUser1[MBase](string) : "Fires in response to PassUser1 input, with the parameter passed through unchanged."
+ output OutUser2[MBase](string) : "Fires in response to PassUser2 input, with the parameter passed through unchanged."
+ output OutUser3[MBase](string) : "Fires in response to PassUser3 input, with the parameter passed through unchanged."
+ output OutUser4[MBase](string) : "Fires in response to PassUser4 input, with the parameter passed through unchanged."
+]
\ No newline at end of file
diff --git a/fgd/bases/BaseEntityPhysics.fgd b/fgd/bases/BaseEntityPhysics.fgd
index cb80c583e..23fb360c7 100644
--- a/fgd/bases/BaseEntityPhysics.fgd
+++ b/fgd/bases/BaseEntityPhysics.fgd
@@ -64,4 +64,5 @@
// Outputs
output OnIgnite(void) : "Fired when this object catches fire."
+ output OnFizzled[P2](void) : "Fired when this object is fizzled."
]
diff --git a/fgd/bases/BaseEntityPoint.fgd b/fgd/bases/BaseEntityPoint.fgd
index 8c16ec3f1..0a7d54bf8 100644
--- a/fgd/bases/BaseEntityPoint.fgd
+++ b/fgd/bases/BaseEntityPoint.fgd
@@ -1,4 +1,4 @@
-@BaseClass base(BaseEntityIO) = BaseEntityPoint
+@BaseClass base(BaseEntityInputs, BaseEntityOutputs) = BaseEntityPoint
[
targetname(target_source) : "Name" : : "The name that other entities refer to this entity by."
globalname(string) : "Global Entity Name" : : "Name by which this entity is linked to another entity in a different map. " +
@@ -12,15 +12,15 @@
parentname[!srctools](target_destination) : "Parent" : : "The name of this entity's parent in the movement hierarchy. Entities with parents move with their parent. Set an attachment point via 'parentname,attachment'."
parentname[srctools](target_destination) : "Parent" : : "The name of this entity's parent in the movement hierarchy. Entities with parents move with their parent."
- parent_attachment_point[srctools](string) : "Attachment Point" : : "If set, attach to this attachment point on the parent during spawn."
+ parent_attachment_point[srctools](string) : "[HA] Attachment Point" : : "If set, attach to this attachment point on the parent during spawn."
linedivider_vscript[+VSCRIPT, !engine](string) readonly : "-------------------------------------------------------------------------------------------------------" : ""
vscripts[VSCRIPT](scriptlist) : "Entity Scripts" : : "Name(s) of script files that are executed after all entities have spawned."
thinkfunction[VSCRIPT](string) : "Script think function" : : "Name of a function in this entity's script scope which will be called automatically."
- vscript_init_code[+VSCRIPT, +srctools](string) : "Init Code" : : "This code will be executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings."
- vscript_init_code2[+VSCRIPT, +srctools](string) : "Init Code 2" : : "This code will be the second line executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings. " +
+ vscript_init_code[+VSCRIPT, +srctools](string) : "[HA] Init Code" : : "This code will be executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings."
+ vscript_init_code2[+VSCRIPT, +srctools](string) : "[HA] Init Code 2" : : "This code will be the second line executed after the Entity Scripts option. Backtick ( ` ) characters will be converted to quotes in-game for strings. " +
"Additional Init Code keyvalues can be added with SmartEdit off."
// etc
@@ -38,8 +38,8 @@
input SetParentAttachment(string) : "Change this entity to attach to a specific attachment point on its parent. Entities must be parented before being sent this input. The parameter passed in should be the name of the attachment."
input SetParentAttachmentMaintainOffset(string) : "Change this entity to attach to a specific attachment point on it's parent. Entities must be parented before being sent this input. The parameter passed in should be the name of the attachment. The entity will maintain it's position relative to the parent at the time it is attached."
input ClearParent(void) : "Removes this entity from the the movement hierarchy, leaving it free to move independently."
- input SetLocalAngles[since_ASW, MBase](vector) : "Sets the rotation of the entity relative to the parent's rotation."
- input SetLocalOrigin[since_ASW, MBase](vector) : "Sets the position of the entity relative to its parent if one exists. Otherwise relative to the world."
+ input SetLocalAngles[since_ASW, MBase, GMod](vector) : "Sets the rotation of the entity relative to the parent's rotation."
+ input SetLocalOrigin[since_ASW, MBase, GMod](vector) : "Sets the position of the entity relative to its parent if one exists. Otherwise relative to the world."
input SetAbsAngles[MBase](vector) : "Set this entity's angles, always relative to the world origin."
// Mapbase BaseEntity changes:
diff --git a/fgd/bases/BaseEntityVisBrush.fgd b/fgd/bases/BaseEntityVisBrush.fgd
index bc5fe31c9..55e7d731a 100644
--- a/fgd/bases/BaseEntityVisBrush.fgd
+++ b/fgd/bases/BaseEntityVisBrush.fgd
@@ -48,8 +48,8 @@
// Inputs
input DisableShadow(void) : "Allows the entity to draw a render target (dynamic) shadow."
input EnableShadow(void) : "Prevents the entity from drawing a render target (dynamic) shadow."
- input DisableReceivingFlashlight[since_L4D](void) : "This object will not recieve light or shadows from projected textures (flashlights)."
- input EnableReceivingFlashlight[since_L4D](void) : "This object may recieve light or shadows from projected textures (flashlights)."
+ input DisableReceivingFlashlight[since_L4D, GMod](void) : "This object will not recieve light or shadows from projected textures (flashlights)."
+ input EnableReceivingFlashlight[since_L4D, GMod](void) : "This object may recieve light or shadows from projected textures (flashlights)."
input EnableDamageForces(void) : "Damaging the entity applies physics forces to it."
input DisableDamageForces(void) : "Damaging the entity does not apply physics forces to it."
diff --git a/fgd/bases/BaseLight.fgd b/fgd/bases/BaseLight.fgd
index a4c1b1fa7..e32f803ba 100644
--- a/fgd/bases/BaseLight.fgd
+++ b/fgd/bases/BaseLight.fgd
@@ -1,32 +1,14 @@
-@BaseClass
+@BaseClass
sphere(_fifty_percent_distance)
sphere(_zero_percent_distance)
sphere(_distance)
color(255 255 0)
-= BaseLight
+= BaseLight: "Parameters common to light and light_spot."
[
_light(color255) : "Brightness" : "255 255 255 200" : "Color and brightness of the light."
_lightHDR(color255) : "BrightnessHDR" : "-1 -1 -1 1"
_lightscaleHDR(float) : "BrightnessScaleHDR" : "1" : "Amount to scale the light by when compiling for HDR."
- style[engine](integer) : "Appearance" : 0
- style(choices) : "Appearance" : 0 =
- [
- 0 : "Normal"
- 10: "Fluorescent flicker"
- 2 : "Slow, strong pulse"
- 11: "Slow pulse, noblack"
- 5 : "Gentle pulse"
- 1 : "Flicker A"
- 6 : "Flicker B"
- 3 : "Candle A"
- 7 : "Candle B"
- 8 : "Candle C"
- 4 : "Fast strobe"
- 9 : "Slow strobe"
- 12 : "Underwater light mutation"
- ]
- pattern(string) : "Custom Appearance" : "" : "Set a custom pattern of light brightness for this light. Pattern format is a string of characters, where 'a' is total darkness, 'z' fully bright. i.e. 'aaggnnttzz' would be a steppy fade in from dark to light."
_constant_attn(string) : "Constant" : "0"
_linear_attn(string) : "Linear" : "0"
_quadratic_attn(string) : "Quadratic" : "1"
@@ -35,19 +17,4 @@
_hardfalloff(integer) : "Hard Falloff" : 0 : "If set, causes lights to fall to exactly zero beyond the zero percent distance. May cause unrealistic lightijng if not used carefully."
_distance(integer) : "Maximum Distance" : 0 : "The distance that light is allowed to cast."
-
- // GMOD: GOPORT
- _castentityshadow[engine](boolean)
- _castentityshadow[GMod](Choices) : "Cast entity shadows" : 0 : "Objects illuminated by this light will cast a directional shadow." =
- [
- 0 : "Don't affect entity shadow angles"
- 1 : "Affect entity shadow angles"
- ]
-
- // Inputs
- input TurnOn(void) : "Turn the light on."
- input TurnOff(void) : "The the light off."
- input Toggle(void) : "Toggle the light's current state."
- input SetPattern(string) : "Set a custom pattern of light brightness for this light. Pattern format is a string of characters, where 'a' is total darkness, 'z' fully bright. i.e. 'aaggnnttzz' would be a steppy fade in from dark to light."
- input FadeToPattern(string) : "Fades from first value in old pattern, to first value in the new given pattern. Pattern format is a string of characters, where 'a' is total darkness, 'z' fully bright. i.e. 'aaggnnttzz' would be a steppy fade in from dark to light."
]
diff --git a/fgd/bases/BaseMesaWeaponPickup.fgd b/fgd/bases/BaseMesaWeaponPickup.fgd
new file mode 100644
index 000000000..f4fadc528
--- /dev/null
+++ b/fgd/bases/BaseMesaWeaponPickup.fgd
@@ -0,0 +1,8 @@
+@BaseClass base(BaseMesaPickup) appliesto(Mesa) = BaseMesaWeaponPickup
+ [
+ @resources
+ [
+ // These item_weapon_XXX ents should include the relevant weapon script.
+ func weapon_script
+ ]
+ ]
diff --git a/fgd/bases/BaseObject.fgd b/fgd/bases/BaseObject.fgd
index c3316eef0..de7f8553b 100644
--- a/fgd/bases/BaseObject.fgd
+++ b/fgd/bases/BaseObject.fgd
@@ -3,8 +3,18 @@
teamnum[engine](integer) : "Team" : 2
teamnum(choices) : "Team" : 2 : "Team" =
[
- 2: "Red"
- 3: "Blue"
+ 0: "Unassigned" [+complete]
+ 1: "Spectators" [+complete]
+ 2: "RED"
+ 3: "BLU"
+ ]
+
+ defaultupgrade[engine](integer) : "Starting Upgrade Level" : 0
+ defaultupgrade(choices) : "Starting Upgrade Level" : "0" =
+ [
+ 0: "Level 1"
+ 1: "Level 2"
+ 2: "Level 3"
]
spawnflags(flags) : "spawnflags" =
@@ -13,8 +23,8 @@
]
// Inputs
- input SetBuilder(string) : "Sets the builder of this object to the player given (from an output)"
- input SetSolidToPlayer(string) : "Sets the builder solid to the player given (from an output)"
+ input SetBuilder(string) : "Sets the builder of this object to the !activator"
+ input SetSolidToPlayer(integer) : "Sets if the building should be solid to players other than its builder"
input Show(void) : "Makes the building visible and tries to re-enable it."
input Hide(void) : "Makes the building invisible and disables it."
input SetHealth(integer) : "Sets a new value for the breakable's health. If the breakable's health reaches zero it will break."
diff --git a/fgd/bases/BasePedButton.fgd b/fgd/bases/BasePedButton.fgd
index cdbc0fee8..25ab0876e 100644
--- a/fgd/bases/BasePedButton.fgd
+++ b/fgd/bases/BasePedButton.fgd
@@ -4,7 +4,6 @@
delay(float) : "Delay Before Reset" : 1 : "Amount of time, in seconds, after the button has been pressed before it returns to the starting position. Once it has returned, it can be used again."
istimer(boolean) : "Play timer sound?" : 0 : "If set, this button will play timer sounds while button is depressed. This allows fast reset by default - use Prevent fast reset to stop this."
preventfastreset(boolean) : "Prevent fast reset?" : 0 : "Buttons that are timer's allow you to reset early - use this to make the button stick for the entire duration."
- solid(boolean) : "Is Solid" : 1 : "Makes button able to be passed through."
// Inputs
input Press(void) : "Cause the button to be pressed."
diff --git a/fgd/bases/BaseTrain.fgd b/fgd/bases/BaseTrain.fgd
index 99cedac0f..0d8f92f1f 100644
--- a/fgd/bases/BaseTrain.fgd
+++ b/fgd/bases/BaseTrain.fgd
@@ -53,6 +53,12 @@
movesoundmintime(float) : "Min move sound interval" : 0 : "Minimum interval at which to play the move ping sound."
movesoundmaxtime(float) : "Max move sound interval" : 0 : "Maximum interval at which to play the move ping sound."
+ // Not in the default FGD post-Left 4 Dead, but seems to exist in engine
+ manualspeedchanges(boolean) : "Manual Train Speed" : 0 : "Train Speed is controlled through IO, handles accel, decel times."
+
+ manualaccelspeed(float) : "Manual Accel Speed" : 0 : "Units per second to accelerate to target speed."
+ manualdecelspeed(float) : "Manual Decel Speed" : 0 : "Units per second to decelerate to target speed."
+
// Inputs
input SetSpeed(float) : "Set the speed of the train, as a ratio of max speed [0, 1]"
input SetSpeedDir(float) : "Set the speed of the train, as a ratio of max speed. Negative values reverse the direction [-1, 1]"
@@ -63,4 +69,28 @@
input Resume(void) : "Resume the train moving in the current direction after it was stopped via the 'Stop' or 'Toggle' input."
input Reverse(void) : "Reverse the direction of the train."
input Toggle(void) : "Toggle the train between start and stop."
+
+ // Added to 2007 post-release for TF2 Payload mode, didn't make it into later games
+ input TeleportToPathTrack[until_L4D](string) : "Teleport train to the designated path track. This can be in a new path."
+ input SetSpeedForwardModifier[until_L4D](float) : "Applies the given modifier to all forward speeds. [0, 1]"
+
+ // This specific input did get ported in L4D2
+ input SetSpeedDirAccel[!L4D](float) : "Accel/Decel to the specified speed, as a ratio of max speed. Negative values reverse the direction [-1, 1]"
+
+ // Added in Portal 2, Gmod backported
+ input TeleportToPathNode[since_P2, GMod](string) : "Teleport to a destination and stop there. This can be in a new path."
+ input MoveToPathNode[since_P2, GMod](string) : "Start moving to a destination and stop when you get there. This must be in the same path."
+ input LockOrientation[since_P2, GMod](void) : "Lock the current orientation of the train."
+ input UnlockOrientation[since_P2, GMod](void) : "Unlock the current orientation of the train."
+ input SetMaxSpeed[since_P2, GMod](float) : "Set a new max speed for the train."
+
+ input SetVelocityType[MESA](integer) : ""
+ input EnableControls[MESA](void) : ""
+ input DisableControls[MESA](void) : ""
+
+ // Outputs
+ output OnStart(void) : "Fired when the train starts moving in either direction."
+ // The default FGD mislabels this as OnNext
+ output OnNextPoint(string) : "Fires continuously every frame when the train is moving to its next destination."
+ output OnArrivedAtDestinationNode[since_P2, GMod](void) : "Fired when this train arrives at a destination that was specified by the MoveToPathNode Input."
]
diff --git a/fgd/bases/Breakable.fgd b/fgd/bases/Breakable.fgd
index 105c70f32..96f51cfa2 100644
--- a/fgd/bases/Breakable.fgd
+++ b/fgd/bases/Breakable.fgd
@@ -7,7 +7,7 @@
explodemagnitude(integer) : "Explode Magnitude" : 0 : "If non-zero, when this entity breaks it will create an explosion that causes the specified amount of damage."
performancemode[engine](integer) : "Performance Mode" : 0
- performancemode[complete](choices) : "Performance Mode" : 0 : "Used to limit the amount of gibs produced when this entity breaks, for performance reasons." =
+ performancemode(choices) : "Performance Mode" : 0 : "Used to limit the amount of gibs produced when this entity breaks, for performance reasons." =
[
0: "Normal"
1: "No Gibs"
diff --git a/fgd/bases/CombineBallSpawners.fgd b/fgd/bases/CombineBallSpawners.fgd
index 6ad2d629a..40c326175 100644
--- a/fgd/bases/CombineBallSpawners.fgd
+++ b/fgd/bases/CombineBallSpawners.fgd
@@ -12,13 +12,6 @@
maxspeed(float) : "Max ball speed" : 600.0 : "The maximum speed of balls that fly in the spawner"
ballradius(float) : "Ball radius" : 12.0 : "The size of the sprite and the collsion. This is restricted to within 1-12 units."
- balltype(choices) : "Ball Type" : "Combine Energy Ball 1" =
- [
- 0: "Combine Energy Ball 1"
- 1: "Combine Energy Ball 2"
- 2: "Combine Energy Ball 3"
- ]
- balltype[engine](integer): "Ball Type": 0
ballrespawntime(float) : "Ball Respawn Time" : 4.0 : "The energy balls respawn time"
diff --git a/fgd/bases/DamageType.fgd b/fgd/bases/DamageType.fgd
index 321fa6162..d214a74be 100644
--- a/fgd/bases/DamageType.fgd
+++ b/fgd/bases/DamageType.fgd
@@ -60,23 +60,23 @@
damageor3[engine](integer) : "Damage Or" : 0
damageor4[engine](integer) : "Damage Or" : 0
- damageor1[srctools](choices) : "Damage - Gibbing" : 0 : "Optional flags that can accompany the damage type." =
+ damageor1[srctools](choices) : "[HA] Damage - Gibbing" : 0 : "Optional flags that can accompany the damage type." =
[
0 : "Normal Behaviour"
4096 : "Never use gibs"
8192 : "Always gib if possible"
]
- damageor2[srctools](choices) : "Damage - Prevent Physics Force" : 0 : "Prevent applying physics force to the target." =
+ damageor2[srctools](choices) : "[HA] Damage - Prevent Physics Force" : 0 : "Prevent applying physics force to the target." =
[
0 : "Apply force"
2048 : "Prevent force"
]
- damageor3[srctools](choices) : "Damage - No Ragdoll On Death" : 0 : "Prevent any ragdoll on death" =
+ damageor3[srctools](choices) : "[HA] Damage - No Ragdoll On Death" : 0 : "Prevent any ragdoll on death" =
[
0 : "Allow ragdolls"
4194304 : "Prevent ragdolls"
]
- damageor4[srctools](choices) : "Damage - Blast Surface" : 0 : "This is ignored by players when fully underwater." =
+ damageor4[srctools](choices) : "[HA] Damage - Blast Surface" : 0 : "This is ignored by players when fully underwater." =
[
0 : "Damage underwater"
134217728 : "Damage only above the surface"
diff --git a/fgd/bases/Door.fgd b/fgd/bases/Door.fgd
index 9e5e62f48..d87f78948 100644
--- a/fgd/bases/Door.fgd
+++ b/fgd/bases/Door.fgd
@@ -42,7 +42,7 @@
32: "Toggle" : 0
256: "Use Opens" : 0
512: "NPCs Can't" : 0
- 1024: "Touch Opens" : 1
+ 1024: "Touch Opens" : 0
2048: "Starts locked" : 0
4096: "Door Silent" : 0
131072: "Block Infected nav when closed" : 0 [L4D, L4D2]
diff --git a/fgd/bases/Item.fgd b/fgd/bases/Item.fgd
index 0878bebbf..27b52e53a 100644
--- a/fgd/bases/Item.fgd
+++ b/fgd/bases/Item.fgd
@@ -11,7 +11,8 @@
4 : "Not puntable by Gravity Gun" : 0 [MBase]
8 : "Deny NPC pickup (reserve for player)" : 0 [MBase]
64 : "Always touchable (no obstruction checking)" : 0 [MBase]
- 1073741824: "Never Respawn" : 0 [TF2]
+ // Technically in every game, but most won't use it
+ 1073741824: "Never respawn in multiplayer" : 0 [HL2DM, TF2, complete]
]
powerup_model[TF2](string) : "Model" : : "Change the model to something other than the default model."
diff --git a/fgd/bases/LightPattern.fgd b/fgd/bases/LightPattern.fgd
new file mode 100644
index 000000000..bce54c37a
--- /dev/null
+++ b/fgd/bases/LightPattern.fgd
@@ -0,0 +1,28 @@
+@BaseClass = LightPattern
+[
+ style[engine](integer) : "Appearance" : 0
+ style(choices) : "Appearance" : 0 =
+ [
+ 0 : "Normal"
+ 10: "Fluorescent flicker"
+ 2 : "Slow, strong pulse"
+ 11: "Slow pulse, noblack"
+ 5 : "Gentle pulse"
+ 1 : "Flicker A"
+ 6 : "Flicker B"
+ 3 : "Candle A"
+ 7 : "Candle B"
+ 8 : "Candle C"
+ 4 : "Fast strobe"
+ 9 : "Slow strobe"
+ 12 : "Underwater light mutation"
+ ]
+ pattern(string) : "Custom Appearance" : "" : "Set a custom pattern of light brightness for this light. Pattern format is a string of characters, where 'a' is total darkness, 'z' fully bright. i.e. 'aaggnnttzz' would be a steppy fade in from dark to light."
+
+ // Inputs
+ input TurnOn(void) : "Turn the light on."
+ input TurnOff(void) : "The the light off."
+ input Toggle(void) : "Toggle the light's current state."
+ input SetPattern(string) : "Set a custom pattern of light brightness for this light. Pattern format is a string of characters, where 'a' is total darkness, 'z' fully bright. i.e. 'aaggnnttzz' would be a steppy fade in from dark to light."
+ input FadeToPattern(string) : "Fades from first value in old pattern, to first value in the new given pattern. Pattern format is a string of characters, where 'a' is total darkness, 'z' fully bright. i.e. 'aaggnnttzz' would be a steppy fade in from dark to light."
+]
diff --git a/fgd/bases/LightShadows.fgd b/fgd/bases/LightShadows.fgd
new file mode 100644
index 000000000..4000955dc
--- /dev/null
+++ b/fgd/bases/LightShadows.fgd
@@ -0,0 +1,12 @@
+@BaseClass = LightShadows
+[
+ // GMod backports this feature.
+ _castentityshadow[engine](boolean)
+ _castentityshadow[since_L4D, GMod](Choices) : "Cast entity shadows" : 0 : "Objects illuminated by this light can be set to cast a fake directional shadow away from this light." =
+ [
+ 0 : "Don't affect entity shadow angles"
+ 1 : "Affect entity shadow angles"
+ ]
+
+ _shadoworiginoffset[since_L4D, GMod](vec_dir) : "Shadow Cast Offset" : "0 0 0" : "A world-space offset that gets applied to the light origin when casting entity shadows. Useful for dealing with funny-looking shadows from very low lights: Just offset up the z axis. Default 0 0 0."
+]
diff --git a/fgd/bases/NavAttributeRegion.fgd b/fgd/bases/NavAttributeRegion.fgd
index c6834634d..4c1a9c78b 100644
--- a/fgd/bases/NavAttributeRegion.fgd
+++ b/fgd/bases/NavAttributeRegion.fgd
@@ -20,4 +20,10 @@
precise(boolean) : "Precise" : 0
crouch(boolean) : "Crouch" : 0
stairs(boolean) : "Stairs" : 0
+ remove_attributes(integer) : "Remove Attributes" : 0 : "Should remove attributes from nav areas instead of applying them?"
+ tank_only(boolean) : "Tank Only" : 0
+ mob_only(boolean) : "Mob Only" : 0
+
+ // Inputs
+ input ApplyNavAttributes(void) : "Applies the nav attributes."
]
diff --git a/fgd/bases/NavBlocker.fgd b/fgd/bases/NavBlocker.fgd
index 787050ebf..1a9525602 100644
--- a/fgd/bases/NavBlocker.fgd
+++ b/fgd/bases/NavBlocker.fgd
@@ -5,6 +5,7 @@
teamtoblock[TF2](choices) : "Team(s) to block" : -1 : "Team(s) this entity should block." =
[
-1: "Everyone"
+ 0: "Unassigned" [+complete]
2: "RED"
3: "BLU"
5: "Halloween Bosses"
@@ -13,6 +14,7 @@
teamtoblock[CSGO](choices) : "Team(s) to block" : -1 : "Team(s) this entity should block" =
[
-1: "Everyone"
+ 0: "Unassigned" [+complete]
2: "Terrorists"
3: "Counter-Terrorists"
]
@@ -20,6 +22,7 @@
teamtoblock[L4D, L4D2](choices) : "Team(s) to block" : -1 : "Team(s) this entity should block" =
[
-1: "Everyone"
+ 0: "Unassigned" [+complete]
2: "Survivors"
3: "Infected"
]
diff --git a/fgd/bases/RenderFields.fgd b/fgd/bases/RenderFields.fgd
index 444eea39e..c33339c82 100644
--- a/fgd/bases/RenderFields.fgd
+++ b/fgd/bases/RenderFields.fgd
@@ -117,8 +117,8 @@
input SetViewHideFlags[MBase](integer) : "Sets this entity's view ID nodraw flags (takes raw flag combination)."
input AddEffects[MBase](integer) : "Adds an entity effect."
input RemoveEffects[MBase](integer) : "Removes an entity effect."
- input EnableDraw[!MBase, since_P2](void) : "Draws an entity if it is not drawn."
- input DisableDraw[!MBase, since_P2](void) : "Undraws an entity if it is drawn."
+ input EnableDraw[!MBase, since_P2, GMod](void) : "Draws an entity if it is not drawn."
+ input DisableDraw[!MBase, since_P2, GMod](void) : "Undraws an entity if it is drawn."
input EnableDraw[MBase](void) : "Draws an entity if it is not drawn. Equivalent to RemoveEffects > 32."
input DisableDraw[MBase](void) : "Undraws an entity if it is drawn. Equivalent to AddEffects > 32."
input AddEFlags[MBase](integer) : "Adds an entity flag. NOTE: Entity flags are not the spawn flags you see in Hammer. Use AddSpawnFlags to add spawnflags."
diff --git a/fgd/bases/RopeKeyFrame.fgd b/fgd/bases/RopeKeyFrame.fgd
index b028da2e7..0ca45e60d 100644
--- a/fgd/bases/RopeKeyFrame.fgd
+++ b/fgd/bases/RopeKeyFrame.fgd
@@ -53,7 +53,7 @@
// Inputs
input SetScrollSpeed(float) : "Set the speed at which the texture scrolls."
input SetForce(vector) : "Apply a force instantaneously to the rope. The parameter should be a vector containing the force to be applied (X Y Z)."
- input Break(void) : "Break the rope, if it's marked to do so."
+ input Break(void) : "Detach this end of the rope, causing it to fall."
input SetSlack[MBase](integer) : "Set the rope's slack. (Wind may need to be enabled for changes to apply.)"
input SetWidth[MBase](float) : "Set the rope's width."
input SetSubdivision[MBase](integer) : "Set the rope's subdivision. (Wind may need to be enabled for changes to apply.)"
diff --git a/fgd/bases/SRCIndicator.fgd b/fgd/bases/SRCIndicator.fgd
index 9539f096e..b03b43450 100644
--- a/fgd/bases/SRCIndicator.fgd
+++ b/fgd/bases/SRCIndicator.fgd
@@ -3,6 +3,6 @@
appliesto(srctools)
= SRCIndicator: "Adds an Indicator Name option to toggle overlays."
[
- indicatorname(target_destination) : "Indicator Name" : : "Set to the name of a set of info_overlays to toggle when this is activated and deactivated. The name may also point to a prop_indicator_panel, which will also be toggled appropriately."
+ indicatorname(target_destination) : "[HA] Indicator Name" : : "Set to the name of a set of info_overlays to toggle when this is activated and deactivated. The name may also point to a prop_indicator_panel, which will also be toggled appropriately."
input SetTextureIndex(integer) : "Manually change the index of the overlays. prop_indicator_panels must not be used."
]
diff --git a/fgd/bases/SRCModel.fgd b/fgd/bases/SRCModel.fgd
new file mode 100644
index 000000000..a492572e2
--- /dev/null
+++ b/fgd/bases/SRCModel.fgd
@@ -0,0 +1,7 @@
+@BaseClass appliesto(+P2, +srctools)
+= SRCModel: "Adds keyvalues to set a custom model."
+[
+ comp_custom_model_type[srctools, -engine](boolean) : "[HA] Override Model" : 0 : "If enabled, automatically pack a VScript to override the entity's model on spawn."+
+ " NOTE: If you run into problems with players getting stuck on the model, make sure it has the same collisions as the base model,"+
+ " as this is known to sometimes cause issues."
+]
diff --git a/fgd/bases/SetSkin.fgd b/fgd/bases/SetSkin.fgd
index c075bfbff..627dec0f0 100644
--- a/fgd/bases/SetSkin.fgd
+++ b/fgd/bases/SetSkin.fgd
@@ -3,6 +3,6 @@
[
skin(integer) : "Skin" : 0 : "Some models have multiple versions of their textures, called skins. " +
"Set this to a number other than 0 to use that skin instead of the default."
- skinset[srctools](string) : "Used Skins" : : "Set this to a space seperated list of all the skin numbers which will be used by this ent ('0 4 8' for example). " +
+ skinset[srctools](string) : "[HA] Used Skins" : : "Set this to a space seperated list of all the skin numbers which will be used by this ent ('0 4 8' for example). " +
"This allows auto-packing to skip unused ones. If blank all skins are assumed to be used."
]
diff --git a/fgd/bases/TFPickup.fgd b/fgd/bases/TFPickup.fgd
new file mode 100644
index 000000000..0232e6ad2
--- /dev/null
+++ b/fgd/bases/TFPickup.fgd
@@ -0,0 +1,12 @@
+@BaseClass base(Item)
+ appliesto(TF2)
+ sphere(fademindist)
+ sphere(fademaxdist) = TFPickup: "Base class for TF2 item pickups"
+ [
+ pickup_sound(string) : "Sound Effect" : : "The sound script entry that is played when the item is picked up."
+ pickup_particle(string) : "Particle Effect" : : "The particle effect that is displayed when the item is picked up."
+
+ // Outputs
+ output OnRedPickup(void) : "Sent when RED picks-up the item."
+ output OnBluePickup(void) : "Sent when BLU picks-up the item."
+ ]
\ No newline at end of file
diff --git a/fgd/bases/TeamNum.fgd b/fgd/bases/TeamNum.fgd
index 3ee93c27f..682aed2b9 100644
--- a/fgd/bases/TeamNum.fgd
+++ b/fgd/bases/TeamNum.fgd
@@ -5,7 +5,7 @@
[
0: "Any"
2: "RED"
- 3: "BLU/ROBOTS"
+ 3: "BLU/Robots"
5 : "Halloween Bosses"
1 : "Spectator / Halloween Souls"
]
@@ -14,13 +14,15 @@
[
-1: "None"
0: "All Teams"
+ 1: "Spectators" [+complete]
2: "Terrorist"
3: "Counter-Terrorist"
]
teamnum[P2](choices) : "Team" : 0 =
[
- 0: "Chell/Bendy"
+ 0: "Singleplayer/Unassigned"
+ 1: "Spectators" [+complete]
2: "P-Body"
3: "ATLAS"
]
diff --git a/fgd/bases/ToggleDraw.fgd b/fgd/bases/ToggleDraw.fgd
index b8561b7f1..a2f3c855e 100644
--- a/fgd/bases/ToggleDraw.fgd
+++ b/fgd/bases/ToggleDraw.fgd
@@ -2,6 +2,6 @@
@BaseClass = ToggleDraw
[
// Inputs
- input DisableDraw[since_P2](void) : "Add the EF_NODRAW flag to this entity. Some entities manage this on their own so be aware you can override that value."
- input EnableDraw[since_P2](void) : "Remove the EF_NODRAW flag to this entity. Some entities manage this on their own so be aware you can override that value."
+ input DisableDraw[since_P2, GMod](void) : "Add the EF_NODRAW flag to this entity. Some entities manage this on their own so be aware you can override that value."
+ input EnableDraw[since_P2, GMod](void) : "Remove the EF_NODRAW flag to this entity. Some entities manage this on their own so be aware you can override that value."
]
diff --git a/fgd/bases/TriggerOnce.fgd b/fgd/bases/TriggerOnce.fgd
index ab442a4f3..e8dd0fe21 100644
--- a/fgd/bases/TriggerOnce.fgd
+++ b/fgd/bases/TriggerOnce.fgd
@@ -11,7 +11,7 @@
2: "NPCs" : 0 [!ASW]
2: "Marines and Aliens" : 0 [ASW]
4: "func_pushable" : 0
- 8: "Physics Objects" : 0
+ 8: "VPhysics Objects" : 0
8192: "Items (weapons, items, projectiles)" : 0 [MBase]
16: "Only player ally NPCs" : 0 [!ASW]
16: "Only marines" : 1 [ASW]
@@ -20,7 +20,6 @@
512: "Only clients *not* in vehicles" : 0 [!ASW]
1024: "Physics debris" : 0
2048: "Only NPCs in vehicles (respects player ally flag)" : 0
- 4096: "Correctly account for object mass (trigger_push used to assume 100Kg) and multiple component physobjs (car, blob...)" : 1 [!CSGO, !TF2]
4096: "Disallow Bots" : 0 [CSGO, TF2, MESA]
]
@@ -52,7 +51,8 @@
output OnTouching(void) : "Fired when the TouchTest input is called, and an entity is touching this. Does not call activators."
output OnNotTouching(void) : "Fired when the TouchTest input is called, and no entity is touching this. Does not call activators."
- // This I/O does actually exist, but it couldn't ever be used usefully.
+ // This I/O does actually exist, but it couldn't ever be used usefully.
+ // Entities that can use them should inherit Trigger instead.
input EndTouch[engine](void)
input DisableAndEndTouch[TF2, engine](void)
output OnStartTouchAll[engine](void) // Always fires along with OnStartTouch, so useless.
diff --git a/fgd/bases/Weapon.fgd b/fgd/bases/Weapon.fgd
index 6e2759e63..d14071ae4 100644
--- a/fgd/bases/Weapon.fgd
+++ b/fgd/bases/Weapon.fgd
@@ -13,6 +13,8 @@
16 : "Preserve ammo values when picked up" : 0 [MBase]
32 : "Preserve name on player pickup" : 0 [MBase]
64 : "Always touchable (no obstruction checking)" : 0 [MBase]
+ // Technically in every game, but most won't use it
+ 1073741824 : "Never respawn in multiplayer" : 0 [HL2DM, TF2, complete]
]
SetAmmo1[MBase](integer) : "Ammo 1 Override" : 0 : "Overrides the amount of primary ammo this weapon has. Be sure to set 'Preserve ammo values when picked up' for this to be maintained upon pickup."
@@ -37,5 +39,9 @@
output OnPlayerPickup(void) : "Fires when the player picks up this weapon."
output OnNPCPickup(void) : "Fires when an NPC picks up this weapon."
output OnCacheInteraction(void) : "Fires when the player 'proves' they've found this weapon. " +
- "Fires on: Player Touch, +USE pickup, Physcannon pickup, Physcannon pun" + "t."
+ "Fires on: Player Touch, +USE pickup, Physcannon pickup, Physcannon punt."
+
+ @resources
+ [
+ ]
]
diff --git a/fgd/bases/WeaponSpawnSingle.fgd b/fgd/bases/WeaponSpawnSingle.fgd
index a394316d5..860ce9ed9 100644
--- a/fgd/bases/WeaponSpawnSingle.fgd
+++ b/fgd/bases/WeaponSpawnSingle.fgd
@@ -6,13 +6,14 @@
weaponskin[L4D2](integer) : "Weapon Skin" : -1 : "Some weapons have multiple versions of their textures, called skins. Set this to a number other than -1 to make the given weapon use that skin instead of the default."
glowrange[L4D2](float) : "Glow Range" : 0 : "Set a custom glow range for this spawner. 0 means use the default range."
- solid[engine](integer) : "Collisions" : 6
- solid(choices) : "Collisions" : 6 =
- [
- 0: "Not Solid"
- 2: "Use Bounding Box"
- 6: "Use VPhysics"
- ]
+ // Should be inherited from base physics
+ // solid[engine](integer) : "Collisions" : 6
+ // solid(choices) : "Collisions" : 6 =
+ // [
+ // 0: "Not Solid"
+ // 2: "Use Bounding Box"
+ // 6: "Use VPhysics"
+ // ]
spawnflags(flags) =
[
diff --git a/fgd/bases/asw_alien.fgd b/fgd/bases/asw_alien.fgd
index 9769d02cc..db7b152fa 100644
--- a/fgd/bases/asw_alien.fgd
+++ b/fgd/bases/asw_alien.fgd
@@ -1,4 +1,5 @@
@BaseClass base(BaseNPC)
+ line(255 255 255, targetname, moveclone)
appliesto(ASW)
= asw_alien: "Alien Base class."
[
diff --git a/fgd/bases/trigger_asw_use_area.fgd b/fgd/bases/trigger_asw_use_area.fgd
index 9dbd152d3..57b3362ae 100644
--- a/fgd/bases/trigger_asw_use_area.fgd
+++ b/fgd/bases/trigger_asw_use_area.fgd
@@ -1,4 +1,4 @@
-@BaseClass base(trigger_multiple) = trigger_asw_use_area: "A trigger volume that is used to define areas for using various things."
+@BaseClass base(trigger_multiple) line(255 255 0, targetname, usetargetname) = trigger_asw_use_area: "A trigger volume that is used to define areas for using various things."
[
spawnflags(flags) : "spawnflags" =
[
diff --git a/fgd/brush/func/func_areaportal.fgd b/fgd/brush/func/func_areaportal.fgd
index ec27a6684..4b960150f 100644
--- a/fgd/brush/func/func_areaportal.fgd
+++ b/fgd/brush/func/func_areaportal.fgd
@@ -1,5 +1,6 @@
@SolidClass base(BaseEntity)
- color(0 255 255)
+ color(0 255 255)
+ line(255 255 0, targetname, target)
= func_areaportal: "A portal brush used to manage visibility in maps. " +
"Portals define areas, which are spaces that are connected in the map. " +
"Both sides of a portal cannot touch the same area, for example, a doughnut shaped map would require at least two portals to divide the map into two areas. " +
diff --git a/fgd/brush/func/func_commandredirect.fgd b/fgd/brush/func/func_commandredirect.fgd
index e3eb42a47..21f31f387 100644
--- a/fgd/brush/func/func_commandredirect.fgd
+++ b/fgd/brush/func/func_commandredirect.fgd
@@ -1,5 +1,6 @@
@SolidClass
base(BaseEntityBrush, Origin, EnableDisable)
+ line(255 255 255, targetname, target)
appliesto(MBase)
= func_commandredirect :
"A brush entity that redirects the player's squad commands. Also functions as a limited trigger for the player AND their squad members."
diff --git a/fgd/brush/func/func_fake_worldportal.fgd b/fgd/brush/func/func_fake_worldportal.fgd
index f31a77d5e..a88711ee5 100644
--- a/fgd/brush/func/func_fake_worldportal.fgd
+++ b/fgd/brush/func/func_fake_worldportal.fgd
@@ -1,5 +1,7 @@
@SolidClass base(func_brush)
appliesto(MBase)
+ line(255 255 0, targetname, target)
+ line(255 255 255, targetname, FogController)
= func_fake_worldportal:
"Used to produce perfectly reflective glass that renders world + entities. " +
"Typically, you want your glass brush to have nodraw on all non-reflective surfaces " +
diff --git a/fgd/brush/func/func_flag_alert.fgd b/fgd/brush/func/func_flag_alert.fgd
index 2b4426980..99eda24c7 100644
--- a/fgd/brush/func/func_flag_alert.fgd
+++ b/fgd/brush/func/func_flag_alert.fgd
@@ -7,5 +7,5 @@
// Outputs
output OnTriggeredByTeam1(void) : "Sent when RED triggers the alert."
- output OnTriggeredByTeam2(void) : "Sent when BLUE triggers the alert."
+ output OnTriggeredByTeam2(void) : "Sent when BLU triggers the alert."
]
diff --git a/fgd/brush/func/func_physbox.fgd b/fgd/brush/func/func_physbox.fgd
index 36387b13d..9cfd3a5b4 100644
--- a/fgd/brush/func/func_physbox.fgd
+++ b/fgd/brush/func/func_physbox.fgd
@@ -27,6 +27,7 @@
]
massscale(float) : "Mass Scale" : 0 : "A scale multiplier for the object's mass."
+ ha_override_mass[srctools](float) : "[HA] Mass Override" : : "If set, the postcompiler will modify the brush data to directly set it to this mass value."
overridescript(string) : "Override Parameters" : : "A list of physics key/value pairs that are usually in a physics prop .qc file. Format is 'key,value,key,value,etc'."
damagetoenablemotion(integer) : "Health Level to Override Motion" : 0 : "If specified, this object will start motion disabled. Once its health has dropped below this specified amount, it will enable motion."
forcetoenablemotion(float) : "Physics Impact Force to Override Motion" : 0 : "If specified, this object will start motion disabled. Any impact that imparts a force greater than this value on the physbox will enable motion."
diff --git a/fgd/brush/func/func_respawnroomvisualizer.fgd b/fgd/brush/func/func_respawnroomvisualizer.fgd
index 36e5e7d12..e128102d7 100644
--- a/fgd/brush/func/func_respawnroomvisualizer.fgd
+++ b/fgd/brush/func/func_respawnroomvisualizer.fgd
@@ -1,4 +1,5 @@
@SolidClass base(func_brush)
+ line(255 255 0, targetname, respawnroomname)
appliesto(TF2) = func_respawnroomvisualizer:
"Brushes that become visible to enemy players when they get close. " +
"Use them to mark areas that they're unable to enter (i.e. respawn rooms)."
diff --git a/fgd/brush/func/func_tankairboatgun.fgd b/fgd/brush/func/func_tankairboatgun.fgd
index 9d393588b..c532ef617 100644
--- a/fgd/brush/func/func_tankairboatgun.fgd
+++ b/fgd/brush/func/func_tankairboatgun.fgd
@@ -1,4 +1,5 @@
@SolidClass base(BaseTank)
+ line(255 0 0, targetname, airboat_gun_model)
appliesto(EP1, EP2, HL2, P1, ASW) = func_tankairboatgun: "Airboat Gun Turret"
[
shootsound[MBase](sound) : "Shoot Sound" : "" : "Plays a specific sound each time this tank fires."
diff --git a/fgd/brush/func/func_tanklaser.fgd b/fgd/brush/func/func_tanklaser.fgd
index e5da61f4f..df90eab8f 100644
--- a/fgd/brush/func/func_tanklaser.fgd
+++ b/fgd/brush/func/func_tanklaser.fgd
@@ -1,4 +1,5 @@
@SolidClass base(BaseTank)
+ line(255 255 0, targetname, laserentity)
appliesto(EP1, EP2, HL2, P1, ASW) = func_tanklaser: "Brush Laser Turret"
[
laserentity(target_destination) : "env_laser Entity"
diff --git a/fgd/brush/func/func_tankphyscannister.fgd b/fgd/brush/func/func_tankphyscannister.fgd
index be0d64e8e..bb9706e8d 100644
--- a/fgd/brush/func/func_tankphyscannister.fgd
+++ b/fgd/brush/func/func_tankphyscannister.fgd
@@ -1,5 +1,6 @@
-@SolidClass base(BaseTank)
+@SolidClass base(BaseTank)
+ line(255 255 255, targetname, barrel_volume)
appliesto(EP1, EP2, HL2, P1, ASW) = func_tankphyscannister: "Tank which launches phys_canister entities placed inside it."
[
barrel_volume(target_destination) : "Barrel Volume" : : "Name of a trigger the specifies the volume in which cannisters must be placed."
diff --git a/fgd/brush/func/func_tfbot_hint.fgd b/fgd/brush/func/func_tfbot_hint.fgd
index 47fd70114..ad2be2e65 100644
--- a/fgd/brush/func/func_tfbot_hint.fgd
+++ b/fgd/brush/func/func_tfbot_hint.fgd
@@ -5,8 +5,9 @@
team(choices) : "Team" : "-2" : "Which team will use this hint" =
[
-2: "Everyone"
- 2: "Red"
- 3: "Blue"
+ 0: "Unassigned" [+complete]
+ 2: "RED"
+ 3: "BLU"
5 : "Halloween Bosses"
]
diff --git a/fgd/brush/func/func_tracktrain.fgd b/fgd/brush/func/func_tracktrain.fgd
index 91486cf61..2352a0f93 100644
--- a/fgd/brush/func/func_tracktrain.fgd
+++ b/fgd/brush/func/func_tracktrain.fgd
@@ -3,31 +3,4 @@
"NOTE: Build your train so that the front of the train is facing down the X axis. " +
"When it spawns it will automatically rotate to face the next path_track on the path."
[
- manualspeedchanges[until_L4D](boolean) : "Manual Train Speed" : "0" : "Train Speed is controlled through IO, handles accel, decel times."
-
- manualaccelspeed[until_L4D](float) : "Manual Accel Speed" : "0" : "Units per second to accelerate to target speed."
- manualdecelspeed[until_L4D](float) : "Manual Decel Speed" : "0" : "Units per second to decelerate to target speed."
-
- // Inputs
- input SetSpeedDirAccel[until_L4D](float) : "Accel/Decel to the specified speed, as a ratio of max speed. Negative values reverse the direction [-1, 1]"
- // Todo - when did this get renamed??
- input TeleportToPathTrack[until_L4D](string) : "Teleport train to the designated path track. This can be in a new path."
- input TeleportToPathNode[since_L4D](string) : "Teleport to a destination and stop there. This can be in a new path."
- input SetSpeedForwardModifier[!ASW, !L4D2](float) : "Applies the given modifier to all forward speeds. [0, 1]"
- input MoveToPathNode[!L4D2](string) : "Start moving to a destination and stop when you get there. This must be in the same path."
- input LockOrientation[P2](void) : "Lock the current orientation of the train."
- input UnlockOrientation[P2](void) : "Unlock the current orientation of the train."
- input SetMaxSpeed[P2](float) : "Set a new max speed for the train."
-
- input SetVelocityType[MESA](integer) : ""
- input EnableControls[MESA](void) : ""
- input DisableControls[MESA](void) : ""
-
- // Outputs
- output OnStart(void) : "Fired when the train starts moving in either direction."
- output OnNextPoint(string) : "Fires continuously every frame when the train is moving to its next destination."
- output OnArrivedAtDestinationNode[P2](void) : "Fired when this train arrives at a destination that was specified by the MoveToPathNode Input."
- output OnNext[L4D2](string) : "Fires when this train picks a new point to move towards (and just after OnStart)."
-
- @resources []
]
diff --git a/fgd/brush/func/func_wall.fgd b/fgd/brush/func/func_wall.fgd
index 0d45f1584..afb78cf07 100644
--- a/fgd/brush/func/func_wall.fgd
+++ b/fgd/brush/func/func_wall.fgd
@@ -1,4 +1,4 @@
-@SolidClass base(BaseEntityBrush)
+@SolidClass base(BaseEntityVisBrush)
= func_wall: "Legacy support for Half-Life. Use func_brush instead. A general brush entity."
[
@resources []
diff --git a/fgd/brush/info/info_changelevel.fgd b/fgd/brush/info/info_changelevel.fgd
index 530cb70ac..8051ed96c 100644
--- a/fgd/brush/info/info_changelevel.fgd
+++ b/fgd/brush/info/info_changelevel.fgd
@@ -1,4 +1,4 @@
-@SolidClass base(BaseEntityBrush) appliesto(L4D, L4D2)
+@SolidClass base(BaseEntityBrush) line(255 255 255, targetname, landmark) appliesto(L4D, L4D2)
= info_changelevel: "An entity that marks a level change.\n" +
"Place an info_landmark in both maps that marks the 'same' location in each map.\n" +
"TIPS & TRICKS: To fire events in the next level, use the OnLevelChange output to turn on an env_global in the current level. " +
diff --git a/fgd/brush/momentary_rot_button.fgd b/fgd/brush/momentary_rot_button.fgd
index bff1bccb4..6c70d2859 100644
--- a/fgd/brush/momentary_rot_button.fgd
+++ b/fgd/brush/momentary_rot_button.fgd
@@ -98,7 +98,7 @@
1: "Backward"
]
- solidbsp[ASW](boolean) : "Solid BSP" : 0 : "If set, use the SOLID_BSP collision type."
+ solidbsp(boolean) : "Solid BSP" : 0 : "If set, use the SOLID_BSP collision type."
glow[L4D](target_destination) : "Glow Entity" : : "The name of an entity that will get the +use glow for this button."
diff --git a/fgd/brush/trigger/trigger_asw_computer_area.fgd b/fgd/brush/trigger/trigger_asw_computer_area.fgd
index 0448e7f83..5b3ce9a27 100644
--- a/fgd/brush/trigger/trigger_asw_computer_area.fgd
+++ b/fgd/brush/trigger/trigger_asw_computer_area.fgd
@@ -1,5 +1,8 @@
@SolidClass base(trigger_asw_use_area)
+ line(255 255 255, targetname, panelpropname)
+ line(255 255 255, targetname, securitycam1name)
+ line(255 255 255, targetname, turret1name)
appliesto(ASW) = trigger_asw_computer_area: "A trigger volume in which marines can use a computer."
[
locked[engine](boolean) : "Locked" : 1
diff --git a/fgd/brush/trigger/trigger_asw_jump.fgd b/fgd/brush/trigger/trigger_asw_jump.fgd
index c41624362..73dc6e064 100644
--- a/fgd/brush/trigger/trigger_asw_jump.fgd
+++ b/fgd/brush/trigger/trigger_asw_jump.fgd
@@ -1,4 +1,5 @@
@SolidClass base(Trigger)
+ line(255 255 0, targetname, jumpdestname)
appliesto(ASW) = trigger_asw_jump: "A trigger volume that causes Swarm Drones to jump when they come into contact with it"
[
jumpdestname(target_destination) : "Jump Destination Name" : : "The name of the item Drones should jump to (use an info_target)."
diff --git a/fgd/brush/trigger/trigger_capture_area.fgd b/fgd/brush/trigger/trigger_capture_area.fgd
index 5e58526f4..dabd9660e 100644
--- a/fgd/brush/trigger/trigger_capture_area.fgd
+++ b/fgd/brush/trigger/trigger_capture_area.fgd
@@ -6,22 +6,22 @@
area_time_to_cap(integer) : "Time to cap (sec)" : 5
team_cancap_2(boolean) : "Can RED Cap?" : 1
- team_cancap_3(boolean) : "Can BLUE Cap?" : 1
+ team_cancap_3(boolean) : "Can BLU Cap?" : 1
team_startcap_2(integer) : "Number of RED players to start capping" : 1
- team_startcap_3(integer) : "Number of BLUE players to start capping" : 1
+ team_startcap_3(integer) : "Number of BLU players to start capping" : 1
team_numcap_2(integer) : "Number of RED players to cap" : 1
- team_numcap_3(integer) : "Number of BLUE players to cap" : 1
+ team_numcap_3(integer) : "Number of BLU players to cap" : 1
- team_spawn_2(integer) : "Red Spawn Adjust" : 0 : "Adjust the minimum respawn time for the red team by this amount (in seconds) when red captures this point. " +
- "If the red team owns this point when blue captures it, this adjustment is reversed."
- team_spawn_3(integer) : "Blue Spawn Adjust" : 0 : "Adjust the minimum respawn time for the blue team by this amount (in seconds) when blue captures this point. " +
- "If the blue team owns this point when red captures it, this adjustment is reversed."
+ team_spawn_2(integer) : "RED Spawn Adjust" : 0 : "Adjust the minimum respawn time for RED by this amount (in seconds) when RED captures this point. " +
+ "If the RED owns this point when BLU captures it, this adjustment is reversed."
+ team_spawn_3(integer) : "BLU Spawn Adjust" : 0 : "Adjust the minimum respawn time for BLU by this amount (in seconds) when BLU captures this point. " +
+ "If BLU owns this point when RED captures it, this adjustment is reversed."
// Inputs
- input SetTeamCanCap(string) : "Set whether a specific team is allowed to capture this point. Format is: <(0/1)>. i.e. '2 0' would prevent RED from capturing this point, whereas '3 1' would allow BLUE to cap it."
+ input SetTeamCanCap(string) : "Set whether a specific team is allowed to capture this point. Format is: <(0/1)>. i.e. '2 0' would prevent RED from capturing this point, whereas '3 1' would allow BLU to cap it."
input SetControlPoint(string) : "Assign area capture to the passed control point."
input CaptureCurrentCP(string) : "If we're being capped, forces the current point to capture."
input RoundSpawn(void) : "Find our control point"
@@ -30,9 +30,9 @@
output OnStartTeam1(void) : "Sent when RED start capture."
output OnBreakTeam1(void) : "Sent when a RED capture is broken."
output OnCapTeam1(void) : "Sent when RED end capture."
- output OnStartTeam2(void) : "Sent when BLUE start capture."
- output OnBreakTeam2(void) : "Sent when a BLUE capture is broken."
- output OnCapTeam2(void) : "Sent when BLUE end capture."
+ output OnStartTeam2(void) : "Sent when BLU start capture."
+ output OnBreakTeam2(void) : "Sent when a BLU capture is broken."
+ output OnCapTeam2(void) : "Sent when BLU end capture."
output OnStartCap(void) : "Sent when either team starts capture."
output OnBreakCap(void) : "Sent when either team break capture."
output OnEndCap(void) : "Sent when either team end capture."
diff --git a/fgd/brush/trigger/trigger_changelevel.fgd b/fgd/brush/trigger/trigger_changelevel.fgd
index 7ead83159..6bcf4e3cd 100644
--- a/fgd/brush/trigger/trigger_changelevel.fgd
+++ b/fgd/brush/trigger/trigger_changelevel.fgd
@@ -13,7 +13,7 @@
spawnflags(flags) =
[
2: "Disable Touch" : 0
- 4: "To Previous Chapter" : 0
+ 4: "To Previous Chapter - disable if map was loaded from a new game" : 0
]
diff --git a/fgd/brush/trigger/trigger_look.fgd b/fgd/brush/trigger/trigger_look.fgd
index d117a3f52..5000d393e 100644
--- a/fgd/brush/trigger/trigger_look.fgd
+++ b/fgd/brush/trigger/trigger_look.fgd
@@ -19,7 +19,7 @@
looktime(float) : "LookTime" : "0.5" : "The time, in seconds, that the player must look the target before firing the output. " +
"Resets if player leaves trigger, or looks outside the Field of View threshold."
fieldofview(float) : "FieldOfView" : "0.9" : "How close the player has to be looking at the target. " +
- "1.0 = straight ahead\n 0.0 = +/- 90 degrees\n -1.0 = all directions)."
+ "1.0 = perfectly straight ahead, 0.0 = +/- 90 degrees, -1.0 = all directions). This is actually cos(angle)."
timeout(float) : "Timeout" : 0 : "The time, in seconds, to wait after player enters the trigger before firing the OnTimeout output, 0 = never."
NotLookingFrequency(float) : "Not-Looking Frequency" : "0.5" : "time in second between 2 fires of OnNotLooking output."
diff --git a/fgd/brush/trigger/trigger_multiple.fgd b/fgd/brush/trigger/trigger_multiple.fgd
index d37e9b7ba..e2ec1e9db 100644
--- a/fgd/brush/trigger/trigger_multiple.fgd
+++ b/fgd/brush/trigger/trigger_multiple.fgd
@@ -1,10 +1,12 @@
@SolidClass base(Trigger)
= trigger_multiple: "A trigger volume that can be triggered multiple times."
[
- wait[-KZ](float) : "Delay Before Reset" : 1 : "Amount of time, in seconds, after the trigger_multiple has triggered before it can be triggered again. " +
- "If set to -1, it will never trigger again (in which case you should just use a trigger_once). If set to 0, it will be reset to 0.2 seconds."
- wait[KZ](float) : "Delay Before Reset" : 0.1 : "Amount of time, in seconds, after the trigger_multiple has triggered before it can be triggered again. " +
- "If set to -1, it will never trigger again (in which case you should just use a trigger_once). If set to 0, it will be reset to 0.2 seconds."
+ wait[-KZ](float) : "Delay Before Reset" : 1 : "Amount of time, in seconds, after an initial touch that the trigger_multiple will fire OnTrigger again (if they're still touching). " +
+ "If set to -1, it will never trigger again (in which case you should just use a trigger_once). If set to 0, it will be reset to 0.2 seconds. " +
+ "This only affects the OnTrigger output, not OnStartTouch/OnEndTouch and friends."
+ wait[KZ](float) : "Delay Before Reset" : 0.1 : "Amount of time, in seconds, after the initial touch that the trigger_multiple will fire OnTrigger again. " +
+ "If set to -1, it will never trigger again (in which case you should just use a trigger_once). If set to 0, it will be reset to 0.2 seconds." +
+ "This only affects the OnTrigger output, not OnStartTouch/OnEndTouch and friends."
entireteam[engine](integer) : "Entire Team Number" : 0
entireteam[L4D, L4D2](choices) : "Entire Team Number" : 0 : "If the entire team is touching, fire OnEntireTeamStartTouch." =
@@ -23,8 +25,9 @@
]
// Outputs
+ output OnTrigger(void) : "Fired repeatedly whenever the trigger is activated, and the wait time has expired."
output OnEntireTeamStartTouch[L4D, L4D2](void) : "Fired when an entire team starts touching the trigger."
output OnEntireTeamEndTouch[L4D, L4D2](void) : "Fired when an entire team stops touching the trigger."
-
+
@resources []
]
diff --git a/fgd/brush/trigger/trigger_push.fgd b/fgd/brush/trigger/trigger_push.fgd
index 13a25e94e..daeb99cb7 100644
--- a/fgd/brush/trigger/trigger_push.fgd
+++ b/fgd/brush/trigger/trigger_push.fgd
@@ -4,9 +4,10 @@
pushdir(angle) : "Push Direction (Pitch Yaw Roll)" : "0 0 0" : "Angles indicating the direction to push touched entities."
spawnflags(flags) =
[
- 128: "Once Only" : 0
+ 128: "Fire once, then delete trigger" : 0
256: "Affects Ladders (Half-Life 2)" : 0
512: "No gravity while in contact (Players only)" : 0 [KZ]
+ 4096: "Correctly account for object mass (trigger_push used to assume 100Kg) and multiple component physobjs (car, blob...)" : 1 [!CSGO, !TF2]
]
surfacecontactmode[engine](integer): "Require player contact with a surface?" : 0 : "Push triggers by default apply a boost to the player once they exit the bounds of the push. This boost is the effective force that launches the player. However, by doubleducking in a short push trigger, a player may be able to cause the boost to apply twice rapidly, causing unintended velocity to be applied. These settings allow you to require the player to be in contact with a surface to receive velocity (and not receive it if in the air, such as during a doubleduck)."
diff --git a/fgd/brush/trigger/trigger_teleport.fgd b/fgd/brush/trigger/trigger_teleport.fgd
index 85e74bb60..71ebab52a 100644
--- a/fgd/brush/trigger/trigger_teleport.fgd
+++ b/fgd/brush/trigger/trigger_teleport.fgd
@@ -58,8 +58,8 @@
input RemoveAllowForRunners[KZ](void) : "Disallow runners from using this teleporter if they were allowed through AllowForRunners (Tag Arena)."
// Outputs
- output OnTeleport(void) : "Outputted when a player teleports."
- output OnTeleportNotAllowed(void) : "Outputted when a player tries to teleport, but can't because they are not allowed to use this teleporter."
+ output OnTeleport[KZ](void) : "Outputted when a player teleports."
+ output OnTeleportNotAllowed[KZ](void) : "Outputted when a player tries to teleport, but can't because they are not allowed to use this teleporter."
@resources []
]
diff --git a/fgd/brush/trigger/trigger_timer_door.fgd b/fgd/brush/trigger/trigger_timer_door.fgd
index beeb7fd22..8c1a4d146 100644
--- a/fgd/brush/trigger/trigger_timer_door.fgd
+++ b/fgd/brush/trigger/trigger_timer_door.fgd
@@ -5,20 +5,20 @@
area_cap_point(target_source) : "Control point" : : "Name of the control point this area is linked to."
team_cancap_2(boolean) : "Can RED Cap?" : 1
- team_cancap_3(boolean) : "Can BLUE Cap?" : 1
+ team_cancap_3(boolean) : "Can BLU Cap?" : 1
team_startcap_2(integer) : "Number of RED players to start capping" : 1
- team_startcap_3(integer) : "Number of BLUE players to start capping" : 1
+ team_startcap_3(integer) : "Number of BLU players to start capping" : 1
team_numcap_2(integer) : "Number of RED players to cap" : 1
- team_numcap_3(integer) : "Number of BLUE players to cap" : 1
- team_spawn_2(integer) : "Red Spawn Adjust" : 0 : "Adjust the minimum respawn time for the red team by this amount (in seconds) " +
- "when red captures this point. If the red team owns this point when blue captures it, this adjustment is reversed."
- team_spawn_3(integer) : "Blue Spawn Adjust" : 0 : "Adjust the minimum respawn time for the blue team by this amount (in seconds) " +
- "when blue captures this point. If the blue team owns this point when red captures it, this adjustment is reversed."
+ team_numcap_3(integer) : "Number of BLU players to cap" : 1
+ team_spawn_2(integer) : "RED Spawn Adjust" : 0 : "Adjust the minimum respawn time for RED by this amount (in seconds) " +
+ "when RED captures this point. If RED owns this point when BLU captures it, this adjustment is reversed."
+ team_spawn_3(integer) : "BLU Spawn Adjust" : 0 : "Adjust the minimum respawn time for BLU by this amount (in seconds) " +
+ "when BLU captures this point. If BLU owns this point when RED captures it, this adjustment is reversed."
area_time_to_cap(integer) : "Time to cap (sec)" : 5
// Inputs
- input SetTeamCanCap(string) : "Set whether a specific team is allowed to capture this point. Format is: <(0/1)>. i.e. '2 0' would prevent RED from capturing this point, whereas '3 1' would allow BLUE to cap it."
+ input SetTeamCanCap(string) : "Set whether a specific team is allowed to capture this point. Format is: <(0/1)>. i.e. '2 0' would prevent RED from capturing this point, whereas '3 1' would allow BLU to cap it."
input SetControlPoint(string) : "Assign area capture to the passed control point."
input CaptureCurrentCP(string) : "If we're being capped, forces the current point to capture."
input RoundSpawn(void) : "Find our control point"
@@ -28,9 +28,9 @@
output OnBreakTeam1(void) : "Sent when a RED capture is broken."
output OnCapTeam1(void) : "Sent when RED end capture."
- output OnStartTeam2(void) : "Sent when BLUE start capture."
- output OnBreakTeam2(void) : "Sent when a BLUE capture is broken."
- output OnCapTeam2(void) : "Sent when BLUE end capture."
+ output OnStartTeam2(void) : "Sent when BLU start capture."
+ output OnBreakTeam2(void) : "Sent when a BLU capture is broken."
+ output OnCapTeam2(void) : "Sent when BLU end capture."
output OnStartCap(void) : "Sent when either team starts capture."
output OnBreakCap(void) : "Sent when either team break capture."
diff --git a/fgd/brush/trigger/trigger_transition.fgd b/fgd/brush/trigger/trigger_transition.fgd
index e30e50d92..c0e2d46f6 100644
--- a/fgd/brush/trigger/trigger_transition.fgd
+++ b/fgd/brush/trigger/trigger_transition.fgd
@@ -1,5 +1,5 @@
@SolidClass
- base(Trigger, Origin)
+ base(BaseEntityBrush, Origin)
= trigger_transition: "A volume that's used to control which entities go through the level transition. " +
"Create one or more trigger_transitions and give them the same name as the changelevel landmark. " +
"Any entities within the trigger_transition(s) will go to the next map. " +
diff --git a/fgd/point/asw/asw_spawn_group.fgd b/fgd/point/asw/asw_spawn_group.fgd
index d97a73452..fd85be1c8 100644
--- a/fgd/point/asw/asw_spawn_group.fgd
+++ b/fgd/point/asw/asw_spawn_group.fgd
@@ -1,5 +1,13 @@
@PointClass base(BaseEntityPoint)
+ line(255 255 255, targetname, spawnername00)
+ line(255 255 255, targetname, spawnername01)
+ line(255 255 255, targetname, spawnername02)
+ line(255 255 255, targetname, spawnername03)
+ line(255 255 255, targetname, spawnername04)
+ line(255 255 255, targetname, spawnername05)
+ line(255 255 255, targetname, spawnername06)
+ line(255 255 255, targetname, spawnername07)
appliesto(ASW) = asw_spawn_group: "The named spawners will belong to this spawn group. In holdout mode, spawning is done via spawn groups rather than individual spawners."
[
spawnername00(target_destination) : "Spawner 01" : : "The name of one or more spawners."
diff --git a/fgd/point/bot/bot_action_point.fgd b/fgd/point/bot/bot_action_point.fgd
index 67641991d..b63e86adc 100644
--- a/fgd/point/bot/bot_action_point.fgd
+++ b/fgd/point/bot/bot_action_point.fgd
@@ -2,6 +2,7 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2)
autovis(TF2, TFBots, Action Point)
+ iconsprite("editor/ficool2/bot_action_point")
sphere(desired_distance) = bot_action_point: "A potential destination for a bot"
[
next_action_point(target_destination) : "Next Action Point" : : "The next Action Point to approach after performing this one."
diff --git a/fgd/point/bot/bot_controller.fgd b/fgd/point/bot/bot_controller.fgd
index ec89167b6..a3dd89187 100644
--- a/fgd/point/bot/bot_controller.fgd
+++ b/fgd/point/bot/bot_controller.fgd
@@ -1,13 +1,15 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2)
autovis(TF2, TFBots, Bot Controller)
+ iconsprite("editor/ficool2/bot_controller")
= bot_controller: "An entity used to create a bot, and then issue commands to it."
[
teamnum[engine](integer) : "Team" : 2
teamnum(choices) : "Team" : 2 : "Team" =
[
- 2: "Red"
- 3: "Blue"
+ 0: "Unassigned" [+complete]
+ 2: "RED"
+ 3: "BLU"
]
bot_class[engine](integer) : "Class" : 0
diff --git a/fgd/point/bot/bot_generator.fgd b/fgd/point/bot/bot_generator.fgd
index 05374ed2a..5a7622ef8 100644
--- a/fgd/point/bot/bot_generator.fgd
+++ b/fgd/point/bot/bot_generator.fgd
@@ -1,14 +1,15 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2)
autovis(TF2, TFBots, Bot Generator)
+ iconsprite("editor/ficool2/bot_generator")
= bot_generator: "Entity spawns TFBots every seconds, with at most active at once"
[
team[engine](string) : "Team" : "auto"
team(choices) : "Team" : "auto" : "Team" =
[
"auto": "Any"
- "red": "Red"
- "blue": "Blue"
+ "red": "RED"
+ "blue": "BLU"
]
class[engine](string) : "Class" : "auto"
diff --git a/fgd/point/bot/bot_hint_engineer_nest.fgd b/fgd/point/bot/bot_hint_engineer_nest.fgd
index 911bbc135..f3e17190f 100644
--- a/fgd/point/bot/bot_hint_engineer_nest.fgd
+++ b/fgd/point/bot/bot_hint_engineer_nest.fgd
@@ -1,5 +1,5 @@
-@PointClass base(BaseEntityPoint, BaseObject, EnableDisable)
+@PointClass base(BaseEntityPoint, EnableDisable)
appliesto(TF2)
autovis(TF2, TFBots, Bot Hint)
studio("models/bots/engineer/bot_engineer.mdl") = bot_hint_engineer_nest: "TF2 Engineer Nest Hint for Bots"
diff --git a/fgd/point/bot/bot_hint_sentrygun.fgd b/fgd/point/bot/bot_hint_sentrygun.fgd
index 6873d2d48..6004fb908 100644
--- a/fgd/point/bot/bot_hint_sentrygun.fgd
+++ b/fgd/point/bot/bot_hint_sentrygun.fgd
@@ -1,8 +1,8 @@
-@PointClass base(BaseEntityPoint, BaseObject, EnableDisable)
+@PointClass base(BaseEntityPoint, EnableDisable)
appliesto(TF2)
autovis(TF2, TFBots, Bot Hint)
- studio("models/buildables/sentry3.mdl") = bot_hint_sentrygun: "TF2 Sentry Gun Placement Hint for Bots"
+ studio("models/buildables/sentry1_blueprint.mdl") = bot_hint_sentrygun: "TF2 Sentry Gun Placement Hint for Bots"
[
sequence(integer) : "Sequence" : 5 : "Default animation sequence for the model to be playing after spawning."
sticky(boolean) : "Sticky" : "0" : "If set, Engineer bots using this hint will stay here instead of destroying their equipment and moving up as the scenario changes."
diff --git a/fgd/point/bot/bot_hint_sniper_spot.fgd b/fgd/point/bot/bot_hint_sniper_spot.fgd
deleted file mode 100644
index 7b68d342a..000000000
--- a/fgd/point/bot/bot_hint_sniper_spot.fgd
+++ /dev/null
@@ -1,10 +0,0 @@
-
-@PointClass base(BaseEntityPoint, BaseObject)
- appliesto(TF2)
- autovis(TF2, TFBots, Bot Hint)
- studio("models/player/sniper.mdl")
- sphere(radius)
-= bot_hint_sniper_spot: "TF2 Sniper Spot Hint for Bots"
- [
- radius(float) : "Hint Radius" : 100 : "Radius of hint influence."
- ]
diff --git a/fgd/point/bot/bot_hint_teleporter_exit.fgd b/fgd/point/bot/bot_hint_teleporter_exit.fgd
index 3c84734a5..4c37d4864 100644
--- a/fgd/point/bot/bot_hint_teleporter_exit.fgd
+++ b/fgd/point/bot/bot_hint_teleporter_exit.fgd
@@ -1,5 +1,5 @@
-@PointClass base(BaseEntityPoint, BaseObject)
+@PointClass base(BaseEntityPoint)
appliesto(TF2)
autovis(TF2, TFBots, Bot Hint)
studio("models/buildables/teleporter_blueprint_exit.mdl") = bot_hint_teleporter_exit: "TF2 Teleporter Exit Placement Hint for Bots"
diff --git a/fgd/point/bot/bot_proxy.fgd b/fgd/point/bot/bot_proxy.fgd
index 88f779b59..244607140 100644
--- a/fgd/point/bot/bot_proxy.fgd
+++ b/fgd/point/bot/bot_proxy.fgd
@@ -2,6 +2,7 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2)
autovis(TF2, TFBots, Bot Proxy)
+ iconsprite("editor/ficool2/bot_proxy")
= bot_proxy: "An entity that spawns a TFBot and relays events to/from it"
[
bot_name(string) : "Bot Name" : "TFBot" : "The bot's player name"
@@ -10,8 +11,8 @@
team(choices) : "Team" : "auto" : "Team" =
[
"auto": "Any"
- "red": "Red"
- "blue": "Blue"
+ "red": "RED"
+ "blue": "BLU"
]
class[engine](string) : "Class" : "auto"
diff --git a/fgd/point/bot/bot_roster.fgd b/fgd/point/bot/bot_roster.fgd
index 191da6c69..aaffd4700 100644
--- a/fgd/point/bot/bot_roster.fgd
+++ b/fgd/point/bot/bot_roster.fgd
@@ -2,14 +2,15 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2)
autovis(TF2, TFBots, Bot Roster)
+ iconsprite("editor/ficool2/bot_roster")
= bot_roster: "Entity specifies what classes TFBots can choose"
[
team[engine](string) : "Team" : "auto"
team(choices) : "Team" : "auto" : "Team" =
[
"auto": "Any"
- "red": "Red"
- "blue": "Blue"
+ "red": "RED"
+ "blue": "BLU"
]
allowclasschanges(boolean) : "Allow Class Changes" : "1" : "Allow TFBots to choose a new class when they respawn."
diff --git a/fgd/point/commentary/commentary_dummy.fgd b/fgd/point/commentary/commentary_dummy.fgd
index c60dae136..4812686d0 100644
--- a/fgd/point/commentary/commentary_dummy.fgd
+++ b/fgd/point/commentary/commentary_dummy.fgd
@@ -4,6 +4,7 @@
studio()
= commentary_dummy: "Commentary Dummy"
[
+ model[engine](string) : "Hammer Preview"
model[L4D](studio) : "Dummy Model" : "models/survivors/survivor_biker.mdl"
model[L4D2](studio) : "Dummy Model" : "models/survivors/survivor_coach.mdl"
diff --git a/fgd/point/comp/comp_adv_output.fgd b/fgd/point/comp/comp_adv_output.fgd
new file mode 100644
index 000000000..c24cd3be7
--- /dev/null
+++ b/fgd/point/comp/comp_adv_output.fgd
@@ -0,0 +1,45 @@
+@PointClass base(ControlEnables)
+ iconsprite("editor/comp_adv_output")
+ appliesto(srctools)
+ autovis(Postcompiler, Advanced Output)
+= comp_adv_output : "Adds a single output to an entity, with precise control over fixup behaviour."
+ [
+ out_ent(target_destination) : "Outputting Entity" : : "The name of the entity or entities to add the output to."
+
+ out_name(string) : "Output Name" : : "The output name to use."
+
+ target_global(string) : "Target - String" : : "A fixed entity name, !special name or classname to fire inputs at."
+ target_local(target_destination) : "Target - Ent Name" : : "If set, the entity to fire inputs at."
+
+ target_instname(string) : "Target - Instance Name" : : "If set, this is appended to the target to form a full target-inst_name name."
+
+ inp_name(string) : "Input Name" : : "The input to fire."
+
+ delay(float) : "Delay" : "0.0": "The delay to add to the output."
+ delay2(float) : "Extra Delay" : "0.0" : "A second delay to add to the first. Useful for instance parameters."
+
+ times(integer) : "Times to Fire" : -1 : "The number of times this output can fire, or -1 for infinite. Hammer normally only allows setting this to 1 or -1."
+
+ params_fmt(string) : "Parameter" : "{1}" : "Sets the parameter to use. This can contain placeholders like {1},{2} etc which will be filled by values in the" +
+ " following parameters. Use two braces like {{ or }} if you need them in the parameter directly."
+
+ params_global1(target_destination) : "Parameter 1 - String" : : "A value which will replace {1} in the parameter."
+ params_local1(target_destination) : "Parameter 1 - Ent Name" : : "If set, this is a fixed up entity name which will be used in the parameter, replacing {1}."
+ params_pos1(vector) : "Parameter 1 - Position" : : "If set, this is a XYZ position which will be used in the parameter, replacing {1}. This will be offset by instancing."
+
+ params_global2(target_destination) : "Parameter 2 - String" : : "A value which will replace {2} in the parameter."
+ params_local2(target_destination) : "Parameter 2 - Ent Name" : : "If set, this is a fixed up entity name which will be used in the parameter, replacing {1}."
+ params_pos2(vector) : "Parameter 2 - Position" : : "If set, this is a XYZ position which will be used in the parameter, replacing {2}. This will be offset by instancing."
+
+ params_global3(target_destination) : "Parameter 3 - String" : : "A value which will replace {3} in the parameter."
+ params_local3(target_destination) : "Parameter 3 - Ent Name" : : "If set, this is a fixed up entity name which will be used in the parameter, replacing {3}."
+ params_pos3(vector) : "Parameter 3 - Position" : : "If set, this is a XYZ position which will be used in the parameter, replacing {3}. This will be offset by instancing."
+
+ params_global4(target_destination) : "Parameter 4 - Ent Name" : : "A value which will replace {4} in the parameter."
+ params_local4(target_destination) : "Parameter 4 - Ent Name" : : "If set, this is a fixed up entity name which will be used in the parameter, replacing {4}."
+ params_pos4(vector) : "Parameter 4 - Position" : : "If set, this is a XYZ position which will be used in the parameter, replacing {4}. This will be offset by instancing."
+
+ params_global5(target_destination) : "Parameter 5 - String" : : "A value which will replace {5} in the parameter."
+ params_local5(target_destination) : "Parameter 5 - Ent Name" : : "If set, this is a fixed up entity name which will be used in the parameter, replacing {5}."
+ params_pos5(vector) : "Parameter 5 - Position" : : "If set, this is a XYZ position which will be used in the parameter, replacing {5}. This will be offset by instancing."
+ ]
diff --git a/fgd/point/comp/comp_case.fgd b/fgd/point/comp/comp_case.fgd
new file mode 100644
index 000000000..8b3d55cf2
--- /dev/null
+++ b/fgd/point/comp/comp_case.fgd
@@ -0,0 +1,74 @@
+@PointClass base(StaticTargetName, ControlEnables)
+ iconsprite("editor/comp_case")
+ appliesto(srctools)
+= comp_case:
+ "Simplified version of logic_case which is able to be optimised away by the compiler."+
+ "" +
+ "This is primarly intended to be used in instances - depending on a fixup value, it will produce different results." +
+ "It can be used alternatively to pick a random output, though this is fixed at compile time for each inputting entity."
+ [
+ MultipleCasesAllowed(boolean) : "Multiple case hits allowed" : 0 : "If an input value matches a given case, " +
+ "are we allowed to test the rest of the cases or should we stop there? " +
+ "Don't worry about this if you're only using this entity for PickRandom."
+
+ value(string) : "Input Value" : : "If the InValue parameter is blank or Trigger is used, this value will be used instead."
+
+ mode[engine](string) : "Mode" : "string"
+ mode(choices) : "Mode" : "casefold" : "Specifies how comparisons are performed. Text mode simply checks for a case that matches the input text. " +
+ "Numeric treats values as numbers, allowing cases to additionally specify a comparison like '< 3.14'. Weighted Random instead changes the case values to specify the chance to produce any given case. In all modes, each case is compared in order." =
+ [
+ "string" : "Text - Case Sensitive"
+ "casefold" : "Text - Case Insensitive"
+ "numeric" : "Numeric"
+ "randweight" : "Weighted Random"
+ ]
+
+ seed(string) : "Random Seed" : : "For the PickRandom input, the position and name of the input entity and the case are used to seed a random number generator. This can be set to further randomise the chosen case."
+ misschance(float) : "Miss Chance (%)" : 0 : "If nonzero, PickRandom will skip picking cases entirely this often. Only OnUsed and OnMissed will be fired."
+
+ case01(string) : "Case 01" : : "Fires OnCase01 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case02(string) : "Case 02" : : "Fires OnCase02 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case03(string) : "Case 03" : : "Fires OnCase03 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case04(string) : "Case 04" : : "Fires OnCase04 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case05(string) : "Case 05" : : "Fires OnCase05 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case06(string) : "Case 06" : : "Fires OnCase06 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case07(string) : "Case 07" : : "Fires OnCase07 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case08(string) : "Case 08" : : "Fires OnCase08 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case09(string) : "Case 09" : : "Fires OnCase09 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case10(string) : "Case 10" : : "Fires OnCase10 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case11(string) : "Case 11" : : "Fires OnCase11 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case12(string) : "Case 12" : : "Fires OnCase12 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case13(string) : "Case 13" : : "Fires OnCase13 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case14(string) : "Case 14" : : "Fires OnCase14 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case15(string) : "Case 15" : : "Fires OnCase15 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+ case16(string) : "Case 16" : : "Fires OnCase16 if the InValue parameter matches this value. In Numeric mode, comparison operators such as <, >, =, !=, >=, or <= may be put at the start of the value. In Weighted Random mode, this instead is the chance that this case will be picked."
+
+ // Inputs
+ input InValue(string) : "Replaced by whichever case matches the parameter. Does nothing in Weighted Random mode."
+ input Trigger(void) : "Replaced by whichever case matches the input keyvalue. In Weighted Random mode, behaves like PickRandom."
+ input PickRandom(void) : "Replaced by a random case with outputs defined."
+
+ // Outputs
+ output OnCase01(void) : "Fired when the input value equals the Case01 value."
+ output OnCase02(void) : "Fired when the input value equals the Case02 value."
+ output OnCase03(void) : "Fired when the input value equals the Case03 value."
+ output OnCase04(void) : "Fired when the input value equals the Case04 value."
+ output OnCase05(void) : "Fired when the input value equals the Case05 value."
+ output OnCase06(void) : "Fired when the input value equals the Case06 value."
+ output OnCase07(void) : "Fired when the input value equals the Case07 value."
+ output OnCase08(void) : "Fired when the input value equals the Case08 value."
+ output OnCase09(void) : "Fired when the input value equals the Case09 value."
+ output OnCase10(void) : "Fired when the input value equals the Case10 value."
+ output OnCase11(void) : "Fired when the input value equals the Case11 value."
+ output OnCase12(void) : "Fired when the input value equals the Case12 value."
+ output OnCase13(void) : "Fired when the input value equals the Case13 value."
+ output OnCase14(void) : "Fired when the input value equals the Case14 value."
+ output OnCase15(void) : "Fired when the input value equals the Case15 value."
+ output OnCase16(void) : "Fired when the input value equals the Case16 value."
+ output OnDefault(void) : "Fired when the input value does not equal any of the Case values."
+ output OnUsed(string) : "Fired when an input value is received, regardless of whether it matches a case."
+ output OnMatched(string) : "Fired when an input value matches any of the cases."
+ output OnMissed(string) : "Fired when the miss chance succeeded."
+
+ @resources []
+ ]
diff --git a/fgd/point/comp/comp_cubemap_parallax.fgd b/fgd/point/comp/comp_cubemap_parallax.fgd
new file mode 100644
index 000000000..3ac62356c
--- /dev/null
+++ b/fgd/point/comp/comp_cubemap_parallax.fgd
@@ -0,0 +1,13 @@
+@PointClass
+ appliesto(+srctools, ASRD)
+ base(Angles)
+ iconsprite("editor/comp_cubemap_parallax")
+ wirebox(mins, maxs)
+ sphere()
+= comp_cubemap_parallax :
+"Specifies the positions of the walls of a box-shaped room for parallax-corrected cubemaps."
+[
+ mins(vector) : "BBox Mins" : "-32 -32 -32" : "Minimum offset from the entity, defining the shape."
+ maxs(vector) : "BBox Maxes" : "32 32 32" : "Maximum offset from the entity, defining the shape."
+ radius(float) : "Cubemap Radius" : "32" : "Bounding radius to find env_cubemap entities to modify."
+]
diff --git a/fgd/point/comp/comp_flicker.fgd b/fgd/point/comp/comp_flicker.fgd
index a433773ba..720637903 100644
--- a/fgd/point/comp/comp_flicker.fgd
+++ b/fgd/point/comp/comp_flicker.fgd
@@ -6,9 +6,9 @@
= comp_flicker: "Fires on/off inputs repeatedly to simulate a flicker-on effect. " +
"This converts to an info_target, and uses all of the FireUserX inputs/outputs."
[
- target_mdl(target_destination) : "Model to Control" : : "An entity which will have skins swapped to turn on/off."
- mdl_skin_on(integer) : "On Skin" : 0 : "The 'on' skin for the model."
- mdl_skin_off(integer) : "Off Skin" : 1 : "The 'on' skin for the model."
+ target_mdl(target_destination) : "Model to Control" : : "An entity which will have skins swapped to turn on/off. This is simply a shortcut for adding OnTurnedOn/Off outputs."
+ mdl_skin_on(integer) : "On Skin" : 0 : "The 'on' skin for the model. This is a shortcut for adding OnTurnedOn -> Skin outputs."
+ mdl_skin_off(integer) : "Off Skin" : 1 : "The 'on' skin for the model. This is a shortcut for adding OnTurnedOff -> Skin outputs."
total_time(float) : "Total Time" : 1.5 : "The overall time taken to complete the on or off flicker."
flicker_min(float) : "Flicker Min" : 0.05 : "The delay used at the start of the on cycle, or at the end of the off cycle."
diff --git a/fgd/point/comp/comp_kv_setter.fgd b/fgd/point/comp/comp_kv_setter.fgd
index b5513b292..a03a07863 100644
--- a/fgd/point/comp/comp_kv_setter.fgd
+++ b/fgd/point/comp/comp_kv_setter.fgd
@@ -1,4 +1,4 @@
-@PointClass base(Angles)
+@PointClass base(Angles, ControlEnables)
iconsprite("editor/comp_kv_setter")
appliesto(srctools)
autovis(Postcompiler, KV Setter)
@@ -17,6 +17,7 @@
kv_value_global(string) : "Value - String" : : "The value to apply."
kv_value_local(target_destination) : "Value - Ent Name" : : "If set, use this fixed-up entity name."
+ kv_value_pos(vector) : "Value - Position" : : "If set, overrides the regular value. This will be offset by instancing."
invert(boolean) : "Invert Value" : 0 : "If enabled, invert the value so 0 and 1 are swapped."
rotate(boolean) : "Rotate Value" : 0 : "If enabled, treat the value as a vector and rotate it by the angles set on this entity first."
diff --git a/fgd/point/comp/comp_numeric_transition.fgd b/fgd/point/comp/comp_numeric_transition.fgd
index c1b39613a..c51a374c6 100644
--- a/fgd/point/comp/comp_numeric_transition.fgd
+++ b/fgd/point/comp/comp_numeric_transition.fgd
@@ -59,4 +59,6 @@
"sine" : "Sinusoidal"
// "overshoot" : "Overshoot"
]
+
+ output OnFinished(void) : "Fired once the transition has completed."
]
diff --git a/fgd/point/comp/comp_pack_rename.fgd b/fgd/point/comp/comp_pack_rename.fgd
index a85c2a72a..e3e32d3ab 100644
--- a/fgd/point/comp/comp_pack_rename.fgd
+++ b/fgd/point/comp/comp_pack_rename.fgd
@@ -10,7 +10,7 @@
filedest(string): "Destination Filename": : "Filename to pack under."
filetype[engine](string): "File Type": "GENERIC" : "File type to record it as."
- filetype(choices): "File Type": "GENERIC" : "File type to record it as." =
+ filetype(choices): "File Type": "GENERIC" : "File type to record it as. For Model files, the .vtx/vtx/phy etc files are also packed automatically." =
[
"GENERIC": "Generic"
"SOUNDSCRIPT": "SoundScript file (add to manifest)"
diff --git a/fgd/point/comp/comp_precache_model.fgd b/fgd/point/comp/comp_precache_model.fgd
index a6f12a8b1..5587b889b 100644
--- a/fgd/point/comp/comp_precache_model.fgd
+++ b/fgd/point/comp/comp_precache_model.fgd
@@ -3,6 +3,7 @@
studioprop()
appliesto(srctools)
autovis(Postcompiler, Precacher)
+ line(255 255 255, targetname, lineent)
= comp_precache_model:
"Force a specific model to load, for runtime switching. Duplicates will be removed."
[
@@ -10,4 +11,5 @@
skin(integer): "Skin": : "Skin to show."
skinset(string) : "Used Skins" : : "Set this to a space seperated list of all the skin numbers which will be used. " +
"This allows auto-packing to skip unused ones. If blank all skins are assumed to be used."
+ lineent(target_destination) : "Line Entity" : : "Draws a line to the specified entity. Use this to indicate in Hammer if the model is meant for a specific entity."
]
diff --git a/fgd/point/comp/comp_prop_cable.fgd b/fgd/point/comp/comp_prop_cable.fgd
index 7461537aa..8096df6f7 100644
--- a/fgd/point/comp/comp_prop_cable.fgd
+++ b/fgd/point/comp/comp_prop_cable.fgd
@@ -14,11 +14,12 @@
// Valve's interplator keyvalue just happens to provide the right visuals we want.
positioninterpolator[engine](integer): "Type": 2
- positioninterpolator(choices) : "Type" : 2 : "How to interpolate the cable. Straight makes it straight. Spline uses a spline curve, which smoothly blends between points (no visuals). Catenary makes it hang down, like the original move_rope." =
+ positioninterpolator(choices) : "Type" : 2 : "How to interpolate the cable. Straight makes it straight. Spline uses a spline curve, which smoothly blends between points. Catenary makes it hang down, like the original move_rope. Bezier is an alternate smooth curve, but the visual in Hammer will be incorrect." =
[
0: "Straight"
1: "Spline Curve"
2: "Catenary"
+ 3: "Bezier"
]
segments(integer) : "Segments" : 2 : "Number of nodes to generate between each cable. Higher values make smoother cables, but produce more faces."
@@ -48,7 +49,9 @@
]
u_min(float): "Width Start" : 0.0 : "The distance along the texture to start. 0 is the left/bottom side, 1 is the right/top side. This allows using only part of the texture, if it contains multiple different cable styles."
u_max(float): "Width End" : 1.0 : "The distance along the texture to end. 0 is the left/bottom side, 1 is the right/top side. This allows using only part of the texture, if it contains multiple different cable styles."
-
+
+ bunting(target_destination) : "Bunting Definition" : : "Set to the name of a comp_prop_rope_bunting, to define models which will be placed at each segment across the rope."
+
// A selection of prop_static's keyvalues, excluding some that are rather irrelevant.
linedivider_staticprop[!engine](string) readonly : "----------------------------------------------------------------------------------------------------------" : ""
diff --git a/fgd/point/comp/comp_prop_cable_dynamic.fgd b/fgd/point/comp/comp_prop_cable_dynamic.fgd
index e2f0e587f..72b06adcc 100644
--- a/fgd/point/comp/comp_prop_cable_dynamic.fgd
+++ b/fgd/point/comp/comp_prop_cable_dynamic.fgd
@@ -13,12 +13,19 @@
group(target_source): "Cable Group" : : "Specify the name of the group that will be compiled into this entity."
+ skin1(material) : "Alt Skin 1" : "" : "If set, an alternate material to use for Skin 1. Must be a model material, and the rope must use the same material for the entire prop."
+ skin2(material) : "Alt Skin 2" : "" : "If set, an alternate material to use for Skin 2."
+ skin3(material) : "Alt Skin 3" : "" : "If set, an alternate material to use for Skin 3."
+ skin4(material) : "Alt Skin 4" : "" : "If set, an alternate material to use for Skin 4."
+ skin5(material) : "Alt Skin 5" : "" : "If set, an alternate material to use for Skin 5. If you need more, add the keyvalue with SmartEdit off."
+
// Not inheriting from prop_dynamic_base, since most of the animation KVs are pointless.
glowbackfacemult[L4D2](float) : "Glow backface Multiplier" : "1.0" : "What to multiply glow by on backfaces."
// Inputs
input TurnOn(void) : "Make the cable set visible."
input TurnOff(void) : "Make the cable set invisible."
+ input Skin(integer) : "Change to an alternate skin for the cable set."
input EnableCollision(void) : "Enable collision on the cable set."
input DisableCollision(void) : "Disable collision on the cable set."
input BecomeRagdoll[since_P2](void) : "Change into a ragdoll immediately."
diff --git a/fgd/point/comp/comp_prop_rope.fgd b/fgd/point/comp/comp_prop_rope.fgd
index fcbbf8fc6..d12f813ea 100644
--- a/fgd/point/comp/comp_prop_rope.fgd
+++ b/fgd/point/comp/comp_prop_rope.fgd
@@ -14,11 +14,12 @@
// Valve's interplator keyvalue just happens to provide the right visuals we want.
positioninterpolator[engine](integer): "Type": 2
- positioninterpolator(choices) : "Type" : 2 : "How to interpolate the rope. Straight makes it straight. Spline uses a spline curve, which smoothly blends between points (no visuals). Catenary makes it hang down, like the original move_rope." =
+ positioninterpolator(choices) : "Type" : 2 : "How to interpolate the rope. Straight makes it straight. Spline uses a spline curve, which smoothly blends between points. Catenary makes it hang down, like the original move_rope. Bezier is an alternate smooth curve, but the visual in Hammer will be incorrect." =
[
0: "Straight"
1: "Spline Curve"
2: "Catenary"
+ 3: "Bezier"
]
segments(integer) : "Segments" : 2 : "Number of nodes to generate between each rope. Higher values make smoother ropes, but produce more faces."
diff --git a/fgd/point/comp/comp_prop_rope_bunting.fgd b/fgd/point/comp/comp_prop_rope_bunting.fgd
index 7983204d2..d61ff160e 100644
--- a/fgd/point/comp/comp_prop_rope_bunting.fgd
+++ b/fgd/point/comp/comp_prop_rope_bunting.fgd
@@ -9,7 +9,7 @@
distance(float) : "Placement Distance" : 0 : "If greater than zero, override Placement Interval, and instead place every this many units."
model(studio) : "Model" : : "Specifies the model to place. This can either be an MDL which is placed as invidual prop_statics, " +
- "or a SMD (relative to a game folder) which is merged into the rope model."
+ "or a SMD (relative to a game folder) which is merged into the rope model. Alternatively make it entirely blank to have a chance to randomly skip placing ropes."
angles(angle) : "Rotation" : "0 0 0" : "Rotate the model by this much, before applying the orientation of the rope. " +
"After this is applied, the X axis should be aligned with the rope direction."
diff --git a/fgd/point/comp/comp_prop_rope_dynamic.fgd b/fgd/point/comp/comp_prop_rope_dynamic.fgd
index d4ae7e6f8..4b146c5b3 100644
--- a/fgd/point/comp/comp_prop_rope_dynamic.fgd
+++ b/fgd/point/comp/comp_prop_rope_dynamic.fgd
@@ -3,7 +3,7 @@
sphere(fademaxdist)
studio("models/editor/comp_prop_rope_dynamic.mdl")
appliesto(srctools)
-= comp_prop_rope_dynamic: "Allows using comp_prop_rope/comp_prop_cable as a dynamic prop."
+= comp_prop_rope_dynamic: "Allows using comp_prop_rope/comp_prop_cable as a prop_dynamic."
[
spawnflags(flags) =
[
@@ -11,7 +11,7 @@
]
angles(angle) readonly: "Orientation" : "0 0 0" : "The starting orientation can't be changed, simply move the nodes."
- group(target_source): "Rope Group" : : "Specify the name of the group that will be compiled into this entity."
+ group(target_source): "Rope Group" : : "Specify the same group name as in a comp_prop_rope/comp_prop_cable. The ropes will be compiled with this entity as their origin."
// Not inheriting from prop_dynamic_base, since most of the animation KVs are pointless.
glowbackfacemult[L4D2](float) : "Glow backface Multiplier" : "1.0" : "What to multiply glow by on backfaces."
diff --git a/fgd/point/comp/comp_vactube_spline.fgd b/fgd/point/comp/comp_vactube_spline.fgd
index e585b15fb..1c0d414b7 100644
--- a/fgd/point/comp/comp_vactube_spline.fgd
+++ b/fgd/point/comp/comp_vactube_spline.fgd
@@ -15,7 +15,17 @@
1: "Vactube Junction"
]
segments(integer) : "Segments" : 2 : "Number of nodes to generate for this. Higher values make smoother tubes, but produce more faces."
- collisions(boolean) : "Enable Collisions" : 1 : "Sholuld a collision mesh should be generated?"
+ collisions(boolean) : "Enable Collisions" : 1 : "Should a collision mesh should be generated?"
+ positioninterpolator[engine](integer): "Type": 1
+ positioninterpolator(choices) : "Type" : 1 : "How to interpolate the tube. Spline uses a spline curve, which smoothly blends between points. Bezier is an alternate smooth curve, but the visual in Hammer will be incorrect." =
+ [
+ // These all function, but are kinda pointless.
+ // 0: "Straight"
+ 1: "Spline Curve"
+ // 2: "Catenary"
+ 3: "Bezier"
+ ]
+ vac_separateglass(boolean) : "Separate Glass and Frame" : 0 : "Separating glass and frame can help with transparency sorting issue"
// A selection of prop_static's keyvalues, excluding some that are rather irrelevant.
linedivider_staticprop[!engine](string) readonly : "----------------------------------------------------------------------------------------------------------" : ""
@@ -44,5 +54,4 @@
enablelightbounce[since_CSGO](boolean) : "Enable Bounced Lighting" : 0 : "Whether VRAD should create indirect lighting from this prop."
movespeed(integer) readonly: "Speed (unused)" : 1 : "This needs to be greater than zero to show the preview lines."
- positioninterpolator(integer) readonly : "Rope Mode" : 1 : "Needs to be set to '1' to produce the spline curve preview."
]
diff --git a/fgd/point/comp/comp_vactube_start.fgd b/fgd/point/comp/comp_vactube_start.fgd
index aef8b8cf3..3d10ad2be 100644
--- a/fgd/point/comp/comp_vactube_start.fgd
+++ b/fgd/point/comp/comp_vactube_start.fgd
@@ -9,7 +9,14 @@
speed(float) : "Object Speed" : 800.0 : "Set the speed of the objects produced from here, in units per second."
seed(string) : "Rotation Seed" : : "If set, consistently produce the same rotation pattern as the seed. " +
"If not set, a random seed will be selected (and printed to the compile log)."
- timer(boolean) : "Trigger automatically" : 1 : "If true, generate a logic_timer to automatically trigger with a random time."
+
+ timer[engine](integer) : "Activation Mode" : 1
+ timer(choices) : "Activation Mode" : 1 : "Controls whether a logic_timer will be generated to automatically trigger with a random time." =
+ [
+ 0: "No Timer (ForceSpawn input required)"
+ 1: "Auto Timer"
+ 2: "Auto Timer, starts disabled"
+ ]
time_min(float) : "Minimum Time" : 0.15 : "The minimum time between objects."
time_max(float) : "Maximum Time" : 0.5 : "The maximum time between objects."
diff --git a/fgd/point/entity/entity_spawn_manager.fgd b/fgd/point/entity/entity_spawn_manager.fgd
index 954b88356..00b7b3781 100644
--- a/fgd/point/entity/entity_spawn_manager.fgd
+++ b/fgd/point/entity/entity_spawn_manager.fgd
@@ -1,6 +1,7 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2)
autovis(Point Entities, Globals,Ent Spawn Manager)
+ iconsprite("editor/ficool2/entity_spawn_manager")
= entity_spawn_manager: "An entity that spawns stuff at spawn points."
[
entity_name(string) : "Entity Name" : : "Name of the entity class we are supposed to spawn."
diff --git a/fgd/point/entity/entity_spawn_point.fgd b/fgd/point/entity/entity_spawn_point.fgd
index d3ef02a92..b1da50f72 100644
--- a/fgd/point/entity/entity_spawn_point.fgd
+++ b/fgd/point/entity/entity_spawn_point.fgd
@@ -2,6 +2,7 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2)
line(128 128 0, targetname, spawn_manager_name)
+ iconsprite("editor/ficool2/entity_spawn_point")
= entity_spawn_point: "A spawn location associated with a spawn manager."
[
spawn_manager_name(string) : "Spawn Manager Name" : : "Name of the spawn manager entity we are associated with."
diff --git a/fgd/point/env/env_beverage.fgd b/fgd/point/env/env_beverage.fgd
index 6988c2ae2..baf6ebdd8 100644
--- a/fgd/point/env/env_beverage.fgd
+++ b/fgd/point/env/env_beverage.fgd
@@ -1,5 +1,6 @@
@PointClass base(BaseEntityPoint)
iconsprite("editor/ficool2/env_beverage")
+ appliesto(+complete)
= env_beverage: "HL1 Legacy: Beverage Dispenser."
[
health(integer) : "Capacity" : 10 : "Number of cans in the dispenser."
diff --git a/fgd/point/env/env_break_shooter.fgd b/fgd/point/env/env_break_shooter.fgd
index e0256a245..20cfaa5c6 100644
--- a/fgd/point/env/env_break_shooter.fgd
+++ b/fgd/point/env/env_break_shooter.fgd
@@ -7,7 +7,7 @@
[
angles(angle) : "Gib Direction (Pitch Yaw Roll)" : "0 0 0" : "The direction the gibs will fly."
- model[engine](string) : "Model" : ""
+ model[engine](string) : "Model" : "" // Suppress default behaviour, this isn't always a path.
model(choices) : "Model" : "WoodChunks" : "Thing(s) to shoot out. The choices only matter when the model type is Breakable Chunks. If a specific model is needed, enter its file path. If a point_template is needed, enter the point_template's name." =
[
"WoodChunks" : "WoodChunks"
diff --git a/fgd/point/env/env_explosion.fgd b/fgd/point/env/env_explosion.fgd
index ff8e22c75..e8bb7b17a 100644
--- a/fgd/point/env/env_explosion.fgd
+++ b/fgd/point/env/env_explosion.fgd
@@ -7,7 +7,7 @@
[
imagnitude(integer) : "Magnitude" : 100 : "The amount of damage done by the explosion."
iradiusoverride(integer) : "Radius Override" : 0 : "If specified, the radius in which the explosion damages entities. If unspecified, the radius will be based on the magnitude."
- fireballsprite(sprite) : "Fireball Sprite" : "sprites/zerogxplode.spr"
+ fireballsprite(sprite) : "Fireball Sprite" : "sprites/zerogxplode.vmt"
DamageForce(float) : "Damage Force" : 0 : "The force to apply the damage with. If unspecified, the explosion won't push entities."
rendermode[engine](integer) : "Render Mode" : 5
diff --git a/fgd/point/env/env_fade.fgd b/fgd/point/env/env_fade.fgd
index 6b9be9edc..2e330b539 100644
--- a/fgd/point/env/env_fade.fgd
+++ b/fgd/point/env/env_fade.fgd
@@ -6,9 +6,9 @@
spawnflags(flags) =
[
1: "Fade From" : 0
- 2: "Modulate" : 0
- 4: "Triggering player only" : 0 [!L4D]
- 8: "Stay Out" : 0
+ 2: "Multiply Colors" : 0
+ 4: "Only Fade !activator Player" : 0 [!L4D]
+ 8: "Stay Out (Indefinite Duration)" : 0
]
duration(float) : "Duration (seconds)" : 2 : "The time that it will take to fade the screen in or out."
diff --git a/fgd/point/env/env_global.fgd b/fgd/point/env/env_global.fgd
index 160755c2b..4d611ce94 100644
--- a/fgd/point/env/env_global.fgd
+++ b/fgd/point/env/env_global.fgd
@@ -18,6 +18,8 @@
"friendly_encounter": "Friendly encounter sequence (lower weapons, etc.)"
"gordon_invulnerable": "Player is invulnerable"
"no_seagulls_on_jeep": "Don't spawn seagulls on the jeep"
+ "citizens_passive": "Non-rebel citizens, doesn't work exactly like 'Gordon pre-criminal'"
+ "gordon_protect_driver": "Protect driver. Changes damage when in a vehicle and being crushed."
"ep2_alyx_injured": "Episode 2: Alyx injured" [ep2]
"ep_alyx_darknessmode": "Episode 1: Alyx darkness mode" [ep1]
"hunters_to_run_over": "Ep2 Counter: Hunters to run over before they dodge" [ep2]
@@ -26,7 +28,6 @@
globalstate[P2, -INFRA](choices) : "Global State to Set" =
[
- "portalgun_nospawn": "Spawn without Portalgun"
"no_pinging_blue": "Prevent Pinging ATLAS"
"no_pinging_orange": "Prevent Pinging P-Body"
"no_taunting_blue": "Prevent Taunting ATLAS"
diff --git a/fgd/point/env/env_headcrabcanister.fgd b/fgd/point/env/env_headcrabcanister.fgd
index d2f322823..e7f619b14 100644
--- a/fgd/point/env/env_headcrabcanister.fgd
+++ b/fgd/point/env/env_headcrabcanister.fgd
@@ -1,6 +1,7 @@
@PointClass base(BaseEntityAnimating)
appliesto(EP1, EP2, HL2, P1)
sphere(DamageRadius)
+ line(255 255 0, targetname, launchpositionname)
studio("models/props_combine/headcrabcannister01b.mdl") = env_headcrabcanister: "Headcrab canister"
[
spawnflags(flags) : "spawnflags" =
diff --git a/fgd/point/env/env_movieexplosion.fgd b/fgd/point/env/env_movieexplosion.fgd
index 72dd4473c..27bd40ade 100644
--- a/fgd/point/env/env_movieexplosion.fgd
+++ b/fgd/point/env/env_movieexplosion.fgd
@@ -1,5 +1,6 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2)
+ iconsprite("editor/ficool2/env_movieexplosion")
= env_movieexplosion : ""
[
@resources
diff --git a/fgd/point/env/env_portal_path_track.fgd b/fgd/point/env/env_portal_path_track.fgd
index bfe2accd8..d685a4921 100644
--- a/fgd/point/env/env_portal_path_track.fgd
+++ b/fgd/point/env/env_portal_path_track.fgd
@@ -4,14 +4,7 @@
= env_portal_path_track: "An unused variant of path_track, presumably intended for Unstationary Scaffolds. " +
"It produces a beam between each node, as well as (somewhat buggy) endpoint effects which are based on the entity's angles."
[
- track_beam_scale(float) : "Scale Track FX" : 0 : "The amount to scale the track FX size. Appears non-functional."
- end_point_scale(float) : "Scale Endpoint FX" : 0 : "The amount to scale the endpoint FX size. Appears non-functional."
- end_point_fadeout(float) : "Fade Out Endpoint" : 0 : "Amount of time to fade out the endpoint FX. Appears non-functional."
- end_point_fadein(float) : "Fade In Endpoint" : 0 : "Amount of time to fade in the endpoint FX. Appears non-functional."
-
- // Inputs
+ // Most of the keyvalues and inputs in the original FGD are disabled in code
input ActivateTrackFX(void) : "Enable the track beam FX."
- input ActivateEndPointFX(void) : "Enable the endpoint FX. Appears non-functional."
input DeactivateTrackFX(void) : "Disable the track beam FX."
- input DeactivateEndPointFX(void) : "Disable the endpoint FX. Appears non-functional."
]
diff --git a/fgd/point/env/env_projectedtexture.fgd b/fgd/point/env/env_projectedtexture.fgd
index 9adb83fa7..3e8cc1f5b 100644
--- a/fgd/point/env/env_projectedtexture.fgd
+++ b/fgd/point/env/env_projectedtexture.fgd
@@ -12,7 +12,7 @@
spawnflags(flags) =
[
1: "Enabled" : 1
- 2: "Always Update (moving light)" : 0 [since_ASW. MBase]
+ 2: "Always Update (moving light)" : 0 [since_ASW, MBase]
]
target(target_destination) : "target" : : "target"
diff --git a/fgd/point/env/env_rock_launcher.fgd b/fgd/point/env/env_rock_launcher.fgd
index e144e13f9..64094bac2 100644
--- a/fgd/point/env/env_rock_launcher.fgd
+++ b/fgd/point/env/env_rock_launcher.fgd
@@ -1,6 +1,7 @@
@PointClass base(BaseEntityPoint)
appliesto(L4D, L4D2)
studio("models/editor/cone_helper.mdl")
+ line(255 255 255, targetname, rocktargetname)
= env_rock_launcher: "Rock launcher"
[
rocktargetname(target_destination) : "Target Name" : : "The name of the entity to throw the rock at."
diff --git a/fgd/point/env/env_smoketrail.fgd b/fgd/point/env/env_smoketrail.fgd
index 745ab35f1..da9a0466e 100644
--- a/fgd/point/env/env_smoketrail.fgd
+++ b/fgd/point/env/env_smoketrail.fgd
@@ -17,8 +17,8 @@
startsize(float) : "Starting particle size" : 15 : "Starting particle size."
endsize(float) : "Ending particle size" : 50 : "Ending particle size."
spawnradius(float) : "Spawn radius" : 15 : "Distance from env_smoketrail at which particles are emitted."
- firesprite(sprite) : "Fire Sprite" : "sprites/firetrail.spr"
- smokesprite(sprite) : "Smoke Puff" : "sprites/whitepuff.spr"
+ firesprite(sprite) : "Fire Sprite" : "sprites/firetrail.vmt"
+ smokesprite(sprite) : "Smoke Puff" : "sprites/whitepuff.vmt"
@resources
[
diff --git a/fgd/point/env/env_soundscape_proxy.fgd b/fgd/point/env/env_soundscape_proxy.fgd
index fa5e2ae3c..b944fe1a4 100644
--- a/fgd/point/env/env_soundscape_proxy.fgd
+++ b/fgd/point/env/env_soundscape_proxy.fgd
@@ -2,6 +2,14 @@
sphere()
autovis(Sounds, Soundscapes)
line(255 255 255, targetname, MainSoundscapeName)
+ line(128 128 128, targetname, position0)
+ line(128 128 128, targetname, position1)
+ line(128 128 128, targetname, position2)
+ line(128 128 128, targetname, position3)
+ line(128 128 128, targetname, position4)
+ line(128 128 128, targetname, position5)
+ line(128 128 128, targetname, position6)
+ line(128 128 128, targetname, position7)
iconsprite("editor/env_soundscape_proxy.vmt")
= env_soundscape_proxy: "An entity that acts like a soundscape but gets all of its sound parameters from another env_soundscape entity."
[
diff --git a/fgd/point/env/env_speaker.fgd b/fgd/point/env/env_speaker.fgd
index fb23559d7..c11338598 100644
--- a/fgd/point/env/env_speaker.fgd
+++ b/fgd/point/env/env_speaker.fgd
@@ -1,4 +1,5 @@
-@PointClass base(BaseEntityPoint, ResponseContext)
+@PointClass base(BaseEntityPoint, ResponseContext)
+ line(255 255 255, targetname, target)
iconsprite("editor/ambient_generic.vmt") = env_speaker: "Announcement Speaker"
[
delaymin(string) : "Min Delay Between Announcements" : 15
diff --git a/fgd/point/env/env_sprite.fgd b/fgd/point/env/env_sprite.fgd
index 60c791366..ca9f6a20f 100644
--- a/fgd/point/env/env_sprite.fgd
+++ b/fgd/point/env/env_sprite.fgd
@@ -6,7 +6,7 @@
= env_sprite: "An entity that controls the drawing of a sprite in the world."
[
framerate(float) : "Framerate" : "10.0" : "Rate at which the sprite should animate, if at all."
- model(sprite) : "Sprite Name" : "sprites/glow01.spr" : "Material of the sprite to be drawn."
+ model(sprite) : "Sprite Name" : "sprites/glow01.vmt" : "Material of the sprite to be drawn."
scale(float) : "Scale" : 0.25 : "Scale multiplier of the sprite."
spawnflags(flags) =
[
diff --git a/fgd/point/env/env_tracer.fgd b/fgd/point/env/env_tracer.fgd
index 97d0182f5..b1b165bf6 100644
--- a/fgd/point/env/env_tracer.fgd
+++ b/fgd/point/env/env_tracer.fgd
@@ -1,5 +1,6 @@
@PointClass base(BaseEntityPoint)
+line(255 255 255, targetname, target)
appliesto(ASW, EP1, EP2, HL2, MBase, P1, CSGO, Mesa) = env_tracer: "An entity that fires a tracer between itself and a specified target, with a configurable delay."
[
target(target_destination) : "Target" : : "The target to shoot a tracer at."
diff --git a/fgd/point/env/env_weaponfire.fgd b/fgd/point/env/env_weaponfire.fgd
index 052b0da56..3bd2bd117 100644
--- a/fgd/point/env/env_weaponfire.fgd
+++ b/fgd/point/env/env_weaponfire.fgd
@@ -19,9 +19,10 @@
targetteam[engine](integer) : "Target Team" : 3
targetteam(choices) : "Target Team" : 3 =
[
- 3: "Zombies"
+ -1: "Any"
+ 0: "Unassigned" [+complete]
2: "Survivors"
- -1: "Either"
+ 3: "Infected"
]
ignoreplayers[engine](boolean) : "Ignore Players" : 0
diff --git a/fgd/point/filter/filter_activator_context.fgd b/fgd/point/filter/filter_activator_context.fgd
index 198f14d6b..a276af3d7 100644
--- a/fgd/point/filter/filter_activator_context.fgd
+++ b/fgd/point/filter/filter_activator_context.fgd
@@ -1,6 +1,6 @@
@FilterClass base(filter_base)
autovis(Logic, Filters)
- appliesto(since_L4D, MBase)
+ appliesto(since_L4D, MBase, GMod)
iconsprite("editor/filter_context.vmt")
= filter_activator_context: "A filter that filters by a context on the activator."
[
diff --git a/fgd/point/filter/filter_activator_involume.fgd b/fgd/point/filter/filter_activator_involume.fgd
index fac439ceb..7efa750bb 100644
--- a/fgd/point/filter/filter_activator_involume.fgd
+++ b/fgd/point/filter/filter_activator_involume.fgd
@@ -3,6 +3,7 @@
appliesto(MBase)
iconsprite("editor/filter_involume.vmt")
line(255 255 255, targetname, target)
+ line(0 255 255, targetname, tester)
= filter_activator_involume : "A filter that tests whether the activator is within a volume."
[
target(target_destination) : "Volume" : : "The volume to be tested with. This filter passes if the activator is within this volume. " +
diff --git a/fgd/point/filter/filter_activator_model.fgd b/fgd/point/filter/filter_activator_model.fgd
index f6bb463f1..0055c4ccb 100644
--- a/fgd/point/filter/filter_activator_model.fgd
+++ b/fgd/point/filter/filter_activator_model.fgd
@@ -1,9 +1,12 @@
@FilterClass base(filter_base)
autovis(Logic, Filters)
- appliesto(since_L4D2, MBase, Mesa)
+ appliesto(since_L4D2, MBase, Mesa, GMod)
iconsprite("editor/filter_model.vmt")
= filter_activator_model: "A filter that filters by the model of the activator."
[
+ // Though this is a model KV, the filter won't be loading the model itself.
+ // That's up to the target entities.
+ model[engine](string) : "Filter Model"
model(studio) : "Filter Model" : : "The model to filter by. " +
"If the filter mode is Allow, only entities whose model matches the given string will pass the filter. " +
"If the filter mode is Disallow, all entities EXCEPT those whose model matches the string will pass the filter."
diff --git a/fgd/point/filter/filter_activator_team.fgd b/fgd/point/filter/filter_activator_team.fgd
index 954eb2b44..8345284cb 100644
--- a/fgd/point/filter/filter_activator_team.fgd
+++ b/fgd/point/filter/filter_activator_team.fgd
@@ -13,15 +13,19 @@
"If the filter mode is Allow, only entities whose team number matches the given team will pass the filter. " +
"If the filter mode is Disallow, all entities EXCEPT those whose team number matches the given team will pass the filter." =
[
- 2: "Terrorist"
- 3: "Counter-Terrorist"
+ 0: "Unassigned" [+complete]
+ 1: "Spectators" [+complete]
+ 2: "Terrorists"
+ 3: "Counter-Terrorists"
]
filterteam[L4D, L4D2](choices) : "Filter Team Number" : 2 : "The team number to filter by. " +
"If the filter mode is Allow, only entities whose team number matches the given team will pass the filter. " +
"If the filter mode is Disallow, all entities EXCEPT those whose team number matches the given team will pass the filter." =
[
- 2: "Survivor"
+ 0: "Unassigned" [+complete]
+ 1: "Spectators" [+complete]
+ 2: "Survivors"
3: "Infected"
]
@@ -29,6 +33,8 @@
"If the filter mode is Allow, only entities whose team number matches the given team will pass the filter. " +
"If the filter mode is Disallow, all entities EXCEPT those whose team number matches the given team will pass the filter." =
[
+ 0: "Singleplayer/Unassigned"
+ 1: "Spectators" [+complete]
2: "P-Body"
3: "ATLAS"
]
@@ -37,8 +43,10 @@
"If the filter mode is Allow, only entities whose team number matches the given team will pass the filter. " +
"If the filter mode is Disallow, all entities EXCEPT those whose team number matches the given team will pass the filter." =
[
- 2 : "Hgrunt"
- 3 : "Scientist"
+ 0: "Unassigned"
+ 1: "Spectators" [+complete]
+ 2 : "HECU"
+ 3 : "Scientists"
]
@resources []
diff --git a/fgd/point/filter/filter_activator_tfteam.fgd b/fgd/point/filter/filter_activator_tfteam.fgd
index 0ad5a964d..aeaaf5f4c 100644
--- a/fgd/point/filter/filter_activator_tfteam.fgd
+++ b/fgd/point/filter/filter_activator_tfteam.fgd
@@ -1,7 +1,7 @@
@FilterClass base(filter_base, TeamNum)
appliesto(TF2)
autovis(Logic, Filters)
- iconsprite("editor/filter_team.vmt")
+ iconsprite("editor/ficool2/filter_activator_tfteam.vmt")
line(0 255 0, targetname, controlpoint)
= filter_activator_tfteam: "A filter that filters by the team of the activator. "
[
diff --git a/fgd/point/filter/filter_damage_transfer.fgd b/fgd/point/filter/filter_damage_transfer.fgd
index 037f1760e..1a31d5ce2 100644
--- a/fgd/point/filter/filter_damage_transfer.fgd
+++ b/fgd/point/filter/filter_damage_transfer.fgd
@@ -1,6 +1,7 @@
@FilterClass base(BaseRedirectFilter)
autovis(Logic, Filters)
appliesto(MBase)
+ line(255 255 255, targetname, target)
iconsprite("editor/filter_damage_transfer.vmt")
= filter_damage_transfer :
"Whenever an entity using this as a damage filter takes damage, that damage is transferred to another entity. " +
diff --git a/fgd/point/func/func_instance_io_proxy.fgd b/fgd/point/func/func_instance_io_proxy.fgd
index 03e9c23a6..259116375 100644
--- a/fgd/point/func/func_instance_io_proxy.fgd
+++ b/fgd/point/func/func_instance_io_proxy.fgd
@@ -33,21 +33,21 @@
input OnProxyRelay13[engine](string) : "This input will cause the corresponding output to be fired."
input OnProxyRelay14[engine](string) : "This input will cause the corresponding output to be fired."
input OnProxyRelay15[engine](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay16[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay17[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay18[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay19[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay20[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay21[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay22[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay23[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay24[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay25[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay26[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay27[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay28[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay29[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
- input OnProxyRelay30[engine, since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay16[engine](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay17[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay18[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay19[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay20[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay21[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay22[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay23[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay24[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay25[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay26[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay27[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay28[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay29[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
+ input OnProxyRelay30[engine, +since_P2](string) : "This input will cause the corresponding output to be fired."
output OnProxyRelay1[engine](string) : "This will be fired when the corresponding input is triggered."
output OnProxyRelay2[engine](string) : "This will be fired when the corresponding input is triggered."
@@ -65,20 +65,20 @@
output OnProxyRelay14[engine](string) : "This will be fired when the corresponding input is triggered."
output OnProxyRelay15[engine](string) : "This will be fired when the corresponding input is triggered."
output OnProxyRelay16[engine](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay17[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay18[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay19[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay20[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay21[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay22[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay23[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay24[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay25[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay26[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay27[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay28[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay29[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
- output OnProxyRelay30[engine, since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay17[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay18[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay19[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay20[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay21[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay22[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay23[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay24[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay25[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay26[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay27[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay28[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay29[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
+ output OnProxyRelay30[engine, +since_P2](string) : "This will be fired when the corresponding input is triggered."
@resources []
]
diff --git a/fgd/point/game/game_forcerespawn.fgd b/fgd/point/game/game_forcerespawn.fgd
index adb8606c8..02b99beb2 100644
--- a/fgd/point/game/game_forcerespawn.fgd
+++ b/fgd/point/game/game_forcerespawn.fgd
@@ -1,11 +1,12 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/game_forcerespawn")
appliesto(TF2) = game_forcerespawn: "Removes buildings, grenades, etc., from the world and forces all players to respawn (without being killed)."
[
// Inputs
input ForceRespawn(void) : "Force players to respawn and remove buildings, grenades, etc., from the world.."
input ForceRespawnSwitchTeams(void) : "Switch all players to the opposite team, and then respawn all players (and remove buildings, grenades, etc., from the world)."
- input ForceTeamRespawn(integer) : "Force players on a specific team to respawn. 2 for Red, 3 for Blue. This does NOT remove buildings, grenades, etc., from the world..."
+ input ForceTeamRespawn(integer) : "Force players on a specific team to respawn. 2 for RED, 3 for BLU. This does NOT remove buildings, grenades, etc., from the world..."
// Outputs
output OnForceRespawn(void) : "Sent when the entity respawns the players."
diff --git a/fgd/point/game/game_intro_viewpoint.fgd b/fgd/point/game/game_intro_viewpoint.fgd
index 5aed88de7..341abf87a 100644
--- a/fgd/point/game/game_intro_viewpoint.fgd
+++ b/fgd/point/game/game_intro_viewpoint.fgd
@@ -6,9 +6,10 @@
teamnum[engine](integer) : "Team" : 0
teamnum(choices) : "Team" : 0 : "Team" =
[
- 0: "None (Shared)"
- 2: "Red"
- 3: "Blue"
+ 0: "Both"
+ 1: "Spectators" [+complete]
+ 2: "RED"
+ 3: "BLU"
]
step_number(integer) : "Step Number. Intro starts at 1." : 1
diff --git a/fgd/point/game/game_player_team.fgd b/fgd/point/game/game_player_team.fgd
index 6a1a3cb2f..7d36a752f 100644
--- a/fgd/point/game/game_player_team.fgd
+++ b/fgd/point/game/game_player_team.fgd
@@ -1,5 +1,6 @@
@PointClass base(BaseEntityPoint, MasterEnt)
iconsprite("editor/ficool2/game_player_team")
+ line(255 255 0, targetname, target)
color(200 0 0)
= game_player_team: "An entity that changes the team of the player who activates it."
[
diff --git a/fgd/point/game/game_round_win.fgd b/fgd/point/game/game_round_win.fgd
index 631377624..3faed6af4 100644
--- a/fgd/point/game/game_round_win.fgd
+++ b/fgd/point/game/game_round_win.fgd
@@ -1,20 +1,23 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2, Mesa)
autovis(Point Entities, Globals, Game Round End)
+ iconsprite("editor/ficool2/game_round_win")
= game_round_win: "Tells the game rules that the round has either been won (if a team is assigned) or (for TF2) enter Sudden Death mode (if no team is assigned)."
[
teamnum[engine](integer) : "Team" : 0
teamnum[TF2](choices) : "Team" : 0 : "Team" =
[
0: "None (Sudden Death)"
- 2: "Red"
- 3: "Blue"
+ 1: "Spectators (?)" [+complete]
+ 2: "RED"
+ 3: "BLU"
]
team[engine](integer) : "Team" : 0
team[Mesa](choices) : "Team" : 0 : "Team" =
[
0 : "None"
+ 1 : "Spectators (?)" [+complete]
2 : "Marines (Team-based game modes only)"
3 : "Scientists (Team-based game modes only)"
]
diff --git a/fgd/point/game/game_text.fgd b/fgd/point/game/game_text.fgd
index 41da377e7..24ad69015 100644
--- a/fgd/point/game/game_text.fgd
+++ b/fgd/point/game/game_text.fgd
@@ -39,12 +39,14 @@
"stored in channels. Select which channel this text should be placed in, " +
"which will overwrite any active message already in that channel." =
[
- 0: "Channel 0 (warning: may be used by some HUD elements)"
- 1: "Channel 1 (medium text size)"
- 2: "Channel 2 (small text size)"
- 3: "Channel 3 (large text size)"
- 4: "Channel 4 (medium text size)"
- 5: "Channel 5 (warning: may be used by some HUD elements)"
+ 0: "Channel 0 (warning: may be used by HUD)"
+ 1: "Channel 1"
+ 2: "Channel 2" [!P2]
+ 3: "Channel 3" [!P2]
+ 2: "Channel 2 (small text size)" [P2]
+ 3: "Channel 3 (large text size)" [P2]
+ 4: "Channel 4"
+ 5: "Channel 5 (warning: may be used by HUD)"
]
customfont[KZ](string) : "Custom Font Name" : "" : "The name of the Game Font to use for this text. Game font lists are found in the KreedzClimbing/kz/resource/ClientScheme.res and SourceScheme.res (examples: ClientTitleFont, DefaultSmall). Custom .ttf files are currently not supported. Leave blank to use the default font."
autobreak[MBase](boolean) : "Automatically break lines" : 0 : "Allows text to automatically shift to the next line whenever it can't fit on a player's screen. " +
diff --git a/fgd/point/game/game_text_tf.fgd b/fgd/point/game/game_text_tf.fgd
index 796802f4c..da4f77aaa 100644
--- a/fgd/point/game/game_text_tf.fgd
+++ b/fgd/point/game/game_text_tf.fgd
@@ -412,8 +412,9 @@
display_to_team(choices) : "Audience" : 0 =
[
0: "Everyone"
- 2: "Red Team Only"
- 3: "Blue Team Only"
+ 1: "Spectators Only" [+complete]
+ 2: "RED Team Only"
+ 3: "BLU Team Only"
]
background[engine](integer) : "Background Panel Color" : 0
diff --git a/fgd/point/halloween/halloween_fortune_teller.fgd b/fgd/point/halloween/halloween_fortune_teller.fgd
index 4b7553a03..c1b34efcd 100644
--- a/fgd/point/halloween/halloween_fortune_teller.fgd
+++ b/fgd/point/halloween/halloween_fortune_teller.fgd
@@ -2,8 +2,8 @@
appliesto(TF2)
studio("models/bots/merasmus/merasmas_misfortune_teller.mdl") = halloween_fortune_teller: "Halloween Fortune Teller trigger"
[
- red_teleport(string) : "Red Teleport Entity" : : "Where to teleport the red team"
- blue_teleport(string) : "Blue Teleport Entity" : : "Where to teleport the blue team"
+ red_teleport(string) : "RED Teleport Entity" : : "Where to teleport the RED team"
+ blue_teleport(string) : "BLU Teleport Entity" : : "Where to teleport the BLU team"
// Inputs
input EnableFortuneTelling(void) : "Enable fortune telling"
diff --git a/fgd/point/halloween/halloween_souls_pack.fgd b/fgd/point/halloween/halloween_souls_pack.fgd
index 14fc57841..8ad8c44ae 100644
--- a/fgd/point/halloween/halloween_souls_pack.fgd
+++ b/fgd/point/halloween/halloween_souls_pack.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityAnimating, TeamNum)
+ iconsprite("editor/ficool2/halloween_souls_pack")
appliesto(TF2)
= halloween_souls_pack : "GARGOYLE SOUL"
[
diff --git a/fgd/point/halloween/halloween_zapper.fgd b/fgd/point/halloween/halloween_zapper.fgd
index 5c3fbcfa3..4ae4ccd08 100644
--- a/fgd/point/halloween/halloween_zapper.fgd
+++ b/fgd/point/halloween/halloween_zapper.fgd
@@ -1,5 +1,6 @@
@PointClass base(BaseEntityPoint)
- appliesto(TF2)
+ appliesto(TF2)
+ line(255 255 255, targetname, touch_trigger)
iconsprite("editor/bullseye.vmt") = halloween_zapper: "Halloween Hell Zapper"
[
touch_trigger(target_destination) : "Custom Touch Trigger"
diff --git a/fgd/point/hammer/hammer_notes.fgd b/fgd/point/hammer/hammer_notes.fgd
index fe88c0907..35e4b9783 100644
--- a/fgd/point/hammer/hammer_notes.fgd
+++ b/fgd/point/hammer/hammer_notes.fgd
@@ -7,12 +7,14 @@
worldtext()
= hammer_notes: "Fake entity to store notes and comments inside. Won`t spawn."
[
- // If not in CSGO, this isn't going to do anything, so remove the size/color KVs,
- // and change help.
- message[until_CSGO](string) : "Message" : : "A text field for entering any notes."
- message[since_CSGO](string) : "Display Message" : : "Text to display in the 3D view."
- textsize[since_CSGO](float) : "Text Size" : 10 : "Text Size."
- color[since_CSGO](color255) : "Color" : "255 255 255"
+ // If not in CSGO or Hammer++, this isn't going to do anything so change help.
+ // FIXME: We could maybe replace the hammerplusplus_fgd.fgd file to make these only appear when actually using hammer++
+ message[until_CSGO](string) : "Message" : : "A text field for entering any notes. If you are using Hammer++, this will also appear in the 3D view."
+ textsize[since_CSGO](float) : "Text Size" : 10 : "Size of the text in the 3D view (Hammer++)"
+ color[since_CSGO](color255) : "Color" : "255 255 255" : "Color of the text in the 3D view (Hammer++)"
+ message[since_CSGO](string) : "Display Message" : : "Text to display in the 3D view"
+ textsize[since_CSGO](float) : "Text Size" : 10 : "Size of the text in the 3D view"
+ color[since_CSGO](color255) : "Color" : "255 255 255" : "Color of the text in the 3D view"
scale(float) : "Scale" : "0.25" : "Changes the icon size, to allow seeing this from further away."
linename1(target_destination) : "White Related Entity" : : "Add entity names to have lines drawn to them."
diff --git a/fgd/point/hightower_teleport_vortex.fgd b/fgd/point/hightower_teleport_vortex.fgd
index 039a0835c..b235096c8 100644
--- a/fgd/point/hightower_teleport_vortex.fgd
+++ b/fgd/point/hightower_teleport_vortex.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/hightower_teleport_vortex")
appliesto(TF2) = hightower_teleport_vortex: "Halloween Vortex"
[
target_base_name(string) : "Destination base name" : : "The base name of the destination. (ie. If using 'hell_winner' and 'hell_loser', then 'hell' is the base name.)"
diff --git a/fgd/point/hl2_gamerules.fgd b/fgd/point/hl2_gamerules.fgd
index 3f3d3956b..35e0bfc87 100644
--- a/fgd/point/hl2_gamerules.fgd
+++ b/fgd/point/hl2_gamerules.fgd
@@ -64,4 +64,10 @@
input SetLegacyFlashlight(bool) : "Sets legacy flashlight."
input SetStunstickPickupBehavior(bool) : "Sets stunstick pickup behavior."
input SetAllowSPRespawn(bool) : "Sets SP respawning."
+
+ @resources
+ [
+ // We want to include the resources for the specified citizen type.
+ func hl2_gamerules
+ ]
]
diff --git a/fgd/point/hot/hot_potato.fgd b/fgd/point/hot/hot_potato.fgd
index fd26a026b..988287906 100644
--- a/fgd/point/hot/hot_potato.fgd
+++ b/fgd/point/hot/hot_potato.fgd
@@ -1,7 +1,18 @@
+@PointClass base(BasePropPhysics, SRCModel)
+ appliesto(P2)
+ studioprop()
+ line(255 255 0, targetname, spawnername)
+= hot_potato: "A glass futbol variant which explodes and can't be thrown. Spawning this from a hot_potato_spawner allows it to have a timer set."
+[
+ model[-srctools](studio) : "[H] Model" : "models/props/futbol.mdl" : "The model to display in Hammer. VScript must be used to set the in-game model."
+ model[+srctools](studio) : "[HA] Custom Model" : "models/props/futbol.mdl" : "The model to display in Hammer, and the custom model to use if Override Model is enabled."
+ skin(integer) : "Skin" : 0 : "Skin on the model to use."
-@PointClass base(prop_glass_futbol, prop_exploding_futbol)
- appliesto(P2)
- studioprop("models/props/futbol.mdl")
- line(255 255 0, targetname, spawnername) = hot_potato: "This uses the futbol model. It can be carried around, but on impact it explodes, similar to prop_exploding_futbols."
- [
- ]
+ explodeontouch(boolean) : "Explode on touch" : 1 : "If the hot potato should explode when it touches something."
+ ShouldRespawn(boolean) : "Should respawn" : 1 : "If the hot potato should respawn at the specified spawner when destroyed. Not specifying a spawner is functionally identical to turning this off, but causes extra console spam."
+ spawnername(target_destination) : "Spawner Name" : : "Name of a hot_potato_spawner for this hot potato to respawn in once broken."
+
+ // Inputs
+ input Explode(void) : "Explodes the hot potato."
+ input Dissolve(void) : "Fizzles the hot potato. Doesn't fire the OnFizzled output."
+]
diff --git a/fgd/point/hot/hot_potato_catcher.fgd b/fgd/point/hot/hot_potato_catcher.fgd
index 439661cc4..85dcb2d5e 100644
--- a/fgd/point/hot/hot_potato_catcher.fgd
+++ b/fgd/point/hot/hot_potato_catcher.fgd
@@ -1,6 +1,6 @@
-@PointClass base(prop_glass_futbol_socket)
+@PointClass base(hot_potato_socket)
appliesto(P2)
- studio("models/editor/axis_helper.mdl") = hot_potato_catcher: "Catches 'hot potatos' and fires an output."
+= hot_potato_catcher: "Invisible entity that holds 'hot potatos' and fires an output. Identical to hot_potato_socket, except it doesn't play any sounds when a hot potato is inserted."
[
]
diff --git a/fgd/point/hot/hot_potato_socket.fgd b/fgd/point/hot/hot_potato_socket.fgd
index d9f8443e4..de6a2d51f 100644
--- a/fgd/point/hot/hot_potato_socket.fgd
+++ b/fgd/point/hot/hot_potato_socket.fgd
@@ -1,6 +1,10 @@
-
-@PointClass base(prop_glass_futbol_socket)
+@PointClass base(BaseEntityPoint)
appliesto(P2)
- studio("models/editor/axis_helper.mdl") = hot_potato_socket: "Catches (bombs?) and fires an output."
+ studio("models/editor/angle_helper.mdl")
+= hot_potato_socket: "Invisible entity that holds 'hot potatos' and fires an output. When a hot potato comes close it will snap into place."
[
+
+ // Outputs
+ output OnHotPotatoReleased(void) : "Player has taken the hot potato out of this socket."
+ output OnHotPotatoCaught(void) : "This socket has captured a hot potato."
]
diff --git a/fgd/point/hot/hot_potato_spawner.fgd b/fgd/point/hot/hot_potato_spawner.fgd
index 50c399ba5..c4653952b 100644
--- a/fgd/point/hot/hot_potato_spawner.fgd
+++ b/fgd/point/hot/hot_potato_spawner.fgd
@@ -1,6 +1,20 @@
-
-@PointClass base(prop_glass_futbol_spawner)
+@PointClass base(BaseEntityAnimating)
appliesto(P2)
- studioprop("models/props/futbol_dispenser.mdl") = hot_potato_spawner: "Catches 'hot potatos' and fires an output."
+ studioprop("models/props/futbol_dispenser.mdl")
+= hot_potato_spawner: "Spawns 'hot potatos'. Will re-create a hot potato when its created hot potato breaks."
[
+ startwithhotpotato(boolean) : "Start with Hot Potato" : 1 : "Set true if this spawner starts with a hot potato in it. " +
+ "Set to false if this spawner's hot potato will be manually placed in the map."
+ IsTimed(boolean) : "Is Timed" : 0 : "If enabled, the hot potatos created from this spawner will automatically explode after a set amount of time."
+ Timer(float) : "Timer" : "10" : "Length of the timer, in seconds."
+ TimerIndicatorName(target_destination) : "Timer Indicator Name" : : "Name of a prop_indicator_panel that should show the time remaining."
+
+ // Inputs
+ input ForceSpawn(void) : "Spawns a new hot potato. Usually isn't necessary, because hot potatos respawn automatically if broken."
+
+ // Outputs
+ output OnHotPotatoSpawned(void) : "Created a new hot potato."
+ output OnHotPotatoGrabbed(void) : "Player has taken the hot potato out of this spawner."
+ output OnHotPotatoCaught(void) : "Player has put the hot potato back into this spawner."
+ output OnHotPotatoReleased(void) : "Player has grabbed a hot potato from or put a hot potato back into this spawner."
]
diff --git a/fgd/point/info/info_ladder_dismount.fgd b/fgd/point/info/info_ladder_dismount.fgd
index 1ee22bc9e..fa58007d8 100644
--- a/fgd/point/info/info_ladder_dismount.fgd
+++ b/fgd/point/info/info_ladder_dismount.fgd
@@ -1,5 +1,6 @@
@PointClass base(BaseEntityPoint)
size(-16 -16 0, 16 16 4)
+ line(255 255 255, targetname, target)
color(255 128 255)
= info_ladder_dismount: "An entity to handle endpoints for multiple ladders that are too close to each other."
[
diff --git a/fgd/point/info/info_lighting_relative.fgd b/fgd/point/info/info_lighting_relative.fgd
index c8c3f9226..23dfeca8e 100644
--- a/fgd/point/info/info_lighting_relative.fgd
+++ b/fgd/point/info/info_lighting_relative.fgd
@@ -1,6 +1,7 @@
@PointClass
base(BaseEntityPoint)
- appliesto(until_L4D, +complete)
+ appliesto(until_L4D)
+ line(255 255 255, targetname, lightinglandmark)
iconsprite("editor/ficool2/info_lighting_relative.vmt")
halfgridsnap
= info_lighting_relative
diff --git a/fgd/point/info/info_player_deathmatch.fgd b/fgd/point/info/info_player_deathmatch.fgd
index 4d89881f9..8fddf7ebf 100644
--- a/fgd/point/info/info_player_deathmatch.fgd
+++ b/fgd/point/info/info_player_deathmatch.fgd
@@ -1,8 +1,12 @@
@PointClass base(BaseEntityPoint, PlayerClass)
autovis(Point Entities, Globals, Player Spawn, Deathmatch Spawn)
appliesto(HL2DM, Mesa, HL2, EP1, EP2, P1)
- studio("models/editor/playerstart.mdl") = info_player_deathmatch: "Generic multiplayer spawn point, used in games which don't have their own."
+ studio("models/editor/playerstart.mdl")
+ sphere(_blocked_dist) = info_player_deathmatch: "Generic multiplayer spawn point, used in games which don't have their own."
[
+ _blocked_dist[!engine](integer) readonly : "Blocked Radius" : 128 : "If another player is within this radius, the spawn point is condsidered to be blocked"+
+ " and players won't spawn here. This is a hardcoded value, listed here for visualization."
+
itemstogive[Mesa](string) : "List of items to spawn the player with."
input Enable[Mesa](void) : "Enable this spawnpoint."
diff --git a/fgd/point/info/info_player_teamspawn.fgd b/fgd/point/info/info_player_teamspawn.fgd
index 32e03c67d..925e788b5 100644
--- a/fgd/point/info/info_player_teamspawn.fgd
+++ b/fgd/point/info/info_player_teamspawn.fgd
@@ -1,9 +1,10 @@
@PointClass base(BaseEntityPoint, PlayerClass, TeamNum, EnableDisable)
autovis(Point Entities, Globals, Player Spawn)
appliesto(TF2)
- studio("models/editor/playerstart.mdl")
+ studio()
line(255 0 0, targetname, round_redspawn)
line(0 255 0, targetname, round_bluespawn)
+ line(255 255 255, targetname, controlpoint)
= info_player_teamspawn: "This entity marks the spawn point for Team Fortress players."
[
controlpoint(target_destination) : "Associated Control Point" : : "The team_control_point associated with this spawn. " +
@@ -39,8 +40,38 @@
256: "Engineer" : 1
]
- round_bluespawn(target_destination) : "Blue spawn for round" : : "Blue spawn point when the associated round is being played."
- round_redspawn(target_destination) : "Red spawn for round" : : "Red spawn point when the associated round is being played."
+ round_bluespawn(target_destination) : "BLU spawn for round" : : "BLU spawn point when the associated round is being played."
+ round_redspawn(target_destination) : "RED spawn for round" : : "RED spawn point when the associated round is being played."
+
+ skin[!engine](choices) : "[H] Team" : 0 : "Team color to display in Hammer" =
+ [
+ 0 : "RED"
+ 1 : "BLU"
+ ]
+
+ model[engine](string) : "Model" : : "Doesn't exist in engine, this is a hack to prevent auto packing"
+ model(choices) : "[H] Model" : "models/editor/playerstart_tf.mdl" : "Model to display in Hammer" =
+ [
+ "models/editor/playerstart_tf.mdl" : "Player Start"
+ "models/player/scout.mdl" : "Scout"
+ "models/player/soldier.mdl" : "Soldier"
+ "models/player/pyro.mdl" : "Pyro"
+ "models/player/demo.mdl" : "Demoman"
+ "models/player/heavy.mdl" : "Heavy"
+ "models/player/engineer.mdl" : "Engineer"
+ "models/player/medic.mdl" : "Medic"
+ "models/player/sniper.mdl" : "Sniper"
+ "models/player/spy.mdl" : "Spy"
+ "models/bots/scout/bot_scout.mdl" : "Robot Scout"
+ "models/bots/soldier/bot_soldier.mdl" : "Robot Soldier"
+ "models/bots/pyro/bot_pyro.mdl" : "Robot Pyro"
+ "models/bots/demo/bot_demo.mdl" : "Robot Demoman"
+ "models/bots/heavy/bot_heavy.mdl" : "Robot Heavy"
+ "models/bots/engineer/bot_engineer.mdl" : "Robot Engineer"
+ "models/bots/medic/bot_medic.mdl" : "Robot Medic"
+ "models/bots/sniper/bot_sniper.mdl" : "Robot Sniper"
+ "models/bots/spy/bot_spy.mdl" : "Robot Spy"
+ ]
input RoundSpawn(void) : "Re-find control points."
diff --git a/fgd/point/info/info_player_view_proxy.fgd b/fgd/point/info/info_player_view_proxy.fgd
index a08e06733..49334a281 100644
--- a/fgd/point/info/info_player_view_proxy.fgd
+++ b/fgd/point/info/info_player_view_proxy.fgd
@@ -1,5 +1,7 @@
@PointClass base(BaseEntityPoint) appliesto(MBase)
- iconsprite("editor/vizzys/info_player_view_proxy.vmt")
+ line(255 255 0, targetname, MeasureReference)
+ line(255 255 0, targetname, TargetReference)
+ iconsprite("editor/vizzys/info_player_view_proxy.vmt")
= info_player_view_proxy : "Copies a player's view as if they're at a different position. Intended to be used with script_intro."
[
Enabled(boolean) : "Start Activated" : 0 : "Starts with position offsetting enabled."
diff --git a/fgd/point/info/info_powerup_spawn.fgd b/fgd/point/info/info_powerup_spawn.fgd
index 30d50f3d4..4fba0141d 100644
--- a/fgd/point/info/info_powerup_spawn.fgd
+++ b/fgd/point/info/info_powerup_spawn.fgd
@@ -11,7 +11,8 @@
team(choices) : "Owner Team" : -2 : "Teams can own spawn points. When Powerups are dropped, they resposition themselves after timing out. They will try to pick a spawn point based on what team designation they had when they repositioned. Set to Everyone to have no team bias in spawn positioning" =
[
-2: "Everyone"
- 2: "Red"
- 3: "Blue"
+ 0: "Unassigned" [+complete]
+ 2: "RED"
+ 3: "BLU"
]
]
diff --git a/fgd/point/info/info_survivor_rescue.fgd b/fgd/point/info/info_survivor_rescue.fgd
index 02d6ada71..cf6cfcf4a 100644
--- a/fgd/point/info/info_survivor_rescue.fgd
+++ b/fgd/point/info/info_survivor_rescue.fgd
@@ -3,5 +3,7 @@
= info_survivor_rescue: "Survivor rescue point"
[
rescueeyepos(vecline) : "Eye position of survivors waiting for rescue"
+
+ model[engine](string) : "Hammer Preview"
model(studio) : "World model" : "models/editor/playerstart.mdl"
]
diff --git a/fgd/point/info/info_target.fgd b/fgd/point/info/info_target.fgd
index 53c05e467..6c6cf8871 100644
--- a/fgd/point/info/info_target.fgd
+++ b/fgd/point/info/info_target.fgd
@@ -7,7 +7,7 @@
spawnflags(flags) : "spawnflags" =
[
1: "Transmit to client (respect PVS)" : 0
- 2: "Always transmit to client (ignore PVS)" : 0
+ 2: "Always transmit to client (ignore PVS)" : 0 [since_L4D2, gmod]
]
@resources []
diff --git a/fgd/point/item/item_ammo_ar2_altfire.fgd b/fgd/point/item/item_ammo_ar2_altfire.fgd
index 69196b8d6..88192b5a0 100644
--- a/fgd/point/item/item_ammo_ar2_altfire.fgd
+++ b/fgd/point/item/item_ammo_ar2_altfire.fgd
@@ -4,7 +4,8 @@
[
@resources
[
- model "models/items/combine_rifle_ammo01.mdl"
+ model "models/items/combine_rifle_ammo01.mdl" [-entropyzero2]
+ func item_ammo_ar2_altfire [+entropyzero2] // EZ2 has multiple variants.
particle "combineball"
]
]
diff --git a/fgd/point/item/item_battery.fgd b/fgd/point/item/item_battery.fgd
index e2d3a57ca..dc8f45582 100644
--- a/fgd/point/item/item_battery.fgd
+++ b/fgd/point/item/item_battery.fgd
@@ -1,21 +1,24 @@
-@BaseClass appliesto(-mesa, -MBase) studio("models/items/battery.mdl") = _item_battery_hl2 []
-@BaseClass appliesto(-mesa, +MBase) studio() = _item_battery_mbase []
+@BaseClass appliesto(-mesa, -MBase, -EZ2) studio("models/items/battery.mdl") = _item_battery_hl2 []
+@BaseClass appliesto(-mesa, +MBase, -EZ2) studio() = _item_battery_mbase []
+@BaseClass appliesto(-mesa, -MBase, -EZ2) studio("models/items/battery.mdl") = _item_battery_ez2 []
@BaseClass appliesto(+mesa) studio("models/weapons/w_battery.mdl") = _item_battery_mesa []
@PointClass base(Item, BaseMesaPickup)
appliesto(EP1, EP2, HL2, P1, Mesa)
- base(_item_battery_hl2, _item_battery_mbase, _item_battery_mesa)
+ base(_item_battery_hl2, _item_battery_mbase, _item_battery_ez2, _item_battery_mesa)
= item_battery: "HEV battery"
[
PowerMultiplier[MBase](float) : "Power Multiplier" : "1.0" : "Multiplies the amount of armor this item gives."
- model[MBase](studio) : "Model" : "models/items/battery.mdl" : "The battery's model."
+ // Mapbase makes this customisable, but EZ2 removes that.
+ model[MBase, -EZ2](studio) : "Model" : "models/items/battery.mdl" : "The battery's model."
// Inputs
input SetPowerMultiplier[MBase](float) : "Sets the multiplier for the amount of armor this item gives."
@resources
[
- model "models/items/battery.mdl" [-Mbase] // Taken case of by model keyvalue.
+ model "models/items/battery.mdl" [-Mbase, -entropyzero2] // Taken case of by model keyvalue.
sound "ItemBattery.Touch"
+ func item_battery [+entropyzero2] // EZ2 has multiple variants.
]
]
diff --git a/fgd/point/item/item_mesa_weapons.fgd b/fgd/point/item/item_mesa_weapons.fgd
index bb597d39d..f2f37c7ed 100644
--- a/fgd/point/item/item_mesa_weapons.fgd
+++ b/fgd/point/item/item_mesa_weapons.fgd
@@ -1,14 +1,14 @@
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_357.mdl") = item_weapon_357 : "357 Revolver" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_crowbar.mdl") = item_weapon_crowbar : "Crowbar" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_crossbow.mdl") = item_weapon_crossbow : "Crossbow" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_grenade.mdl") = item_weapon_frag : "Frag Grenade" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_glock.mdl") = item_weapon_glock : "Glock-18 Handgun" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_egon_pickup.mdl") = item_weapon_gluon : "Gluon Gun" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_hgun.mdl") = item_weapon_hivehand : "Hivearm" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_mp5.mdl") = item_weapon_mp5 : "MP5 Submachinegun" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_shotgun.mdl") = item_weapon_shotgun : "SPAS-12 Shotgun" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_rpg.mdl") = item_weapon_rpg : "RPG" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_satchel.mdl") = item_weapon_satchel : "Satchel Charge" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/xenians/snarknest.mdl") = item_weapon_snark : "Snarks" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_gauss.mdl") = item_weapon_tau : "Tau Cannon" []
-@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaPickup) studio("models/weapons/w_tripmine.mdl") = item_weapon_tripmine : "Tripmine" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_357.mdl") = item_weapon_357 : "357 Revolver" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_crowbar.mdl") = item_weapon_crowbar : "Crowbar" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_crossbow.mdl") = item_weapon_crossbow : "Crossbow" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_grenade.mdl") = item_weapon_frag : "Frag Grenade" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_glock.mdl") = item_weapon_glock : "Glock-18 Handgun" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_egon_pickup.mdl") = item_weapon_gluon : "Gluon Gun" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_hgun.mdl") = item_weapon_hivehand : "Hivearm" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_mp5.mdl") = item_weapon_mp5 : "MP5 Submachinegun" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_shotgun.mdl") = item_weapon_shotgun : "SPAS-12 Shotgun" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_rpg.mdl") = item_weapon_rpg : "RPG" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_satchel.mdl") = item_weapon_satchel : "Satchel Charge" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/xenians/snarknest.mdl") = item_weapon_snark : "Snarks" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_gauss.mdl") = item_weapon_tau : "Tau Cannon" []
+@PointClass appliesto(Mesa) autovis(Weapons, Mesa Weapons) base(BaseMesaWeaponPickup) studio("models/weapons/w_tripmine.mdl") = item_weapon_tripmine : "Tripmine" []
diff --git a/fgd/point/item/item_sodacan.fgd b/fgd/point/item/item_sodacan.fgd
index 8a30db5ca..7c6b49e3e 100644
--- a/fgd/point/item/item_sodacan.fgd
+++ b/fgd/point/item/item_sodacan.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityAnimating)
+ appliesto(+complete)
studio("models/can.mdl") = item_sodacan : "HL1 soda can."
[
@resources
diff --git a/fgd/point/item/item_teamflag.fgd b/fgd/point/item/item_teamflag.fgd
index 4d43d7d58..90ad742a2 100644
--- a/fgd/point/item/item_teamflag.fgd
+++ b/fgd/point/item/item_teamflag.fgd
@@ -1,6 +1,6 @@
@PointClass base(BaseEntityPhysics, TeamNum, EnableDisable, TFGameType)
appliesto(TF2)
- studio("models/flag/briefcase.mdl") = item_teamflag: "Team Fortress flag entity."
+ studioprop() = item_teamflag: "Team Fortress flag entity."
[
returntime(integer) : "Return time (in seconds)" : 60 : "Length of time (in seconds) before dropped flag/intelligence returns to base."
@@ -22,7 +22,7 @@
1: "Increment capture count"
]
- flag_model(string) : "Model" : "models/flag/briefcase.mdl" : "The model to be used for this entity."
+ flag_model(studio) : "Model" : "models/flag/briefcase.mdl" : "The model to be used for this entity."
flag_icon(string) : "Icon" : "../hud/objectives_flagpanel_carried" : "The icons used for the HUD in some game modes. " +
"Format: materials/vgui/[materialname]_red and materials/vgui/[materialname]_blue"
flag_paper(particlesystem) : "Paper Particle" : "player_intel_papertrail" : "Particle effect used for the falling paper trail."
@@ -44,7 +44,15 @@
returnbetweenwaves(boolean) : "Return Between Waves" : "1" : "Used only for MvM mode. Determines if the flag should return home between waves."
- tags(string) : "tags" : : "Tags used for the AI bomb carrier to avoid nav areas that have matching tags. Tags need to be separated by empty space."
+ tags(string) : "AI nav avoid tags" : : "Tags used for the AI bomb carrier to avoid nav areas that have matching tags. Tags need to be separated by empty space."
+
+ model(studio) : "[H] Model" : "models/flag/briefcase.mdl" : "The model to show in Hammer"
+ skin(choices) : "[H] Team" : 0 : "The team to show in Hammer" =
+ [
+ 0 : "RED"
+ 1 : "BLU"
+ 2 : "Neutral"
+ ]
// Inputs
input ForceDrop(void) : "Force the flag to be dropped if it's being carried by a player."
diff --git a/fgd/point/light/light.fgd b/fgd/point/light/light.fgd
index 51f616eaf..906edd09e 100644
--- a/fgd/point/light/light.fgd
+++ b/fgd/point/light/light.fgd
@@ -1,9 +1,7 @@
-@PointClass base(BaseEntityPoint, BaseLight)
+@PointClass base(BaseEntityPoint, BaseLight, LightPattern, LightShadows)
autovis(Lights, Omnidirectional Light)
- light()
- iconsprite("editor/light.vmt")
- sphere(_distance)
- line(255 255 255, targetname, target)
+ light()
+ iconsprite("editor/light.vmt")
= light: "An invisible omnidirectional lightsource."
[
spawnflags(flags) =
diff --git a/fgd/point/light/light_directional.fgd b/fgd/point/light/light_directional.fgd
index 266ac374d..19c72344d 100644
--- a/fgd/point/light/light_directional.fgd
+++ b/fgd/point/light/light_directional.fgd
@@ -1,10 +1,10 @@
-@PointClass base(Angles)
+@PointClass base(Angles)
autovis(Lights, Directional Light)
color(255 255 0)
- appliesto(since_L4D)
+ appliesto(since_L4D)
iconsprite("editor/light_directional.vmt") = light_directional: "A directional light with no falloff. Similar to sunlight in light_environment."
[
- pitch(integer) : "Pitch" : 0 : "The downward pitch of the light from the sun. 0 is horizontal, -90 is straight down."
+ pitch(angle_negative_pitch) : "Pitch" : 0 : "The downward pitch of the light from the sun. 0 is horizontal, -90 is straight down."
_light(color255) : "Brightness" : "255 255 255 200"
_lighthdr(color255) : "BrightnessHDR" : "-1 -1 -1 1"
_lightscalehdr(float) : "BrightnessScaleHDR" : 0.7 : "Amount to scale the light by when compiling for HDR."
diff --git a/fgd/point/light/light_environment.fgd b/fgd/point/light/light_environment.fgd
index 3c15e24ee..3a62654da 100644
--- a/fgd/point/light/light_environment.fgd
+++ b/fgd/point/light/light_environment.fgd
@@ -1,4 +1,4 @@
-@PointClass base(BaseEntityPoint, Angles)
+@PointClass base(BaseEntityPoint, Angles, LightPattern, LightShadows)
autovis(Lights, Environment Light)
iconsprite("editor/light_environment.vmt")
color(255 255 0)
@@ -15,38 +15,5 @@
_ambientscalehdr(float) : "AmbientScaleHDR" : 1 : "Amount to scale the ambient light by when compiling for hdr."
sunspreadangle(float) : "SunSpreadAngle" : 5 : "The angular extent of the sun for casting soft shadows. Higher numbers are more diffuse. 5 is a good starting value."
- style[engine](integer) : "Appearance" : 0
- style(choices) : "Appearance" : 0 =
- [
- 0 : "Normal"
- 10: "Fluorescent flicker"
- 2 : "Slow, strong pulse"
- 11: "Slow pulse, noblack"
- 5 : "Gentle pulse"
- 1 : "Flicker A"
- 6 : "Flicker B"
- 3 : "Candle A"
- 7 : "Candle B"
- 8 : "Candle C"
- 4 : "Fast strobe"
- 9 : "Slow strobe"
- 12 : "Underwater light mutation"
- ]
- pattern(string) : "Custom Appearance" : "" : "Set a custom pattern of light brightness for this light. Pattern format is a string of characters, where 'a' is total darkness, 'z' fully bright. i.e. 'aaggnnttzz' would be a steppy fade in from dark to light."
-
- _castentityshadow[engine](boolean)
- _castentityshadow[GMod](Choices) : "Cast entity shadows" : 0 : "Objects illuminated by this light will cast a directional shadow." =
- [
- 0 : "Don't affect entity shadow angles"
- 1 : "Affect entity shadow angles"
- ]
-
- // Inputs
- input TurnOn(void) : "Turn the Sun on."
- input TurnOff(void) : "The the Sun off."
- input Toggle(void) : "Toggle the Sun's current state."
- input SetPattern(string) : "Set a custom pattern of light brightness for the Sun. Pattern format is a string of characters, where 'a' is total darkness, 'z' fully bright. i.e. 'aaggnnttzz' would be a steppy fade in from dark to light."
- input FadeToPattern(string) : "Fades from first value in old pattern, to first value in the new given pattern. Pattern format is a string of characters, where 'a' is total darkness, 'z' fully bright. i.e. 'aaggnnttzz' would be a steppy fade in from dark to light."
-
@resources []
]
diff --git a/fgd/point/light/light_spot.fgd b/fgd/point/light/light_spot.fgd
index c275f56bf..107579d81 100644
--- a/fgd/point/light/light_spot.fgd
+++ b/fgd/point/light/light_spot.fgd
@@ -1,8 +1,7 @@
-@PointClass base(BaseEntityPoint, BaseLight)
+@PointClass base(BaseEntityPoint, BaseLight, LightPattern, LightShadows)
autovis(Lights, Spotlight)
- lightprop("models/editor/spot.mdl")
- lightcone()
- sphere(_distance)
+ lightprop("models/editor/spot.mdl")
+ lightcone()
line(255 255 255, targetname, target)
= light_spot: "An invisible and directional spotlight."
[
diff --git a/fgd/point/logic/PlayerInputs.fgd b/fgd/point/logic/PlayerInputs.fgd
index e8b1ec36d..4d0d00b15 100644
--- a/fgd/point/logic/PlayerInputs.fgd
+++ b/fgd/point/logic/PlayerInputs.fgd
@@ -1,7 +1,7 @@
-@BaseClass = PlayerInputs: "The inputs that can be fired on the player, for entities that pass through those."
+@BaseClass base(BaseEntityInputs) = PlayerInputs: "The inputs that can be fired on the player, for entities that pass through those."
[
- input IgnoreFallDamage[HL2](float) : "Prevent the player from taking fall damage for [n] seconds, but reset back to taking fall damage after the first impact (so players will be hurt if they bounce off what they hit)."
- input IgnoreFallDamageWithoutReset[HL2](float) : "Absolutely prevent the player from taking fall damage for [n] seconds. "
+ input IgnoreFallDamage[HL2, P1](float) : "Prevent the player from taking fall damage for [n] seconds, but reset back to taking fall damage after the first impact (so players will be hurt if they bounce off what they hit)."
+ input IgnoreFallDamageWithoutReset[HL2, P1](float) : "Absolutely prevent the player from taking fall damage for [n] seconds. "
input SetHUDVisibility(bool) : "Set if the player's HUD is visible or not."
input SetFogController(target_destination) : "Set the current env_fog_controller entity."
@@ -11,9 +11,9 @@
input HandleMapEvent(string) : "Generic hook for triggering game/mod-specific events like achievements for a player."
input SetSuppressAttacks(bool) : "Prevent or re-allow the player from being able to use weapons."
- input DisableFlashlight[HL2](void) : "Disable the player's flashlight."
- input EnableFlashlight[HL2](void) : "Disable the player's flashlight."
- input ForceDropPhysObjects[HL2](void) : "Force the player to drop any physics objects they're carrying"
+ input DisableFlashlight[HL2, P1](void) : "Disable the player's flashlight."
+ input EnableFlashlight[HL2, P1](void) : "Disable the player's flashlight."
+ input ForceDropPhysObjects[HL2, P1](void) : "Force the player to drop any physics objects they're carrying"
input SetBodyGroup(integer) : "HACK: Sets this player's body group (from 0 - n). You'd better know what you are doing!"
input Ignite(void) : "Ignite, burst into flames"
@@ -21,8 +21,8 @@
input IgniteNumHitboxFires(integer) : "Ignite, with a parameter number of hitbox fires."
input IgniteHitboxFireScalev(float) : "Ignite, with a parameter hitbox fire scale."
- input GiveWeapon[HL2](string) : "Gives the player a weapon of the specified class name."
- input DropWeapon[HL2](string) : "Causes the player to drop its current weapon in front of them."
+ input GiveWeapon[HL2, P1](string) : "Gives the player a weapon of the specified class name."
+ input DropWeapon[HL2, P1](string) : "Causes the player to drop its current weapon in front of them."
input AddArmor[MBase](integer) : "Adds to the player's current armor value. " +
"Total armor cannot exceed 100 unless a different value is set in logic_playerproxy."
diff --git a/fgd/point/logic/logic_auto.fgd b/fgd/point/logic/logic_auto.fgd
index 96a2378a2..d4da29a19 100644
--- a/fgd/point/logic/logic_auto.fgd
+++ b/fgd/point/logic/logic_auto.fgd
@@ -42,7 +42,6 @@
"is_console": "Game is running on a console"
"is_pc": "Game is running on a PC"
- "portalgun_nospawn": "Spawn without Portalgun"
"no_pinging_blue": "Prevent Pinging ATLAS"
"no_pinging_orange": "Prevent Pinging P-Body"
"no_taunting_blue": "Prevent Taunting ATLAS"
diff --git a/fgd/point/logic/logic_eventlistener.fgd b/fgd/point/logic/logic_eventlistener.fgd
index cff710266..21f23a28b 100644
--- a/fgd/point/logic/logic_eventlistener.fgd
+++ b/fgd/point/logic/logic_eventlistener.fgd
@@ -13,13 +13,16 @@
teamnum[P2](choices) : "Team Number" : -1 : "If set, will only fire its output if the event is generated from someone of the specified team." =
[
-1: "Don't care"
- 1: "Team 1"
- 2: "Team 2 (ORANGE)"
- 3: "Team 3 (BLUE)"
+ 0: "Singleplayer/Unassigned"
+ 1: "Spectators" [+complete]
+ 2: "P-Body"
+ 3: "ATLAS"
]
teamnum[CSGO](choices) : "Team Number" : -1 : "If set, will only fire its output if the event is generated from someone of the specified team." =
[
-1: "Don't care"
+ 0: "Unassigned" [+complete]
+ 1: "Spectators" [+complete]
2: "Terrorists"
3: "Counter-Terrorists"
]
@@ -27,13 +30,13 @@
[
0: "Any"
2: "RED"
- 3: "BLU/ROBOTS"
+ 3: "BLU/Robots"
5 : "Halloween Bosses"
1 : "Spectator / Halloween Souls"
]
// TODO: CSGO-only?
- fetcheventdata[since_CSGO](boolean) : "Fetch Event Data" : "0" : "If set, will write the data from the event into the table 'event_data' on this entity."
+ fetcheventdata[since_CSGO, TF2](boolean) : "Fetch Event Data" : "0" : "If set, will write the data from the event into the table 'event_data' on this entity."
// Inputs
input Enable(void) : "Enable the logic_eventlistener."
diff --git a/fgd/point/logic/logic_eventlistener_itemequip.fgd b/fgd/point/logic/logic_eventlistener_itemequip.fgd
index 990c487ae..a798dff5b 100644
--- a/fgd/point/logic/logic_eventlistener_itemequip.fgd
+++ b/fgd/point/logic/logic_eventlistener_itemequip.fgd
@@ -23,6 +23,7 @@
teamnum(choices) : "Team Number" : -1 : "If set, will only fire its output if the event is generated from someone of the specified team." =
[
-1: "Don't care"
+ 0: "Unassigned" [+complete]
2: "Terrorists"
3: "Counter-Terrorists"
]
diff --git a/fgd/point/logic/logic_playerproxy.fgd b/fgd/point/logic/logic_playerproxy.fgd
index 234d71bdc..0e4172791 100644
--- a/fgd/point/logic/logic_playerproxy.fgd
+++ b/fgd/point/logic/logic_playerproxy.fgd
@@ -4,7 +4,7 @@
color(200 0 0)
iconsprite("editor/logic_playerproxy.vmt")
autovis(Point Entities, Globals, Player Proxy)
- appliesto(!L4D, !L4D2, !TF2)
+ appliesto(HL2, P1, P2) // Also in Alien Swarm and CS:GO, but it doesn't work in those games
= logic_playerproxy: "An entity that is used to relay inputs/outputs to the player and back to the world."
[
SetMaxInputArmor[MBase](integer) : "Max Input Armor" : 100 : "Sets the maximum armor a player can receive from the " +
@@ -22,8 +22,8 @@
HandsVMBody[MBase](string) : "Hands Viewmodel Bodygroup" : : "Bodygroup value for the custom hands viewmodel."
// Inputs and Outputs
- input RequestPlayerHealth(void) : "Requests the current player's health from the proxy. This will fire the PlayerHealth output with the value."
- output PlayerHealth(integer) : "The player's current health value, fired in response to RequestPlayerHealth."
+ input RequestPlayerHealth[HL2, P1](void) : "Requests the current player's health from the proxy. This will fire the PlayerHealth output with the value."
+ output PlayerHealth[HL2, P1](integer) : "The player's current health value, fired in response to RequestPlayerHealth."
input RequestPlayerArmor[MBase](void) : "Requests the current player's armor from the proxy. This will fire the PlayerArmor output with the value."
output PlayerArmor[MBase](integer) : "The player's current armor value, fired in response to RequestPlayerArmor."
@@ -34,25 +34,25 @@
input RequestPlayerFlashBattery[MBase](void) : "Requests the current player's current flashlight battery from the proxy. This will fire the PlayerFlashBattery output with the value.\n\nNOTE: If legacy flashlight is enabled (aux power flashlight), this will return the player's current auxiliary power."
output PlayerFlashBattery[MBase](float) : "The player's current flashlight battery percentage, fired in response to RequestPlayerFlashBattery."
- input RequestAmmoState(void) : "Request the ammo state of the player. It will fire PlayerHasAmmo or PlayerHasNoAmmo outputs."
- output PlayerHasAmmo(void) : "Fired by request if the player has any ammo."
- output PlayerHasNoAmmo(void) : "Fired by request if the player doesn't have any ammo."
+ input RequestAmmoState[HL2, P1](void) : "Request the ammo state of the player. It will fire PlayerHasAmmo or PlayerHasNoAmmo outputs."
+ output PlayerHasAmmo[HL2, P1](void) : "Fired by request if the player has any ammo."
+ output PlayerHasNoAmmo[HL2, P1](void) : "Fired by request if the player doesn't have any ammo."
- input SetFlashlightSlowDrain(void) : "Puts the player's flashlight in slow-power-drain mode (for Episodic darkness)"
- input SetFlashlightNormalDrain(void) : "Puts the player's flashlight to default power drain"
+ input SetFlashlightSlowDrain[HL2, P1](void) : "Puts the player's flashlight in slow-power-drain mode (for Episodic darkness)"
+ input SetFlashlightNormalDrain[HL2, P1](void) : "Puts the player's flashlight to default power drain"
- input SetPlayerHealth(integer) : "Sets the player's health to this value."
+ input SetPlayerHealth[HL2, P1](integer) : "Sets the player's health to this value."
input SetMaxInputArmor[MBase](integer) : "Sets the maximum armor value that could be set by armor inputs."
input SetSuitZoomFOV[MBase](integer) : "Sets the FOV used by suit zoom."
- input LowerWeapon(void) : "Lowers the players weapon."
+ input LowerWeapon[HL2, P1](void) : "Lowers the players weapon."
input SuppressCrosshair[P1](void) : "Disable the player's crosshair."
- input EnableCappedPhysicsDamage(void) : "Cause player to take less damage from physics objects, and never more than 30 points from any individual strike."
- input DisableCappedPhysicsDamage(void) : "Undo effects of EnableCappedPhysicsDamage"
+ input EnableCappedPhysicsDamage[HL2, P1](void) : "Cause player to take less damage from physics objects, and never more than 30 points from any individual strike."
+ input DisableCappedPhysicsDamage[HL2, P1](void) : "Undo effects of EnableCappedPhysicsDamage"
- input SetLocatorTargetEntity(string) : "Set the entity that the HUD locator should track. (Usually a vehicle)"
+ input SetLocatorTargetEntity[HL2, P1](string) : "Set the entity that the HUD locator should track. (Usually a vehicle)"
input AddPotatosToPortalgun[P2](void) : "Change portalgun bodygroup to show potatos."
input RemovePotatosFromPortalgun[P2](void) : "Change portalgun bodygroup to not show potatos."
@@ -61,23 +61,27 @@
input ForcePhysicsGrabController[P2](void) : "Force the player to use the physics grab controller for all objects that are picked up."
input ResetGrabControllerBehavior[P2](void) : "Resets the grab controller used by the player to its default behavior."
input SetMotionBlurAmount[P2](float) : "Forces the motion blur effect on the player. Set to < 0 to disable this override."
+ input PaintPlayerWithPortalPaint[P2](void) : "Displays a Conversion Gel splashing effect on the player's screen."
// Outputs
- output OnFlashlightOn(float) : "Fired when the player turns on their flashlight. This output has the value of how much energy the player had when this happened [0..1]."
- output OnFlashlightOff(float) : "Fired when the player turns off their flashlight. This output has the value of how much energy the player had when this happened [0..1]."
+ output OnFlashlightOn[HL2, P1](float) : "Fired when the player turns on their flashlight. This output has the value of how much energy the player had when this happened [0..1]."
+ output OnFlashlightOff[HL2, P1](float) : "Fired when the player turns off their flashlight. This output has the value of how much energy the player had when this happened [0..1]."
output OnSquadMemberKilled[MBase](void) : "Fires when a member of the player's squad dies. Fires with this member as the activator."
- output PlayerDied(void) : "Fires when the player dies."
+ output PlayerDied[EP1, P1](void) : "Fires when the player dies."
output PlayerDamaged[MBase](void) : "Fires when the player is damaged."
- output PlayerMissedAR2AltFire(void) : "Player fired an AR2 combine ball that didn't kill any enemies."
+ output PlayerMissedAR2AltFire[EP1, P1](void) : "Player fired an AR2 combine ball that didn't kill any enemies."
output OnPlayerSpawn[MBase](void) : "Fires when the player respawns, if 'Allow SP respawn' is enabled in hl2_gamerules."
- output OnStartSlowingTime[!TF2, ASW](void) : "Fired when a Portal player initiates slow time."
- output OnStopSlowingTime[!TF2, ASW](void) : "Fired when a Portal player stops slowing time."
+ // Cut mechanic
+ // output OnStartSlowingTime[P2](void) : "Fired when a Portal player initiates slow time."
+ // output OnStopSlowingTime[P2](void) : "Fired when a Portal player stops slowing time."
output OnPrimaryPortalPlaced[P2](void) : "Fired when a Portal player successfully places the primary portal."
output OnSecondaryPortalPlaced[P2](void) : "Fired when a Portal player successfully places the secondary portal."
+ // Only responds to the old unused +coop_ping command, not the normal pings
+ output OnCoopPing[+P2, +complete](void) : "Fired in response to the unused +coop_ping command."
output OnDuck[since_P2](void) : "Fired when a player starts to duck."
output OnUnDuck[since_P2](void) : "Fired when a player releases the duck button."
output OnJump[since_P2](void) : "Fired when a player jumps."
diff --git a/fgd/point/logic/logic_relay.fgd b/fgd/point/logic/logic_relay.fgd
index 9c9692831..c25874b80 100644
--- a/fgd/point/logic/logic_relay.fgd
+++ b/fgd/point/logic/logic_relay.fgd
@@ -7,7 +7,7 @@
[
spawnflags(flags) : "spawnflags" =
[
- 1: "Only trigger once" : 0
+ 1: "Only trigger once (remove after OnSpawn or OnTrigger outputs fire)" : 0
2: "Allow fast retrigger" : 0
]
diff --git a/fgd/point/logic/logic_script.fgd b/fgd/point/logic/logic_script.fgd
index d6ac4c408..2733636f0 100644
--- a/fgd/point/logic/logic_script.fgd
+++ b/fgd/point/logic/logic_script.fgd
@@ -18,6 +18,7 @@
line(200 200 200, targetname, group14)
line(200 200 200, targetname, group07)
line(200 200 200, targetname, group15)
+ line(200 200 200, targetname, group16)
= logic_script: "An entity that acts as a container for scripts."
[
group00(target_destination) : "EntityGroup[0]" : : "If set, the specified entity will be stored in the EntityGroup array. Unused slots before the last used slot will become null."
diff --git a/fgd/point/mapobj_cart_dispenser.fgd b/fgd/point/mapobj_cart_dispenser.fgd
index e53716822..dbbe7bdb3 100644
--- a/fgd/point/mapobj_cart_dispenser.fgd
+++ b/fgd/point/mapobj_cart_dispenser.fgd
@@ -1,6 +1,7 @@
@PointClass base(BaseEntityPoint, BaseObject)
+ line(255 255 255, targetname, touch_trigger)
appliesto(TF2)
- iconsprite("editor/bullseye.vmt") = mapobj_cart_dispenser: "TF2 Dispenser"
+ iconsprite("editor/ficool2/mapobj_cart_dispenser.vmt") = mapobj_cart_dispenser: "TF2 Dispenser"
[
spawnflags(flags) : "spawnflags" =
[
diff --git a/fgd/point/material_modify_control.fgd b/fgd/point/material_modify_control.fgd
index eb5c1f71d..f28879b00 100644
--- a/fgd/point/material_modify_control.fgd
+++ b/fgd/point/material_modify_control.fgd
@@ -4,11 +4,17 @@
iconsprite("editor/ficool2/material_modify_control.vmt")
= material_modify_control: "An entity that can be used to directly control material vars. " +
"To use it, you need to add the MaterialModify or MaterialModifyAnimated proxy to the material you intend to change. " +
- "Parent this entity the entity who's material you want to control. " +
- "If not parented, this applies to all materials in the map with the given name."
+ "Parent this entity the entity who's material you want to control."
[
- materialname(string) : "Material to modify."
- materialvar(string) : "Material variable to modify."
+ parentname(target_destination) : "Parent / Target" : : "Materials are modified only on the parent of the material_modify_control."
+
+ srctools_search_parent[+srctools](boolean) : "[HA] Search Parent" : : "If set, the postcompiler will duplicate this entity for each material on the parent that have the appropriate proxy. " +
+ "If Material Name is set, only materials containing that value will be considered."
+
+ materialname(material): "Material Name" : : "The single material to modify on the parent. 'materials/' and '.vmt' is not required. Maximum of 255 characters allowed."
+ materialvar[-srctools](string): "Variable Name" : : "Material variable to modify, '$frame' for example. Maximum of 255 characters allowed."
+ materialvar[+srctools](string): "Variable Name" : : "Material variable to modify, '$frame' for example. Maximum of 255 characters allowed. " +
+ "If the $ is omitted, the postcompiler will add it. This prevents the variable from being detected for instances."
// Inputs
input SetMaterialVar(string) : "Fire to modify a material variable. The argument is the value to set the variable to."
diff --git a/fgd/point/monster_furniture.fgd b/fgd/point/monster_furniture.fgd
new file mode 100644
index 000000000..d8cb4d96f
--- /dev/null
+++ b/fgd/point/monster_furniture.fgd
@@ -0,0 +1,6 @@
+@PointClass aliasof(npc_furniture)
+ studio()
+ autovis(NPCs, Furniture)
+= monster_furniture: "Alternate name for npc_furniture."
+ [
+ ]
diff --git a/fgd/point/npc/npc_cscanner.fgd b/fgd/point/npc/npc_cscanner.fgd
index c5f683eee..a76bd5cd9 100644
--- a/fgd/point/npc/npc_cscanner.fgd
+++ b/fgd/point/npc/npc_cscanner.fgd
@@ -4,6 +4,7 @@
autovis(Entities, NPCs, Combine, City Scanner)
= npc_cscanner: "City Scanner"
[
+ model[engine](string) : "Hammer Preview"
model[!engine](choices) : "[H] Model" : "models/combine_scanner.mdl" : "These become Claw Scanners if the map name starts with 'd3_c17'. "+
"Use this to change the model shown in Hammer." =
[
diff --git a/fgd/point/npc/npc_personality_core.fgd b/fgd/point/npc/npc_personality_core.fgd
index 836b4d053..8d54f105e 100644
--- a/fgd/point/npc/npc_personality_core.fgd
+++ b/fgd/point/npc/npc_personality_core.fgd
@@ -1,18 +1,26 @@
-@PointClass base(TalkNPC)
+@PointClass base(TalkNPC, SRCModel)
appliesto(P2)
autovis(Entities, NPCs, Aper. Personality Core)
studioprop()
= npc_personality_core: "Aperture Science Personality Construct. Animated balls with handles."
[
- modelskin[engine](integer) : "Model Skin" : 0
- modelskin(choices) : "Model Skin" : 0 : "If using the 'alt' skin, this sets the eye color -- If not using the alt skin, (0 = broken) (1=normal)" =
+ // The default core FGD uses the keyvalue ModelSkin to set the skin, which doesn't preview in Hammer
+ // Using the regular skin keyvalue instead allows it to preview and actually works fine, but only if ModelSkin isn't also set
+ // This will create some weirdness when opening existing maps where ModelSkin will need to be removed for this keyvalue to function,
+ // but existing untouched core entities should still keep working fine so I think it's worth the tradeoff
+ skin[engine](integer) : "Model Skin" : 0
+ skin(choices) : "Model Skin" : 0 : "Sets the skin of the core. If using the alternate model, this sets the eye color. If using the normal model, (0=broken) (1=intact). If using a custom model, any skin number can be entered here. " +
+ "NOTE: Older maps may have the keyvalue ModelSkin set instead, disable SmartEdit and remove it to ensure this value is used." =
[
- 0: "Blue Eye / Broken"
- 1: "Green Eye / Normal"
- 2: "Orange Eye / NA"
- 3: "Purple Eye / NA"
+ 0: "[0] Blue Eye / Broken"
+ 1: "[1] Green Eye / Intact"
+ 2: "[2] Orange Eye / NA"
+ 3: "[3] Purple Eye / NA"
]
+ // this is still supported by the engine, but shouldn't appear in hammer
+ ModelSkin[engine](integer) : "Model Skin" : 0
+
altmodel[engine](boolean) : "Use Alternate Skins" : 0
altmodel(choices) : "Use Alternate Skins" : 0 : "Use the model with corrupted skins, instead of the skins in the original model. " =
[
@@ -20,23 +28,17 @@
1: "Yes"
]
- model[engine](studio) : "Model" : "models/npcs/personality_sphere/personality_sphere.mdl"
- model(choices) : "[H] Model" : "models/npcs/personality_sphere/personality_sphere.mdl" : "Choose the model to show in hammer. Set to the same as Use Alternate Skins." =
+ model[-srctools](choices) : "[H] Model" : "models/npcs/personality_sphere/personality_sphere.mdl" : "Choose the model to show in Hammer. Set to the same as Use Alternate Skins." =
[
"models/npcs/personality_sphere/personality_sphere.mdl": "Original (Wheatley)"
"models/npcs/personality_sphere/personality_sphere_skins.mdl": "Alternate (Corrupt Cores)"
]
-
- skin[engine](integer) : "Skin" : 0
- skin(choices) : "[H] Skin" : 0 : "If using the 'alt' skin, this sets the eye color (in hammer) -- If not using the alt skin, (0 = broken) (1=normal)" =
+ model[+srctools](choices) : "[HA] Custom/Hammer Model" : "models/npcs/personality_sphere/personality_sphere.mdl" : "Choose the model to show in Hammer. Set to the same as Use Alternate Skins. Alternatively, if Override Model is enabled you can type/paste in a custom model path here." =
[
- 0: "Blue Eye / Broken"
- 1: "Green Eye / Normal"
- 2: "Orange Eye / NA"
- 3: "Purple Eye / NA"
+ "models/npcs/personality_sphere/personality_sphere.mdl": "Original (Wheatley)"
+ "models/npcs/personality_sphere/personality_sphere_skins.mdl": "Alternate (Corrupt Cores)"
]
-
// Inputs
input EnableMotion(void) : "Enable physics motion/collision response."
input DisableMotion(void) : "Disable physics motion/collision response."
diff --git a/fgd/point/npc/npc_rocket_turret.fgd b/fgd/point/npc/npc_rocket_turret.fgd
index 6ffe777c3..510a5e3e2 100644
--- a/fgd/point/npc/npc_rocket_turret.fgd
+++ b/fgd/point/npc/npc_rocket_turret.fgd
@@ -4,7 +4,7 @@
@BaseClass appliesto(P2) studioprop() line(0 0 255, targetname, TripwireAimTarget)
= _npc_rocket_turret_p2 []
-@PointClass base(BaseNPC, ResponseContext, _npc_rocket_turret_p1, _npc_rocket_turret_p2)
+@PointClass base(BaseNPC, ResponseContext, _npc_rocket_turret_p1, _npc_rocket_turret_p2, SRCModel)
appliesto(P1, P2)
autovis(Entities, NPCs, Portal Rocket Turret)
sphere(_sphere_radius)
@@ -17,13 +17,17 @@
1: "Start Retracted" : 0
]
+ model[P2, -srctools](studio) : "[H] Model" : "models/props_bts/rocket_sentry.mdl" : "The model to display in Hammer. VScript must be used to set the in-game model."
+ model[P2, +srctools](studio) : "[HA] Custom Model" : "models/props_bts/rocket_sentry.mdl" : "The model to display in Hammer, and the custom model to use if Override Model is enabled."
+
rocketspeed[P2](float) : "Rocket Speed" : 450 : "Speed the rocket will travel at."
rocketlifetime[P2](float) : "Rocket Lifetime" : 20 : "The rocket will automatically detonate after this number of seconds."
TripwireMode[P2](boolean) : "Tripwire Mode" : 0 : "Makes the turret aim in a specific direction instead of following the target. When the beam is crossed, a rocket instantly fires."
TripwireAimTarget[P2](target_destination) : "Tripwire Aim Target" : : "In tripwire mode, the entity to aim at."
- model[P2](studio) : "[H] Model" : "models/props_bts/rocket_sentry.mdl" : "Model to display in Hammer. Use Init Code and a comp_precache_model to change the model in-game."
_sphere_radius[!engine](integer) readonly : "" : 8192 : "How far the turret will be able to see targets. Always 8192, but this keyvalue is needed to display the preview."
+ // Hammer automatically adds this when selecting a model, this prevents it from appearing as invalid
+ skin[P2](integer) readonly : "" : 0 : "Skin on the model to use. The game overrides this based on the rocket turret's firing state, so changing it here has no effect."
// Inputs
input Toggle(void) : "Toggles between activated and deactivated states."
diff --git a/fgd/point/npc/npc_security_camera.fgd b/fgd/point/npc/npc_security_camera.fgd
index 6667b04c8..07b26fbfe 100644
--- a/fgd/point/npc/npc_security_camera.fgd
+++ b/fgd/point/npc/npc_security_camera.fgd
@@ -45,8 +45,8 @@
input LookAllTeams[P2](void) : "Make the camera follow all players."
// Outputs
- output OnDeploy(void) : "Camera is becoming active and dangerous."
- output OnRetire(void) : "Camera is becoming inactive and harmless."
+ output OnDeploy(void) : "Fired in response to the Enable input"
+ output OnRetire(void) : "Fired in response to the Disable input"
output OnTaunted[P2](void) : "A player STARTED taunting the camera."
output OnTauntedBlue[P2](void) : "ATLAS STARTED taunting the camera."
diff --git a/fgd/point/npc/npc_turret_floor.fgd b/fgd/point/npc/npc_turret_floor.fgd
index 451f498d8..88b01ed41 100644
--- a/fgd/point/npc/npc_turret_floor.fgd
+++ b/fgd/point/npc/npc_turret_floor.fgd
@@ -1,5 +1,5 @@
@PointClass base(BaseNPC)
- appliesto(EP1, EP2, HL2, P1)
+ appliesto(EP1, EP2, HL2, P1, P2)
studioprop("models/combine_turrets/floor_turret.mdl")
frustum(_frustum_fov, _frustum_near, _frustum_far, 255 0 0, -1)
autovis(Entities, NPCs, Combine, Floor Turret)
diff --git a/fgd/point/obj/obj_dispenser.fgd b/fgd/point/obj/obj_dispenser.fgd
index 179cc23c1..94590804c 100644
--- a/fgd/point/obj/obj_dispenser.fgd
+++ b/fgd/point/obj/obj_dispenser.fgd
@@ -1,15 +1,24 @@
@PointClass base(BaseEntityAnimating, BaseObject)
- appliesto(TF2)
- studio("models/buildables/dispenser_light.mdl")
+ appliesto(TF2)
+ line(255 255 255, targetname, touch_trigger)
+ studioprop()
= obj_dispenser: "TF2 Dispenser"
[
- defaultupgrade[engine](integer) : "Starting Upgrade Level" : 0
- defaultupgrade(choices) : "Starting Upgrade Level" : "0" =
- [
- 0: "Level 1"
- 1: "Level 2"
- 2: "Level 3"
- ]
+
+ touch_trigger(target_destination) : "Custom Touch Trigger"
+ skin[!engine](choices) : "[H] Team" : 0 : "Team to show in Hammer" =
+ [
+ 0 : "RED"
+ 1 : "BLU"
+ ]
+
+ model[engine](string) : "Model" : : "Doesn't exist in engine, this is a hack to prevent auto packing"
+ model(choices) : "[H] Upgrade Level" : "models/buildables/dispenser_light.mdl" : "Upgrade level to show in Hammer" =
+ [
+ "models/buildables/dispenser_light.mdl" : "Level 1"
+ "models/buildables/dispenser_lvl2_light.mdl" : "Level 2"
+ "models/buildables/dispenser_lvl3_light.mdl" : "Level 3"
+ ]
spawnflags(flags) : "spawnflags" =
[
diff --git a/fgd/point/obj/obj_sentrygun.fgd b/fgd/point/obj/obj_sentrygun.fgd
index de79bd85c..ca53e4cf0 100644
--- a/fgd/point/obj/obj_sentrygun.fgd
+++ b/fgd/point/obj/obj_sentrygun.fgd
@@ -1,15 +1,21 @@
@PointClass base(BaseEntityAnimating, BaseObject)
appliesto(TF2)
- studio("models/buildables/sentry3.mdl")
+ studioprop()
= obj_sentrygun: "TF2 Sentrygun"
[
- defaultupgrade[engine](integer) : "Starting Upgrade Level" : 0
- defaultupgrade(choices) : "Starting Upgrade Level" : "0" =
- [
- 0: "Level 1"
- 1: "Level 2"
- 2: "Level 3"
- ]
+ skin[!engine](choices) : "[H] Team" : 0 : "Team to show in Hammer" =
+ [
+ 0 : "RED"
+ 1 : "BLU"
+ ]
+
+ model[engine](string) : "Model" : : "Doesn't exist in engine, this is a hack to prevent auto packing"
+ model(choices) : "[H] Upgrade Level" : "models/buildables/sentry1.mdl" : "Upgrade level to show in Hammer" =
+ [
+ "models/buildables/sentry1.mdl" : "Level 1"
+ "models/buildables/sentry2.mdl" : "Level 2"
+ "models/buildables/sentry3.mdl" : "Level 3"
+ ]
spawnflags(flags) : "spawnflags" =
[
diff --git a/fgd/point/obj/obj_teleporter.fgd b/fgd/point/obj/obj_teleporter.fgd
index 60815ca76..89902d068 100644
--- a/fgd/point/obj/obj_teleporter.fgd
+++ b/fgd/point/obj/obj_teleporter.fgd
@@ -1,17 +1,9 @@
@PointClass base(BaseEntityAnimating, BaseObject)
appliesto(TF2)
- studio("models/buildables/teleporter_light.mdl")
+ studioprop("models/buildables/teleporter_light.mdl")
line(255 255 255, targetname, matchingteleporter)
= obj_teleporter: "TF2 Teleporter"
[
- defaultupgrade[engine](integer) : "Starting Upgrade Level" : 0
- defaultupgrade(choices) : "Starting Upgrade Level" : "0" =
- [
- 0: "Level 1"
- 1: "Level 2"
- 2: "Level 3"
- ]
-
spawnflags(flags) : "spawnflags" =
[
4: "Upgradable" : 0
@@ -26,6 +18,12 @@
matchingteleporter(target_destination) : "Matching Teleporter" : : "The teleporter linked to this one."
+ skin[!engine](choices) : "[H] Team" : 0 : "Team to show in Hammer" =
+ [
+ 0 : "RED"
+ 1 : "BLU"
+ ]
+
// Outputs
output OnDestroyed(void) : "Fired when this entity is destroyed."
]
diff --git a/fgd/point/pd_dispenser.fgd b/fgd/point/pd_dispenser.fgd
index 3dc62f248..577e42362 100644
--- a/fgd/point/pd_dispenser.fgd
+++ b/fgd/point/pd_dispenser.fgd
@@ -1,4 +1,5 @@
-@PointClass base(BaseEntityPoint, BaseObject)
+@PointClass base(BaseEntityPoint, BaseObject)
+ line(255 255 255, targetname, touch_trigger)
appliesto(TF2)
= pd_dispenser: "Player Destruction Leader Dispenser"
[
diff --git a/fgd/point/point/point_bonusmaps_accessor.fgd b/fgd/point/point/point_bonusmaps_accessor.fgd
index e2048cf9c..1b8781faf 100644
--- a/fgd/point/point/point_bonusmaps_accessor.fgd
+++ b/fgd/point/point/point_bonusmaps_accessor.fgd
@@ -1,4 +1,6 @@
@PointClass base(BaseEntityPoint)
+ // Everything has this, but only 2013 singleplayer games will reasonably use it
+ appliesto(HL2, P1, complete)
iconsprite("editor/ficool2/point_bonusmaps_accessor")
color(200 0 0) = point_bonusmaps_accessor: "An entity that relays bonus maps changes."
[
diff --git a/fgd/point/point/point_camera.fgd b/fgd/point/point/point_camera.fgd
index a96209ce2..1ceba18e4 100644
--- a/fgd/point/point/point_camera.fgd
+++ b/fgd/point/point/point_camera.fgd
@@ -1,6 +1,7 @@
@PointClass base(BaseEntityPoint)
studioprop("models/editor/camera.mdl")
- frustum(FOV,fogstart,fogend,250 250 250,-1)
+ // Frustum color must be a KV name, not a raw RGB value
+ frustum(FOV,fogstart,fogend,_frustum_color,-1)
= point_camera: "Camera"
[
spawnflags(flags) : "spawnflags" =
diff --git a/fgd/point/point/point_energy_ball_launcher.fgd b/fgd/point/point/point_energy_ball_launcher.fgd
index fef83f78f..62b6eb447 100644
--- a/fgd/point/point/point_energy_ball_launcher.fgd
+++ b/fgd/point/point/point_energy_ball_launcher.fgd
@@ -7,10 +7,6 @@
ballcount(integer) : "Ball count" : 1 : "The number of Pellets that are alive at once."
maxspeed(float) : "Max ball speed" : 150.0 : "The maximum starting speed."
minspeed(float) : "Min ball speed" : 150.0 : "The minimum starting speed."
- balltype(choices) readonly : "Ball Type" : 0 : "Has no effect." =
- [
- 0 : "HEP"
- ]
balllifetime(float) : "Ball Lifetime" : 12 : "The time in seconds the ball will live before self-destructing. A negative value will give infinite life, appearing green."
minlifeafterportal(float) : "Min life after portal transition" : 6 : "When energy balls created by this launcher pass through a portal their life is refreshed to be this number at minimum."
diff --git a/fgd/point/point/point_glow.fgd b/fgd/point/point/point_glow.fgd
index 556ac80bf..90e9944c1 100644
--- a/fgd/point/point/point_glow.fgd
+++ b/fgd/point/point/point_glow.fgd
@@ -1,5 +1,5 @@
@PointClass base(BaseEntityPoint, EnableDisable)
- line(255 255 255, targetname, damagetarget)
+ line(255 255 255, targetname, target)
iconsprite(editor/vizzys/point_glow)
appliesto(MBase)
= point_glow: "Mapbase off-shoot of tf_glow."
diff --git a/fgd/point/point/point_hurt.fgd b/fgd/point/point/point_hurt.fgd
index 443ab707b..66d8ae46f 100644
--- a/fgd/point/point/point_hurt.fgd
+++ b/fgd/point/point/point_hurt.fgd
@@ -13,6 +13,7 @@
spawnflags(flags) =
[
1: "Start Active" : 0
+ 2: "Bypass UberCharge" : 0 [TF2]
]
diff --git a/fgd/point/point/point_intermission.fgd b/fgd/point/point/point_intermission.fgd
index 396eac5f3..7baef1722 100644
--- a/fgd/point/point/point_intermission.fgd
+++ b/fgd/point/point/point_intermission.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/point_intermission")
appliesto(TF2) = point_intermission: "Entity that ends the match and triggers an intermission."
[
diff --git a/fgd/point/point/point_populator_interface.fgd b/fgd/point/point/point_populator_interface.fgd
index 3fb451624..93a2a230d 100644
--- a/fgd/point/point/point_populator_interface.fgd
+++ b/fgd/point/point/point_populator_interface.fgd
@@ -1,4 +1,5 @@
-@PointClass base(BaseEntityPoint)
+@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/point_populator_interface")
appliesto(TF2) = point_populator_interface: "Entity interface to the populator."
[
diff --git a/fgd/point/point/point_survey.fgd b/fgd/point/point/point_survey.fgd
deleted file mode 100644
index f7890b3f5..000000000
--- a/fgd/point/point/point_survey.fgd
+++ /dev/null
@@ -1,8 +0,0 @@
-@PointClass base(BaseEntityPoint) appliesto(P2) = point_survey : "Displays a survey to the player."
-[
- surveyname(string) : "Survey Script Name" : "end_puzzle_survey" : "Name of a survey keyvalues file, from the 'scripts/surveys' folder."
-
- input ShowSurvey(void) : "Displays the survey."
-
- output OnSurveyComplete(void) : "Fired when the player completes or cancels the survey."
-]
diff --git a/fgd/point/point/point_teleport.fgd b/fgd/point/point/point_teleport.fgd
index fc5884652..dc35db74c 100644
--- a/fgd/point/point/point_teleport.fgd
+++ b/fgd/point/point/point_teleport.fgd
@@ -7,6 +7,7 @@
"If object is physically simulated, simulation is turned off when teleported."
[
target(target_destination) : "Entity To Teleport" : : "Name of the entity that will be teleported."
+ model[engine](string) : "Hammer Preview"
model[!engine](studio) : "[H] Model" : "models/editor/angle_helper.mdl" : "The model shown in Hammer, to use for positioning."
spawnflags(flags) =
[
diff --git a/fgd/point/point/point_viewcontrol.fgd b/fgd/point/point/point_viewcontrol.fgd
index f61f3a018..e8ab72d5f 100644
--- a/fgd/point/point/point_viewcontrol.fgd
+++ b/fgd/point/point/point_viewcontrol.fgd
@@ -1,7 +1,8 @@
@PointClass base(BaseEntityPoint)
studioprop("models/editor/camera.mdl")
color(200 0 0)
- frustum(fov, 4, _frustum_far, 250 250 250, -1)
+ // Frustum color must be a keyvalue name, not a raw RGB value
+ frustum(fov, 4, _frustum_far, _frustum_color, -1)
line(255 255 0, targetname, target)
line(255 255 0, targetname, moveto)
= point_viewcontrol: "A camera entity that controls the player's view. While it's active, the player will see out of the camera."
diff --git a/fgd/point/point/point_viewcontrol_multiplayer.fgd b/fgd/point/point/point_viewcontrol_multiplayer.fgd
index 83dc031b9..c68b104d1 100644
--- a/fgd/point/point/point_viewcontrol_multiplayer.fgd
+++ b/fgd/point/point/point_viewcontrol_multiplayer.fgd
@@ -4,7 +4,7 @@
studioprop("models/editor/camera.mdl")
frustum(fov, _frustum_near, _frustum_far, _frustum_color, -1)
line(255 255 0, targetname, target_entity)
-= point_viewcontrol_multiplayer: "A camera entity that controls players' views. which works in multiplayer. " +
+= point_viewcontrol_multiplayer: "Multiplayer version of point_viewcontrol which can affect multiple players at once. " +
"While it's active, the players will see out of the camera."
[
fov(float) : "Field of view" : 90 : "Player FOV"
@@ -16,16 +16,19 @@
target_team[engine](integer) : "Target Team" : -1
target_team[P2](choices) : "Target Team" : -1 : "Which team (or all) to take over the camera for." =
[
- -1: "All Players"
- 0: "Chell/Bendy"
+ -1: "All players"
+ 0: "Singleplayer/Unassigned"
+ 1: "Spectators" [+complete]
2: "P-Body"
3: "ATLAS"
]
target_team[CSGO](choices) : "Target Team" : -1 : "Which team (or all) to take over the camera for." =
[
- -1: "All Teams"
- 2: "Terrorist"
- 3: "Counter-Terrorist"
+ -1: "All players"
+ 0: "Unassigned" [+complete]
+ 1: "Spectators" [+complete]
+ 2: "Terrorists"
+ 3: "Counter-Terrorists"
]
spawnflags(flags) =
diff --git a/fgd/point/point/point_worldtext.fgd b/fgd/point/point/point_worldtext.fgd
index fb065c2c3..cc02dcba0 100644
--- a/fgd/point/point/point_worldtext.fgd
+++ b/fgd/point/point/point_worldtext.fgd
@@ -1,19 +1,68 @@
-@PointClass base(BaseEntityPoint)
+
+// TF2 hammer has no worldtext() helper, so replace it with a model
+// FIXME: this needs a custom model, vgui_arrows is oriented the wrong way
+@BaseClass studio("models/editor/axis_helper_thick.mdl") appliesto(TF2) = _point_worldtext_tf2
+[
+]
+
+@PointClass base(BaseEntityPoint, _point_worldtext_tf2)
appliesto(since_CSGO, TF2)
worldtext()
= point_worldtext: "An entity that displays a text message oriented in the world, at its origin."
[
spawnflags(flags) : "spawnflags" =
[
- 1: "Start Disabled" : 0
+ 1: "Start Disabled" : 0 [!TF2]
]
message(string) : "Entity Message"
textsize(float) : "Text Size" : 10 : "Text Size."
- color(color255) : "Color" : "255 255 255"
+ color[!TF2](color255) : "Color" : "255 255 255" : "Color of the text"
+ color[TF2](color255) : "Color" : "255 255 255 255" : "Color and opacity of the text"
+
+ font[engine](integer) : "Font" : 0
+ font[TF2](choices) : "Font" : 0 : "The font to use for the text" =
+ [
+ 0 : "TF2 Build"
+ 1 : "TF2 Build (no outline/shadow)"
+ 2 : "TF2"
+ 3 : "TF2 (no outline/shadow)"
+ 4 : "Liberation Sans"
+ 5 : "Liberation Sans (no outline/shadow)"
+ 6 : "TF2 Professor"
+ 7 : "TF2 Professor (no outline/shadow)"
+ 8 : "Roboto Mono"
+ 9 : "Roboto Mono (no outline/shadow)"
+ 10 : "Roboto Mono (shadow only)"
+ 11 : "Roboto Mono (green glow, soft edges)"
+ 12 : "TF2 Build (soft edges)"
+ ]
+
+ orientation[engine](integer) : "Orientation" : 0
+ orientation[TF2](choices) : "Orientation" : 0 : "Text orientation mode. Fixed orientation left aligns the text, the others center align it." =
+ [
+ 0 : "Fixed orientation"
+ 1 : "Face player"
+ 2 : "Face player, yaw only"
+ ]
+
+ textspacingx[TF2](float) : "Text Spacing X" : 0 : "Spacing between each letter along the X axis. Negative values will invert the text."
+ textspacingy[TF2](float) : "Text Spacing Y" : 0 : "Spacing between each letter along the Y axis. Only used when newlines have been inserted into the text."
+ rainbow[TF2](boolean) : "Rainbow text" : 0 : "Enables rainbow text, overriding colors set elsewhere."
// Inputs
- input Enable(void) : "Start displaying the message text, if the player is within the message radius."
- input Disable(void) : "Stop displaying the message text."
- input SetMessage(string) : "Set the message text."
+ input Enable[!TF2](void) : "Start displaying the message text."
+ input Disable[!TF2](void) : "Stop displaying the message text."
+ input SetMessage[!TF2](string) : "Set the message text."
+
+ // TF2 Inputs
+ input SetText[TF2](string) : "Set the message text."
+ input SetTextSize[TF2](float) : "Set the message text size. Setting this to 0 will hide the text. Negative values flip the text upside down."
+ input SetTextSpacingX[TF2](float) : "Set the spacing between letters along the X axis. Negative values will invert the text."
+ input SetTextSpacingY[TF2](float) : "Set the spacing between letters along the Y axis. Only used when newlines are inserted into the text."
+ input SetColor[TF2](color255) : "Set the message color"
+ input SetFont[TF2](integer) : "Set the message font. Accepts values 0-12."
+ input SetOrientation[TF2](integer) : "Sets the message orientation type."
+ input SetRainbow[TF2](integer) : "Sets rainbow text to be enabled/disabled."
+
]
diff --git a/fgd/point/prop/prop_button.fgd b/fgd/point/prop/prop_button.fgd
index ba2cbcf45..25c28dfe7 100644
--- a/fgd/point/prop/prop_button.fgd
+++ b/fgd/point/prop/prop_button.fgd
@@ -1,17 +1,19 @@
@PointClass
- base(BasePedButton)
+ base(BasePedButton, SRCModel)
appliesto(P2)
autovis(Test Elements, P2 Buttons, Pedestal)
studioprop()
= prop_button: "A button which is activated by player use or by game inputs. While pressed it can play a tick-tock sound to indicate limited time."
[
- skin[engine](integer) : "Skin" : 0 : "Should it appear dirty or clean?"
- skin(choices) : "Skin" : "0" : "Should it appear dirty or clean?" =
+ model[-srctools](studio) : "[H] Model" : "models/props/switch001.mdl" : "The model to display in Hammer. VScript must be used to set the in-game model."
+ model[+srctools](studio) : "[HA] Custom Model" : "models/props/switch001.mdl" : "The model to display in Hammer, and the custom model to use if Override Model is enabled."
+
+ skin[engine](integer) : "Skin" : 0 : "Skin on the model to use."
+ skin(choices) : "Skin" : "0" : "Skin on the model to use. With the normal model, this sets if the button is clean or dirty. With a custom model, any skin number can be entered here." =
[
- 0: "Clean"
- 1: "Dirty"
+ 0: "[0] Clean"
+ 1: "[1] Dirty"
]
- model(studio) : "[H] Model" : "models/props/switch001.mdl" : "Model to display in Hammer. Use Init Code and a comp_precache_model to change the model in-game."
@resources
[
diff --git a/fgd/point/prop/prop_contraption_cube.fgd b/fgd/point/prop/prop_contraption_cube.fgd
index 71d79ca23..3e17b76b4 100644
--- a/fgd/point/prop/prop_contraption_cube.fgd
+++ b/fgd/point/prop/prop_contraption_cube.fgd
@@ -1,10 +1,25 @@
@PointClass base(BasePortalCube)
- studioprop("models/props/reflection_cube.mdl")
+ studioprop("models/props_ingame/cubecontraption.mdl")
appliesto(P2EDU)
- autovis(Test Elements, Cubes, Normal)
= prop_contraption_cube : "Contraption Cube"
[
- cube_mass(float) : "Mass" : 40 : "Mass of the cube (kg)"
- ContraptionFrictionIndex(integer) : "Friction" : 0 : "Friction index of the cube [0,4]"
- ContraptionElasticityIndex(integer) : "Elasticity" : 0 : "Elasticity index of the cube [0,4]"
+ cube_mass(float) : "Mass" : 40 : "Mass of the cube (kg)"
+ ContraptionFrictionIndex[engine](integer) : "Friction" : 0
+ ContraptionFrictionIndex(choices) : "Friction" : 0 : "Friction index of the cube" =
+ [
+ 0 : "Frictionless"
+ 1 : "Slippery"
+ 2 : "Normal"
+ 3 : "Sticky"
+ 4 : "Very sticky"
+ ]
+ ContraptionElasticityIndex[engine](integer) : "Elasticity" : 0
+ ContraptionElasticityIndex(choices) : "Elasticity" : 0 : "Elasticity index of the cube" =
+ [
+ 0 : "No rebound"
+ 1 : "Slight rebound"
+ 2 : "Normal"
+ 3 : "Bouncy"
+ 4 : "Very bouncy"
+ ]
]
diff --git a/fgd/point/prop/prop_contraption_cube_button.fgd b/fgd/point/prop/prop_contraption_cube_button.fgd
index 160309c49..a50da7f97 100644
--- a/fgd/point/prop/prop_contraption_cube_button.fgd
+++ b/fgd/point/prop/prop_contraption_cube_button.fgd
@@ -1,8 +1,7 @@
@PointClass base(BasePortButton)
appliesto(P2EDU)
- autovis(Test Elements, P2 Buttons, Floor)
- studioprop("models/props_ingame/button_socket_contraption..mdl")
-= prop_contraption_cube_button: "A floor button which is activated by a prop_contraption_cube."
+ studioprop("models/props_ingame/button_socket_contraption.mdl")
+= prop_contraption_cube_button: "A floor button which is activated by a prop_contraption_cube. Doesn't seem to work."
[
- output OnPulse(string) : "Should be called when the button is being pressed."
+ output OnPulse(string) : "Fired when the button is being pressed."
]
diff --git a/fgd/point/prop/prop_door_rotating.fgd b/fgd/point/prop/prop_door_rotating.fgd
index b746e3a92..fd0ed0278 100644
--- a/fgd/point/prop/prop_door_rotating.fgd
+++ b/fgd/point/prop/prop_door_rotating.fgd
@@ -130,4 +130,10 @@
output OnRotationDone[GMod, since_P2](void) : "Fired when the door arrives at it's goal angle."
output OnBreak[L4D, L4D2](void) : "Fired when the door changes damage states."
output OnKicked[EZ2](void) : "(EZ2) Fired when the door is kicked open."
+
+ @resources
+ [
+ sound "DoorSound.Null"
+ func prop_door_rotating
+ ]
]
diff --git a/fgd/point/prop/prop_dynamic_ornament.fgd b/fgd/point/prop/prop_dynamic_ornament.fgd
index 2365b9c6c..6609508cf 100644
--- a/fgd/point/prop/prop_dynamic_ornament.fgd
+++ b/fgd/point/prop/prop_dynamic_ornament.fgd
@@ -3,7 +3,7 @@
autovis(Props, Dynamic)
= prop_dynamic_ornament: "A way to attach one studio model to another as an ornament. It will render in the way that player/NPC weapons render."
[
- solid(choices) : "Collisions" : "0" =
+ solid(choices) readonly : "Collisions" : "0" : "Collisions don't follow the target entity properly, so this should always be non-solid." =
[
0: "Not Solid"
]
diff --git a/fgd/point/prop/prop_exploding_futbol.fgd b/fgd/point/prop/prop_exploding_futbol.fgd
index 7587d494b..af0bf44f4 100644
--- a/fgd/point/prop/prop_exploding_futbol.fgd
+++ b/fgd/point/prop/prop_exploding_futbol.fgd
@@ -1,12 +1,18 @@
-@PointClass base(BaseEntityPhysics)
+@PointClass base(BasePropPhysics, SRCModel)
appliesto(P2)
- studioprop("models/npcs/personality_sphere_angry.mdl")
+ studioprop()
= prop_exploding_futbol: "The bombs used by Wheatley."
[
+ model[-srctools](studio) : "[H] Model" : "models/npcs/personality_sphere_angry.mdl" : "The model to display in Hammer. VScript must be used to set the in-game model."
+ model[+srctools](studio) : "[HA] Custom Model" : "models/npcs/personality_sphere_angry.mdl" : "The model to display in Hammer, and the custom model to use if Override Model is enabled."
+ skin(integer) : "Skin" : 0 : "Skin on the model to use."
+
explodeontouch(boolean) : "Explode on touch" : 1 : "If the bomb should explode when it touches something."
+ // Keyvalues dump includes ShouldRespawn and SpawnerName keyvalues but they don't seem to work
// Inputs
input Explode(void) : "Explodes the bomb."
+ input Dissolve(void) : "Fizzles the bomb. Doesn't fire the OnFizzled output."
@resources // Assumed
[
diff --git a/fgd/point/prop/prop_floor_ball_button.fgd b/fgd/point/prop/prop_floor_ball_button.fgd
index da5d31da5..b1e555335 100644
--- a/fgd/point/prop/prop_floor_ball_button.fgd
+++ b/fgd/point/prop/prop_floor_ball_button.fgd
@@ -1,9 +1,13 @@
-@PointClass base(BasePortButton)
+@PointClass base(BasePortButton, SRCModel)
appliesto(P2)
autovis(Test Elements, P2 Buttons, Floor)
studioprop() = prop_floor_ball_button: "A floor button which is only activated by a Sphere-type prop_weighted_cube."
[
- model(studio) : "[H] Model" : "models/props/ball_button.mdl" : "Model to display in Hammer. Use Init Code and a comp_precache_model to change the model in-game."
+
+ model[-srctools](studio) : "[H] Model" : "models/props/ball_button.mdl" : "The model to display in Hammer. VScript must be used to set the in-game model."
+ model[+srctools](studio) : "[HA] Custom Model" : "models/props/ball_button.mdl" : "The model to display in Hammer, and the custom model to use if Override Model is enabled."
+ // Hammer automatically adds this when selecting a model, this prevents it from appearing as invalid
+ skin(integer) readonly : "" : 0 : "Skin on the model to use. The game overrides this based on the button's pressed state, so changing it here has no effect."
@resources
[
model "models/props/ball_button.mdl"
diff --git a/fgd/point/prop/prop_floor_cube_button.fgd b/fgd/point/prop/prop_floor_cube_button.fgd
index 743d3e382..fd0cef496 100644
--- a/fgd/point/prop/prop_floor_cube_button.fgd
+++ b/fgd/point/prop/prop_floor_cube_button.fgd
@@ -1,11 +1,14 @@
-@PointClass base(BasePortButton)
+@PointClass base(BasePortButton, SRCModel)
appliesto(P2)
autovis(Test Elements, P2 Buttons, Floor)
studioprop() = prop_floor_cube_button: "A floor button which is activated by a prop_weighted_cube."
[
- model(studio) : "[H]] Model" : "models/props/box_socket.mdl" : "Model to display in Hammer. Use Init Code and a comp_precache_model to change the model in-game."
- acceptsball(boolean) : "Accepts Balls" : 0 : "Do Edgeless Safety Cubes activate this? Should almost always be No unless no balls are in the map."
+ model[-srctools](studio) : "[H] Model" : "models/props/box_socket.mdl" : "The model to display in Hammer. VScript must be used to set the in-game model."
+ model[+srctools](studio) : "[HA] Custom Model" : "models/props/box_socket.mdl" : "The model to display in Hammer, and the custom model to use if Override Model is enabled."
+ acceptsball(boolean) : "Accepts Balls" : 0 : "Do Edgeless Safety Cubes activate this? Should almost always be No."
+ // Hammer automatically adds this when selecting a model, this prevents it from appearing as invalid
+ skin(integer) readonly : "" : 0 : "Skin on the model to use. The game overrides this based on the button's pressed state, so changing it here has no effect."
@resources
[
model "models/props/box_socket.mdl"
diff --git a/fgd/point/prop/prop_glados_core.fgd b/fgd/point/prop/prop_glados_core.fgd
index 6e19c617e..347540d34 100644
--- a/fgd/point/prop/prop_glados_core.fgd
+++ b/fgd/point/prop/prop_glados_core.fgd
@@ -1,21 +1,36 @@
// Switch the model used depending on game.
@BaseClass appliesto(P1) studioprop("models/props_bts/glados_ball_reference.mdl")
= _prop_glados_core_p1_mdl []
-@BaseClass appliesto(P2) studioprop("models/npcs/personality_sphere/personality_sphere.mdl")
+@BaseClass appliesto(P2) studioprop()
= _prop_glados_core_p2_mdl []
-@PointClass base(BasePropPhysics, _prop_glados_core_p1_mdl, _prop_glados_core_p2_mdl)
+@PointClass base(BasePropPhysics, _prop_glados_core_p1_mdl, _prop_glados_core_p2_mdl, SRCModel)
appliesto(P1, P2)
= prop_glados_core: "The P1 personality cores for GlaDOS. Resemble little eyeballs with handles. " +
- "These play lines and look around when near the player. "
+ "These play lines and look around when near the player. " +
+ "Portal 2 uses the wrong core model, so this will need to be swapped back with VScript."
[
- coretype[engine](integer) : "Core Personality" : 1
- coretype(choices) : "Core Personality" : 1 : "Which personality VO set the core is set to." =
+ model[P2, -srctools](studio) : "[H] Model" : "models/npcs/personality_sphere/personality_sphere.mdl" : "The model to display in Hammer. VScript must be used to set the in-game model."
+ model[P2, +srctools](studio) : "[HA] Custom Model" : "models/npcs/personality_sphere/personality_sphere.mdl" : "The model to display in Hammer, and the custom model to use if Override Model is enabled."
+
+ coretype[engine](integer) : "Core Personality" : 3
+ coretype(choices) : "Core Personality" : 3 : "Which personality the core is set to, determines the voice lines and skin." =
+ [
+ // Ordered to match P1 boss fight
+ 3: "Morality Core"
+ 0: "Curiosity Core"
+ 2: "Intelligence/Cake Core"
+ 1: "Anger Core"
+ ]
+
+ skin[engine](integer) : "Skin" : 0
+ skin(choices) : "[H] Skin" : 0 : "Skin to show in Hammer." =
[
- 0: "Curious"
- 1: "Aggressive"
- 2: "Crazy"
- 3: "None"
+ // Ordered to match P1 boss fight
+ 0: "Morality Core"
+ 1: "Curiosity Core"
+ 3: "Intelligence/Cake Core"
+ 2: "Anger Core"
]
delaybetweenlines(float) : "Pause (in secs) between VO Lines." : 0.4 : "When the core is talking, this is the number of seconds delay between it's spoken lines."
diff --git a/fgd/point/prop/prop_glass_futbol.fgd b/fgd/point/prop/prop_glass_futbol.fgd
index 523d88bcd..1a249c8b1 100644
--- a/fgd/point/prop/prop_glass_futbol.fgd
+++ b/fgd/point/prop/prop_glass_futbol.fgd
@@ -1,9 +1,16 @@
-@PointClass base(BasePropPhysics)
+@PointClass base(BasePropPhysics, SRCModel)
appliesto(P2)
- studioprop("models/props/futbol.mdl")
- line(255 255 0, targetname, spawnername) = prop_glass_futbol: "A fragile glass ball that the player can pick up and toss. On contact with surfaces it will shatter, and it can be put into holders to power them. It is affected by gel, but the shattering means this has little effect."
+ studioprop()
+ line(255 255 0, targetname, spawnername)
+= prop_glass_futbol: "A fragile glass ball that the player can pick up and toss. On contact with surfaces it will shatter, and it can be put into holders to power them. It is affected by gel, but the shattering means this has little effect."
[
- spawnername(target_destination) : "Spawner Name" : : "Name of prop_glass_futbol_spawner for this futbol to respawn in once broken."
+ model[-srctools](studio) : "[H] Model" : "models/props/futbol.mdl" : "The model to display in Hammer. VScript must be used to set the in-game model."
+ model[+srctools](studio) : "[HA] Custom Model" : "models/props/futbol.mdl" : "The model to display in Hammer, and the custom model to use if Override Model is enabled."
+ skin(integer) : "Skin" : 0 : "Skin on the model to use."
+
+ spawnername(target_destination) : "Spawner Name" : : "Name of a prop_glass_futbol_spawner for this futbol to respawn in once broken."
+
+
// Inputs
input Dissolve(void) : "Dissolve"
diff --git a/fgd/point/prop/prop_glass_futbol_spawner.fgd b/fgd/point/prop/prop_glass_futbol_spawner.fgd
index 0a0e29327..22e2932be 100644
--- a/fgd/point/prop/prop_glass_futbol_spawner.fgd
+++ b/fgd/point/prop/prop_glass_futbol_spawner.fgd
@@ -1,4 +1,4 @@
-@PointClass base(BaseEntityPoint)
+@PointClass base(BaseEntityAnimating)
appliesto(P2)
studioprop("models/props/futbol_dispenser.mdl") = prop_glass_futbol_spawner: "Spawns futbols. Will re-create a futbol when its created futbol breaks."
[
diff --git a/fgd/point/prop/prop_glowing_object.fgd b/fgd/point/prop/prop_glowing_object.fgd
index e80461b71..0f29f5175 100644
--- a/fgd/point/prop/prop_glowing_object.fgd
+++ b/fgd/point/prop/prop_glowing_object.fgd
@@ -10,6 +10,8 @@
glowforteam(choices) : "Glow For Team" : -1 : "Team(s) this entity should glow for" =
[
-1: "Everyone"
+ 0: "Unassigned" [+complete]
+ 1: "Spectators" [+complete]
2: "Survivors"
3: "Infected"
]
diff --git a/fgd/point/prop/prop_laser_catcher.fgd b/fgd/point/prop/prop_laser_catcher.fgd
index 7382953d3..93b25e32b 100644
--- a/fgd/point/prop/prop_laser_catcher.fgd
+++ b/fgd/point/prop/prop_laser_catcher.fgd
@@ -26,7 +26,7 @@
"models/props/laser_catcher.mdl": "Offset"
]
- src_fix_skins[srctools](boolean) : "Fix Skins Logic" : 1 : "If set, add extra outputs to fix the bug with skins not changing after a reload from save."
+ src_fix_skins[srctools](boolean) : "[HA] Fix Skins Logic" : 1 : "If set, add extra outputs to fix the bug with skins not changing after a reload from save."
// Inputs
input Skin(integer) : "Set the skin of the catcher manually."
diff --git a/fgd/point/prop/prop_monster_box.fgd b/fgd/point/prop/prop_monster_box.fgd
index 5163b9738..53fff9b76 100644
--- a/fgd/point/prop/prop_monster_box.fgd
+++ b/fgd/point/prop/prop_monster_box.fgd
@@ -1,13 +1,12 @@
@PointClass base(BaseEntityPhysics)
appliesto(P2)
- autovis(Test Elements, Cubes, Franken)
studioprop() = prop_monster_box: "FrankenCubes, they walk about when oriented correctly but otherwise behave like normal Storage Cubes."
[
startasbox(boolean) : "Start As Box" : 0 : "Start the FrankenTurret in cube form."
boxswitchspeed(float) : "Box Switch Speed" : 400 : "Speed to force switch to a box."
allowsilentdissolve(boolean) : "Allow SilentDissolve input" : 1 : "Allow the SilentDissolve input to dissolve this FrankenCube."
- model[engine](studio) : "Model" : "models/npcs/monsters/monster_a.mdl"
+ model[engine](string) : "Hammer Preview" : "models/npcs/monsters/monster_a.mdl"
model(choices) : "[H] Pose" : "models/npcs/monsters/monster_a.mdl" : "What pose to show in Hammer." =
[
"models/npcs/monsters/monster_a.mdl": "Extended"
diff --git a/fgd/point/prop/prop_paint_bomb.fgd b/fgd/point/prop/prop_paint_bomb.fgd
index a07c80297..fd5e482ac 100644
--- a/fgd/point/prop/prop_paint_bomb.fgd
+++ b/fgd/point/prop/prop_paint_bomb.fgd
@@ -13,7 +13,9 @@
allowsilentdissolve(boolean) : "Allow SilentDissolve input" : 0 : "Allow the SilentDissolve input to dissolve this bomb."
playspawnsound(boolean) : "Play Spawn Sound" : 1 : "Whether or not this bomb should play a sound on spawn (PaintBlob.Inception)."
- model(studio) readonly : "Model" : "models/error.mdl" : "Paint bombs need a model set to suppress a warning message. This model would be loaded already."
+
+ model[engine](string) : "" // Not actually a model it really loads.
+ model(studio) readonly : "Model" : "models/props/futbol.mdl" : "Paint bombs need a model set to suppress a warning message. This model gets loaded already."
// Inputs
input Dissolve(void) : "Dissolves the paint bomb."
diff --git a/fgd/point/prop/prop_physics_respawnable.fgd b/fgd/point/prop/prop_physics_respawnable.fgd
index 1c8690eed..753870b2b 100644
--- a/fgd/point/prop/prop_physics_respawnable.fgd
+++ b/fgd/point/prop/prop_physics_respawnable.fgd
@@ -1,4 +1,4 @@
-@PointClass base(prop_physics) appliesto(Mesa)
+@PointClass base(prop_physics)
studioprop()
= prop_physics_respawnable : "This class is the same as prop_physics, except it respawns after it breaks"
[
diff --git a/fgd/point/prop/prop_scaled_cube.fgd b/fgd/point/prop/prop_scaled_cube.fgd
index 176687ba9..9b222b3da 100644
--- a/fgd/point/prop/prop_scaled_cube.fgd
+++ b/fgd/point/prop/prop_scaled_cube.fgd
@@ -1,7 +1,6 @@
@PointClass base(BasePortalCube)
studioprop("models/props/sixense/box/sixensebox.mdl")
appliesto(P2SIXENSE)
- autovis(Test Elements, Cubes, Scalable)
= prop_scaled_cube : "Scalable Cube"
[
-]
\ No newline at end of file
+]
diff --git a/fgd/point/prop/prop_sphere.fgd b/fgd/point/prop/prop_sphere.fgd
index 9ae393b07..4082f6a47 100644
--- a/fgd/point/prop/prop_sphere.fgd
+++ b/fgd/point/prop/prop_sphere.fgd
@@ -4,5 +4,5 @@
sphere(radius)
= prop_sphere : "A variant of prop_physics which has a perfect sphere shape. It is normally restricted to a radius of 12 units."
[
- radius[MBase](float) : "Radius" : 12 : "The size of the sphere collision."
+ radius[MBase, GMod](float) : "Radius" : 12 : "The size of the sphere collision."
]
diff --git a/fgd/point/prop/prop_static.fgd b/fgd/point/prop/prop_static.fgd
index e31866ae5..55cd3a4dc 100644
--- a/fgd/point/prop/prop_static.fgd
+++ b/fgd/point/prop/prop_static.fgd
@@ -36,21 +36,20 @@
uniformscale[PROP_SCALING](float) : "Uniform Scale Override" : 1 : "Resize the static prop."
-
- solid[engine](integer) : "Collisions" : 6
- solid(choices) : "Collisions" : 6 =
+ solid[engine](integer) : "Collisions": 6
+ solid(choices) : "Collisions" : 6 : "Method of collision for this prop." =
[
- 0: "Not Solid"
- 1: "Use BSP (QPhysics)" [complete]
- 2: "Use Bounding Box"
- 3: "Use Oriented Bounding Box" [complete]
- 4: "Use Oriented Bounding Box, constrained to Yaw only" [complete]
- 6: "Use VPhysics"
+ 0: "None"
+ 1: "BSP (QPhysics)" [complete]
+ 2: "Bounding Box"
+ 3: "Oriented Bounding Box"
+ 4: "Oriented Bounding Box, constrained to Yaw only"
+ 6: "VPhysics"
]
preventpropcombine[PROPCOMBINE](boolean) : "Disable Prop Combine" : 0 : "Prevent this static prop from combining with any other static props in vbsp."
- linedivider_levels[!engine](string) readonly : "----------------------------------------------------------------------------------------------------------" : ""
+ linedivider_levels[!engine, +complete](string) readonly : "----------------------------------------------------------------------------------------------------------" : ""
mincpulevel[engine](integer): "Minimum CPU Level": 0
maxcpulevel[engine](integer): "Maximum CPU Level": 0
@@ -119,7 +118,11 @@
linedivider_light[!engine](string) readonly : "----------------------------------------------------------------------------------------------------------" : ""
- disableshadows(boolean) : "Disable Shadows" : 0
+ disableshadows(boolean) : "Disable Shadows" : 0 : "Prevent this prop from obstructing light to cast shadows."
+ // Doesn't appear to work?
+ disableshadowdepth[since_L4D, +complete](boolean) : "No Affecting Proj Texs" : 0 : "Prevent this entity from affecting projected texture shadows."
+ disableflashlight[since_L4D](boolean) : "No Recieving Proj Texs" : 0 : "Prevent this prop from recieving projected texture shadows."
+
disablevertexlighting(boolean) : "Disable Vertex lighting" : 0 : "Disable per-vertex lighting on this prop."
disableselfshadowing(boolean) : "Disable Self-Shadowing" : 0 : "When vertex lighting is enabled, prevent the geometry from self-shadowing -- casting shadows onto itself."
ignorenormals(boolean) : "Ignore Surface Normal" : 0 : "When vertex lighting is enabled, ignore the surface normal of faces when calculating the vertex lighting. Useful for thin, translucent objects such as leaves on foliage props."
@@ -129,7 +132,7 @@
lightingorigin(target_destination) : "Lighting Origin" : : "Select an info_lighting to specify a location to sample lighting from, instead of using this entity's origin."
- linedivider_lmap[TF2, MESA, !engine](string) readonly : "----------------------------------------------------------------------------------------------------------" : ""
+ linedivider_lmap[TF2, MESA, KZ, !engine](string) readonly : "----------------------------------------------------------------------------------------------------------" : ""
generatelightmaps[TF2, MESA, KZ](boolean) : "Generate (and use) lightmaps for this static prop" : 0
lightmapresolutionx[TF2, MESA, KZ](integer) : "Lightmap Resolution X" : 32 : "The resolution of the generated lightmap in the X (or U) direction (only used if Generate Lightmaps is Yes) "
diff --git a/fgd/point/prop/prop_tractor_beam.fgd b/fgd/point/prop/prop_tractor_beam.fgd
index d016981e7..7bf8e7662 100644
--- a/fgd/point/prop/prop_tractor_beam.fgd
+++ b/fgd/point/prop/prop_tractor_beam.fgd
@@ -25,7 +25,7 @@
"models/props_ingame/tractor_beam_128.mdl": "128 Model (PeTI)"
]
- model[engine](studio): "Funnel model" : "models/props/tractor_beam_emitter.mdl"
+ model[engine](string): "Hammer Preview" : "models/props/tractor_beam_emitter.mdl"
// Inputs
input SetLinearForce(float) : "Set the speed of the Funnel, and therefore the direction."
diff --git a/fgd/point/prop/prop_under_button.fgd b/fgd/point/prop/prop_under_button.fgd
index 81f39cce1..f3ad0fc04 100644
--- a/fgd/point/prop/prop_under_button.fgd
+++ b/fgd/point/prop/prop_under_button.fgd
@@ -1,11 +1,16 @@
-@PointClass base(BasePedButton)
+@PointClass base(BasePedButton, SRCModel)
appliesto(P2)
autovis(Test Elements, P2 Buttons, Pedestal)
- studioprop("models/props_underground/underground_testchamber_button.mdl")
+ studioprop()
= prop_under_button: "A button which is activated by player use or by game inputs, for use in underground test chambers. " +
"Uses different press/release sounds compared to the modern one. " +
"The same tick-tock noise is used to indicate limited time."
[
+
+ model[-srctools](studio) : "[H] Model" : "models/props_underground/underground_testchamber_button.mdl" : "The model to display in Hammer. VScript must be used to set the in-game model."
+ model[+srctools](studio) : "[HA] Custom Model" : "models/props_underground/underground_testchamber_button.mdl" : "The model to display in Hammer, and the custom model to use if Override Model is enabled."
+ skin(integer) : "Skin" : 0 : "Skin on the model to use."
+
@resources
[
model "models/props_underground/underground_testchamber_button.mdl"
diff --git a/fgd/point/prop/prop_under_floor_button.fgd b/fgd/point/prop/prop_under_floor_button.fgd
index d86ef737b..8eddc3b1e 100644
--- a/fgd/point/prop/prop_under_floor_button.fgd
+++ b/fgd/point/prop/prop_under_floor_button.fgd
@@ -1,11 +1,16 @@
-@PointClass base(BasePortButton)
+@PointClass base(BasePortButton, SRCModel)
appliesto(P2)
autovis(Test Elements, P2 Buttons, Floor)
- studioprop("models/props_underground/underground_floor_button.mdl")
+ studioprop()
= prop_under_floor_button: "A floor button which is activated by a player or objects, for use in the underground test chambers. " +
"It plays different sounds, and has a larger trigger area."
[
+ model[-srctools](studio) : "[H] Model" : "models/props_underground/underground_floor_button.mdl" : "The model to display in Hammer. VScript must be used to set the in-game model."
+ model[+srctools](studio) : "[HA] Custom Model" : "models/props_underground/underground_floor_button.mdl" : "The model to display in Hammer, and the custom model to use if Override Model is enabled."
+ // Hammer automatically adds this when selecting a model, this prevents it from appearing as invalid
+ skin(integer) readonly : "" : 0 : "Skin on the model to use. The game overrides this based on the button's pressed state, so changing it here has no effect."
+
// Outputs
output OnPressedBlue(void) : "Called in Coop when the button has been pressed by ATLAS."
output OnPressedOrange(void) : "Called in Coop when the button has been pressed by P-Body."
diff --git a/fgd/point/prop/prop_wall_projector.fgd b/fgd/point/prop/prop_wall_projector.fgd
index d53ade335..82d95afc4 100644
--- a/fgd/point/prop/prop_wall_projector.fgd
+++ b/fgd/point/prop/prop_wall_projector.fgd
@@ -1,15 +1,18 @@
-@PointClass base(BaseProjector)
+@PointClass base(BaseProjector, SRCModel)
appliesto(P2)
autovis(Test Elements, Light Bridge)
- studioprop("models/props/wall_emitter.mdl")
+ studioprop()
= prop_wall_projector: "Aperture Science Hard Light Bridge Projector. " +
"Note: To avoid lag when it first turns on, place an info_particle_system to precache 'projected_wall_impact'."
[
+ model[-srctools](studio) : "[H] Model" : "models/props/wall_emitter.mdl" : "The model to display in Hammer. VScript must be used to set the in-game model."
+ model[+srctools](studio) : "[HA] Custom Model" : "models/props/wall_emitter.mdl" : "The model to display in Hammer, and the custom model to use if Override Model is enabled."
+
skin[engine](integer) : "Skin" : 0
- skin(choices) : "Skin" : 0 : "Which skin to use." =
+ skin(choices) : "Skin" : 0 : "Skin on the model to use. With the normal model, this sets if the emitter is clean or rusted. With a custom model, any skin number can be entered here." =
[
- 0: "Clean"
- 1: "Rusted"
+ 0: "[0] Clean"
+ 1: "[1] Rusted"
]
@resources
diff --git a/fgd/point/prop/prop_weighted_cube.fgd b/fgd/point/prop/prop_weighted_cube.fgd
index 09327c2d8..74f731ca8 100644
--- a/fgd/point/prop/prop_weighted_cube.fgd
+++ b/fgd/point/prop/prop_weighted_cube.fgd
@@ -1,6 +1,5 @@
@PointClass base(BasePortalCube)
appliesto(P2)
- autovis(Test Elements, Cubes, Normal)
studioprop() = prop_weighted_cube: "Aperture Science Weighted Cube. Presses floor buttons, and can be moved around."
[
cubetype[engine](integer) : "Cube Type" : 0
@@ -12,7 +11,7 @@
2: "[2] Discouragement Redirection Cube"
3: "[3] Edgeless Safety Cube"
4: "[4] Antique Storage Cube"
- 6: "[6] Custom model"
+ 6: "Custom model"
]
skintype[engine](boolean) : "Skin Type" : 0
@@ -23,7 +22,7 @@
]
model[engine](studio) : "Model" : ""
- model(choices) : "Model" : "models/props/metal_box.mdl" : "The model to show in Hammer, or a custom model for cube type 6." =
+ model(choices) : "Model" : "models/props/metal_box.mdl" : "The model to show in Hammer. Custom model names can also be typed/pasted in here, and will be shown in-game if the entity is set to use a custom model." =
[
"models/props/metal_box.mdl": "Weighted Storage/Companion Cube"
"models/props/reflection_cube.mdl": "Discouragement Redirection"
@@ -31,6 +30,15 @@
"models/props_underground/underground_weighted_cube.mdl": "Antique"
]
+ comp_custom_model_type[srctools, -engine](choices) : "[HA] Custom Model Type" : 0 : "Automatically handles various methods of setting custom cube models. " +
+ "Cube Type sets the behavior and which skin numbers are used for gel, and the Model keyvalue sets the actual model. " +
+ "Script Override mode requires the collisions to be the same as the base cube type, but tends to produce more correct physics than Cube Type 6." =
+ [
+ 0 : "None"
+ 1 : "Script Override"
+ 2 : "Cube Type 6"
+ ]
+
skin(integer) : "Skin" : 0 : "The old skin property, mainly to show in Hammer. "
newskins(integer) readonly : "Use new skins" : 1 : "Use the values in the Cube Type and Skin Type fields instead of the Skin(OLD) field. You shouldn't need to touch this."
diff --git a/fgd/point/proto_sniper.fgd b/fgd/point/proto_sniper.fgd
new file mode 100644
index 000000000..876565bbb
--- /dev/null
+++ b/fgd/point/proto_sniper.fgd
@@ -0,0 +1,7 @@
+@NpcClass aliasof(npc_sniper)
+ appliesto(EP1, EP2, HL2, P1, Mesa)
+ autovis(Entities, NPCs, Combine, Combine Sniper)
+ studio("models/combine_soldier.mdl")
+= proto_sniper: "Alternate name for npc_sniper."
+ [
+ ]
diff --git a/fgd/point/rd_robot_dispenser.fgd b/fgd/point/rd_robot_dispenser.fgd
index 198f93d4a..5b5e196f3 100644
--- a/fgd/point/rd_robot_dispenser.fgd
+++ b/fgd/point/rd_robot_dispenser.fgd
@@ -1,4 +1,5 @@
-@PointClass base(BaseEntityPoint, BaseObject)
+@PointClass base(BaseEntityPoint, BaseObject)
+ line(255 255 255, targetname, touch_trigger)
appliesto(TF2)
= rd_robot_dispenser: "Robot Destruction Robot Dispenser Level 0.5"
[
diff --git a/fgd/point/team/team_control_point.fgd b/fgd/point/team/team_control_point.fgd
index 7179cc8db..dc2faa901 100644
--- a/fgd/point/team/team_control_point.fgd
+++ b/fgd/point/team/team_control_point.fgd
@@ -1,6 +1,6 @@
@PointClass base(BaseEntityAnimating, EnableDisable)
appliesto(TF2)
- studio("models/effects/cappoint_hologram.mdl")
+ studioprop()
= team_control_point: "Control Point"
[
spawnflags(flags) : "spawnflags" =
@@ -14,7 +14,7 @@
point_start_locked(boolean) : "Start locked" : 0 : "Locked means the point will not be available for capture until it is unlocked via its input."
- point_printname(string) : "Print Name" : "TODO: Set Name" : "LOCALIZED name to print on the HUD."
+ point_printname(string) : "Print Name" : "TODO: Set Name" : "The name of this control point to print on the HUD. Can be a raw text string or a localization token."
point_group(integer) : "Group Index" : 0 : "Used for grouping points together under a team_control_point_master (not using control point rounds)."
point_default_owner[engine](integer) : "Default Owner" : 0
@@ -39,48 +39,54 @@
random_owner_on_restart(boolean) : "Randomly set the owner on restart" : "0" : "Randomly set the owner of this point during a full restart of the map. The ratio of default owners among the points with this flag will be kept when selecting random owners."
team_timedpoints_2(integer) : "Time-based point value for RED." : 0
- team_timedpoints_3(integer) : "Time-based point value for BLUE." : 0
+ team_timedpoints_3(integer) : "Time-based point value for BLU." : 0
team_capsound_0(sound) : "Reset Sound" : : "Sound made when point resets."
- team_capsound_2(sound) : "Red Capture Sound" : : "Sound made when RED captures."
- team_capsound_3(sound) : "Blue Capture Sound" : : "Sound made when BLUE captures."
- team_model_0(studio) : "Reset Model" : "models/effects/cappoint_hologram.mdl" : "Model when point reset."
- team_model_2(studio) : "RED Model" : "models/effects/cappoint_hologram.mdl" : "Model when RED owns the point."
- team_model_3(studio) : "BLUE Model" : "models/effects/cappoint_hologram.mdl" : "Model when BLUE owns the point."
- team_bodygroup_0(integer) : "Reset model bodygroup" : 3
- team_bodygroup_2(integer) : "RED model bodygroup" : 1
- team_bodygroup_3(integer) : "BLUE model bodygroup" : 1
- team_icon_0(material) : "HUD icon neutral" : "sprites/obj_icons/icon_obj_neutral" : "HUD icon material when no one owns the point."
- team_icon_2(material) : "HUD icon RED" : "sprites/obj_icons/icon_obj_red" : "HUD icon material when RED owns the point."
- team_icon_3(material) : "HUD icon BLUE" : "sprites/obj_icons/icon_obj_blu" : "HUD icon material when BLUE owns the point."
- team_overlay_0(material) : "HUD overlay neutral" : : "HUD material that will overlay the icon when no one owns the point."
- team_overlay_2(material) : "HUD overlay RED" : : "HUD material that will overlay the icon when RED owns the point."
- team_overlay_3(material) : "HUD overlay BLUE" : : "HUD material that will overlay the icon when BLUE owns the point."
+ team_capsound_2(sound) : "RED Capture Sound" : : "Sound made when RED captures."
+ team_capsound_3(sound) : "BLU Capture Sound" : : "Sound made when BLU captures."
+ team_model_0(studio) : "Neutral Model" : "models/effects/cappoint_hologram.mdl" : "Model when neither team owns the point. The body group will be set to 0."
+ team_model_2(studio) : "RED Model" : "models/effects/cappoint_hologram.mdl" : "Model when RED owns the point. The body group will be set to 2."
+ team_model_3(studio) : "BLU Model" : "models/effects/cappoint_hologram.mdl" : "Model when BLU owns the point. The body group will be set to 3."
+
+ // These don't seem to be used anywhere in the code
+ // team_bodygroup_0(integer) : "Neutral model bodygroup" : 3 : "Model bodygroup when neither team owns the point"
+ // team_bodygroup_2(integer) : "RED model bodygroup" : 1 : "Model bodygroup when RED owns the point"
+ // team_bodygroup_3(integer) : "BLU model bodygroup" : 1 : "Model bodygroup when BLU owns the point"
+ // team_icon_0(material) : "HUD icon neutral" : "sprites/obj_icons/icon_obj_neutral" : "HUD icon material when no one owns the point."
+ // team_icon_2(material) : "HUD icon RED" : "sprites/obj_icons/icon_obj_red" : "HUD icon material when RED owns the point."
+ // team_icon_3(material) : "HUD icon BLU" : "sprites/obj_icons/icon_obj_blu" : "HUD icon material when BLU owns the point."
+ // team_overlay_0(material) : "HUD overlay neutral" : : "HUD material that will overlay the icon when no one owns the point."
+ // team_overlay_2(material) : "HUD overlay RED" : : "HUD material that will overlay the icon when RED owns the point."
+ // team_overlay_3(material) : "HUD overlay BLU" : : "HUD material that will overlay the icon when BLU owns the point."
+
team_previouspoint_2_0(target_source) : "RED Previous Required Point 1" : : "The name of a previous capture point that RED must own to be able to capture this point. If empty, the team must own all points preceding this one. Pointing to itself means no previous point required."
team_previouspoint_2_1(target_source) : "RED Previous Required Point 2" : : "The name of a second previous capture point that RED must own to be able to capture this point."
team_previouspoint_2_2(target_source) : "RED Previous Required Point 3" : : "The name of a third previous capture point that RED must own to be able to capture this point."
- team_previouspoint_3_0(target_source) : "BLUE Previous Required Point 1" : : "The name of a previous capture point that BLUE must own to be able to capture this point. If empty, the team must own all points preceding this one. Pointing to itself means no previous point required."
- team_previouspoint_3_1(target_source) : "BLUE Previous Required Point 2" : : "The name of a second previous capture point that BLUE must own to be able to capture this point."
- team_previouspoint_3_2(target_source) : "BLUE Previous Required Point 3" : : "The name of a third previous capture point that BLUE must own to be able to capture this point."
+ team_previouspoint_3_0(target_source) : "BLU Previous Required Point 1" : : "The name of a previous capture point that BLU must own to be able to capture this point. If empty, the team must own all points preceding this one. Pointing to itself means no previous point required."
+ team_previouspoint_3_1(target_source) : "BLU Previous Required Point 2" : : "The name of a second previous capture point that BLU must own to be able to capture this point."
+ team_previouspoint_3_2(target_source) : "BLU Previous Required Point 3" : : "The name of a third previous capture point that BLU must own to be able to capture this point."
+
+ model(studio) : "[H] Model" : "models/effects/cappoint_hologram.mdl" : "Model to show in Hammer"
+ src_propname[srctools](target_destination) : "[HA] Linked Prop" : : "Set to the name of a prop that should change its skin based on who owns the point (such as the control point base model)"
// Inputs
input SetOwner(integer) : "Set the owner of the point."
input HideModel(void) : "Hide the control point model."
input ShowModel(void) : "Show the control point model again."
input SetLocked(integer) : "Lock the control point. 0 = unlocked, 1 = locked"
- input SetUnlockTime(integer) : "This will automatically unlock the control point in the specified amound of time (seconds)."
+ input SetUnlockTime(integer) : "Unlock the control point after the specified number of seconds have passed."
input RoundActivate(void) : "Return to its original team and locked."
// Outputs
output OnOwnerChangedToTeam1(void) : "Sent when owner is changed to RED."
- output OnOwnerChangedToTeam2(void) : "Sent when owner is changed to BLUE."
+ output OnOwnerChangedToTeam2(void) : "Sent when owner is changed to BLU."
output OnCapReset(void) : "Sent when owner is changed to neutral."
output OnRoundStartOwnedByTeam1(void) : "Sent when a round is starting and the point is owned by RED."
- output OnRoundStartOwnedByTeam2(void) : "Sent when a round is starting and the point is owned by BLUE."
+ output OnRoundStartOwnedByTeam2(void) : "Sent when a round is starting and the point is owned by BLU."
output OnCapTeam1(void) : "Sent when RED capture this point."
- output OnCapTeam2(void) : "Sent when BLUE capture this point."
+ output OnCapTeam2(void) : "Sent when BLU capture this point."
output OnUnlocked(void) : "Sent when point is unlocked via the SetLocked(0) or SetUnlockTime inputs."
@resources
diff --git a/fgd/point/team/team_control_point_master.fgd b/fgd/point/team/team_control_point_master.fgd
index 7f3bb18c6..a7725ff75 100644
--- a/fgd/point/team/team_control_point_master.fgd
+++ b/fgd/point/team/team_control_point_master.fgd
@@ -1,9 +1,10 @@
@PointClass base(BaseEntityPoint, EnableDisable)
+ iconsprite("editor/ficool2/team_control_point_master")
appliesto(TF2) = team_control_point_master: "Control Point Master"
[
team_base_icon_2(material) : "Material for the RED Base icon" : "sprites/obj_icons/icon_base_red"
- team_base_icon_3(material) : "Material for the BLUE Base icon" : "sprites/obj_icons/icon_base_blu"
+ team_base_icon_3(material) : "Material for the BLU Base icon" : "sprites/obj_icons/icon_base_blu"
caplayout(string) : "Cap Layout" : : "A string that tells the HUD how to lay out the cap points. It should be a string with indexes of cap points seperated by commas to denote a new line. So <2,0 1> would create a pyramid, with cap point 2 on the top and cap points 0 & 1 on the bottom."
custom_position_x(float) : "Custom cap position X" : -1 : "Set the cap layout custom X position [0,1]"
custom_position_y(float) : "Custom cap position Y" : -1 : "Set the cap layout custom Y position [0,1]"
diff --git a/fgd/point/team/team_control_point_round.fgd b/fgd/point/team/team_control_point_round.fgd
index 89f78ca5c..a44c3f721 100644
--- a/fgd/point/team/team_control_point_round.fgd
+++ b/fgd/point/team/team_control_point_round.fgd
@@ -1,5 +1,6 @@
@PointClass base(BaseEntityPoint, EnableDisable)
+ iconsprite("editor/ficool2/team_control_point_round")
appliesto(TF2) = team_control_point_round: "Control Point Round (you may have as many of these in the map as you would like)."
[
cpr_printname(string) : "Print Name" : : "LOCALIZED name to print on the RoundInfo panel"
diff --git a/fgd/point/team/team_round_timer.fgd b/fgd/point/team/team_round_timer.fgd
index e3793c8f6..18b519079 100644
--- a/fgd/point/team/team_round_timer.fgd
+++ b/fgd/point/team/team_round_timer.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint, EnableDisable)
+ iconsprite("editor/ficool2/team_round_timer")
appliesto(TF2)
= team_round_timer: "Round Timer. Timer starts paused by default."
[
@@ -28,7 +29,7 @@
input Resume(void) : "Resume the timer."
input SetTime(integer) : "Set the timer to this value (in seconds)."
input AddTime(integer) : "Add time to the timer (in seconds). Added time cannot excede the max timer length."
- input AddTeamTime(string) : "Input takes a string (space delimited) with the team number and the time to be added (in seconds) because of the team (2 for red, 3 for blue, and 0 for no team...but you could just use AddTime for that). Added time cannot excede the max timer length. Example: 2 600 (adds 10 minutes because of team red)"
+ input AddTeamTime(string) : "Input takes a string (space delimited) with the team number and the time to be added (in seconds) because of the team (2 for RED, 3 for BLU, and 0 for no team...but you could just use AddTime for that). Added time cannot excede the max timer length. Example: 2 600 (adds 10 minutes because of team red)"
input Restart(void) : "Restart the timer."
input ShowInHUD(integer) : "Show this timer in the HUD (0 no, 1 Yes)."
input SetMaxTime(integer) : "Set the max timer length to this value (in seconds). The timer's time will never excede this value."
diff --git a/fgd/point/team/team_train_watcher.fgd b/fgd/point/team/team_train_watcher.fgd
index f75917356..3aa62a4c4 100644
--- a/fgd/point/team/team_train_watcher.fgd
+++ b/fgd/point/team/team_train_watcher.fgd
@@ -2,6 +2,7 @@
@PointClass base(BaseEntityPoint, TeamNum, EnableDisable)
appliesto(TF2)
line(128 128 128, targetname, train)
+ iconsprite("editor/ficool2/team_train_watcher")
= team_train_watcher: "Entity that tracks the train progress through train escort maps"
[
train_can_recede(boolean) : "Can the train recede?" : "1" : "Used to hide the HUD countdown."
diff --git a/fgd/point/tf/tf_base_minigame.fgd b/fgd/point/tf/tf_base_minigame.fgd
index 1b5ad310a..2959ddd90 100644
--- a/fgd/point/tf/tf_base_minigame.fgd
+++ b/fgd/point/tf/tf_base_minigame.fgd
@@ -3,10 +3,11 @@
appliesto(TF2)
line(255 32 32, targetname, redspawn)
line(32 32 255, targetname, bluespawn)
+ iconsprite("editor/ficool2/tf_base_minigame")
= tf_base_minigame: "Base minigame"
[
- redspawn(target_source) : "Red Spawn Name" : : "The name of the spawnpoints for RED for this minigame"
- bluespawn(target_source) : "Blue Spawn Name" : : "The name of the spawnpoints for BLU for this minigame"
+ redspawn(target_source) : "RED Spawn Name" : : "The name of the spawnpoints for RED for this minigame"
+ bluespawn(target_source) : "BLU Spawn Name" : : "The name of the spawnpoints for BLU for this minigame"
inrandompool(boolean) : "Put in Random Pool" : 1 : "If Yes, allowed to be chosen when told to go to a random minigame"
@@ -26,16 +27,16 @@
// Inputs
input ScoreTeamRed(integer) : "Give points to team RED"
- input ScoreTeamBlue(integer) : "Give points to team BLUE"
+ input ScoreTeamBlue(integer) : "Give points to team BLU"
input ReturnFromMinigame(void) : "Force players to return from the current minigame."
input ChangeHudResFile(string) : "Change the HUD resource file."
// Outputs
output OnReturnFromMinigame(void) : "Sent when players return from this minigame."
output OnTeleportToMinigame(void) : "Sent when players arrive in this minigame."
- output OnRedHitMaxScore(void) : "Sent RED hits the max score for this minigame."
- output OnBlueHitMaxScore(void) : "Sent BLUE hits the max score for this minigame."
+ output OnRedHitMaxScore(void) : "Sent when RED hits the max score for this minigame."
+ output OnBlueHitMaxScore(void) : "Sent when BLU hits the max score for this minigame."
output OnAllRedDead(void) : "Sent when the entire RED team is dead."
- output OnAllBlueDead(void) : "Send when the entire BLUE team is dead."
+ output OnAllBlueDead(void) : "Send when the entire BLU team is dead."
output OnSuddenDeathStart(void) : "Sent when sudden death starts."
]
diff --git a/fgd/point/tf/tf_bonus_duck_pickup.fgd b/fgd/point/tf/tf_bonus_duck_pickup.fgd
index 8f09ad9e9..fe0838716 100644
--- a/fgd/point/tf/tf_bonus_duck_pickup.fgd
+++ b/fgd/point/tf/tf_bonus_duck_pickup.fgd
@@ -1,11 +1,6 @@
-@PointClass base(Item)
+@PointClass base(TFPickup)
appliesto(TF2)
- studio("models/workshop/player/items/pyro/eotl_ducky/eotl_bonus_duck.mdl")
+ studioprop("models/workshop/player/items/pyro/eotl_ducky/eotl_bonus_duck.mdl")
= tf_bonus_duck_pickup : "EOTL Bonus Ducks"
[
- pickup_sound(sound) : "Sound Effect" : "" : "The sound script entry that is played when the item is picked up."
- pickup_particle(string) : "Particle Effect" : "" : "The particle effect that is displayed when the item is picked up."
-
- output OnRedPickup(void) : "Sent when Red picks-up the item."
- output OnBluePickup(void) : "Sent when Blue picks-up the item."
]
diff --git a/fgd/point/tf/tf_gamerules.fgd b/fgd/point/tf/tf_gamerules.fgd
index 04b538562..fab190574 100644
--- a/fgd/point/tf/tf_gamerules.fgd
+++ b/fgd/point/tf/tf_gamerules.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/tf_gamerules")
appliesto(TF2) = tf_gamerules: "Proxy entity for TF Gamerules"
[
gamemode(string) : "Gamemode Type" : "" : "Server Tags."
@@ -43,11 +44,11 @@
// Outputs
output OnWonByTeam1(void) : "Sent when RED wins the round."
- output OnWonByTeam2(void) : "Sent when BLUE wins the round."
+ output OnWonByTeam2(void) : "Sent when BLU wins the round."
output Team1PlayersChanged(integer) : "Sent when RED team player count changes, due to a player joining or leaving the team."
- output Team2PlayersChanged(integer) : "Sent when BLUE team player count changes, due to a player joining or leaving the team."
- output OnPowerupImbalanceTeam1(void) : "Sent when BLUE team has a powerup kill advantage over the RED team. Initiate RED team assist measures now."
- output OnPowerupImbalanceTeam2(void) : "Sent when RED team has a powerup kill advantage over the BLUE team. Initiate BLUE team assist measures now."
+ output Team2PlayersChanged(integer) : "Sent when BLU team player count changes, due to a player joining or leaving the team."
+ output OnPowerupImbalanceTeam1(void) : "Sent when BLU team has a powerup kill advantage over the RED team. Initiate RED team assist measures now."
+ output OnPowerupImbalanceTeam2(void) : "Sent when RED team has a powerup kill advantage over the BLU team. Initiate BLU team assist measures now."
output OnPowerupImbalanceMeasuresOver(void) : "Sent when powerup imbalance measures should be stopped"
output OnStateEnterBetweenRounds(void) : "Fired when entering the between-rounds state (MvM and Competitive)."
output OnStateEnterPreRound(void) : "Fired when entering the pre-round state (just before round running)."
diff --git a/fgd/point/tf/tf_generic_bomb.fgd b/fgd/point/tf/tf_generic_bomb.fgd
index bfc05cf8b..7f8c786e7 100644
--- a/fgd/point/tf/tf_generic_bomb.fgd
+++ b/fgd/point/tf/tf_generic_bomb.fgd
@@ -15,7 +15,7 @@
0: "Damage attacker and enemies"
1: "Damage everyone"
]
-
+ passActivator(boolean) : "Pass Activator" : 0 : "Pass the activator in the OnDetonate output"
// Inputs
input Detonate(void) : "Force detonation."
diff --git a/fgd/point/tf/tf_glow.fgd b/fgd/point/tf/tf_glow.fgd
index 99e74d7b1..9ec7e2f7c 100644
--- a/fgd/point/tf/tf_glow.fgd
+++ b/fgd/point/tf/tf_glow.fgd
@@ -1,4 +1,6 @@
@PointClass base(BaseEntityPoint, EnableDisable)
+ line(255 255 255, targetname, target)
+ iconsprite("editor/ficool2/tf_glow")
appliesto(TF2) = tf_glow
[
target(target_destination) : "Target - ONE TARGET ONLY"
diff --git a/fgd/point/tf/tf_halloween_gift_pickup.fgd b/fgd/point/tf/tf_halloween_gift_pickup.fgd
index b602684ea..267b4a095 100644
--- a/fgd/point/tf/tf_halloween_gift_pickup.fgd
+++ b/fgd/point/tf/tf_halloween_gift_pickup.fgd
@@ -1,13 +1,6 @@
-@PointClass base(Item)
+@PointClass base(TFPickup)
appliesto(TF2)
- studio("models/props_halloween/halloween_gift.mdl")
- sphere(fademindist)
- sphere(fademaxdist) = tf_halloween_gift_pickup: "Halloween pickup"
+ studioprop("models/props_halloween/halloween_gift.mdl")
+= tf_halloween_gift_pickup: "Halloween pickup"
[
- pickup_sound(string) : "Sound Effect" : : "The sound script entry that is played when the item is picked up."
- pickup_particle(string) : "Particle Effect" : : "The particle effect that is displayed when the item is picked up."
-
- // Outputs
- output OnRedPickup(void) : "Sent when Red picks-up the item."
- output OnBluePickup(void) : "Sent when Blue picks-up the item."
]
diff --git a/fgd/point/tf/tf_halloween_minigame.fgd b/fgd/point/tf/tf_halloween_minigame.fgd
index 68c184754..b1cfb2a0e 100644
--- a/fgd/point/tf/tf_halloween_minigame.fgd
+++ b/fgd/point/tf/tf_halloween_minigame.fgd
@@ -13,9 +13,9 @@
// Inputs
input KartWinAnimationRed(void) : "Play win animation for all players in kart on team RED"
- input KartWinAnimationBlue(void) : "Play win animation for all players in kart on team BLUE"
+ input KartWinAnimationBlue(void) : "Play win animation for all players in kart on team BLU"
input KartLoseAnimationRed(void) : "Play lose animation for all players in kart on team RED"
- input KartLoseAnimationBlue(void) : "Play lose animation for all players in kart on team BLUE"
+ input KartLoseAnimationBlue(void) : "Play lose animation for all players in kart on team BLU"
input EnableSpawnBoss(string) : "Spawn Halloween boss HHH at specified target entity"
input DisableSpawnBoss(void) : "Stop spawning Halloween boss"
]
diff --git a/fgd/point/tf/tf_halloween_pickup.fgd b/fgd/point/tf/tf_halloween_pickup.fgd
index c4c848fda..4b4059ac7 100644
--- a/fgd/point/tf/tf_halloween_pickup.fgd
+++ b/fgd/point/tf/tf_halloween_pickup.fgd
@@ -1,14 +1,6 @@
-
-@PointClass base(Item)
+@PointClass base(TFPickup)
appliesto(TF2)
- studio("models/items/target_duck.mdl")
- sphere(fademindist)
- sphere(fademaxdist) = tf_halloween_pickup: "Halloween pickup"
+ studioprop("models/items/target_duck.mdl")
+= tf_halloween_pickup: "Halloween pickup"
[
- pickup_sound(string) : "Sound Effect" : : "The sound script entry that is played when the item is picked up."
- pickup_particle(string) : "Particle Effect" : : "The particle effect that is displayed when the item is picked up."
-
- // Outputs
- output OnRedPickup(void) : "Sent when Red picks-up the item."
- output OnBluePickup(void) : "Sent when Blue picks-up the item."
]
diff --git a/fgd/point/tf/tf_logic_arena.fgd b/fgd/point/tf/tf_logic_arena.fgd
index fe8d92579..717605824 100644
--- a/fgd/point/tf/tf_logic_arena.fgd
+++ b/fgd/point/tf/tf_logic_arena.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint, EnableDisable)
+ iconsprite("editor/ficool2/tf_logic_arena")
appliesto(TF2) = tf_logic_arena: "This activates Arena Mode, and controls round specific stuff."
[
capenabledelay(float) : "Capture Point Enable Time" : 0
diff --git a/fgd/point/tf/tf_logic_boss_battle.fgd b/fgd/point/tf/tf_logic_boss_battle.fgd
deleted file mode 100644
index 36776ed18..000000000
--- a/fgd/point/tf/tf_logic_boss_battle.fgd
+++ /dev/null
@@ -1,5 +0,0 @@
-
-@PointClass base(BaseEntityPoint)
- appliesto(TF2) = tf_logic_boss_battle: "Boss Battle Entity. This is used to detect a Boss Battle map."
- [
- ]
diff --git a/fgd/point/tf/tf_logic_competitive.fgd b/fgd/point/tf/tf_logic_competitive.fgd
index 02c2a5953..4a5cd2dd2 100644
--- a/fgd/point/tf/tf_logic_competitive.fgd
+++ b/fgd/point/tf/tf_logic_competitive.fgd
@@ -1,5 +1,6 @@
@PointClass base(BaseEntityPoint, EnableDisable)
+ iconsprite("editor/ficool2/tf_logic_competitive")
appliesto(TF2) = tf_logic_competitive: "Logic specifically for competitive mode."
[
diff --git a/fgd/point/tf/tf_logic_cp_timer.fgd b/fgd/point/tf/tf_logic_cp_timer.fgd
index 7c8cf05d9..b44165694 100644
--- a/fgd/point/tf/tf_logic_cp_timer.fgd
+++ b/fgd/point/tf/tf_logic_cp_timer.fgd
@@ -1,4 +1,6 @@
-@PointClass base(BaseEntityPoint)
+@PointClass base(BaseEntityPoint, TeamNum)
+ iconsprite("editor/ficool2/tf_logic_cp_timer")
+ line(0 255 0, targetname, controlpoint)
appliesto(TF2) = tf_logic_cp_timer: "Control Point Timer Entity."
[
controlpoint(target_destination) : "Control Point" : : "The team_control_point associated with this timer."
diff --git a/fgd/point/tf/tf_logic_holiday.fgd b/fgd/point/tf/tf_logic_holiday.fgd
index b1f193046..4a266edf7 100644
--- a/fgd/point/tf/tf_logic_holiday.fgd
+++ b/fgd/point/tf/tf_logic_holiday.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/tf_logic_holiday")
appliesto(TF2) = tf_logic_holiday: "Holiday Entity. This is used to detect a holiday map."
[
holiday_type[engine](integer) : "Holiday" : 1
diff --git a/fgd/point/tf/tf_logic_hybrid_ctf_cp.fgd b/fgd/point/tf/tf_logic_hybrid_ctf_cp.fgd
index 7444b7b4d..ed658c14d 100644
--- a/fgd/point/tf/tf_logic_hybrid_ctf_cp.fgd
+++ b/fgd/point/tf/tf_logic_hybrid_ctf_cp.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint, EnableDisable)
+ iconsprite("editor/ficool2/tf_logic_hybrid_ctf_cp")
appliesto(TF2) = tf_logic_hybrid_ctf_cp: "When present, this activates Atack/Defend With Intelligence mode."
[
]
diff --git a/fgd/point/tf/tf_logic_koth.fgd b/fgd/point/tf/tf_logic_koth.fgd
index 5b3ec2026..ebbf1c67b 100644
--- a/fgd/point/tf/tf_logic_koth.fgd
+++ b/fgd/point/tf/tf_logic_koth.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/tf_logic_koth")
appliesto(TF2) = tf_logic_koth: "King of the Hill Entity. This is used to detect a KOTH map."
[
timer_length(integer) : "Timer length (in seconds)" : 180 : "Initial timer length for each team."
@@ -6,9 +7,9 @@
// Inputs
input SetRedTimer(integer) : "Set the time remaining for the RED timer."
- input SetBlueTimer(integer) : "Set the time remaining for the BLUE timer."
+ input SetBlueTimer(integer) : "Set the time remaining for the BLU timer."
input AddRedTimer(integer) : "Add time to the RED timer."
- input AddBlueTimer(integer) : "Add time to the BLUE timer."
+ input AddBlueTimer(integer) : "Add time to the BLU timer."
input RoundActivate(void) : "Find control points and its master."
input RoundSpawn(void) : "Create new team_round_timer entities for both team."
diff --git a/fgd/point/tf/tf_logic_mann_vs_machine.fgd b/fgd/point/tf/tf_logic_mann_vs_machine.fgd
index 0763fcf4e..87d7221a1 100644
--- a/fgd/point/tf/tf_logic_mann_vs_machine.fgd
+++ b/fgd/point/tf/tf_logic_mann_vs_machine.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint, EnableDisable)
+ iconsprite("editor/ficool2/tf_logic_mann_vs_machine")
appliesto(TF2) = tf_logic_mann_vs_machine: "When present, this activates Mann VS Machine Mode."
[
]
diff --git a/fgd/point/tf/tf_logic_mannpower.fgd b/fgd/point/tf/tf_logic_mannpower.fgd
index f99d17ab3..f268c0b2b 100644
--- a/fgd/point/tf/tf_logic_mannpower.fgd
+++ b/fgd/point/tf/tf_logic_mannpower.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint, EnableDisable)
+ iconsprite("editor/ficool2/tf_logic_mannpower")
appliesto(TF2) = tf_logic_mannpower: "When present, this activates Mannpower Mode."
[
]
diff --git a/fgd/point/tf/tf_logic_medieval.fgd b/fgd/point/tf/tf_logic_medieval.fgd
index 825cefa72..17b479f48 100644
--- a/fgd/point/tf/tf_logic_medieval.fgd
+++ b/fgd/point/tf/tf_logic_medieval.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint, EnableDisable)
+ iconsprite("editor/ficool2/tf_logic_medieval")
appliesto(TF2) = tf_logic_medieval: "When present, this enables Medieval mode."
[
]
diff --git a/fgd/point/tf/tf_logic_minigames.fgd b/fgd/point/tf/tf_logic_minigames.fgd
index 2cacc8eaa..73c2e72a2 100644
--- a/fgd/point/tf/tf_logic_minigames.fgd
+++ b/fgd/point/tf/tf_logic_minigames.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/tf_logic_minigames")
appliesto(TF2) = tf_logic_minigames: "Minigame mode logic."
[
// Inputs
diff --git a/fgd/point/tf/tf_logic_multiple_escort.fgd b/fgd/point/tf/tf_logic_multiple_escort.fgd
index 0c1f69907..f4b9d3159 100644
--- a/fgd/point/tf/tf_logic_multiple_escort.fgd
+++ b/fgd/point/tf/tf_logic_multiple_escort.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/tf_logic_multiple_escort")
appliesto(TF2) = tf_logic_multiple_escort: "When present, activates Playload Race Mode."
[
]
diff --git a/fgd/point/tf/tf_logic_on_holiday.fgd b/fgd/point/tf/tf_logic_on_holiday.fgd
index 8b8d93cb8..762404ff1 100644
--- a/fgd/point/tf/tf_logic_on_holiday.fgd
+++ b/fgd/point/tf/tf_logic_on_holiday.fgd
@@ -1,6 +1,6 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2)
- iconsprite("editor/logic_auto.vmt")
+ iconsprite("editor/ficool2/tf_logic_on_holiday")
= tf_logic_on_holiday: "This entity allows you execute map actions on holidays. " +
"Will send all relevant outputs every time the Fire input is called."
[
diff --git a/fgd/point/tf/tf_logic_player_destruction.fgd b/fgd/point/tf/tf_logic_player_destruction.fgd
index f8258045a..02bfca896 100644
--- a/fgd/point/tf/tf_logic_player_destruction.fgd
+++ b/fgd/point/tf/tf_logic_player_destruction.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/tf_logic_player_destruction")
appliesto(TF2) = tf_logic_player_destruction: "Player Destruction Entity. This is used to detect a Player Destruction map."
[
prop_model_name(studio) : "Prop Model Name" : "models/flag/flag.mdl" : "model of prop that drops from player on death"
@@ -8,8 +9,8 @@
loser_respawn_bonus_per_bot(float) : "Loser Respawn Bonus Per Bot (percentage)" : 0 : "How much faster the losing team will respawn per bot difference."
score_interval(float) : "Robot Scoring Interval (in seconds)" : 1 : "How often a robot should score a point while hacking."
- red_respawn_time(float) : "Red Respawn Time (in seconds)" : 10 : "Respawn times for Red"
- blue_respawn_time(float) : "Blue Respawn Time (in seconds)" : 10 : "Respawn times for Blue"
+ red_respawn_time(float) : "RED Respawn Time (in seconds)" : 10 : "Respawn times for RED"
+ blue_respawn_time(float) : "BLU Respawn Time (in seconds)" : 10 : "Respawn times for BLU"
min_points(integer) : "Min Points" : 10 : "The minimum points to win"
max_points(integer) : "Max Points" : 200 : "The number of points a team must get to unlock their win condition."
@@ -21,8 +22,8 @@
heal_distance(integer) : "Heal Distance" : 450 : "The distance for the team leader's ability to heal teammates."
// Inputs
- input ScoreRedPoints(void) : "Score points for red."
- input ScoreBluePoints(void) : "Score points for blue."
+ input ScoreRedPoints(void) : "Score points for RED."
+ input ScoreBluePoints(void) : "Score points for BLU."
input EnableMaxScoreUpdating(void) : "Allow the max score to update based on player count."
input DisableMaxScoreUpdating(void) : "Disallow the max score to update based on player count."
input SetCountdownTimer(integer) : "Set the countdown time and start the timer."
@@ -31,24 +32,24 @@
input SetPointsOnPlayerDeath(integer) : "Set number of points per flag dropped upon player death."
// Outputs
- output OnBlueHitMaxPoints(void) : "Sent when Blue hits the max points."
- output OnRedHitMaxPoints(void) : "Sent when Red hits the max points."
- output OnBlueLeaveMaxPoints(void) : "Sent when blue goes from max points to fewer."
- output OnRedLeaveMaxPoints(void) : "Sent when red goes from max points to fewer."
- output OnBlueHitZeroPoints(void) : "Sent when Blue hits 0 points."
- output OnRedHitZeroPoints(void) : "Sent when Red hits 0 points"
- output OnBlueHasPoints(void) : "Sent when Blue goes from 0 to any points"
- output OnRedHasPoints(void) : "Sent when Red goes from 0 to any points"
-
- output OnRedFinalePeriodEnd(void) : "Sent when the red finale period ends."
- output OnBlueFinalePeriodEnd(void) : "Sent when the blue finale period ends."
-
- output OnRedFirstFlagStolen(void) : "Sent when red's first flag gets stolen."
- output OnRedFlagStolen(void) : "Sent when a flag gets stolen from red."
- output OnRedLastFlagReturned(void) : "Sent when red's last stolen flag gets returned."
- output OnBlueFirstFlagStolen(void) : "Sent when blue's first flag gets stolen."
- output OnBlueFlagStolen(void) : "Sent when a flag gets stolen from blue."
- output OnBlueLastFlagReturned(void) : "Sent when blue's last stolen flag gets returned."
+ output OnBlueHitMaxPoints(void) : "Sent when BLU hits the max points."
+ output OnRedHitMaxPoints(void) : "Sent when RED hits the max points."
+ output OnBlueLeaveMaxPoints(void) : "Sent when BLU goes from max points to fewer."
+ output OnRedLeaveMaxPoints(void) : "Sent when RED goes from max points to fewer."
+ output OnBlueHitZeroPoints(void) : "Sent when BLU hits 0 points."
+ output OnRedHitZeroPoints(void) : "Sent when RED hits 0 points"
+ output OnBlueHasPoints(void) : "Sent when BLU goes from 0 to any points"
+ output OnRedHasPoints(void) : "Sent when RED goes from 0 to any points"
+
+ output OnRedFinalePeriodEnd(void) : "Sent when the RED finale period ends."
+ output OnBlueFinalePeriodEnd(void) : "Sent when the BLU finale period ends."
+
+ output OnRedFirstFlagStolen(void) : "Sent when RED's first flag gets stolen."
+ output OnRedFlagStolen(void) : "Sent when a flag gets stolen from RED."
+ output OnRedLastFlagReturned(void) : "Sent when RED's last stolen flag gets returned."
+ output OnBlueFirstFlagStolen(void) : "Sent when BLU's first flag gets stolen."
+ output OnBlueFlagStolen(void) : "Sent when a flag gets stolen from BLU."
+ output OnBlueLastFlagReturned(void) : "Sent when BLU's last stolen flag gets returned."
output OnRedScoreChanged(float) : "Send when score changes, and is a value representing total progress from [0..1]."
output OnBlueScoreChanged(float) : "Send when score changes, and is a value representing total progress from [0..1]."
diff --git a/fgd/point/tf/tf_logic_raid.fgd b/fgd/point/tf/tf_logic_raid.fgd
deleted file mode 100644
index 6d791226a..000000000
--- a/fgd/point/tf/tf_logic_raid.fgd
+++ /dev/null
@@ -1,4 +0,0 @@
-@PointClass base(BaseEntityPoint)
- appliesto(TF2) = tf_logic_raid: "Raid Entity. This is used to detect a Raid map."
- [
- ]
diff --git a/fgd/point/tf/tf_logic_robot_destruction.fgd b/fgd/point/tf/tf_logic_robot_destruction.fgd
index 3a7a00f56..6fe6d6d69 100644
--- a/fgd/point/tf/tf_logic_robot_destruction.fgd
+++ b/fgd/point/tf/tf_logic_robot_destruction.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint, RobotDestruction)
+ iconsprite("editor/ficool2/tf_logic_robot_destruction")
appliesto(TF2) = tf_logic_robot_destruction: "Robot Destruction Entity. This is used to detect a Robot Destruction map."
[
max_robots(float) : "Max Robots" : 0 : "How many Robot"
@@ -6,32 +7,32 @@
score_interval(float) : "Robot Scoring Interval (in seconds)" : 1 : "How often a robot should score a point while hacking."
loser_respawn_bonus_per_bot(float) : "Loser Respawn Bonus Per Bot (percentage)" : 0 : "How much faster the losing team will respawn per bot difference."
- red_respawn_time(float) : "Red Respawn Time (in seconds)" : 10 : "Respawn times for Red"
- blue_respawn_time(float) : "Blue Respawn Time (in seconds)" : 10 : "Respawn times for Blue"
+ red_respawn_time(float) : "RED Respawn Time (in seconds)" : 10 : "Respawn times for Red"
+ blue_respawn_time(float) : "BLU Respawn Time (in seconds)" : 10 : "Respawn times for BLU"
max_points(integer) : "Max Points" : 200 : "The number of points a team must get to unlock their win condition."
finale_length(float) : "Finale Length" : 30 : "The amount of time from after max score is reached a team will win."
res_file(string) : "HUD Res File" : "resource/UI/HudObjectiveRobotDestruction.res" : "What res file to use for the HUD"
// Outputs
- output OnBlueHitMaxPoints(void) : "Sent when Blue hits the max points."
- output OnRedHitMaxPoints(void) : "Sent when Red hits the max points."
- output OnBlueLeaveMaxPoints(void) : "Sent when blue goes from max points to fewer."
- output OnRedLeaveMaxPoints(void) : "Sent when red goes from max points to fewer."
- output OnBlueHitZeroPoints(void) : "Sent when Blue hits 0 points."
- output OnRedHitZeroPoints(void) : "Sent when Red hits 0 points"
- output OnBlueHasPoints(void) : "Sent when Blue goes from 0 to any points"
- output OnRedHasPoints(void) : "Sent when Red goes from 0 to any points"
+ output OnBlueHitMaxPoints(void) : "Sent when BLU hits the max points."
+ output OnRedHitMaxPoints(void) : "Sent when RED hits the max points."
+ output OnBlueLeaveMaxPoints(void) : "Sent when BLU goes from max points to fewer."
+ output OnRedLeaveMaxPoints(void) : "Sent when RED goes from max points to fewer."
+ output OnBlueHitZeroPoints(void) : "Sent when BLU hits 0 points."
+ output OnRedHitZeroPoints(void) : "Sent when RED hits 0 points"
+ output OnBlueHasPoints(void) : "Sent when BLU goes from 0 to any points"
+ output OnRedHasPoints(void) : "Sent when RED goes from 0 to any points"
- output OnRedFinalePeriodEnd(void) : "Sent when the red finale period ends."
- output OnBlueFinalePeriodEnd(void) : "Sent when the blue finale period ends."
+ output OnRedFinalePeriodEnd(void) : "Sent when the RED finale period ends."
+ output OnBlueFinalePeriodEnd(void) : "Sent when the BLU finale period ends."
- output OnRedFirstFlagStolen(void) : "Sent when red's first flag gets stolen."
- output OnRedFlagStolen(void) : "Sent when a flag gets stolen from red."
- output OnRedLastFlagReturned(void) : "Sent when red's last stolen flag gets returned."
- output OnBlueFirstFlagStolen(void) : "Sent when blue's first flag gets stolen."
- output OnBlueFlagStolen(void) : "Sent when a flag gets stolen from blue."
- output OnBlueLastFlagReturned(void) : "Sent when blue's last stolen flag gets returned."
+ output OnRedFirstFlagStolen(void) : "Sent when RED's first flag gets stolen."
+ output OnRedFlagStolen(void) : "Sent when a flag gets stolen from RED."
+ output OnRedLastFlagReturned(void) : "Sent when RED's last stolen flag gets returned."
+ output OnBlueFirstFlagStolen(void) : "Sent when BLU's first flag gets stolen."
+ output OnBlueFlagStolen(void) : "Sent when a flag gets stolen from BLU."
+ output OnBlueLastFlagReturned(void) : "Sent when BLU's last stolen flag gets returned."
input RoundActivate(void) : "Reactivate."
]
diff --git a/fgd/point/tf/tf_logic_training_mode.fgd b/fgd/point/tf/tf_logic_training_mode.fgd
index 15ef7381c..d849ca831 100644
--- a/fgd/point/tf/tf_logic_training_mode.fgd
+++ b/fgd/point/tf/tf_logic_training_mode.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/tf_logic_training_mode")
appliesto(TF2) = tf_logic_training_mode: "Training logic entity. This is used to detect a training map."
[
nextmap[engine](string) : "Next Map"
diff --git a/fgd/point/tf/tf_point_nav_interface.fgd b/fgd/point/tf/tf_point_nav_interface.fgd
index d8f0f4868..6e2babdf5 100644
--- a/fgd/point/tf/tf_point_nav_interface.fgd
+++ b/fgd/point/tf/tf_point_nav_interface.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/tf_point_nav_interface")
appliesto(TF2) = tf_point_nav_interface: "Entity interface to the TF nav mesh."
[
diff --git a/fgd/point/tf/tf_projectiles.fgd b/fgd/point/tf/tf_projectiles.fgd
index 2c4b31525..fb4824170 100644
--- a/fgd/point/tf/tf_projectiles.fgd
+++ b/fgd/point/tf/tf_projectiles.fgd
@@ -1,120 +1,127 @@
@BaseClass base(BaseEntityAnimating, TeamNum) = BaseTFProjectile []
-@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/props_halloween/hwn_spellbook_flying.mdl")
-= tf_projectile_spellmeteorshower : "Meteor Spell Particle" []
-
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_spellmeteorshower")
= tf_projectile_spellmeteorshower : "Meteor Spell Particle" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_spellfireball")
= tf_projectile_spellfireball : "FireBall Spell Particle" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_spellspawnzombie")
= tf_projectile_spellspawnzombie : "Skeleton Spell" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_lightningorb")
= tf_projectile_lightningorb : "Lightning orb Spell" []
+
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_mechanicalarmorb")
= tf_projectile_mechanicalarmorb : "Short Circuit orb" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/w_models/w_arrow.mdl")
+ studioprop("models/weapons/w_models/w_arrow.mdl")
= tf_projectile_arrow : "" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/c_models/c_xms_festive_ornament.mdl")
+ studioprop("models/weapons/c_models/c_xms_festive_ornament.mdl")
= tf_projectile_ball_ornament : "" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_balloffire")
= tf_projectile_balloffire : "Dragon's Fury's Flame" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/c_models/c_sd_cleaver/c_sd_cleaver.mdl")
+ studioprop("models/weapons/c_models/c_sd_cleaver/c_sd_cleaver.mdl")
= tf_projectile_cleaver : "" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_energy_ball")
= tf_projectile_energy_ball : "Cow Mangler 5000 Projectile" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_energy_ring")
= tf_projectile_energy_ring : "Righteous Bison Projectile" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/w_models/w_flaregun_shell.mdl")
+ studioprop("models/weapons/w_models/w_flaregun_shell.mdl")
= tf_projectile_flare : "Flare Projectile" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/c_models/c_grappling_hook/c_grappling_hook.mdl")
+ studioprop("models/weapons/c_models/c_grappling_hook/c_grappling_hook.mdl")
= tf_projectile_grapplinghook : "Grappling Hook Projectile" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/w_models/w_repair_claw.mdl")
+ studioprop("models/weapons/w_models/w_repair_claw.mdl")
= tf_projectile_healing_bolt : "Rescue Ranger Arrow" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/c_models/urinejar.mdl")
+ studioprop("models/weapons/c_models/urinejar.mdl")
= tf_projectile_jar : "Jarate" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/c_models/c_gascan/c_gascan.mdl")
+ studioprop("models/weapons/c_models/c_gascan/c_gascan.mdl")
= tf_projectile_jar_gas : "Gas Passer Projectile" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/c_models/c_madmilk/c_madmilk.mdl")
+ studioprop("models/weapons/c_models/c_madmilk/c_madmilk.mdl")
= tf_projectile_jar_milk : "Mad Milk Projectile" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/w_models/w_grenade_grenadelauncher.mdl")
+ studioprop("models/weapons/w_models/w_grenade_grenadelauncher.mdl")
= tf_projectile_pipe : "Pipe Bomb" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/w_models/w_stickybomb.mdl")
+ studioprop("models/weapons/w_models/w_stickybomb.mdl")
= tf_projectile_pipe_remote : "Sticky Bomb" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/w_models/w_rocket.mdl")
+ studioprop("models/weapons/w_models/w_rocket.mdl")
= tf_projectile_rocket : "Rocket" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/buildables/sentry3_rockets.mdl")
+ studioprop("models/buildables/sentry3_rockets.mdl")
= tf_projectile_sentryrocket : "Sentry Level 3 Rockets" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_spellbats")
= tf_projectile_spellbats : "Bats spell" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_spellkartbats")
= tf_projectile_spellkartbats : "Bumper Car's Bats spell" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_spellkartorb")
= tf_projectile_spellkartorb : "" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_spellmirv")
= tf_projectile_spellmirv : "" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_spellpumpkin")
= tf_projectile_spellpumpkin : "" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/props_mvm/mvm_human_skull_collide.mdl")
+ iconsprite("editor/ficool2/tf_projectile_spellspawnboss")
= tf_projectile_spellspawnboss : "" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/props_mvm/mvm_human_skull_collide.mdl")
+ iconsprite("editor/ficool2/tf_projectile_spellspawnhorde")
= tf_projectile_spellspawnhorde : "" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/props_mvm/mvm_human_skull_collide.mdl")
-= tf_projectile_spellspawnzombie : "" []
-
-@PointClass base(BaseTFProjectile) appliesto(TF2)
+ iconsprite("editor/ficool2/tf_projectile_spelltransposeteleport")
= tf_projectile_spelltransposeteleport : "" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/w_models/w_baseball.mdl")
+ studioprop("models/weapons/w_models/w_baseball.mdl")
= tf_projectile_stun_ball : "" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
- studio("models/weapons/w_models/w_syringe_proj.mdl")
+ studioprop("models/weapons/w_models/w_syringe_proj.mdl")
= tf_projectile_syringe : "" []
@PointClass base(BaseTFProjectile) appliesto(TF2)
@@ -128,6 +135,3 @@
@PointClass base(BaseTFProjectile) appliesto(TF2)
= tf_projectile_throwable_repel : "Unused Balloon with no model" []
-
-@PointClass base(BaseTFProjectile) appliesto(TF2)
-= tf_projectile_mechanicalarmorb : "Short Circult Enegry Ball" []
diff --git a/fgd/point/tf/tf_robot_destruction_robot_spawn.fgd b/fgd/point/tf/tf_robot_destruction_robot_spawn.fgd
index 995bcde46..d40921ba6 100644
--- a/fgd/point/tf/tf_robot_destruction_robot_spawn.fgd
+++ b/fgd/point/tf/tf_robot_destruction_robot_spawn.fgd
@@ -1,6 +1,6 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2)
- studio("models/bots/bot_worker/bot_worker_a.mdl")
+ iconsprite("editor/ficool2/tf_robot_destruction_robot_spawn")
line(255 255 255, targetname, startpath)
line(255 255 0, targetname, spawngroup)
= tf_robot_destruction_robot_spawn: "Robot Destruction Robot spawn point."
diff --git a/fgd/point/tf/tf_robot_destruction_spawn_group.fgd b/fgd/point/tf/tf_robot_destruction_spawn_group.fgd
index 9982fcc2f..2e80b6ad1 100644
--- a/fgd/point/tf/tf_robot_destruction_spawn_group.fgd
+++ b/fgd/point/tf/tf_robot_destruction_spawn_group.fgd
@@ -1,4 +1,5 @@
@PointClass base(BaseEntityPoint)
+ iconsprite("editor/ficool2/tf_robot_destruction_spawn_group")
appliesto(TF2) = tf_robot_destruction_spawn_group: "Robot Destruction spawn group. This groups the Robot Destruction spawn points"
[
respawn_time(float) : "Respawn Time" : 0 : "Respawn time for this group"
@@ -7,6 +8,8 @@
team_number[engine](integer): "Team Number" : 2
team_number(choices) : "Team Number" : 2 =
[
+ 0: "Unassigned" [+complete]
+ 1: "Spectators" [+complete]
2: "RED"
3: "BLU"
]
diff --git a/fgd/point/tf/tf_spawner.fgd b/fgd/point/tf/tf_spawner.fgd
index 6ebb95584..5146c448a 100644
--- a/fgd/point/tf/tf_spawner.fgd
+++ b/fgd/point/tf/tf_spawner.fgd
@@ -1,6 +1,7 @@
@PointClass base(BaseEntityPoint)
appliesto(TF2)
line(255 255 255, targetname, template)
+ iconsprite("editor/ficool2/tf_spawner")
= tf_spawner: "An entity that spawns templatized entities."
[
count(integer) : "Count" : 1 : "Total number of entities to spawn over the lifetime of this spawner."
diff --git a/fgd/point/training/training_annotation.fgd b/fgd/point/training/training_annotation.fgd
index 2cfc5df87..2b535a804 100644
--- a/fgd/point/training/training_annotation.fgd
+++ b/fgd/point/training/training_annotation.fgd
@@ -1,6 +1,6 @@
@PointClass base(BaseEntityAnimating)
appliesto(TF2)
- studio("models/extras/info_speech.mdl")
+ iconsprite("editor/ficool2/training_annotation")
= training_annotation: "Training Annotation"
[
display_text(string) : "Displayed Text" : "" : "The text to be displayed in the annotation popup."
diff --git a/fgd/point/weapon/weapon_357.fgd b/fgd/point/weapon/weapon_357.fgd
index 0916c3e90..9ffe7d626 100644
--- a/fgd/point/weapon/weapon_357.fgd
+++ b/fgd/point/weapon/weapon_357.fgd
@@ -3,5 +3,9 @@
autovis(Weapons, HL2 Weapons, Magnum Pistol)
studioprop("models/weapons/w_357.mdl") = weapon_357: "357"
[
- @resources []
+ @resources
+ [
+ weapon_script "scripts/gameplay/weapons/weapon_357.dmx" [+mesa]
+ weapon_script "scripts/weapon_357.txt" [-mesa]
+ ]
]
diff --git a/fgd/point/weapon/weapon_adrenaline_spawn.fgd b/fgd/point/weapon/weapon_adrenaline_spawn.fgd
index 60f676eca..13be5f619 100644
--- a/fgd/point/weapon/weapon_adrenaline_spawn.fgd
+++ b/fgd/point/weapon/weapon_adrenaline_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, L4D Items)
= weapon_adrenaline_spawn: "Adrenaline"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_adrenaline.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_ak47.fgd b/fgd/point/weapon/weapon_ak47.fgd
index 1acb8d73d..9109cb9a3 100644
--- a/fgd/point/weapon/weapon_ak47.fgd
+++ b/fgd/point/weapon/weapon_ak47.fgd
@@ -1,4 +1,3 @@
-
@PointClass base(Weapon)
appliesto(CSGO)
autovis(Weapons, CSGO Weapons, CS Assault Rifles)
diff --git a/fgd/point/weapon/weapon_alyxgun.fgd b/fgd/point/weapon/weapon_alyxgun.fgd
index e27de130d..17fb21233 100644
--- a/fgd/point/weapon/weapon_alyxgun.fgd
+++ b/fgd/point/weapon/weapon_alyxgun.fgd
@@ -3,5 +3,8 @@
autovis(Weapons, HL2 Weapons, Alyx's Gun)
studioprop("models/weapons/W_Alyx_Gun.mdl") = weapon_alyxgun: "Alyx's Gun"
[
- @resources []
+ @resources
+ [
+ weapon_script "scripts/weapon_alyxgun.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_ammo_spawn.fgd b/fgd/point/weapon/weapon_ammo_spawn.fgd
index a44fe8dc6..f374ef728 100644
--- a/fgd/point/weapon/weapon_ammo_spawn.fgd
+++ b/fgd/point/weapon/weapon_ammo_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_ammo_spawn: "Ammo"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_ammo_pack.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_annabelle.fgd b/fgd/point/weapon/weapon_annabelle.fgd
index a789ad50d..61aa5fc50 100644
--- a/fgd/point/weapon/weapon_annabelle.fgd
+++ b/fgd/point/weapon/weapon_annabelle.fgd
@@ -3,5 +3,8 @@
autovis(Weapons, HL2 Weapons, Annabelle)
studioprop("models/weapons/W_annabelle.mdl") = weapon_annabelle: "Annabelle (Grigori)"
[
- @resources []
+ @resources
+ [
+ weapon_script "scripts/weapon_annabelle.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_ar2.fgd b/fgd/point/weapon/weapon_ar2.fgd
index c8806d4c8..407055d54 100644
--- a/fgd/point/weapon/weapon_ar2.fgd
+++ b/fgd/point/weapon/weapon_ar2.fgd
@@ -5,6 +5,7 @@
[
@resources
[
+ weapon_script "scripts/weapon_ar2.txt"
entity prop_combine_ball
entity env_entity_dissolver
]
diff --git a/fgd/point/weapon/weapon_ar2_prototype.fgd b/fgd/point/weapon/weapon_ar2_prototype.fgd
index a42ef7475..8813d0597 100644
--- a/fgd/point/weapon/weapon_ar2_prototype.fgd
+++ b/fgd/point/weapon/weapon_ar2_prototype.fgd
@@ -3,4 +3,10 @@
autovis(Weapons, EZ Weapons)
studioprop("models/weapons/w_irifle.mdl") = weapon_ar2_proto: "Assault Rifle 2 Prototype"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_ar2_proto.txt"
+ entity prop_combine_ball
+ entity env_entity_dissolver
+ ]
]
diff --git a/fgd/point/weapon/weapon_autoshotgun_spawn.fgd b/fgd/point/weapon/weapon_autoshotgun_spawn.fgd
index b6a4f30cc..213c7a0c3 100644
--- a/fgd/point/weapon/weapon_autoshotgun_spawn.fgd
+++ b/fgd/point/weapon/weapon_autoshotgun_spawn.fgd
@@ -4,4 +4,8 @@
studioprop("models/w_models/Weapons/w_autoshot_m4super.mdl")
= weapon_autoshotgun_spawn: "Auto Shotgun"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_autoshotgun.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_bugbait.fgd b/fgd/point/weapon/weapon_bugbait.fgd
index 6a28ba0de..6430afdc1 100644
--- a/fgd/point/weapon/weapon_bugbait.fgd
+++ b/fgd/point/weapon/weapon_bugbait.fgd
@@ -5,6 +5,7 @@
[
@resources
[
+ weapon_script "scripts/weapon_bugbait.txt"
sound "Weapon_Bugbait.Splat" // Squeeze!
entity npc_grenade_bugbait
]
diff --git a/fgd/point/weapon/weapon_chainsaw_spawn.fgd b/fgd/point/weapon/weapon_chainsaw_spawn.fgd
index c6047cca3..922fb5b7e 100644
--- a/fgd/point/weapon/weapon_chainsaw_spawn.fgd
+++ b/fgd/point/weapon/weapon_chainsaw_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_chainsaw_spawn: "Chainsaw"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_chainsaw.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_citizenpackage.fgd b/fgd/point/weapon/weapon_citizenpackage.fgd
index 8c88cfb10..144b9de25 100644
--- a/fgd/point/weapon/weapon_citizenpackage.fgd
+++ b/fgd/point/weapon/weapon_citizenpackage.fgd
@@ -2,5 +2,8 @@
appliesto(HL2, EP1, EP2, P1)
studioprop("models/weapons/w_package.mdl") = weapon_citizenpackage: "A Combine ration Citizens are seen retrieving at the start of HL2."
[
- @resources []
+ @resources
+ [
+ weapon_script "scripts/weapon_citizenpackage.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_citizensuitcase.fgd b/fgd/point/weapon/weapon_citizensuitcase.fgd
index 9d6d1ad27..4d1674c15 100644
--- a/fgd/point/weapon/weapon_citizensuitcase.fgd
+++ b/fgd/point/weapon/weapon_citizensuitcase.fgd
@@ -2,5 +2,8 @@
appliesto(HL2, EP1, EP2, P1)
studioprop("models/weapons/w_suitcase_passenger.mdl") = weapon_citizensuitcase: "A generic suitcase carried by Citizens."
[
- @resources []
+ @resources
+ [
+ weapon_script "scripts/weapon_citizensuitcase.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_crossbow.fgd b/fgd/point/weapon/weapon_crossbow.fgd
index 71ddfda0f..00ddbe32c 100644
--- a/fgd/point/weapon/weapon_crossbow.fgd
+++ b/fgd/point/weapon/weapon_crossbow.fgd
@@ -5,6 +5,7 @@
[
@resources
[
+ weapon_script "scripts/weapon_crossbow.txt"
material "sprites/blueflare1.vmt"
material "sprites/light_glow02_noz.vmt"
sound "Weapon_Crossbow.BoltHitBody"
diff --git a/fgd/point/weapon/weapon_crowbar.fgd b/fgd/point/weapon/weapon_crowbar.fgd
index 8aece4f9e..414fb66c1 100644
--- a/fgd/point/weapon/weapon_crowbar.fgd
+++ b/fgd/point/weapon/weapon_crowbar.fgd
@@ -3,5 +3,9 @@
autovis(Weapons, HL2 Weapons, Crowbar)
studioprop("models/weapons/w_crowbar.mdl") = weapon_crowbar: "Crowbar"
[
- @resources []
+ @resources
+ [
+ weapon_script "scripts/gameplay/weapons/weapon_crowbar.dmx" [+mesa]
+ weapon_script "scripts/weapon_crowbar.txt" [-mesa]
+ ]
]
diff --git a/fgd/point/weapon/weapon_cubemap.fgd b/fgd/point/weapon/weapon_cubemap.fgd
index 34093943d..8fa5915ca 100644
--- a/fgd/point/weapon/weapon_cubemap.fgd
+++ b/fgd/point/weapon/weapon_cubemap.fgd
@@ -3,5 +3,8 @@
appliesto(until_L4D, ASW, P2, -MESA, -TF2)
studioprop("models/shadertest/envballs.mdl") = weapon_cubemap: "Debugging weapon used to show cubemaps in a region."
[
- @resources []
+ @resources
+ [
+ weapon_script "scripts/weapon_cubemap.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_custom_scripted1.fgd b/fgd/point/weapon/weapon_custom_scripted1.fgd
index 89f101c88..ace9afaa8 100644
--- a/fgd/point/weapon/weapon_custom_scripted1.fgd
+++ b/fgd/point/weapon/weapon_custom_scripted1.fgd
@@ -3,4 +3,7 @@
appliesto(MBase)
studioprop()
sphere(fademindist) sphere(fademaxdist)
-= weapon_custom_scripted1: "Scripted Weapon 1" []
+= weapon_custom_scripted1: "Scripted Weapon 1"
+ [
+
+ ]
diff --git a/fgd/point/weapon/weapon_defibrillator_spawn.fgd b/fgd/point/weapon/weapon_defibrillator_spawn.fgd
index a88b0b9f3..a939fff6d 100644
--- a/fgd/point/weapon/weapon_defibrillator_spawn.fgd
+++ b/fgd/point/weapon/weapon_defibrillator_spawn.fgd
@@ -3,4 +3,8 @@
studioprop("models/w_models/weapons/w_eq_defibrillator.mdl")
= weapon_defibrillator_spawn: "Defibrillator"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_defibrillator.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_displacer_pistol.fgd b/fgd/point/weapon/weapon_displacer_pistol.fgd
index f6f41d9b9..06567ba29 100644
--- a/fgd/point/weapon/weapon_displacer_pistol.fgd
+++ b/fgd/point/weapon/weapon_displacer_pistol.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, EZ Weapons)
studioprop("models/weapons/w_flaregun.mdl") = weapon_displacer_pistol: "Displacer Pistol"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_displacer_pistol.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_endgame.fgd b/fgd/point/weapon/weapon_endgame.fgd
index 625295585..2097c71c3 100644
--- a/fgd/point/weapon/weapon_endgame.fgd
+++ b/fgd/point/weapon/weapon_endgame.fgd
@@ -4,4 +4,9 @@
studioprop("models/weapons/w_xengrenade.mdl") = weapon_endgame: "Special ending Xen Grenade"
[
output OnEndGame(void) : "Fired when the endgame Xen Relay Grenade is thrown."
+
+ @resources
+ [
+ weapon_script "scripts/weapon_endgame.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_first_aid_kit.fgd b/fgd/point/weapon/weapon_first_aid_kit.fgd
index 3e30dc09b..9e7400dee 100644
--- a/fgd/point/weapon/weapon_first_aid_kit.fgd
+++ b/fgd/point/weapon/weapon_first_aid_kit.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Scripted Weapons)
= weapon_first_aid_kit: "Physics First Aid Kit - This entity is intended to be used in scripted events where a single item needs to spawned with physics active."
[
+ @resources
+ [
+ weapon_script "scripts/weapon_first_aid_kit.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_first_aid_kit_spawn.fgd b/fgd/point/weapon/weapon_first_aid_kit_spawn.fgd
index 5f0eea94c..7b9b20dfe 100644
--- a/fgd/point/weapon/weapon_first_aid_kit_spawn.fgd
+++ b/fgd/point/weapon/weapon_first_aid_kit_spawn.fgd
@@ -4,4 +4,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_first_aid_kit_spawn: "First Aid Kit"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_first_aid_kit.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_flaregun.fgd b/fgd/point/weapon/weapon_flaregun.fgd
index d6e30243b..bea758907 100644
--- a/fgd/point/weapon/weapon_flaregun.fgd
+++ b/fgd/point/weapon/weapon_flaregun.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, HL2 Weapons)
studioprop("models/weapons/w_pistol.mdl") = weapon_flaregun : "Flaregun"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_flaregun.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_flashbang.fgd b/fgd/point/weapon/weapon_flashbang.fgd
index 60c6dd960..f55dfd2b0 100644
--- a/fgd/point/weapon/weapon_flashbang.fgd
+++ b/fgd/point/weapon/weapon_flashbang.fgd
@@ -4,4 +4,8 @@
autovis(Weapons, CSGO Weapons, CS Equipment)
studioprop("models/weapons/w_eq_flashbang_dropped.mdl") = weapon_flashbang: "Flashbang"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_flashbang.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_frag.fgd b/fgd/point/weapon/weapon_frag.fgd
index dfa665881..a7791079d 100644
--- a/fgd/point/weapon/weapon_frag.fgd
+++ b/fgd/point/weapon/weapon_frag.fgd
@@ -5,6 +5,9 @@
[
@resources
[
+ weapon_script "scripts/gameplay/weapons/weapon_frag.dmx" [+mesa]
+ weapon_script "scripts/weapon_frag.txt" [-mesa]
+
sound "WeaponFrag.Throw"
sound "WeaponFrag.Roll"
entity npc_grenade_frag
diff --git a/fgd/point/weapon/weapon_gascan_spawn.fgd b/fgd/point/weapon/weapon_gascan_spawn.fgd
index 5d2ae554d..29fbbd49b 100644
--- a/fgd/point/weapon/weapon_gascan_spawn.fgd
+++ b/fgd/point/weapon/weapon_gascan_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D, Weapon Spawners)
= weapon_gascan_spawn: "Gas Can"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_gascan.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_grenade_launcher.fgd b/fgd/point/weapon/weapon_grenade_launcher.fgd
index eaaea0ae9..a2b735ea9 100644
--- a/fgd/point/weapon/weapon_grenade_launcher.fgd
+++ b/fgd/point/weapon/weapon_grenade_launcher.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Scripted Weapons)
= weapon_grenade_launcher: "Grenade Launcher - This entity is intended to be used in scripted events where a single item needs to spawned with physics active."
[
+ @resources
+ [
+ weapon_script "scripts/weapon_grenade_launcher.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_grenade_launcher_spawn.fgd b/fgd/point/weapon/weapon_grenade_launcher_spawn.fgd
index b26b7927e..12894feb9 100644
--- a/fgd/point/weapon/weapon_grenade_launcher_spawn.fgd
+++ b/fgd/point/weapon/weapon_grenade_launcher_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_grenade_launcher_spawn: "Grenade Launcher"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_grenade_launcher.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_hopwire.fgd b/fgd/point/weapon/weapon_hopwire.fgd
index 4a660859b..1727b1b41 100644
--- a/fgd/point/weapon/weapon_hopwire.fgd
+++ b/fgd/point/weapon/weapon_hopwire.fgd
@@ -5,6 +5,7 @@
[
@resources
[
+ weapon_script "items/weapon_hopwire.txt"
// This also precaches the recipe table, not easy to do here though.
sound "WeaponFrag.Throw"
sound "WeaponFrag.Roll"
diff --git a/fgd/point/weapon/weapon_hunting_rifle_spawn.fgd b/fgd/point/weapon/weapon_hunting_rifle_spawn.fgd
index c520c50ed..b598dda57 100644
--- a/fgd/point/weapon/weapon_hunting_rifle_spawn.fgd
+++ b/fgd/point/weapon/weapon_hunting_rifle_spawn.fgd
@@ -4,4 +4,8 @@
studioprop("models/w_models/Weapons/w_sniper_mini14.mdl")
= weapon_hunting_rifle_spawn: "Hunting Rifle"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_hunting_rifle.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_item_spawn.fgd b/fgd/point/weapon/weapon_item_spawn.fgd
index b1931ea48..674d07a19 100644
--- a/fgd/point/weapon/weapon_item_spawn.fgd
+++ b/fgd/point/weapon/weapon_item_spawn.fgd
@@ -1,4 +1,4 @@
-@PointClass appliesto(L4D2) base(BaseEntityPoint)
+@PointClass appliesto(L4D2) base(WeaponSpawnSingle)
iconsprite(editor/weapon_item_spawn)
autovis(Weapons, L4D Weapons, L4D Items)
= weapon_item_spawn
@@ -18,11 +18,4 @@
item17(integer) : "Grenade Launcher" : 0
item18(integer) : "M60 Machinegun" : 0
melee_weapon(string) : "Melee Weapon" : : "Options: 'Any' or a comma-delimited string of melee weapon script names. Leave blank for none."
- spawnflags(flags) =
- [
- 1: "Enable Physics on spawned item" : 0
- 2: "Spawned Item Must Exist" : 0
- 8: "Infinite Items" : 0
- ]
-
]
diff --git a/fgd/point/weapon/weapon_manhacktoss.fgd b/fgd/point/weapon/weapon_manhacktoss.fgd
index 0a781caea..0b4a9fad0 100644
--- a/fgd/point/weapon/weapon_manhacktoss.fgd
+++ b/fgd/point/weapon/weapon_manhacktoss.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, EZ Weapons)
studioprop("models/manhack.mdl") = weapon_manhacktoss: "Deployable Manhack"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_manhacktoss.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_molotov_spawn.fgd b/fgd/point/weapon/weapon_molotov_spawn.fgd
index dde2a3e91..e3c9cc9a4 100644
--- a/fgd/point/weapon/weapon_molotov_spawn.fgd
+++ b/fgd/point/weapon/weapon_molotov_spawn.fgd
@@ -4,4 +4,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_molotov_spawn: "Molotov"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_molotov.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_pain_pills_spawn.fgd b/fgd/point/weapon/weapon_pain_pills_spawn.fgd
index 185e666f2..cb8e2b672 100644
--- a/fgd/point/weapon/weapon_pain_pills_spawn.fgd
+++ b/fgd/point/weapon/weapon_pain_pills_spawn.fgd
@@ -5,4 +5,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_pain_pills_spawn: "Painkillers"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_pain_pills.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_physcannon.fgd b/fgd/point/weapon/weapon_physcannon.fgd
index 2adbc5a25..a0d8f1a5a 100644
--- a/fgd/point/weapon/weapon_physcannon.fgd
+++ b/fgd/point/weapon/weapon_physcannon.fgd
@@ -5,6 +5,8 @@
[
@resources
[
+ weapon_script "scripts/weapon_physcannon.txt"
+
material "materials/sprites/orangelight1.vmt"
material "materials/sprites/glow04_noz.vmt"
material "materials/sprites/orangeflare1.vmt"
diff --git a/fgd/point/weapon/weapon_pipe_bomb_spawn.fgd b/fgd/point/weapon/weapon_pipe_bomb_spawn.fgd
index ee997d683..1340841ae 100644
--- a/fgd/point/weapon/weapon_pipe_bomb_spawn.fgd
+++ b/fgd/point/weapon/weapon_pipe_bomb_spawn.fgd
@@ -4,4 +4,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_pipe_bomb_spawn: "Pipe Bomb"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_pipe_bomb.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_pistol.fgd b/fgd/point/weapon/weapon_pistol.fgd
index 3e71813c9..67227762b 100644
--- a/fgd/point/weapon/weapon_pistol.fgd
+++ b/fgd/point/weapon/weapon_pistol.fgd
@@ -3,5 +3,8 @@
autovis(Weapons, HL2 Weapons, Pistol)
studioprop("models/weapons/w_pistol.mdl") = weapon_pistol: "Pistol"
[
- @resources []
+ @resources
+ [
+ weapon_script "scripts/weapon_pistol.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_pistol_magnum_spawn.fgd b/fgd/point/weapon/weapon_pistol_magnum_spawn.fgd
index 8f9a127e4..3f92ea5f0 100644
--- a/fgd/point/weapon/weapon_pistol_magnum_spawn.fgd
+++ b/fgd/point/weapon/weapon_pistol_magnum_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_pistol_magnum_spawn: "Magnum Pistol"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_pistol_magnum.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_pistol_spawn.fgd b/fgd/point/weapon/weapon_pistol_spawn.fgd
index 11585566e..599e7c703 100644
--- a/fgd/point/weapon/weapon_pistol_spawn.fgd
+++ b/fgd/point/weapon/weapon_pistol_spawn.fgd
@@ -11,4 +11,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_pistol_spawn: "Pistols"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_pistol.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_portalgun.fgd b/fgd/point/weapon/weapon_portalgun.fgd
index 7a3fb6a20..786b3c536 100644
--- a/fgd/point/weapon/weapon_portalgun.fgd
+++ b/fgd/point/weapon/weapon_portalgun.fgd
@@ -12,7 +12,7 @@
startingteamnum[engine](integer) : "Player" : 0 : "Which player this gun belongs to. Will decide which portals it fires before being picked up, as well as the skin."
startingteamnum[P2](choices) : "Player" : 0 : "Which player this gun belongs to. Will decide which portals it fires before being picked up, as well as the skin." =
[
- 0: "Chell/Bendy"
+ 0: "Singleplayer/Unassigned"
2: "P-Body"
3: "ATLAS"
]
diff --git a/fgd/point/weapon/weapon_pulsepistol.fgd b/fgd/point/weapon/weapon_pulsepistol.fgd
index a1b9e0241..0f1b117f2 100644
--- a/fgd/point/weapon/weapon_pulsepistol.fgd
+++ b/fgd/point/weapon/weapon_pulsepistol.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, EZ Weapons)
studioprop("models/weapons/w_pulsepistol.mdl") = weapon_pulsepistol: "Prototype Gauss Pistol"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_pulsepistol.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_pumpshotgun_spawn.fgd b/fgd/point/weapon/weapon_pumpshotgun_spawn.fgd
index 443bfc74b..985f47b68 100644
--- a/fgd/point/weapon/weapon_pumpshotgun_spawn.fgd
+++ b/fgd/point/weapon/weapon_pumpshotgun_spawn.fgd
@@ -4,4 +4,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_pumpshotgun_spawn: "Pump Shotgun"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_pumpshotgun.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_rifle_ak47_spawn.fgd b/fgd/point/weapon/weapon_rifle_ak47_spawn.fgd
index c262f66b3..6669f9037 100644
--- a/fgd/point/weapon/weapon_rifle_ak47_spawn.fgd
+++ b/fgd/point/weapon/weapon_rifle_ak47_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_rifle_ak47_spawn: "AK47"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_rifle_ak47.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_rifle_desert_spawn.fgd b/fgd/point/weapon/weapon_rifle_desert_spawn.fgd
index 96225e4a1..7e24d9830 100644
--- a/fgd/point/weapon/weapon_rifle_desert_spawn.fgd
+++ b/fgd/point/weapon/weapon_rifle_desert_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_rifle_desert_spawn: "Desert Rifle"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_rifle_desert.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_rifle_sg552_spawn.fgd b/fgd/point/weapon/weapon_rifle_sg552_spawn.fgd
new file mode 100644
index 000000000..c8c2cadb1
--- /dev/null
+++ b/fgd/point/weapon/weapon_rifle_sg552_spawn.fgd
@@ -0,0 +1,11 @@
+@PointClass base(WeaponSpawn)
+ appliesto(L4D2)
+ autovis(Weapons, L4D Weapons, Weapon Spawners)
+ studioprop("models/w_models/Weapons/w_rifle_sg552.mdl")
+= weapon_rifle_sg552_spawn: "SG552"
+ [
+ @resources
+ [
+ weapon_script "scripts/weapon_rifle_sg552.txt"
+ ]
+ ]
diff --git a/fgd/point/weapon/weapon_rifle_spawn.fgd b/fgd/point/weapon/weapon_rifle_spawn.fgd
index 6b704eb95..9339c4d79 100644
--- a/fgd/point/weapon/weapon_rifle_spawn.fgd
+++ b/fgd/point/weapon/weapon_rifle_spawn.fgd
@@ -4,4 +4,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_rifle_spawn: "Assault Rifle"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_rifle.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_rpg.fgd b/fgd/point/weapon/weapon_rpg.fgd
index f7ce6da16..56604510c 100644
--- a/fgd/point/weapon/weapon_rpg.fgd
+++ b/fgd/point/weapon/weapon_rpg.fgd
@@ -5,6 +5,7 @@
[
@resources
[
+ weapon_script "scripts/weapon_rpg.txt"
sound "Missile.Ignite"
sound "Missile.Accelerate"
material "materials/effects/laser1_noz.vmt"
diff --git a/fgd/point/weapon/weapon_shotgun.fgd b/fgd/point/weapon/weapon_shotgun.fgd
index 5eb6e4bde..52940e640 100644
--- a/fgd/point/weapon/weapon_shotgun.fgd
+++ b/fgd/point/weapon/weapon_shotgun.fgd
@@ -3,5 +3,8 @@
autovis(Weapons, HL2 Weapons, Shotgun)
studioprop("models/weapons/w_shotgun.mdl") = weapon_shotgun: "Shotgun"
[
- @resources []
+ @resources
+ [
+ weapon_script "scripts/weapon_shotgun.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_shotgun_chrome_spawn.fgd b/fgd/point/weapon/weapon_shotgun_chrome_spawn.fgd
index 24884888d..9c6a07952 100644
--- a/fgd/point/weapon/weapon_shotgun_chrome_spawn.fgd
+++ b/fgd/point/weapon/weapon_shotgun_chrome_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_shotgun_chrome_spawn: "Chrome Shotgun"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_shotgun_chrome.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_shotgun_spas_spawn.fgd b/fgd/point/weapon/weapon_shotgun_spas_spawn.fgd
index bd396eef1..aab068d99 100644
--- a/fgd/point/weapon/weapon_shotgun_spas_spawn.fgd
+++ b/fgd/point/weapon/weapon_shotgun_spas_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_shotgun_spas_spawn: "SPAS Shotgun"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_shotgun_spas.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_slam.fgd b/fgd/point/weapon/weapon_slam.fgd
index c16bb09c9..7d567a64a 100644
--- a/fgd/point/weapon/weapon_slam.fgd
+++ b/fgd/point/weapon/weapon_slam.fgd
@@ -5,6 +5,7 @@
[
@resources
[
+ weapon_script "scripts/weapon_slam.txt"
sound "Weapon_SLAM.ThrowMode"
sound "Weapon_SLAM.TripMineMode"
sound "Weapon_SLAM.SatchelDetonate"
diff --git a/fgd/point/weapon/weapon_smg1.fgd b/fgd/point/weapon/weapon_smg1.fgd
index e49e30fcc..0166c67ea 100644
--- a/fgd/point/weapon/weapon_smg1.fgd
+++ b/fgd/point/weapon/weapon_smg1.fgd
@@ -5,6 +5,7 @@
[
@resources
[
+ weapon_script "scripts/weapon_smg1.txt"
entity grenade_ar2
]
]
diff --git a/fgd/point/weapon/weapon_smg2.fgd b/fgd/point/weapon/weapon_smg2.fgd
index d6202f4a1..ee328a3c8 100644
--- a/fgd/point/weapon/weapon_smg2.fgd
+++ b/fgd/point/weapon/weapon_smg2.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, EZ Weapons)
studioprop("models/weapons/w_mp5k.mdl") = weapon_smg2: "MP5K"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_smg2.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_smg_mp5_spawn.fgd b/fgd/point/weapon/weapon_smg_mp5_spawn.fgd
new file mode 100644
index 000000000..667f671ff
--- /dev/null
+++ b/fgd/point/weapon/weapon_smg_mp5_spawn.fgd
@@ -0,0 +1,11 @@
+@PointClass base(WeaponSpawn)
+ appliesto(L4D2)
+ autovis(Weapons, L4D Weapons, Weapon Spawners)
+ studioprop("models/w_models/Weapons/w_smg_mp5.mdl")
+= weapon_smg_mp5_spawn: "MP5"
+ [
+ @resources
+ [
+ weapon_script "scripts/weapon_smg_mp5.txt"
+ ]
+ ]
diff --git a/fgd/point/weapon/weapon_smg_silenced_spawn.fgd b/fgd/point/weapon/weapon_smg_silenced_spawn.fgd
index fecfffaa4..eeb5e205e 100644
--- a/fgd/point/weapon/weapon_smg_silenced_spawn.fgd
+++ b/fgd/point/weapon/weapon_smg_silenced_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_smg_silenced_spawn: "MicroUZI"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_smg_silenced.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_smg_spawn.fgd b/fgd/point/weapon/weapon_smg_spawn.fgd
index 53936759e..c235ab9c5 100644
--- a/fgd/point/weapon/weapon_smg_spawn.fgd
+++ b/fgd/point/weapon/weapon_smg_spawn.fgd
@@ -4,4 +4,8 @@
studioprop("models/w_models/Weapons/w_smg_uzi.mdl")
= weapon_smg_spawn: "Submachinegun"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_smg.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_sniper_awp_spawn.fgd b/fgd/point/weapon/weapon_sniper_awp_spawn.fgd
new file mode 100644
index 000000000..2b5579ef6
--- /dev/null
+++ b/fgd/point/weapon/weapon_sniper_awp_spawn.fgd
@@ -0,0 +1,11 @@
+@PointClass base(WeaponSpawn)
+ appliesto(L4D2)
+ autovis(Weapons, L4D Weapons, Weapon Spawners)
+ studioprop("models/w_models/Weapons/w_sniper_awp.mdl")
+= weapon_sniper_awp_spawn: "AWP Sniper"
+ [
+ @resources
+ [
+ weapon_script "scripts/weapon_sniper_awp.txt"
+ ]
+ ]
diff --git a/fgd/point/weapon/weapon_sniper_military_spawn.fgd b/fgd/point/weapon/weapon_sniper_military_spawn.fgd
index 4e2484da7..dec56ad87 100644
--- a/fgd/point/weapon/weapon_sniper_military_spawn.fgd
+++ b/fgd/point/weapon/weapon_sniper_military_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_sniper_military_spawn: "Military Sniper Rifle"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_sniper_military.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_sniper_scout_spawn.fgd b/fgd/point/weapon/weapon_sniper_scout_spawn.fgd
new file mode 100644
index 000000000..e22cde8b2
--- /dev/null
+++ b/fgd/point/weapon/weapon_sniper_scout_spawn.fgd
@@ -0,0 +1,7 @@
+@PointClass base(WeaponSpawn)
+ appliesto(L4D2)
+ autovis(Weapons, L4D Weapons, Weapon Spawners)
+ studioprop("models/w_models/Weapons/w_sniper_scout.mdl")
+= weapon_sniper_scout_spawn: "Scout Sniper"
+[
+]
\ No newline at end of file
diff --git a/fgd/point/weapon/weapon_spawn.fgd b/fgd/point/weapon/weapon_spawn.fgd
index 28f2a8753..ec96cdbb2 100644
--- a/fgd/point/weapon/weapon_spawn.fgd
+++ b/fgd/point/weapon/weapon_spawn.fgd
@@ -30,8 +30,17 @@
"weapon_rifle_ak47": "AK47"
"weapon_hunting_rifle": "Hunting Rifle"
"weapon_sniper_military": "Sniper Military"
+ "weapon_smg_mp5" : "MP5"
+ "weapon_rifle_sg552" : "SG552"
+ "weapon_sniper_awp" : "Sniper AWP"
+ "weapon_sniper_scout" : "Sniper Scout"
]
spawn_without_director(boolean) : "Spawn instantly without director" : 0 : "Bypass the proximity checks that make nearby weapons be the same tier / not the same weapon."
+ no_cs_weapons(boolean) : "No CS Weapons" : 0 : "When selecting 'any' weapon, set this to true if you do not want CS weapons."
+ spawnflags(flags) =
+ [
+ 16 : "Constrain to spawn position (don't drop to the ground)" : 0
+ ]
]
diff --git a/fgd/point/weapon/weapon_stunstick.fgd b/fgd/point/weapon/weapon_stunstick.fgd
index 274c38819..899526dd5 100644
--- a/fgd/point/weapon/weapon_stunstick.fgd
+++ b/fgd/point/weapon/weapon_stunstick.fgd
@@ -5,6 +5,7 @@
[
@resources
[
+ weapon_script "scripts/weapon_stunstick.txt"
sound "Weapon_StunStick.Activate"
sound "Weapon_StunStick.Deactivate"
]
diff --git a/fgd/point/weapon/weapon_upgradepack_explosive_spawn.fgd b/fgd/point/weapon/weapon_upgradepack_explosive_spawn.fgd
index dea206da8..692fa6c01 100644
--- a/fgd/point/weapon/weapon_upgradepack_explosive_spawn.fgd
+++ b/fgd/point/weapon/weapon_upgradepack_explosive_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, L4D Items)
= weapon_upgradepack_explosive_spawn: "Upgrade Pack - Explosive"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_upgradepack_explosive.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_upgradepack_incendiary_spawn.fgd b/fgd/point/weapon/weapon_upgradepack_incendiary_spawn.fgd
index 17499e537..298202e2a 100644
--- a/fgd/point/weapon/weapon_upgradepack_incendiary_spawn.fgd
+++ b/fgd/point/weapon/weapon_upgradepack_incendiary_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, L4D Items)
= weapon_upgradepack_incendiary_spawn: "Upgrade Pack - Incendiary"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_upgradepack_incendiary.txt"
+ ]
]
diff --git a/fgd/point/weapon/weapon_vomitjar_spawn.fgd b/fgd/point/weapon/weapon_vomitjar_spawn.fgd
index f10312920..7eba75334 100644
--- a/fgd/point/weapon/weapon_vomitjar_spawn.fgd
+++ b/fgd/point/weapon/weapon_vomitjar_spawn.fgd
@@ -3,4 +3,8 @@
autovis(Weapons, L4D Weapons, Weapon Spawners)
= weapon_vomitjar_spawn: "Vomit Jar"
[
+ @resources
+ [
+ weapon_script "scripts/weapon_vomitjar.txt"
+ ]
]
diff --git a/fgd/visgroups.cfg b/fgd/visgroups.cfg
index 82030a0ce..ebbfde20d 100644
--- a/fgd/visgroups.cfg
+++ b/fgd/visgroups.cfg
@@ -165,6 +165,7 @@
* `npc_arbeit_helicopter`
- Rocket Turrets
* `npc_rocket_tripwire`
+ * `prop_rocket_tripwire`
* `npc_rocket_turret`
* `rocket_turret_projectile`
- Wheatley (`npc_wheatley_boss`)
@@ -253,24 +254,38 @@
- Simple NextBot (`simple_bot`)
- Spy NextBot (`bot_npc_decoy`)
- Nodes
- * `info_node_air`
+ * `info_bigmomma`
+ * `info_marine_hint`
* `info_node_air_hint`
+ * `info_node_air`
* `info_node_climb`
- * `info_bigmomma`
- * `info_node`
* `info_node_hint`
- * `info_node_marine_hint`
- * `info_node_link`
* `info_node_link_controller`
* `info_node_link_filtered`
* `info_node_link_logic`
* `info_node_link_oneway`
- * `info_template_link_controller`
+ * `info_node_link`
+ * `info_node_marine_hint`
+ * `info_node`
* `info_radial_link_controller`
+ * `info_template_link_controller`
- Brush Entities
- Clips
+ * `func_bulletshield`
+ * `func_clip_client`
* `func_clip_vphysics`
+ * `func_precipitation_blocker`
* `func_vehicleclip`
+ - Gameplay Zones
+ # Marks game-specific locations.
+ * `func_achievement`
+ * `func_bomb_target`
+ * `func_buyzone`
+ * `func_capturezone`
+ * `func_changeclass`
+ * `func_respawnroom`
+ * `func_powerupvolume`
+ * `func_respawnflag`
- Triggers
- Death Triggers
* `trigger_hurt`
@@ -303,6 +318,7 @@
* `trigger_changelevel`
* `trigger_finale`
* `trigger_transition`
+ * `game_zone_player`
* `trigger_standoff`
* `trigger_active_weapon_detect`
* `trigger_add_tf_player_condition`
@@ -348,23 +364,74 @@
* `trigger_teleport_relative`
* `trigger_timer_door`
* `trigger_togglesave`
- * `trigger_tonemap`
* `trigger_upgrade_laser_sight`
* `trigger_weaponfire`
- Func Brush
+ * `func_brush_kzmod`
* `func_brush`
- * `func_wall`
* `func_wall_toggle`
+ * `func_wall`
+ * `func_illusionary`
- LOD Brushes (`func_lod`)
+ - FX Swap Triggers
+ * `trigger_tonemap`
+ * `color_correction_volume`
+ * `fog_volume`
- Conveyors
* `func_conveyor`
* `func_conveyor_bms`
- Physbox
* `func_physbox`
* `func_physbox_multiplayer`
+ * `func_pushable`
- Breakables
* `func_breakable`
* `func_breakable_surf`
+ - FX
+ * `env_bubbles`
+ * `env_embers`
+ * `func_dustcloud`
+ * `func_dustmotes`
+ * `func_forcefield`
+ * `func_precipitation`
+ * `func_respawnroomvisualizer`
+ * `func_fish_pool`
+ * `newxog_volume`
+ - Dynamic Water
+ * `func_water`
+ * `func_water_analog`
+ - Linear Movement
+ * `func_buildable_button`
+ * `func_button`
+ * `func_door`
+ * `func_elevator`
+ * `func_movelinear`
+ * `func_plat`
+ * `func_platrot`
+ * `momentary_door`
+ - Rotational Movement
+ * `func_door_rotating`
+ * `func_platrot`
+ * `func_rotating`
+ * `momentary_rot_button`
+ - Tanks
+ * `func_tank_combine_cannon`
+ * `func_tank`
+ * `func_tankairboatgun`
+ * `func_tankapcrocket`
+ * `func_tanklaser`
+ * `func_tanklogic`
+ * `func_tankmortar`
+ * `func_tankphyscannister`
+ * `func_tankpulselaser`
+ * `func_tankrocket`
+ * `func_tanktrain`
+ - Trains
+ * `func_tanktrain`
+ * `func_tracktrain`
+ * `func_train`
+ * `func_traincontrols`
+ * `func_guntarget`
- Point Entities
- Physics
@@ -429,6 +496,10 @@
* `env_shooter`
* `env_smokestack`
* `env_smoketrail`
+ * `env_effectscript`
+ * `env_dustpuff`
+ * `env_entity_igniter`
+ * `env_entity_dissolver`
- Sprites
* `env_sprite_clientside`
* `env_sprite_oriented`
@@ -437,6 +508,7 @@
- Logic
* `logic_auto`
* `logic_relay`
+ * `sixense_logic_relay`
* `logic_relay_queue`
* `comp_relay`
* `logic_branch`
@@ -501,17 +573,6 @@
* `logic_script`
* `lua_run`
- Filters
- * `filter_damage_class`
- * `filter_damage_mod`
- * `filter_damage_transfer`
- * `filter_damage_type`
- * `filter_tf_damaged_by_weapon_in_slot`
- * `filter_melee_damage`
- * `filter_health`
- * `filter_redirect_inflictor`
- * `filter_redirect_owner`
- * `filter_redirect_weapon`
- * `filter_blood_control`
* `filter_activator_class`
* `filter_activator_classify`
* `filter_activator_context`
@@ -529,13 +590,25 @@
* `filter_activator_team`
* `filter_activator_tfteam`
* `filter_base`
+ * `filter_blood_control`
* `filter_combineball_type`
+ * `filter_damage_class`
+ * `filter_damage_mod`
+ * `filter_damage_transfer`
+ * `filter_damage_type`
* `filter_enemy`
+ * `filter_health`
+ * `filter_melee_damage`
* `filter_multi`
* `filter_player_held`
+ * `filter_redirect_inflictor`
+ * `filter_redirect_owner`
+ * `filter_redirect_weapon`
+ * `filter_script`
* `filter_tf_bot_has_tag`
* `filter_tf_class`
* `filter_tf_condition`
+ * `filter_tf_damaged_by_weapon_in_slot`
* `filter_tf_player_can_cap`
- Globals
* `logic_achievement`
@@ -586,7 +659,10 @@
* `game_weapon_manager`
* `wheel_of_doom`
* `env_wind`
+ * `point_bonusmaps_accessor`
+ * `point_changelevel`
* `point_clientcommand`
+ * `point_broadcastclientcommand`
* `point_servercommand`
* `postprocess_controller`
* `shadow_control`
@@ -668,14 +744,15 @@
* `npc_maker`
* `npc_template_maker`
- VGUI
- * `vgui_movie_display`
* `prop_portal_stats_display`
* `vgui_level_placard_display`
+ * `vgui_movie_display`
* `vgui_mp_lobby_display`
* `vgui_neurotoxin_countdown`
* `vgui_screen`
- * `func_monitor`
- * `point_camera`
+ * `vgui_slideshow_display`
+ * `vgui_text_display`
+ * `vgui_world_text_panel`
* `env_xen_healpool`
* `env_xen_healshower`
* `info_darknessmode_lightsource`
@@ -697,8 +774,11 @@
* `comp_propcombine_volume`
- Sceneset (`comp_choreo_sceneset`)
- Logic
- * `comp_sequential_call`
+ * `comp_adv_output`
+ * `comp_flicker`
* `comp_numeric_transition`
+ * `comp_player_input_helper`
+ * `comp_sequential_call`
- Setters
* `comp_scriptvar_setter`
* `comp_kv_setter`
@@ -749,26 +829,27 @@
* `point_worldtext`
* `point_message`
* `point_message_localized`
- - Doors
- * `func_door`
- * `func_door_rotating`
- * `prop_door_rotating_checkpoint`
- * `prop_door_rotating`
- * `prop_testchamber_door`
- * `prop_linked_portal_door`
- * `func_lookdoor`
- * `asw_door`
- Teleporters
* `trigger_teleport`
* `trigger_teleport_relative`
* `point_teleport`
* `prop_linked_portal_door`
* `linked_portal_door`
+ * `func_fake_worldportal`
- Ladders
* `func_ladder`
* `func_ladderendpoint`
* `func_useableladder`
* `info_ladder_dismount`
+ - Doors
+ * `func_door`
+ * `func_door_rotating`
+ * `prop_door_rotating_checkpoint`
+ * `prop_door_rotating`
+ * `prop_testchamber_door`
+ * `prop_linked_portal_door`
+ * `func_lookdoor`
+ * `asw_door`
- Buttons
* `func_button`
* `momentary_rot_button`
@@ -777,6 +858,7 @@
* `func_weight_button`
* `infra_button`
* `prop_interactable`
+ * `prop_tsp_button`
- Autosaves
* `trigger_autosave`
* `logic_autosave`
@@ -794,16 +876,23 @@
* `item_suitcharger`
* `prop_hev_charger`
- Thumpers (`prop_thumper`)
- - Portals (`prop_portal`)
+ - Portals
+ * `prop_portal`
+ * `prop_linked_portal_door`
+ * `linked_portal_door`
+ * `func_fake_worldportal`
- Portal Control
* `func_noportal_volume`
* `func_portal_bumper`
+ * `info_placement_helper`
+ * `sixense_info_placement_helper`
- Radiation Ammo Charger (`prop_radiation_charger`)
- Headcrab Canister (`env_headcrabcanister`)
- Cubes
- - FrankenTurrets (`prop_monster_box`)
- - Normal (`prop_weighted_cube`)
- - Scaled Cube (`prop_scaled_cube`)
+ * `prop_contraption_cube`
+ * `prop_monster_box`
+ * `prop_scaled_cube`
+ * `prop_weighted_cube`
- Excursion Funnels (`prop_tractor_beam`)
- Fizzlers
* `trigger_paint_cleanser`
@@ -826,12 +915,13 @@
* `projected_wall_entity`
- Excursion Funnels (`prop_tractor_beam`)
- Buttons
+ * `prop_button`
+ * `prop_contraption_cube_button`
* `prop_floor_ball_button`
* `prop_floor_button`
* `prop_floor_cube_button`
- * `prop_under_floor_button`
- * `prop_button`
* `prop_under_button`
+ * `prop_under_floor_button`
- Paint
* `info_paint_sprayer`
* `paint_sphere`
@@ -862,7 +952,12 @@
* `info_coop_spawn`
* `info_player_start`
* `info_player_teamspawn`
+ * `info_l4d1_survivor_spawn`
- Wilson Scanners (`prop_wilson_scanner`)
+ - RT Camera
+ * `func_monitor`
+ * `info_camera_link`
+ * `point_camera`
- Tool Brushes
- Areaportals
* `func_areaportal`
@@ -870,9 +965,11 @@
* `func_areaportal_oneway`
- Occluders (`func_occluder`)
- Propcombine (`comp_propcombine_volume`)
+ - Viscluster (`func_viscluster`)
- Vehicles
* `prop_vehicle_airboat`
* `prop_vehicle_apc`
+ * `prop_vehicle_drivable_apc`
* `prop_vehicle_crane`
* `infra_crane`
* `infra_boat`
@@ -956,27 +1053,24 @@
* `weapon_slam`
# L4D
- * `prop_minigun`
* `prop_minigun_l4d1`
- * `weapon_pain_pills_spawn`
+ * `prop_minigun`
* `weapon_adrenaline_spawn`
- * `weapon_item_spawn`
- * `weapon_scavenge_item_spawn`
- * `weapon_upgradepack_explosive_spawn`
- * `weapon_upgradepack_incendiary_spawn`
- * `weapon_first_aid_kit`
- * `weapon_grenade_launcher`
* `weapon_ammo_spawn`
* `weapon_autoshotgun_spawn`
* `weapon_chainsaw_spawn`
* `weapon_defibrillator_spawn`
* `weapon_first_aid_kit_spawn`
+ * `weapon_first_aid_kit`
* `weapon_gascan_spawn`
* `weapon_grenade_launcher_spawn`
+ * `weapon_grenade_launcher`
* `weapon_hunting_rifle_spawn`
+ * `weapon_item_spawn`
* `weapon_melee_spawn`
* `weapon_molotov_spawn`
* `weapon_pain_pills_spawn`
+ * `weapon_pain_pills_spawn`
* `weapon_pipe_bomb_spawn`
* `weapon_pistol_magnum_spawn`
* `weapon_pistol_spawn`
@@ -984,13 +1078,20 @@
* `weapon_rifle_ak47_spawn`
* `weapon_rifle_desert_spawn`
* `weapon_rifle_m60_spawn`
+ * `weapon_rifle_sg552_spawn`
* `weapon_rifle_spawn`
+ * `weapon_scavenge_item_spawn`
* `weapon_shotgun_chrome_spawn`
* `weapon_shotgun_spas_spawn`
+ * `weapon_smg_mp5_spawn`
* `weapon_smg_silenced_spawn`
* `weapon_smg_spawn`
+ * `weapon_sniper_awp_spawn`
* `weapon_sniper_military_spawn`
+ * `weapon_sniper_scout_spawn`
* `weapon_spawn`
+ * `weapon_upgradepack_explosive_spawn`
+ * `weapon_upgradepack_incendiary_spawn`
* `weapon_vomitjar_spawn`
# Mesa
@@ -1018,6 +1119,19 @@
* `weapon_manhacktoss`
* `weapon_pulsepistol`
* `weapon_smg2`
+
+ # Alien Swarm
+ * `asw_pickup_autogun`
+ * `asw_pickup_chainsaw`
+ * `asw_pickup_flamer`
+ * `asw_pickup_mines`
+ * `asw_pickup_mining_laser`
+ * `asw_pickup_pdw`
+ * `asw_pickup_pistol`
+ * `asw_pickup_prifle`
+ * `asw_pickup_rifle`
+ * `asw_pickup_shotgun`
+ * `asw_pickup_vindicator`
- Items
- Ammunition
* `item_ammo_357`
@@ -1039,6 +1153,15 @@
* `item_box_lrounds`
* `item_box_mrounds`
* `item_box_srounds`
+ * `asw_ammo_autogun`
+ * `asw_ammo_drop`
+ * `asw_ammo_flamer`
+ * `asw_ammo_mining_laser`
+ * `asw_ammo_pdw`
+ * `asw_ammo_pistol`
+ * `asw_ammo_rifle`
+ * `asw_ammo_shotgun`
+ * `asw_ammo_vindicator`
- Large Ammunition
* `item_ammo_357_large`
* `item_ammo_ar2_large`
@@ -1117,6 +1240,16 @@
* `tf_projectile_throwable_repel`
- Health and Ammo Kit (`item_healthammokit`)
+ - Pickups
+ * `asw_pickup_medkit`
+ * `asw_pickup_fire_extinguisher`
+ * `asw_pickup_flares`
+ * `asw_pickup_flashlight`
+ * `asw_pickup_grenades`
+ * `asw_pickup_sentry`
+ * `asw_pickup_stim`
+ * `asw_pickup_welder`
+
- AA Batteries (`item_aa_batteries`)
- D Batteries (`item_d_batteries`)
- Geocache (`infra_geocache`)
@@ -1140,17 +1273,20 @@
- World Details
- Props
- Dynamic
- * `prop_dynamic`
+ * `dynamic_prop`
+ * `prop_car_alarm`
+ * `prop_dropship_container`
* `prop_dynamic_glow`
+ * `prop_dynamic_kzmod`
* `prop_dynamic_ornament`
* `prop_dynamic_override`
- * `dynamic_prop`
- * `prop_car_alarm`
- * `prop_train_awesome`
- * `prop_train_apprehension`
- * `prop_retinalscanner`
+ * `prop_dynamic`
+ * `prop_hallucination`
* `prop_interactable`
+ * `prop_retinalscanner`
* `prop_scalable`
+ * `prop_train_apprehension`
+ * `prop_train_awesome`
- Nihilanth Battle
* `nihilanth_pylon`
* `nihiportalsbase`
@@ -1160,17 +1296,17 @@
- Ragdoll
* `prop_ragdoll`
* `prop_ragdoll_original`
- * `prop_physics`
+ * `physics_cannister`
* `physics_prop`
+ * `prop_car_glass`
* `prop_physics_multiplayer`
* `prop_physics_override`
* `prop_physics_paintable`
* `prop_physics_respawnable`
+ * `prop_physics`
* `prop_sphere`
* `simple_physics_brush`
* `simple_physics_prop`
- * `prop_car_glass`
- * `physics_cannister`
- Static
* `prop_detail`
* `prop_detail_sprite`
diff --git a/fgd/worldspawn.fgd b/fgd/worldspawn.fgd
index 8fdb09d5a..7073928e5 100644
--- a/fgd/worldspawn.fgd
+++ b/fgd/worldspawn.fgd
@@ -1,7 +1,10 @@
// Super-extra special, so don't use normal bases.
@SolidClass base(BaseEntity, ResponseContext) = worldspawn: "This is the world entity. Each map can only contain one, and it's automatically created for you."
[
- message(string) : "Map Description / Title"
+ world_mins[engine](vector) : "World Minimums" : : "Set by VBSP to the minimum bounds of the map geometry, excluding the 3D skybox (if present)."
+ world_maxs[engine](vector) : "World Maximums" : : "Set by VBSP to the maximum bounds of the map geometry, excluding the 3D skybox (if present)."
+ // "Doesn't seem to be used anywhere anymore." - VDC
+ // message(string) : "Map Description / Title"
skyname(string) : "SkyBox Texture Name" : : "Texture used for the 2D skybox."
skyname[HL2, EP1, EP2](string) : "SkyBox Texture Name" : "sky_day01_01" : "Texture used for the 2D skybox."
@@ -23,11 +26,13 @@
"when the map loads or whether it should only be used for savegame comments and RPC. " +
"This would normally be set to ''Yes'' outside of Mapbase."
- startdark(boolean) : "Level Fade In" : 0
- gametitle[!P2](boolean) : "Display Game Title" : 0 : "Game Title that appears onscreen when this level starts."
+ startdark(boolean) : "Level Fade In" : 0 : "Fade from black after starting the level or loading a save. If you need something more configurable, use a logic_auto and env_fade instead."
+ gametitle[+complete](boolean) : "Display Game Title" : 0 : "Display the game logo onscreen when this level starts. Crashes unless the HL1 logo sprite is ported."
newunit[engine](boolean) : "New Level Unit" : 0
- newunit(choices) : "New Level Unit" : 0 : "Used to clear out savegame data of previous levels to keep the savegame size as small as possible. " +
+ // Portal 2 force enables this
+ // TODO: we can probably hide it in multiplayer-only games too
+ newunit[!P2](choices) : "New Level Unit" : 0 : "Used to clear out savegame data of previous levels to keep the savegame size as small as possible. " +
"Only set it to Yes if the player cannot return to any previous levels." =
[
0: "No, keep current"
@@ -62,10 +67,11 @@
musicpostfix[L4D2](string) : "Music Post-Fix String" : "Waterfront"
- maxoccludeearea(float) : "Max occludee area" : 0 : "[Used on PC] Prevents occlusion testing for entities that take up more than X% of the screen."
- minoccluderarea(float) : "Min occluder area" : 0 : "[Used on PC] Prevents occluders from being used if they take up less than X% of the screen."
- maxoccludeearea_x360(float) : "Max occludee area (Xbox)" : 0 : "[Used on 360] Prevents occlusion testing for entities that take up more than X% of the screen."
- minoccluderarea_x360(float) : "Min occluder area (Xbox)" : 0 : "[Used on 360] Prevents occluders from being used if they take up less than X% of the screen."
+ maxoccludeearea(float) : "Max occludee area" : 0 : "Prevents occlusion testing for entities that take up more than X% of the screen."
+ minoccluderarea(float) : "Min occluder area" : 0 : "Prevents occluders from being used if they take up less than X% of the screen."
+ // Most users are not mapping for Xbox
+ maxoccludeearea_x360[+complete](float) : "Max occludee area (Xbox)" : 0 : "[Used on 360] Prevents occlusion testing for entities that take up more than X% of the screen."
+ minoccluderarea_x360[+complete](float) : "Min occluder area (Xbox)" : 0 : "[Used on 360] Prevents occluders from being used if they take up less than X% of the screen."
maxpropscreenwidth(float) : "Start Fade Pixels" : -1 : "Number of pixels wide at which all props in the level start to fade (<0 = use fademaxdist). " +
"This number is ignored if the prop has a specific fade distance specified."
minpropscreenwidth(float) : "End Fade Pixels" : 0 : "Minimum number of pixels wide at which the prop is visible (0 = don't fade out). " +
@@ -99,7 +105,7 @@
//4 : "Python (Unsupported)"
]
- coldworld(boolean) : "World is cold" : 0 : "Emit steam from NPC's mouths and similar effects."
+ coldworld[DODS](boolean) : "World is cold" : 0 : "Emit steam from players' mouths and similar effects."
WaveHeight[engine](float) : "Wave Height" : : "Unused keyvalue, likely to indicate the amount of HL1-style wavy water."
fixtriggerpushbug[engine](integer) : "Fix contact trigger_push bug" : 1 : "This fixes a bug with very thin contact mode trigger_push pushing downwards. This should be set to Yes unless this is an old map which worked around the bug and needs it in order to work correctly."
diff --git a/hammer/materials/editor/comp_adv_output.vmt b/hammer/materials/editor/comp_adv_output.vmt
new file mode 100644
index 000000000..3d6ec8010
--- /dev/null
+++ b/hammer/materials/editor/comp_adv_output.vmt
@@ -0,0 +1,8 @@
+Sprite
+{
+ $baseTexture "editor/comp_adv_output"
+ $spriteorientation "vp_parallel"
+ $spriteorigin "[ 0.50 0.50 ]"
+ $spriterendermode 2
+ $no_fullbright 1
+}
diff --git a/hammer/materials/editor/comp_adv_output.vtf b/hammer/materials/editor/comp_adv_output.vtf
new file mode 100644
index 000000000..857a6ff0a
Binary files /dev/null and b/hammer/materials/editor/comp_adv_output.vtf differ
diff --git a/hammer/materials/editor/comp_case.vmt b/hammer/materials/editor/comp_case.vmt
new file mode 100644
index 000000000..6e91679f5
--- /dev/null
+++ b/hammer/materials/editor/comp_case.vmt
@@ -0,0 +1,8 @@
+Sprite
+{
+ $baseTexture "editor/comp_case"
+ $spriteorientation "vp_parallel"
+ $spriteorigin "[ 0.50 0.50 ]"
+ $spriterendermode 2
+ $no_fullbright 1
+}
diff --git a/hammer/materials/editor/comp_case.vtf b/hammer/materials/editor/comp_case.vtf
new file mode 100644
index 000000000..92ab9b457
Binary files /dev/null and b/hammer/materials/editor/comp_case.vtf differ
diff --git a/hammer/materials/editor/comp_cubemap_parallax.vmt b/hammer/materials/editor/comp_cubemap_parallax.vmt
new file mode 100644
index 000000000..48f23d3e4
--- /dev/null
+++ b/hammer/materials/editor/comp_cubemap_parallax.vmt
@@ -0,0 +1,8 @@
+Sprite
+{
+ $baseTexture "editor/comp_cubemap_parallax"
+ $spriteorientation "vp_parallel"
+ $spriteorigin "[ 0.50 0.50 ]"
+ $spriterendermode 2
+ $no_fullbright 1
+}
diff --git a/hammer/materials/editor/comp_cubemap_parallax.vtf b/hammer/materials/editor/comp_cubemap_parallax.vtf
new file mode 100644
index 000000000..c338b8665
Binary files /dev/null and b/hammer/materials/editor/comp_cubemap_parallax.vtf differ
diff --git a/hammer/materials/editor/comp_scriptvar_setter.vtf b/hammer/materials/editor/comp_scriptvar_setter.vtf
index 3ef99b004..5d649a9a9 100644
Binary files a/hammer/materials/editor/comp_scriptvar_setter.vtf and b/hammer/materials/editor/comp_scriptvar_setter.vtf differ
diff --git a/hammer/materials/editor/point_broadcastclientcommand.vtf b/hammer/materials/editor/point_broadcastclientcommand.vtf
index 15d96a725..a1b601345 100644
Binary files a/hammer/materials/editor/point_broadcastclientcommand.vtf and b/hammer/materials/editor/point_broadcastclientcommand.vtf differ
diff --git a/hammer/materials/models/editor/invisible.vmt b/hammer/materials/models/editor/invisible.vmt
new file mode 100644
index 000000000..1f14216aa
--- /dev/null
+++ b/hammer/materials/models/editor/invisible.vmt
@@ -0,0 +1,6 @@
+UnlitGeneric
+ {
+ // Don't draw this at all, but it'll be traced for selection checks.
+ $no_draw 1
+ $model 1
+ }
diff --git a/hammer/materials/models/editor/playerstart_tf_blu.vmt b/hammer/materials/models/editor/playerstart_tf_blu.vmt
new file mode 100644
index 000000000..674a6772e
--- /dev/null
+++ b/hammer/materials/models/editor/playerstart_tf_blu.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$basetexture" "models/editor/playerstart_tf_blu"
+}
\ No newline at end of file
diff --git a/hammer/materials/models/editor/playerstart_tf_blu.vtf b/hammer/materials/models/editor/playerstart_tf_blu.vtf
new file mode 100644
index 000000000..bbd9dfbe9
Binary files /dev/null and b/hammer/materials/models/editor/playerstart_tf_blu.vtf differ
diff --git a/hammer/materials/models/editor/playerstart_tf_red.vmt b/hammer/materials/models/editor/playerstart_tf_red.vmt
new file mode 100644
index 000000000..4cd095c4a
--- /dev/null
+++ b/hammer/materials/models/editor/playerstart_tf_red.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$basetexture" "models/editor/playerstart_tf_red"
+}
\ No newline at end of file
diff --git a/hammer/materials/models/editor/playerstart_tf_red.vtf b/hammer/materials/models/editor/playerstart_tf_red.vtf
new file mode 100644
index 000000000..dabe13e09
Binary files /dev/null and b/hammer/materials/models/editor/playerstart_tf_red.vtf differ
diff --git a/hammer/materials/models/editor/ts/sky_camera.vtf b/hammer/materials/models/editor/ts/sky_camera.vtf
index 15a776451..d9c567069 100644
Binary files a/hammer/materials/models/editor/ts/sky_camera.vtf and b/hammer/materials/models/editor/ts/sky_camera.vtf differ
diff --git a/hammer/materials/tools/toolspropcombine.vtf b/hammer/materials/tools/toolspropcombine.vtf
index 20697d518..4f6423918 100644
Binary files a/hammer/materials/tools/toolspropcombine.vtf and b/hammer/materials/tools/toolspropcombine.vtf differ
diff --git a/hammer/models/editor/axis_helper_white.dx80.vtx b/hammer/models/editor/axis_helper_white.dx80.vtx
index 9b9c42d27..00b987f21 100644
Binary files a/hammer/models/editor/axis_helper_white.dx80.vtx and b/hammer/models/editor/axis_helper_white.dx80.vtx differ
diff --git a/hammer/models/editor/axis_helper_white.dx90.vtx b/hammer/models/editor/axis_helper_white.dx90.vtx
index 5668e3909..c9ca88aef 100644
Binary files a/hammer/models/editor/axis_helper_white.dx90.vtx and b/hammer/models/editor/axis_helper_white.dx90.vtx differ
diff --git a/hammer/models/editor/axis_helper_white.mdl b/hammer/models/editor/axis_helper_white.mdl
index b5dee9a3c..5a5d3fc3a 100644
Binary files a/hammer/models/editor/axis_helper_white.mdl and b/hammer/models/editor/axis_helper_white.mdl differ
diff --git a/hammer/models/editor/axis_helper_white.sw.vtx b/hammer/models/editor/axis_helper_white.sw.vtx
index 5d352dc27..10a097c32 100644
Binary files a/hammer/models/editor/axis_helper_white.sw.vtx and b/hammer/models/editor/axis_helper_white.sw.vtx differ
diff --git a/hammer/models/editor/axis_helper_white.vvd b/hammer/models/editor/axis_helper_white.vvd
index 0703c33f2..0fde73dce 100644
Binary files a/hammer/models/editor/axis_helper_white.vvd and b/hammer/models/editor/axis_helper_white.vvd differ
diff --git a/hammer/models/editor/playerstart_tf.dx80.vtx b/hammer/models/editor/playerstart_tf.dx80.vtx
new file mode 100644
index 000000000..8f7b65ff2
Binary files /dev/null and b/hammer/models/editor/playerstart_tf.dx80.vtx differ
diff --git a/hammer/models/editor/playerstart_tf.dx90.vtx b/hammer/models/editor/playerstart_tf.dx90.vtx
new file mode 100644
index 000000000..72fff6abb
Binary files /dev/null and b/hammer/models/editor/playerstart_tf.dx90.vtx differ
diff --git a/hammer/models/editor/playerstart_tf.mdl b/hammer/models/editor/playerstart_tf.mdl
new file mode 100644
index 000000000..4a0051ccc
Binary files /dev/null and b/hammer/models/editor/playerstart_tf.mdl differ
diff --git a/hammer/models/editor/playerstart_tf.sw.vtx b/hammer/models/editor/playerstart_tf.sw.vtx
new file mode 100644
index 000000000..4fc004c2d
Binary files /dev/null and b/hammer/models/editor/playerstart_tf.sw.vtx differ
diff --git a/hammer/models/editor/playerstart_tf.vvd b/hammer/models/editor/playerstart_tf.vvd
new file mode 100644
index 000000000..05fe2716c
Binary files /dev/null and b/hammer/models/editor/playerstart_tf.vvd differ
diff --git a/hammer/scripts/vscripts/srctools/vac_anim.nut b/hammer/scripts/vscripts/srctools/vac_anim.nut
index 1be02c766..8926d2e97 100644
--- a/hammer/scripts/vscripts/srctools/vac_anim.nut
+++ b/hammer/scripts/vscripts/srctools/vac_anim.nut
@@ -168,7 +168,7 @@ function make_cube() {
cargo = EntSet(cur_time + 3.0, mover, visual);
::vactube_objs.append(cargo);
// For tracking spawning, set this.
- printl("Vactube ent count: " + (::vactube_objs.len() * 2).tostring());
+ // printl("Vactube ent count: " + (::vactube_objs.len() * 2).tostring());
} else {
// Teleport to the right position.
cargo.mover.SetAbsOrigin(self.GetOrigin());
diff --git a/materialsrc/editor/comp_adv_output.pdn b/materialsrc/editor/comp_adv_output.pdn
new file mode 100644
index 000000000..7c260c2fe
Binary files /dev/null and b/materialsrc/editor/comp_adv_output.pdn differ
diff --git a/materialsrc/editor/comp_case.pdn b/materialsrc/editor/comp_case.pdn
new file mode 100644
index 000000000..ad3ac9914
Binary files /dev/null and b/materialsrc/editor/comp_case.pdn differ
diff --git a/materialsrc/editor/comp_cubemap_parallax.blend b/materialsrc/editor/comp_cubemap_parallax.blend
new file mode 100644
index 000000000..5cde2601a
Binary files /dev/null and b/materialsrc/editor/comp_cubemap_parallax.blend differ
diff --git a/materialsrc/editor/comp_cubemap_parallax.pdn b/materialsrc/editor/comp_cubemap_parallax.pdn
new file mode 100644
index 000000000..5530c4dbb
Binary files /dev/null and b/materialsrc/editor/comp_cubemap_parallax.pdn differ
diff --git a/materialsrc/models/editor/ts/sky_camera.pdn b/materialsrc/models/editor/ts/sky_camera.pdn
new file mode 100644
index 000000000..f5aabe3df
Binary files /dev/null and b/materialsrc/models/editor/ts/sky_camera.pdn differ
diff --git a/materialsrc/tools/toolspropcombine.pdn b/materialsrc/tools/toolspropcombine.pdn
index efacf9da7..6e60ca7d3 100644
Binary files a/materialsrc/tools/toolspropcombine.pdn and b/materialsrc/tools/toolspropcombine.pdn differ
diff --git a/materialsrc/tools/toolspropcombine.tga b/materialsrc/tools/toolspropcombine.tga
index b04c4e61b..55328e379 100644
Binary files a/materialsrc/tools/toolspropcombine.tga and b/materialsrc/tools/toolspropcombine.tga differ
diff --git a/modelsrc/editor/axis_helper_white/axis_helper.smd b/modelsrc/editor/axis_helper_white/axis_helper.smd
new file mode 100644
index 000000000..39de15057
--- /dev/null
+++ b/modelsrc/editor/axis_helper_white/axis_helper.smd
@@ -0,0 +1,618 @@
+version 1
+nodes
+0 "root" -1
+end
+skeleton
+time 0
+0 0.000000 0.000000 0.000000 0.000000 1.570790 0.000000
+end
+triangles
+axis_helper_white
+0 0.356750 5.500000 0.000000 0.706345 -0.046407 0.706345 0.002002 0.832332 1 0 1.000000
+0 0.000000 5.500000 0.356750 0.706345 -0.046407 0.706345 0.165666 0.832332 1 0 1.000000
+0 0.000000 0.070000 0.000000 0.706345 -0.046407 0.706345 0.165666 0.502002 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.776880 0.021830 0.000000 -1.000000 0.000000 0.728657 0.880334 1 0 1.000000
+0 0.000000 -0.776880 -0.034950 0.000000 -1.000000 0.000000 0.765664 0.843327 1 0 1.000000
+0 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.000000 0.765664 0.880334 1 0 1.000000
+axis_helper_white
+0 0.000000 -0.776880 -0.034950 0.000000 -1.000000 0.000000 0.713667 0.843327 1 0 1.000000
+0 0.026680 -0.776880 0.021830 0.000000 -1.000000 0.000000 0.676660 0.880334 1 0 1.000000
+0 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.000000 0.713667 0.880334 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.776880 0.021830 0.000000 -1.000000 0.000000 0.713667 0.895324 1 0 1.000000
+0 -0.026680 -0.776880 0.021830 0.000000 -1.000000 0.000000 0.676660 0.932331 1 0 1.000000
+0 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.000000 0.713667 0.932331 1 0 1.000000
+axis_helper_white
+0 0.026680 0.931410 0.021830 0.000000 1.000000 0.000000 0.708670 0.838330 1 0 1.000000
+0 0.000000 0.931410 -0.034950 0.000000 1.000000 0.000000 0.671663 0.875337 1 0 1.000000
+0 0.000000 0.931410 0.000000 0.000000 1.000000 0.000000 0.671663 0.838330 1 0 1.000000
+axis_helper_white
+0 0.000000 0.931410 -0.034950 0.000000 1.000000 0.000000 0.723660 0.875337 1 0 1.000000
+0 -0.026680 0.931410 0.021830 0.000000 1.000000 0.000000 0.760668 0.838330 1 0 1.000000
+0 0.000000 0.931410 0.000000 0.000000 1.000000 0.000000 0.723660 0.838330 1 0 1.000000
+axis_helper_white
+0 -0.026680 0.931410 0.021830 0.000000 1.000000 0.000000 0.671663 0.927334 1 0 1.000000
+0 0.026680 0.931410 0.021830 0.000000 1.000000 0.000000 0.708670 0.890327 1 0 1.000000
+0 0.000000 0.931410 0.000000 0.000000 1.000000 0.000000 0.671663 0.890327 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.776880 0.021830 0.905064 0.000000 -0.425275 0.665666 0.873999 1 0 1.000000
+0 0.000000 -0.776880 -0.034950 0.905064 0.000000 -0.425275 0.665666 0.856169 1 0 1.000000
+0 0.026680 0.931410 0.021830 0.905064 0.000000 -0.425275 0.335335 0.873999 1 0 1.000000
+axis_helper_white
+0 0.000000 -0.776880 -0.034950 0.905064 0.000000 -0.425275 0.853166 0.502002 1 0 1.000000
+0 0.000000 0.931410 -0.034950 0.905064 0.000000 -0.425275 0.853166 0.832332 1 0 1.000000
+0 0.026680 0.931410 0.021830 0.905064 0.000000 -0.425275 0.835335 0.832332 1 0 1.000000
+axis_helper_white
+0 0.000000 -0.776880 -0.034950 -0.905064 0.000000 -0.425275 0.665666 0.853166 1 0 1.000000
+0 -0.026680 -0.776880 0.021830 -0.905064 0.000000 -0.425275 0.665666 0.835335 1 0 1.000000
+0 0.000000 0.931410 -0.034950 -0.905064 0.000000 -0.425275 0.335335 0.853166 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.776880 0.021830 -0.905064 0.000000 -0.425275 0.664665 0.834334 1 0 1.000000
+0 -0.026680 0.931410 0.021830 -0.905064 0.000000 -0.425275 0.334334 0.834334 1 0 1.000000
+0 0.000000 0.931410 -0.034950 -0.905064 0.000000 -0.425275 0.334334 0.852165 1 0 1.000000
+axis_helper_white
+0 0.356750 5.500000 0.000000 0.000000 1.000000 0.000000 0.998999 0.498999 1 0 1.000000
+0 0.000000 5.500000 -0.356750 0.000000 1.000000 0.000000 0.835335 0.498999 1 0 1.000000
+0 0.000000 5.500000 0.356750 0.000000 1.000000 0.000000 0.998999 0.335335 1 0 1.000000
+axis_helper_white
+0 0.000000 5.500000 -0.356750 0.000000 1.000000 0.000000 0.997998 0.334334 1 0 1.000000
+0 -0.356750 5.500000 0.000000 0.000000 1.000000 0.000000 0.834334 0.334334 1 0 1.000000
+0 0.000000 5.500000 0.356750 0.000000 1.000000 0.000000 0.834334 0.497998 1 0 1.000000
+axis_helper_white
+0 0.000000 5.500000 0.356750 -0.706345 -0.046407 0.706345 0.335335 0.665666 1 0 1.000000
+0 -0.356750 5.500000 0.000000 -0.706345 -0.046407 0.706345 0.498999 0.665666 1 0 1.000000
+0 0.000000 0.070000 0.000000 -0.706345 -0.046407 0.706345 0.498999 0.335335 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.776880 0.021830 0.000000 0.000000 1.000000 0.665666 0.936499 1 0 1.000000
+0 0.026680 -0.776880 0.021830 0.000000 0.000000 1.000000 0.665666 0.929085 1 0 1.000000
+0 -0.026680 0.931410 0.021830 0.000000 0.000000 1.000000 0.335335 0.936499 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.776880 0.021830 0.000000 0.000000 1.000000 0.335335 0.926082 1 0 1.000000
+0 0.026680 0.931410 0.021830 0.000000 0.000000 1.000000 0.665666 0.926082 1 0 1.000000
+0 -0.026680 0.931410 0.021830 0.000000 0.000000 1.000000 0.665666 0.918669 1 0 1.000000
+axis_helper_white
+0 -0.356750 5.500000 0.000000 -0.706345 -0.046407 -0.706345 0.168669 0.665666 1 0 1.000000
+0 0.000000 5.500000 -0.356750 -0.706345 -0.046407 -0.706345 0.332332 0.665666 1 0 1.000000
+0 0.000000 0.070000 0.000000 -0.706345 -0.046407 -0.706345 0.332332 0.335335 1 0 1.000000
+axis_helper_white
+0 0.000000 5.500000 -0.356750 0.706345 -0.046407 -0.706345 0.331331 0.334334 1 0 1.000000
+0 0.356750 5.500000 0.000000 0.706345 -0.046407 -0.706345 0.167668 0.334334 1 0 1.000000
+0 0.000000 0.070000 0.000000 0.706345 -0.046407 -0.706345 0.167668 0.664665 1 0 1.000000
+axis_helper_white
+0 -0.364710 -5.500000 0.000000 0.000000 -1.000000 0.000000 0.832332 0.832332 1 0 1.000000
+0 0.000000 -5.500000 -0.364710 0.000000 -1.000000 0.000000 0.668669 0.832332 1 0 1.000000
+0 0.000000 -5.500000 0.364710 0.000000 -1.000000 0.000000 0.832332 0.668669 1 0 1.000000
+axis_helper_white
+0 0.000000 -5.500000 -0.364710 0.000000 -1.000000 0.000000 0.831331 0.667668 1 0 1.000000
+0 0.364710 -5.500000 0.000000 0.000000 -1.000000 0.000000 0.667668 0.667668 1 0 1.000000
+0 0.000000 -5.500000 0.364710 0.000000 -1.000000 0.000000 0.667668 0.831331 1 0 1.000000
+axis_helper_white
+0 -0.364710 -5.500000 0.000000 -0.706311 0.047440 0.706311 0.832332 0.502002 1 0 1.000000
+0 0.000000 -5.500000 0.364710 -0.706311 0.047440 0.706311 0.832332 0.665666 1 0 1.000000
+0 0.000000 -0.070000 0.000000 -0.706311 0.047440 0.706311 0.502002 0.665666 1 0 1.000000
+axis_helper_white
+0 0.000000 -5.500000 0.364710 0.706311 0.047440 0.706311 0.668669 0.332332 1 0 1.000000
+0 0.364710 -5.500000 0.000000 0.706311 0.047440 0.706311 0.832332 0.332332 1 0 1.000000
+0 0.000000 -0.070000 0.000000 0.706311 0.047440 0.706311 0.832332 0.002002 1 0 1.000000
+axis_helper_white
+0 0.364710 -5.500000 0.000000 0.706311 0.047440 -0.706311 0.665666 0.002002 1 0 1.000000
+0 0.000000 -5.500000 -0.364710 0.706311 0.047440 -0.706311 0.665666 0.165666 1 0 1.000000
+0 0.000000 -0.070000 0.000000 0.706311 0.047440 -0.706311 0.335335 0.165666 1 0 1.000000
+axis_helper_white
+0 0.000000 -5.500000 -0.364710 -0.706311 0.047440 -0.706311 0.334334 0.164665 1 0 1.000000
+0 -0.364710 -5.500000 0.000000 -0.706311 0.047440 -0.706311 0.334334 0.001001 1 0 1.000000
+0 0.000000 -0.070000 0.000000 -0.706311 0.047440 -0.706311 0.664665 0.001001 1 0 1.000000
+axis_helper_white
+0 -0.356750 5.500000 0.000000 -0.706345 -0.046407 0.706345 0.002002 0.832332 1 0 1.000000
+0 0.000000 0.070000 0.000000 -0.706345 -0.046407 0.706345 0.165666 0.502002 1 0 1.000000
+0 0.000000 5.500000 0.356750 -0.706345 -0.046407 0.706345 0.165666 0.832332 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.776880 0.021830 0.000000 -1.000000 0.000000 0.728657 0.880334 1 0 1.000000
+0 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.000000 0.765664 0.880334 1 0 1.000000
+0 0.000000 -0.776880 -0.034950 0.000000 -1.000000 0.000000 0.765664 0.843327 1 0 1.000000
+axis_helper_white
+0 0.000000 -0.776880 -0.034950 0.000000 -1.000000 0.000000 0.713667 0.843327 1 0 1.000000
+0 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.000000 0.713667 0.880334 1 0 1.000000
+0 -0.026680 -0.776880 0.021830 0.000000 -1.000000 0.000000 0.676660 0.880334 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.776880 0.021830 0.000000 -1.000000 0.000000 0.713667 0.895324 1 0 1.000000
+0 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.000000 0.713667 0.932331 1 0 1.000000
+0 0.026680 -0.776880 0.021830 0.000000 -1.000000 0.000000 0.676660 0.932331 1 0 1.000000
+axis_helper_white
+0 -0.026680 0.931410 0.021830 0.000000 1.000000 0.000000 0.708670 0.838330 1 0 1.000000
+0 0.000000 0.931410 0.000000 0.000000 1.000000 0.000000 0.671663 0.838330 1 0 1.000000
+0 0.000000 0.931410 -0.034950 0.000000 1.000000 0.000000 0.671663 0.875337 1 0 1.000000
+axis_helper_white
+0 0.000000 0.931410 -0.034950 0.000000 1.000000 0.000000 0.723660 0.875337 1 0 1.000000
+0 0.000000 0.931410 0.000000 0.000000 1.000000 0.000000 0.723660 0.838330 1 0 1.000000
+0 0.026680 0.931410 0.021830 0.000000 1.000000 0.000000 0.760668 0.838330 1 0 1.000000
+axis_helper_white
+0 0.026680 0.931410 0.021830 0.000000 1.000000 0.000000 0.671663 0.927334 1 0 1.000000
+0 0.000000 0.931410 0.000000 0.000000 1.000000 0.000000 0.671663 0.890327 1 0 1.000000
+0 -0.026680 0.931410 0.021830 0.000000 1.000000 0.000000 0.708670 0.890327 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.776880 0.021830 -0.905064 0.000000 -0.425275 0.665666 0.873999 1 0 1.000000
+0 -0.026680 0.931410 0.021830 -0.905064 0.000000 -0.425275 0.335335 0.873999 1 0 1.000000
+0 0.000000 -0.776880 -0.034950 -0.905064 0.000000 -0.425275 0.665666 0.856169 1 0 1.000000
+axis_helper_white
+0 0.000000 -0.776880 -0.034950 -0.905064 0.000000 -0.425275 0.853166 0.502002 1 0 1.000000
+0 -0.026680 0.931410 0.021830 -0.905064 0.000000 -0.425275 0.835335 0.832332 1 0 1.000000
+0 0.000000 0.931410 -0.034950 -0.905064 0.000000 -0.425275 0.853166 0.832332 1 0 1.000000
+axis_helper_white
+0 0.000000 -0.776880 -0.034950 0.905064 0.000000 -0.425275 0.665666 0.853166 1 0 1.000000
+0 0.000000 0.931410 -0.034950 0.905064 0.000000 -0.425275 0.335335 0.853166 1 0 1.000000
+0 0.026680 -0.776880 0.021830 0.905064 0.000000 -0.425275 0.665666 0.835335 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.776880 0.021830 0.905064 0.000000 -0.425275 0.664665 0.834334 1 0 1.000000
+0 0.000000 0.931410 -0.034950 0.905064 0.000000 -0.425275 0.334334 0.852165 1 0 1.000000
+0 0.026680 0.931410 0.021830 0.905064 0.000000 -0.425275 0.334334 0.834334 1 0 1.000000
+axis_helper_white
+0 -0.356750 5.500000 0.000000 0.000000 1.000000 0.000000 0.998999 0.498999 1 0 1.000000
+0 0.000000 5.500000 0.356750 0.000000 1.000000 0.000000 0.998999 0.335335 1 0 1.000000
+0 0.000000 5.500000 -0.356750 0.000000 1.000000 0.000000 0.835335 0.498999 1 0 1.000000
+axis_helper_white
+0 0.000000 5.500000 -0.356750 0.000000 1.000000 0.000000 0.997998 0.334334 1 0 1.000000
+0 0.000000 5.500000 0.356750 0.000000 1.000000 0.000000 0.834334 0.497998 1 0 1.000000
+0 0.356750 5.500000 0.000000 0.000000 1.000000 0.000000 0.834334 0.334334 1 0 1.000000
+axis_helper_white
+0 0.000000 5.500000 0.356750 0.706345 -0.046407 0.706345 0.335335 0.665666 1 0 1.000000
+0 0.000000 0.070000 0.000000 0.706345 -0.046407 0.706345 0.498999 0.335335 1 0 1.000000
+0 0.356750 5.500000 0.000000 0.706345 -0.046407 0.706345 0.498999 0.665666 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.776880 0.021830 0.000000 0.000000 1.000000 0.665666 0.936499 1 0 1.000000
+0 0.026680 0.931410 0.021830 0.000000 0.000000 1.000000 0.335335 0.936499 1 0 1.000000
+0 -0.026680 -0.776880 0.021830 0.000000 0.000000 1.000000 0.665666 0.929085 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.776880 0.021830 0.000000 0.000000 1.000000 0.335335 0.926082 1 0 1.000000
+0 0.026680 0.931410 0.021830 0.000000 0.000000 1.000000 0.665666 0.918669 1 0 1.000000
+0 -0.026680 0.931410 0.021830 0.000000 0.000000 1.000000 0.665666 0.926082 1 0 1.000000
+axis_helper_white
+0 0.356750 5.500000 0.000000 0.706345 -0.046407 -0.706345 0.168669 0.665666 1 0 1.000000
+0 0.000000 0.070000 0.000000 0.706345 -0.046407 -0.706345 0.332332 0.335335 1 0 1.000000
+0 0.000000 5.500000 -0.356750 0.706345 -0.046407 -0.706345 0.332332 0.665666 1 0 1.000000
+axis_helper_white
+0 0.000000 5.500000 -0.356750 -0.706345 -0.046407 -0.706345 0.331331 0.334334 1 0 1.000000
+0 0.000000 0.070000 0.000000 -0.706345 -0.046407 -0.706345 0.167668 0.664665 1 0 1.000000
+0 -0.356750 5.500000 0.000000 -0.706345 -0.046407 -0.706345 0.167668 0.334334 1 0 1.000000
+axis_helper_white
+0 0.364710 -5.500000 0.000000 0.000000 -1.000000 0.000000 0.832332 0.832332 1 0 1.000000
+0 0.000000 -5.500000 0.364710 0.000000 -1.000000 0.000000 0.832332 0.668669 1 0 1.000000
+0 0.000000 -5.500000 -0.364710 0.000000 -1.000000 0.000000 0.668669 0.832332 1 0 1.000000
+axis_helper_white
+0 0.000000 -5.500000 -0.364710 0.000000 -1.000000 0.000000 0.831331 0.667668 1 0 1.000000
+0 0.000000 -5.500000 0.364710 0.000000 -1.000000 0.000000 0.667668 0.831331 1 0 1.000000
+0 -0.364710 -5.500000 0.000000 0.000000 -1.000000 0.000000 0.667668 0.667668 1 0 1.000000
+axis_helper_white
+0 0.364710 -5.500000 0.000000 0.706311 0.047440 0.706311 0.832332 0.502002 1 0 1.000000
+0 0.000000 -0.070000 0.000000 0.706311 0.047440 0.706311 0.502002 0.665666 1 0 1.000000
+0 0.000000 -5.500000 0.364710 0.706311 0.047440 0.706311 0.832332 0.665666 1 0 1.000000
+axis_helper_white
+0 0.000000 -5.500000 0.364710 -0.706311 0.047440 0.706311 0.668669 0.332332 1 0 1.000000
+0 0.000000 -0.070000 0.000000 -0.706311 0.047440 0.706311 0.832332 0.002002 1 0 1.000000
+0 -0.364710 -5.500000 0.000000 -0.706311 0.047440 0.706311 0.832332 0.332332 1 0 1.000000
+axis_helper_white
+0 -0.364710 -5.500000 0.000000 -0.706311 0.047440 -0.706311 0.665666 0.002002 1 0 1.000000
+0 0.000000 -0.070000 0.000000 -0.706311 0.047440 -0.706311 0.335335 0.165666 1 0 1.000000
+0 0.000000 -5.500000 -0.364710 -0.706311 0.047440 -0.706311 0.665666 0.165666 1 0 1.000000
+axis_helper_white
+0 0.000000 -5.500000 -0.364710 0.706311 0.047440 -0.706311 0.334334 0.164665 1 0 1.000000
+0 0.000000 -0.070000 0.000000 0.706311 0.047440 -0.706311 0.664665 0.001001 1 0 1.000000
+0 0.364710 -5.500000 0.000000 0.706311 0.047440 -0.706311 0.334334 0.001001 1 0 1.000000
+axis_helper_white
+0 0.356750 0.000000 5.500000 0.706345 -0.706344 -0.046407 0.998999 0.332332 1 0 1.000000
+0 0.000000 -0.356750 5.500000 0.706345 -0.706344 -0.046407 0.835335 0.332332 1 0 1.000000
+0 0.000000 0.000000 0.070000 0.706345 -0.706344 -0.046407 0.998999 0.002002 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.021830 -0.776880 0.000002 0.000000 -1.000000 0.832652 0.880334 1 0 1.000000
+0 0.000000 0.034950 -0.776880 0.000004 0.000000 -1.000000 0.869659 0.843327 1 0 1.000000
+0 0.000000 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.869659 0.880334 1 0 1.000000
+axis_helper_white
+0 0.000000 0.034950 -0.776880 -0.000004 0.000000 -1.000000 0.817662 0.843327 1 0 1.000000
+0 0.026680 -0.021830 -0.776880 -0.000002 0.000000 -1.000000 0.780654 0.880334 1 0 1.000000
+0 0.000000 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.817662 0.880334 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.021830 -0.776880 -0.000002 0.000000 -1.000000 0.817662 0.895324 1 0 1.000000
+0 -0.026680 -0.021830 -0.776880 0.000002 0.000000 -1.000000 0.780654 0.932331 1 0 1.000000
+0 0.000000 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.817662 0.932331 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.021830 0.931410 0.000000 0.000000 1.000000 0.728657 0.932331 1 0 1.000000
+0 0.000000 0.034950 0.931410 0.000000 0.000000 1.000000 0.765664 0.895324 1 0 1.000000
+0 0.000000 -0.000000 0.931410 0.000000 0.000000 1.000000 0.765664 0.932331 1 0 1.000000
+axis_helper_white
+0 0.000000 0.034950 0.931410 0.000000 0.000000 1.000000 0.723660 0.927334 1 0 1.000000
+0 -0.026680 -0.021830 0.931410 0.000000 0.000000 1.000000 0.760668 0.890327 1 0 1.000000
+0 0.000000 -0.000000 0.931410 0.000000 0.000000 1.000000 0.723660 0.890327 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.021830 0.931410 0.000000 0.000000 1.000000 0.921656 0.843327 1 0 1.000000
+0 0.026680 -0.021830 0.931410 0.000000 0.000000 1.000000 0.884649 0.880334 1 0 1.000000
+0 0.000000 -0.000000 0.931410 0.000000 0.000000 1.000000 0.921656 0.880334 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.021830 -0.776880 0.905064 0.425275 0.000000 0.873999 0.832332 1 0 1.000000
+0 0.000000 0.034950 -0.776880 0.905064 0.425275 0.000000 0.856169 0.832332 1 0 1.000000
+0 0.026680 -0.021830 0.931410 0.905064 0.425275 0.000000 0.873999 0.502002 1 0 1.000000
+axis_helper_white
+0 0.000000 0.034950 -0.776880 0.905064 0.425275 0.000000 0.834334 0.831331 1 0 1.000000
+0 0.000000 0.034950 0.931410 0.905064 0.425275 0.000000 0.834334 0.501001 1 0 1.000000
+0 0.026680 -0.021830 0.931410 0.905064 0.425275 0.000000 0.852165 0.501001 1 0 1.000000
+axis_helper_white
+0 0.000000 0.034950 -0.776880 -0.905064 0.425275 0.000000 0.665666 0.894832 1 0 1.000000
+0 -0.026680 -0.021830 -0.776880 -0.905064 0.425275 0.000000 0.665666 0.877002 1 0 1.000000
+0 0.000000 0.034950 0.931410 -0.905064 0.425275 0.000000 0.335335 0.894832 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.021830 -0.776880 -0.905064 0.425275 0.000000 0.664665 0.876001 1 0 1.000000
+0 -0.026680 -0.021830 0.931410 -0.905064 0.425275 0.000000 0.334334 0.876001 1 0 1.000000
+0 0.000000 0.034950 0.931410 -0.905064 0.425275 0.000000 0.334334 0.893831 1 0 1.000000
+axis_helper_white
+0 0.356750 0.000000 5.500000 0.000000 0.000000 1.000000 0.665666 0.832332 1 0 1.000000
+0 0.000000 0.356750 5.500000 0.000000 0.000000 1.000000 0.502002 0.832332 1 0 1.000000
+0 0.000000 -0.356750 5.500000 0.000000 0.000000 1.000000 0.665666 0.668669 1 0 1.000000
+axis_helper_white
+0 0.000000 0.356750 5.500000 0.000000 0.000000 1.000000 0.664665 0.667668 1 0 1.000000
+0 -0.356750 0.000000 5.500000 0.000000 0.000000 1.000000 0.501001 0.667668 1 0 1.000000
+0 0.000000 -0.356750 5.500000 0.000000 0.000000 1.000000 0.501001 0.831331 1 0 1.000000
+axis_helper_white
+0 0.000000 -0.356750 5.500000 -0.706345 -0.706344 -0.046407 0.497998 0.334334 1 0 1.000000
+0 -0.356750 0.000000 5.500000 -0.706345 -0.706344 -0.046407 0.334334 0.334334 1 0 1.000000
+0 0.000000 0.000000 0.070000 -0.706345 -0.706344 -0.046407 0.334334 0.664665 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.021830 -0.776880 0.000000 -1.000000 -0.000000 0.884416 0.832332 1 0 1.000000
+0 0.026680 -0.021830 -0.776880 0.000000 -1.000000 -0.000000 0.877002 0.832332 1 0 1.000000
+0 -0.026680 -0.021830 0.931410 0.000000 -1.000000 -0.000000 0.884416 0.502002 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.021830 -0.776880 0.000000 -1.000000 -0.000000 0.664665 0.917668 1 0 1.000000
+0 0.026680 -0.021830 0.931410 0.000000 -1.000000 -0.000000 0.334334 0.917668 1 0 1.000000
+0 -0.026680 -0.021830 0.931410 0.000000 -1.000000 -0.000000 0.334334 0.925081 1 0 1.000000
+axis_helper_white
+0 -0.356750 0.000000 5.500000 -0.706344 0.706345 -0.046407 0.502002 0.498999 1 0 1.000000
+0 0.000000 0.356750 5.500000 -0.706344 0.706345 -0.046407 0.665666 0.498999 1 0 1.000000
+0 0.000000 0.000000 0.070000 -0.706344 0.706345 -0.046407 0.665666 0.168669 1 0 1.000000
+axis_helper_white
+0 0.000000 0.356750 5.500000 0.706344 0.706345 -0.046407 0.498999 0.832332 1 0 1.000000
+0 0.356750 0.000000 5.500000 0.706344 0.706345 -0.046407 0.498999 0.668669 1 0 1.000000
+0 0.000000 0.000000 0.070000 0.706344 0.706345 -0.046407 0.168669 0.832332 1 0 1.000000
+axis_helper_white
+0 -0.364710 0.000000 -5.500000 0.000000 0.000000 -1.000000 0.832332 0.498999 1 0 1.000000
+0 0.000000 0.364710 -5.500000 0.000000 0.000000 -1.000000 0.832332 0.335335 1 0 1.000000
+0 0.000000 -0.364710 -5.500000 0.000000 0.000000 -1.000000 0.668669 0.498999 1 0 1.000000
+axis_helper_white
+0 0.000000 0.364710 -5.500000 0.000002 0.000000 -1.000000 0.165666 0.835335 1 0 1.000000
+0 0.364710 0.000000 -5.500000 0.000002 0.000000 -1.000000 0.165666 0.998999 1 0 1.000000
+0 0.000000 -0.364710 -5.500000 0.000002 0.000000 -1.000000 0.002002 0.998999 1 0 1.000000
+axis_helper_white
+0 -0.364710 0.000000 -5.500000 -0.706310 -0.706311 0.047440 0.498999 0.168669 1 0 1.000000
+0 0.000000 -0.364710 -5.500000 -0.706310 -0.706311 0.047440 0.498999 0.332332 1 0 1.000000
+0 0.000000 0.000000 -0.070000 -0.706310 -0.706311 0.047440 0.168669 0.332332 1 0 1.000000
+axis_helper_white
+0 0.000000 -0.364710 -5.500000 0.706310 -0.706311 0.047440 0.831331 0.001001 1 0 1.000000
+0 0.364710 0.000000 -5.500000 0.706310 -0.706311 0.047440 0.667668 0.001001 1 0 1.000000
+0 0.000000 0.000000 -0.070000 0.706310 -0.706311 0.047440 0.667668 0.331331 1 0 1.000000
+axis_helper_white
+0 0.364710 0.000000 -5.500000 0.706311 0.706310 0.047440 0.332332 0.165666 1 0 1.000000
+0 0.000000 0.364710 -5.500000 0.706311 0.706310 0.047440 0.332332 0.002002 1 0 1.000000
+0 0.000000 0.000000 -0.070000 0.706311 0.706310 0.047440 0.002002 0.165666 1 0 1.000000
+axis_helper_white
+0 0.000000 0.364710 -5.500000 -0.706311 0.706310 0.047440 0.501001 0.664665 1 0 1.000000
+0 -0.364710 0.000000 -5.500000 -0.706311 0.706310 0.047440 0.501001 0.501001 1 0 1.000000
+0 0.000000 0.000000 -0.070000 -0.706311 0.706310 0.047440 0.831331 0.501001 1 0 1.000000
+axis_helper_white
+0 -0.356750 0.000000 5.500000 -0.706345 -0.706344 -0.046407 0.998999 0.332332 1 0 1.000000
+0 0.000000 0.000000 0.070000 -0.706345 -0.706344 -0.046407 0.998999 0.002002 1 0 1.000000
+0 0.000000 -0.356750 5.500000 -0.706345 -0.706344 -0.046407 0.835335 0.332332 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.021830 -0.776880 -0.000002 0.000000 -1.000000 0.832652 0.880334 1 0 1.000000
+0 0.000000 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.869659 0.880334 1 0 1.000000
+0 0.000000 0.034950 -0.776880 -0.000004 0.000000 -1.000000 0.869659 0.843327 1 0 1.000000
+axis_helper_white
+0 0.000000 0.034950 -0.776880 0.000004 0.000000 -1.000000 0.817662 0.843327 1 0 1.000000
+0 0.000000 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.817662 0.880334 1 0 1.000000
+0 -0.026680 -0.021830 -0.776880 0.000002 0.000000 -1.000000 0.780654 0.880334 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.021830 -0.776880 0.000002 0.000000 -1.000000 0.817662 0.895324 1 0 1.000000
+0 0.000000 0.000000 -0.776880 0.000000 0.000000 -1.000000 0.817662 0.932331 1 0 1.000000
+0 0.026680 -0.021830 -0.776880 -0.000002 0.000000 -1.000000 0.780654 0.932331 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.021830 0.931410 0.000000 0.000000 1.000000 0.728657 0.932331 1 0 1.000000
+0 0.000000 -0.000000 0.931410 0.000000 0.000000 1.000000 0.765664 0.932331 1 0 1.000000
+0 0.000000 0.034950 0.931410 0.000000 0.000000 1.000000 0.765664 0.895324 1 0 1.000000
+axis_helper_white
+0 0.000000 0.034950 0.931410 0.000000 0.000000 1.000000 0.723660 0.927334 1 0 1.000000
+0 0.000000 -0.000000 0.931410 0.000000 0.000000 1.000000 0.723660 0.890327 1 0 1.000000
+0 0.026680 -0.021830 0.931410 0.000000 0.000000 1.000000 0.760668 0.890327 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.021830 0.931410 0.000000 0.000000 1.000000 0.921656 0.843327 1 0 1.000000
+0 0.000000 -0.000000 0.931410 0.000000 0.000000 1.000000 0.921656 0.880334 1 0 1.000000
+0 -0.026680 -0.021830 0.931410 0.000000 0.000000 1.000000 0.884649 0.880334 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.021830 -0.776880 -0.905064 0.425275 0.000000 0.873999 0.832332 1 0 1.000000
+0 -0.026680 -0.021830 0.931410 -0.905064 0.425275 0.000000 0.873999 0.502002 1 0 1.000000
+0 0.000000 0.034950 -0.776880 -0.905064 0.425275 0.000000 0.856169 0.832332 1 0 1.000000
+axis_helper_white
+0 0.000000 0.034950 -0.776880 -0.905064 0.425275 0.000000 0.834334 0.831331 1 0 1.000000
+0 -0.026680 -0.021830 0.931410 -0.905064 0.425275 0.000000 0.852165 0.501001 1 0 1.000000
+0 0.000000 0.034950 0.931410 -0.905064 0.425275 0.000000 0.834334 0.501001 1 0 1.000000
+axis_helper_white
+0 0.000000 0.034950 -0.776880 0.905064 0.425275 0.000000 0.665666 0.894832 1 0 1.000000
+0 0.000000 0.034950 0.931410 0.905064 0.425275 0.000000 0.335335 0.894832 1 0 1.000000
+0 0.026680 -0.021830 -0.776880 0.905064 0.425275 0.000000 0.665666 0.877002 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.021830 -0.776880 0.905064 0.425275 0.000000 0.664665 0.876001 1 0 1.000000
+0 0.000000 0.034950 0.931410 0.905064 0.425275 0.000000 0.334334 0.893831 1 0 1.000000
+0 0.026680 -0.021830 0.931410 0.905064 0.425275 0.000000 0.334334 0.876001 1 0 1.000000
+axis_helper_white
+0 -0.356750 0.000000 5.500000 0.000000 0.000000 1.000000 0.665666 0.832332 1 0 1.000000
+0 0.000000 -0.356750 5.500000 0.000000 0.000000 1.000000 0.665666 0.668669 1 0 1.000000
+0 0.000000 0.356750 5.500000 0.000000 0.000000 1.000000 0.502002 0.832332 1 0 1.000000
+axis_helper_white
+0 0.000000 0.356750 5.500000 0.000000 0.000000 1.000000 0.664665 0.667668 1 0 1.000000
+0 0.000000 -0.356750 5.500000 0.000000 0.000000 1.000000 0.501001 0.831331 1 0 1.000000
+0 0.356750 0.000000 5.500000 0.000000 0.000000 1.000000 0.501001 0.667668 1 0 1.000000
+axis_helper_white
+0 0.000000 -0.356750 5.500000 0.706345 -0.706344 -0.046407 0.497998 0.334334 1 0 1.000000
+0 0.000000 0.000000 0.070000 0.706345 -0.706344 -0.046407 0.334334 0.664665 1 0 1.000000
+0 0.356750 0.000000 5.500000 0.706345 -0.706344 -0.046407 0.334334 0.334334 1 0 1.000000
+axis_helper_white
+0 0.026680 -0.021830 -0.776880 0.000000 -1.000000 -0.000000 0.884416 0.832332 1 0 1.000000
+0 0.026680 -0.021830 0.931410 0.000000 -1.000000 -0.000000 0.884416 0.502002 1 0 1.000000
+0 -0.026680 -0.021830 -0.776880 0.000000 -1.000000 -0.000000 0.877002 0.832332 1 0 1.000000
+axis_helper_white
+0 -0.026680 -0.021830 -0.776880 0.000000 -1.000000 -0.000000 0.664665 0.917668 1 0 1.000000
+0 0.026680 -0.021830 0.931410 0.000000 -1.000000 -0.000000 0.334334 0.925081 1 0 1.000000
+0 -0.026680 -0.021830 0.931410 0.000000 -1.000000 -0.000000 0.334334 0.917668 1 0 1.000000
+axis_helper_white
+0 0.356750 0.000000 5.500000 0.706344 0.706345 -0.046407 0.502002 0.498999 1 0 1.000000
+0 0.000000 0.000000 0.070000 0.706344 0.706345 -0.046407 0.665666 0.168669 1 0 1.000000
+0 0.000000 0.356750 5.500000 0.706344 0.706345 -0.046407 0.665666 0.498999 1 0 1.000000
+axis_helper_white
+0 0.000000 0.356750 5.500000 -0.706344 0.706345 -0.046407 0.498999 0.832332 1 0 1.000000
+0 0.000000 0.000000 0.070000 -0.706344 0.706345 -0.046407 0.168669 0.832332 1 0 1.000000
+0 -0.356750 0.000000 5.500000 -0.706344 0.706345 -0.046407 0.498999 0.668669 1 0 1.000000
+axis_helper_white
+0 0.364710 0.000000 -5.500000 0.000000 0.000000 -1.000000 0.832332 0.498999 1 0 1.000000
+0 0.000000 -0.364710 -5.500000 0.000000 0.000000 -1.000000 0.668669 0.498999 1 0 1.000000
+0 0.000000 0.364710 -5.500000 0.000000 0.000000 -1.000000 0.832332 0.335335 1 0 1.000000
+axis_helper_white
+0 0.000000 0.364710 -5.500000 -0.000002 0.000000 -1.000000 0.165666 0.835335 1 0 1.000000
+0 0.000000 -0.364710 -5.500000 -0.000002 0.000000 -1.000000 0.002002 0.998999 1 0 1.000000
+0 -0.364710 0.000000 -5.500000 -0.000002 0.000000 -1.000000 0.165666 0.998999 1 0 1.000000
+axis_helper_white
+0 0.364710 0.000000 -5.500000 0.706310 -0.706311 0.047440 0.498999 0.168669 1 0 1.000000
+0 0.000000 0.000000 -0.070000 0.706310 -0.706311 0.047440 0.168669 0.332332 1 0 1.000000
+0 0.000000 -0.364710 -5.500000 0.706310 -0.706311 0.047440 0.498999 0.332332 1 0 1.000000
+axis_helper_white
+0 0.000000 -0.364710 -5.500000 -0.706310 -0.706311 0.047440 0.831331 0.001001 1 0 1.000000
+0 0.000000 0.000000 -0.070000 -0.706310 -0.706311 0.047440 0.667668 0.331331 1 0 1.000000
+0 -0.364710 0.000000 -5.500000 -0.706310 -0.706311 0.047440 0.667668 0.001001 1 0 1.000000
+axis_helper_white
+0 -0.364710 0.000000 -5.500000 -0.706311 0.706310 0.047440 0.332332 0.165666 1 0 1.000000
+0 0.000000 0.000000 -0.070000 -0.706311 0.706310 0.047440 0.002002 0.165666 1 0 1.000000
+0 0.000000 0.364710 -5.500000 -0.706311 0.706310 0.047440 0.332332 0.002002 1 0 1.000000
+axis_helper_white
+0 0.000000 0.364710 -5.500000 0.706311 0.706310 0.047440 0.501001 0.664665 1 0 1.000000
+0 0.000000 0.000000 -0.070000 0.706311 0.706310 0.047440 0.831331 0.501001 1 0 1.000000
+0 0.364710 0.000000 -5.500000 0.706311 0.706310 0.047440 0.501001 0.501001 1 0 1.000000
+axis_helper_white
+0 5.500000 0.000000 -0.356750 -0.046407 -0.706344 -0.706345 0.834334 0.001001 1 0 1.000000
+0 5.500000 -0.356750 0.000000 -0.046407 -0.706344 -0.706345 0.997998 0.001001 1 0 1.000000
+0 0.070000 0.000000 0.000000 -0.046407 -0.706344 -0.706345 0.834334 0.331331 1 0 1.000000
+axis_helper_white
+0 -0.776880 -0.021830 0.026680 -1.000000 -0.000002 0.000000 0.812665 0.838330 1 0 1.000000
+0 -0.776880 0.034950 0.000000 -1.000000 0.000000 0.000000 0.775658 0.875337 1 0 1.000000
+0 -0.776880 0.000000 0.000000 -1.000000 -0.000001 0.000000 0.775658 0.838330 1 0 1.000000
+axis_helper_white
+0 -0.776880 0.034950 0.000000 -1.000000 0.000000 0.000000 0.827655 0.875337 1 0 1.000000
+0 -0.776880 -0.021830 -0.026680 -1.000000 -0.000002 0.000000 0.864662 0.838330 1 0 1.000000
+0 -0.776880 0.000000 0.000000 -1.000000 -0.000001 0.000000 0.827655 0.838330 1 0 1.000000
+axis_helper_white
+0 -0.776880 -0.021830 -0.026680 -1.000000 -0.000002 0.000000 0.775658 0.927334 1 0 1.000000
+0 -0.776880 -0.021830 0.026680 -1.000000 -0.000002 0.000000 0.812665 0.890327 1 0 1.000000
+0 -0.776880 0.000000 0.000000 -1.000000 -0.000001 0.000000 0.775658 0.890327 1 0 1.000000
+axis_helper_white
+0 0.931410 -0.021830 -0.026680 1.000000 0.000000 0.000000 0.832652 0.932331 1 0 1.000000
+0 0.931410 0.034950 -0.000000 1.000000 0.000000 0.000000 0.869659 0.895324 1 0 1.000000
+0 0.931410 -0.000000 -0.000000 1.000000 0.000000 0.000000 0.869659 0.932331 1 0 1.000000
+axis_helper_white
+0 0.931410 0.034950 -0.000000 1.000000 0.000000 0.000000 0.827655 0.927334 1 0 1.000000
+0 0.931410 -0.021830 0.026680 1.000000 0.000000 0.000000 0.864662 0.890327 1 0 1.000000
+0 0.931410 -0.000000 -0.000000 1.000000 0.000000 0.000000 0.827655 0.890327 1 0 1.000000
+axis_helper_white
+0 0.931410 -0.021830 0.026680 1.000000 0.000000 0.000000 0.879652 0.875337 1 0 1.000000
+0 0.931410 -0.021830 -0.026680 1.000000 0.000000 0.000000 0.916659 0.838330 1 0 1.000000
+0 0.931410 -0.000000 -0.000000 1.000000 0.000000 0.000000 0.879652 0.838330 1 0 1.000000
+axis_helper_white
+0 -0.776880 -0.021830 -0.026680 -0.000000 0.425276 -0.905064 0.334334 0.855168 1 0 1.000000
+0 -0.776880 0.034950 0.000000 -0.000000 0.425276 -0.905064 0.334334 0.872998 1 0 1.000000
+0 0.931410 -0.021830 -0.026680 -0.000000 0.425275 -0.905064 0.664665 0.855168 1 0 1.000000
+axis_helper_white
+0 -0.776880 0.034950 0.000000 -0.000000 0.425276 -0.905064 0.855168 0.831331 1 0 1.000000
+0 0.931410 0.034950 -0.000000 -0.000000 0.425275 -0.905064 0.855168 0.501001 1 0 1.000000
+0 0.931410 -0.021830 -0.026680 -0.000000 0.425275 -0.905064 0.872998 0.501001 1 0 1.000000
+axis_helper_white
+0 -0.776880 0.034950 0.000000 0.000000 0.425275 0.905064 0.665666 0.915666 1 0 1.000000
+0 -0.776880 -0.021830 0.026680 0.000000 0.425275 0.905064 0.665666 0.897835 1 0 1.000000
+0 0.931410 0.034950 -0.000000 0.000000 0.425275 0.905064 0.335335 0.915666 1 0 1.000000
+axis_helper_white
+0 -0.776880 -0.021830 0.026680 0.000000 0.425275 0.905064 0.664665 0.896834 1 0 1.000000
+0 0.931410 -0.021830 0.026680 0.000000 0.425275 0.905064 0.334334 0.896834 1 0 1.000000
+0 0.931410 0.034950 -0.000000 0.000000 0.425275 0.905064 0.334334 0.914665 1 0 1.000000
+axis_helper_white
+0 5.500000 0.000000 -0.356750 1.000000 0.000000 0.000000 0.332332 0.998999 1 0 1.000000
+0 5.500000 0.356750 0.000000 1.000000 0.000000 0.000000 0.168669 0.998999 1 0 1.000000
+0 5.500000 -0.356750 0.000000 1.000000 0.000000 0.000000 0.332332 0.835335 1 0 1.000000
+axis_helper_white
+0 5.500000 0.356750 0.000000 1.000000 0.000000 0.000000 0.331331 0.834334 1 0 1.000000
+0 5.500000 0.000000 0.356750 1.000000 0.000000 0.000000 0.167668 0.834334 1 0 1.000000
+0 5.500000 -0.356750 0.000000 1.000000 0.000000 0.000000 0.167668 0.997998 1 0 1.000000
+axis_helper_white
+0 5.500000 -0.356750 0.000000 -0.046407 -0.706344 0.706346 0.164665 0.501001 1 0 1.000000
+0 5.500000 0.000000 0.356750 -0.046407 -0.706344 0.706346 0.001001 0.501001 1 0 1.000000
+0 0.070000 0.000000 0.000000 -0.046407 -0.706344 0.706346 0.001001 0.831331 1 0 1.000000
+axis_helper_white
+0 -0.776880 -0.021830 0.026680 -0.000000 -1.000000 0.000000 0.334334 0.928084 1 0 1.000000
+0 -0.776880 -0.021830 -0.026680 -0.000000 -1.000000 0.000000 0.334334 0.935498 1 0 1.000000
+0 0.931410 -0.021830 0.026680 -0.000000 -1.000000 0.000000 0.664665 0.928084 1 0 1.000000
+axis_helper_white
+0 -0.776880 -0.021830 -0.026680 -0.000000 -1.000000 0.000000 0.876001 0.831331 1 0 1.000000
+0 0.931410 -0.021830 -0.026680 -0.000000 -1.000000 0.000000 0.876001 0.501001 1 0 1.000000
+0 0.931410 -0.021830 0.026680 -0.000000 -1.000000 0.000000 0.883415 0.501001 1 0 1.000000
+axis_helper_white
+0 5.500000 0.000000 0.356750 -0.046407 0.706345 0.706345 0.167668 0.831331 1 0 1.000000
+0 5.500000 0.356750 0.000000 -0.046407 0.706345 0.706345 0.167668 0.667668 1 0 1.000000
+0 0.070000 0.000000 0.000000 -0.046407 0.706345 0.706345 0.497998 0.667668 1 0 1.000000
+axis_helper_white
+0 5.500000 0.356750 0.000000 -0.046407 0.706345 -0.706344 0.501001 0.167668 1 0 1.000000
+0 5.500000 0.000000 -0.356750 -0.046407 0.706345 -0.706344 0.664665 0.167668 1 0 1.000000
+0 0.070000 0.000000 0.000000 -0.046407 0.706345 -0.706344 0.501001 0.497998 1 0 1.000000
+axis_helper_white
+0 -5.500000 0.000000 0.364710 -1.000000 0.000000 0.000000 0.001001 0.834334 1 0 1.000000
+0 -5.500000 0.364710 0.000000 -1.000000 0.000000 0.000000 0.001001 0.997998 1 0 1.000000
+0 -5.500000 -0.364710 0.000000 -1.000000 0.000000 0.000000 0.164665 0.834334 1 0 1.000000
+axis_helper_white
+0 -5.500000 0.364710 0.000000 -1.000000 0.000000 0.000000 0.667668 0.497998 1 0 1.000000
+0 -5.500000 0.000000 -0.364710 -1.000000 0.000000 0.000000 0.667668 0.334334 1 0 1.000000
+0 -5.500000 -0.364710 0.000000 -1.000000 0.000000 0.000000 0.831331 0.334334 1 0 1.000000
+axis_helper_white
+0 -5.500000 0.000000 0.364710 0.047440 -0.706311 0.706310 0.002002 0.498999 1 0 1.000000
+0 -5.500000 -0.364710 0.000000 0.047440 -0.706311 0.706310 0.165666 0.498999 1 0 1.000000
+0 -0.070000 0.000000 0.000000 0.047440 -0.706311 0.706310 0.165666 0.168669 1 0 1.000000
+axis_helper_white
+0 -5.500000 -0.364710 0.000000 0.047440 -0.706311 -0.706311 0.167668 0.331331 1 0 1.000000
+0 -5.500000 0.000000 -0.364710 0.047440 -0.706311 -0.706311 0.167668 0.167668 1 0 1.000000
+0 -0.070000 0.000000 0.000000 0.047440 -0.706311 -0.706311 0.497998 0.167668 1 0 1.000000
+axis_helper_white
+0 -5.500000 0.000000 -0.364710 0.047440 0.706310 -0.706311 0.001001 0.167668 1 0 1.000000
+0 -5.500000 0.364710 0.000000 0.047440 0.706310 -0.706311 0.164665 0.167668 1 0 1.000000
+0 -0.070000 0.000000 0.000000 0.047440 0.706310 -0.706311 0.001001 0.497998 1 0 1.000000
+axis_helper_white
+0 -5.500000 0.364710 0.000000 0.047440 0.706311 0.706311 0.001001 0.164665 1 0 1.000000
+0 -5.500000 0.000000 0.364710 0.047440 0.706311 0.706311 0.001001 0.001001 1 0 1.000000
+0 -0.070000 0.000000 0.000000 0.047440 0.706311 0.706311 0.331331 0.001001 1 0 1.000000
+axis_helper_white
+0 -5.500000 0.000000 -0.356750 0.046407 -0.706344 -0.706345 0.834334 0.001001 1 0 1.000000
+0 -0.070000 0.000000 0.000000 0.046407 -0.706344 -0.706345 0.834334 0.331331 1 0 1.000000
+0 -5.500000 -0.356750 0.000000 0.046407 -0.706344 -0.706345 0.997998 0.001001 1 0 1.000000
+axis_helper_white
+0 0.776880 -0.021830 0.026680 1.000000 -0.000002 0.000000 0.812665 0.838330 1 0 1.000000
+0 0.776880 0.000000 0.000000 1.000000 -0.000001 0.000000 0.775658 0.838330 1 0 1.000000
+0 0.776880 0.034950 0.000000 1.000000 0.000000 0.000000 0.775658 0.875337 1 0 1.000000
+axis_helper_white
+0 0.776880 0.034950 0.000000 1.000000 0.000000 0.000000 0.827655 0.875337 1 0 1.000000
+0 0.776880 0.000000 0.000000 1.000000 -0.000001 0.000000 0.827655 0.838330 1 0 1.000000
+0 0.776880 -0.021830 -0.026680 1.000000 -0.000002 0.000000 0.864662 0.838330 1 0 1.000000
+axis_helper_white
+0 0.776880 -0.021830 -0.026680 1.000000 -0.000002 0.000000 0.775658 0.927334 1 0 1.000000
+0 0.776880 0.000000 0.000000 1.000000 -0.000001 0.000000 0.775658 0.890327 1 0 1.000000
+0 0.776880 -0.021830 0.026680 1.000000 -0.000002 0.000000 0.812665 0.890327 1 0 1.000000
+axis_helper_white
+0 -0.931410 -0.021830 -0.026680 -1.000000 0.000000 0.000000 0.832652 0.932331 1 0 1.000000
+0 -0.931410 -0.000000 -0.000000 -1.000000 0.000000 0.000000 0.869659 0.932331 1 0 1.000000
+0 -0.931410 0.034950 -0.000000 -1.000000 0.000000 0.000000 0.869659 0.895324 1 0 1.000000
+axis_helper_white
+0 -0.931410 0.034950 -0.000000 -1.000000 0.000000 0.000000 0.827655 0.927334 1 0 1.000000
+0 -0.931410 -0.000000 -0.000000 -1.000000 0.000000 0.000000 0.827655 0.890327 1 0 1.000000
+0 -0.931410 -0.021830 0.026680 -1.000000 0.000000 0.000000 0.864662 0.890327 1 0 1.000000
+axis_helper_white
+0 -0.931410 -0.021830 0.026680 -1.000000 0.000000 0.000000 0.879652 0.875337 1 0 1.000000
+0 -0.931410 -0.000000 -0.000000 -1.000000 0.000000 0.000000 0.879652 0.838330 1 0 1.000000
+0 -0.931410 -0.021830 -0.026680 -1.000000 0.000000 0.000000 0.916659 0.838330 1 0 1.000000
+axis_helper_white
+0 0.776880 -0.021830 -0.026680 0.000000 0.425276 -0.905064 0.334334 0.855168 1 0 1.000000
+0 -0.931410 -0.021830 -0.026680 0.000000 0.425275 -0.905064 0.664665 0.855168 1 0 1.000000
+0 0.776880 0.034950 0.000000 0.000000 0.425276 -0.905064 0.334334 0.872998 1 0 1.000000
+axis_helper_white
+0 0.776880 0.034950 0.000000 0.000000 0.425276 -0.905064 0.855168 0.831331 1 0 1.000000
+0 -0.931410 -0.021830 -0.026680 0.000000 0.425275 -0.905064 0.872998 0.501001 1 0 1.000000
+0 -0.931410 0.034950 -0.000000 0.000000 0.425275 -0.905064 0.855168 0.501001 1 0 1.000000
+axis_helper_white
+0 0.776880 0.034950 0.000000 -0.000000 0.425275 0.905064 0.665666 0.915666 1 0 1.000000
+0 -0.931410 0.034950 -0.000000 -0.000000 0.425275 0.905064 0.335335 0.915666 1 0 1.000000
+0 0.776880 -0.021830 0.026680 -0.000000 0.425275 0.905064 0.665666 0.897835 1 0 1.000000
+axis_helper_white
+0 0.776880 -0.021830 0.026680 -0.000000 0.425275 0.905064 0.664665 0.896834 1 0 1.000000
+0 -0.931410 0.034950 -0.000000 -0.000000 0.425275 0.905064 0.334334 0.914665 1 0 1.000000
+0 -0.931410 -0.021830 0.026680 -0.000000 0.425275 0.905064 0.334334 0.896834 1 0 1.000000
+axis_helper_white
+0 -5.500000 0.000000 -0.356750 -1.000000 0.000000 0.000000 0.332332 0.998999 1 0 1.000000
+0 -5.500000 -0.356750 0.000000 -1.000000 0.000000 0.000000 0.332332 0.835335 1 0 1.000000
+0 -5.500000 0.356750 0.000000 -1.000000 0.000000 0.000000 0.168669 0.998999 1 0 1.000000
+axis_helper_white
+0 -5.500000 0.356750 0.000000 -1.000000 0.000000 0.000000 0.331331 0.834334 1 0 1.000000
+0 -5.500000 -0.356750 0.000000 -1.000000 0.000000 0.000000 0.167668 0.997998 1 0 1.000000
+0 -5.500000 0.000000 0.356750 -1.000000 0.000000 0.000000 0.167668 0.834334 1 0 1.000000
+axis_helper_white
+0 -5.500000 -0.356750 0.000000 0.046407 -0.706344 0.706346 0.164665 0.501001 1 0 1.000000
+0 -0.070000 0.000000 0.000000 0.046407 -0.706344 0.706346 0.001001 0.831331 1 0 1.000000
+0 -5.500000 0.000000 0.356750 0.046407 -0.706344 0.706346 0.001001 0.501001 1 0 1.000000
+axis_helper_white
+0 0.776880 -0.021830 0.026680 0.000000 -1.000000 0.000000 0.334334 0.928084 1 0 1.000000
+0 -0.931410 -0.021830 0.026680 0.000000 -1.000000 0.000000 0.664665 0.928084 1 0 1.000000
+0 0.776880 -0.021830 -0.026680 0.000000 -1.000000 0.000000 0.334334 0.935498 1 0 1.000000
+axis_helper_white
+0 0.776880 -0.021830 -0.026680 0.000000 -1.000000 0.000000 0.876001 0.831331 1 0 1.000000
+0 -0.931410 -0.021830 0.026680 0.000000 -1.000000 0.000000 0.883415 0.501001 1 0 1.000000
+0 -0.931410 -0.021830 -0.026680 0.000000 -1.000000 0.000000 0.876001 0.501001 1 0 1.000000
+axis_helper_white
+0 -5.500000 0.000000 0.356750 0.046407 0.706345 0.706345 0.167668 0.831331 1 0 1.000000
+0 -0.070000 0.000000 0.000000 0.046407 0.706345 0.706345 0.497998 0.667668 1 0 1.000000
+0 -5.500000 0.356750 0.000000 0.046407 0.706345 0.706345 0.167668 0.667668 1 0 1.000000
+axis_helper_white
+0 -5.500000 0.356750 0.000000 0.046407 0.706345 -0.706344 0.501001 0.167668 1 0 1.000000
+0 -0.070000 0.000000 0.000000 0.046407 0.706345 -0.706344 0.501001 0.497998 1 0 1.000000
+0 -5.500000 0.000000 -0.356750 0.046407 0.706345 -0.706344 0.664665 0.167668 1 0 1.000000
+axis_helper_white
+0 5.500000 0.000000 0.364710 1.000000 0.000000 0.000000 0.001001 0.834334 1 0 1.000000
+0 5.500000 -0.364710 0.000000 1.000000 0.000000 0.000000 0.164665 0.834334 1 0 1.000000
+0 5.500000 0.364710 0.000000 1.000000 0.000000 0.000000 0.001001 0.997998 1 0 1.000000
+axis_helper_white
+0 5.500000 0.364710 0.000000 1.000000 0.000000 0.000000 0.667668 0.497998 1 0 1.000000
+0 5.500000 -0.364710 0.000000 1.000000 0.000000 0.000000 0.831331 0.334334 1 0 1.000000
+0 5.500000 0.000000 -0.364710 1.000000 0.000000 0.000000 0.667668 0.334334 1 0 1.000000
+axis_helper_white
+0 5.500000 0.000000 0.364710 -0.047440 -0.706311 0.706310 0.002002 0.498999 1 0 1.000000
+0 0.070000 0.000000 0.000000 -0.047440 -0.706311 0.706310 0.165666 0.168669 1 0 1.000000
+0 5.500000 -0.364710 0.000000 -0.047440 -0.706311 0.706310 0.165666 0.498999 1 0 1.000000
+axis_helper_white
+0 5.500000 -0.364710 0.000000 -0.047440 -0.706311 -0.706311 0.167668 0.331331 1 0 1.000000
+0 0.070000 0.000000 0.000000 -0.047440 -0.706311 -0.706311 0.497998 0.167668 1 0 1.000000
+0 5.500000 0.000000 -0.364710 -0.047440 -0.706311 -0.706311 0.167668 0.167668 1 0 1.000000
+axis_helper_white
+0 5.500000 0.000000 -0.364710 -0.047440 0.706310 -0.706311 0.001001 0.167668 1 0 1.000000
+0 0.070000 0.000000 0.000000 -0.047440 0.706310 -0.706311 0.001001 0.497998 1 0 1.000000
+0 5.500000 0.364710 0.000000 -0.047440 0.706310 -0.706311 0.164665 0.167668 1 0 1.000000
+axis_helper_white
+0 5.500000 0.364710 0.000000 -0.047440 0.706311 0.706311 0.001001 0.164665 1 0 1.000000
+0 0.070000 0.000000 0.000000 -0.047440 0.706311 0.706311 0.331331 0.001001 1 0 1.000000
+0 5.500000 0.000000 0.364710 -0.047440 0.706311 0.706311 0.001001 0.001001 1 0 1.000000
+invisible
+0 0.000000 0.000000 4.000000 0.000000 0.000000 1.000000 0.500000 0.500000 0
+0 -4.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 0.000000 0.500000 0
+0 0.000000 -4.000000 0.000000 0.000000 -1.000000 0.000000 0.500000 0.000000 0
+invisible
+0 4.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.500000 0
+0 0.000000 0.000000 4.000000 0.000000 0.000000 1.000000 0.500000 0.500000 0
+0 0.000000 -4.000000 0.000000 0.000000 -1.000000 0.000000 0.500000 0.000000 0
+invisible
+0 0.000000 -4.000000 0.000000 0.000000 -1.000000 0.000000 0.500000 0.000000 0
+0 0.000000 0.000000 -4.000000 0.000000 0.000000 -1.000000 0.500000 0.500000 0
+0 4.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.500000 0
+invisible
+0 0.000000 0.000000 -4.000000 0.000000 0.000000 -1.000000 0.500000 0.500000 0
+0 0.000000 -4.000000 0.000000 0.000000 -1.000000 0.000000 0.500000 0.000000 0
+0 -4.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 0.000000 0.500000 0
+invisible
+0 0.000000 0.000000 -4.000000 0.000000 0.000000 -1.000000 0.500000 0.500000 0
+0 -4.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 0.000000 0.500000 0
+0 0.000000 4.000000 0.000000 0.000000 1.000000 0.000000 0.500000 1.000000 0
+invisible
+0 -4.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 0.000000 0.500000 0
+0 0.000000 0.000000 4.000000 0.000000 0.000000 1.000000 0.500000 0.500000 0
+0 0.000000 4.000000 0.000000 0.000000 1.000000 0.000000 0.500000 1.000000 0
+invisible
+0 4.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.500000 0
+0 0.000000 4.000000 0.000000 0.000000 1.000000 0.000000 0.500000 1.000000 0
+0 0.000000 0.000000 4.000000 0.000000 0.000000 1.000000 0.500000 0.500000 0
+invisible
+0 4.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.500000 0
+0 0.000000 0.000000 -4.000000 0.000000 0.000000 -1.000000 0.500000 0.500000 0
+0 0.000000 4.000000 0.000000 0.000000 1.000000 0.000000 0.500000 1.000000 0
+end
diff --git a/modelsrc/editor/axis_helper_white/axis_helper_white.qc b/modelsrc/editor/axis_helper_white/axis_helper_white.qc
new file mode 100644
index 000000000..c0f626bf1
--- /dev/null
+++ b/modelsrc/editor/axis_helper_white/axis_helper_white.qc
@@ -0,0 +1,28 @@
+// A version of the axis helper, designed to tint along with sprites etc.
+
+$modelname "editor/axis_helper_white.mdl"
+
+$bodygroup "Body"
+{
+ studio "axis_helper.smd"
+}
+
+
+$surfaceprop "default"
+
+$contents "solid"
+
+$illumposition 0 0 0
+
+$cdmaterials "models\editor\"
+
+$cbox 0 0 0 0 0 0
+
+$bbox -5.5 -5.5 -5.5 5.5 5.5 5.5
+
+$sequence "idle" {
+ "idle.smd"
+ fadein 0.2
+ fadeout 0.2
+ fps 30
+}
diff --git a/modelsrc/editor/axis_helper_white/helper.blend b/modelsrc/editor/axis_helper_white/helper.blend
new file mode 100644
index 000000000..42efe1f63
Binary files /dev/null and b/modelsrc/editor/axis_helper_white/helper.blend differ
diff --git a/modelsrc/editor/axis_helper_white/idle.smd b/modelsrc/editor/axis_helper_white/idle.smd
new file mode 100644
index 000000000..300709ffc
--- /dev/null
+++ b/modelsrc/editor/axis_helper_white/idle.smd
@@ -0,0 +1,9 @@
+// Created by Crowbar 0.74
+version 1
+nodes
+ 0 "root" -1
+end
+skeleton
+ time 0
+ 0 0.000000 0.000000 0.000000 0 0 0
+end
diff --git a/postcompiler.spec b/postcompiler.spec
index f5b2dc2b2..2ad857077 100644
--- a/postcompiler.spec
+++ b/postcompiler.spec
@@ -1,6 +1,8 @@
"""Build the postcompiler script."""
+import shutil
from pathlib import Path
+from PyInstaller.utils.hooks import collect_submodules
import versioningit
# PyInstaller-injected.
@@ -23,14 +25,9 @@ with open(Path(SPECPATH, 'src', 'hammeraddons', '_version.py'), 'w') as f:
f.write(f'__version__ = {version!r}\n')
DATAS = [
- (str(file), str(file.relative_to(root).parent))
- for file in (root / 'transforms').rglob('*.py')
-] + [
(str(root / 'crowbar_command/Crowbar.exe'), '.'),
(str(root / 'crowbar_command/FluentCommandLineParser.dll'), '.'),
]
-for src, dest in DATAS:
- print(src, '->', dest)
a = Analysis(
['src/hammeraddons/postcompiler.py'],
@@ -38,12 +35,15 @@ a = Analysis(
datas=DATAS,
hiddenimports=[
# Ensure these modules are available for plugins.
- 'abc', 'array', 'base64', 'binascii', 'binhex', 'graphlib',
+ 'abc', 'array', 'base64', 'binascii', 'graphlib',
'bisect', 'colorsys', 'collections', 'csv', 'datetime', 'contextlib',
'decimal', 'difflib', 'enum', 'fractions', 'functools',
'io', 'itertools', 'json', 'math', 'random', 're',
'statistics', 'string', 'struct',
- 'srctools', 'attr', 'attrs',
+ *collect_submodules('srctools', filter=lambda name: 'scripts' not in name),
+ *collect_submodules('attr'),
+ *collect_submodules('attrs'),
+ *collect_submodules('hammeraddons'),
],
excludes=[
'IPython', # Via trio
@@ -60,6 +60,8 @@ exe = EXE(
name='postcompiler',
debug=False,
bootloader_ignore_signals=False,
+ # Don't use bin/, in case someone puts this right in a game dir.
+ contents_directory='binaries',
strip=False,
upx=True,
console=True,
@@ -74,3 +76,11 @@ coll = COLLECT(
upx=True,
name='postcompiler'
)
+
+# Copy transforms to the same place as the EXE, not into the binaries subfolder.
+app_folder = Path(coll.name)
+for file in (root / 'transforms').rglob('*.py'):
+ dest = app_folder / file.relative_to(root)
+ print(file, '->', dest)
+ dest.parent.mkdir(parents=True, exist_ok=True)
+ shutil.copy(file, dest)
diff --git a/requirements.txt b/requirements.txt
index df31fa5b1..2540481c2 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
attrs >= 21.4.0
typing_extensions >= 4.2.0
-srctools >= 2.3.9
+srctools >= 2.3.15
trio >= 0.20.0
trio-typing >= 0.7.0
-pyinstaller >= 5.7.0
+pyinstaller >= 6.1.0
versioningit >= 2.1.0
diff --git a/sprite_font.py b/sprite_font.py
index 1e6de273a..6b483b84e 100644
--- a/sprite_font.py
+++ b/sprite_font.py
@@ -1,11 +1,20 @@
"""Generate entity sprite text images."""
from pathlib import Path
-from PIL import Image
+from PIL import Image, ImageChops
+from srctools import conv_bool
from collections import namedtuple
import sys
+try:
+ text = sys.argv[1]
+except IndexError:
+ text = input('Enter text to produce: ')
+
+golden = text.startswith("comp_")
+print('Gold' if golden else 'White', 'text selected')
+
Char = namedtuple('Char', 'img width')
LETTERS = {}
@@ -14,18 +23,16 @@
letter = file.name[0]
img = Image.open(file)
img.load()
+ if golden:
+ img = ImageChops.multiply(img, Image.new('RGBA', img.size, (224, 174, 0, 255)))
LETTERS[letter] = Char(img, img.width-1)
-try:
- text = sys.argv[1]
-except IndexError:
- text = input('Enter text to produce: ')
-
chars = list(map(LETTERS.__getitem__, text.lower()))
width = sum(c.width for c in chars) + 1
+height = max(c.img.height for c in chars)
-img = Image.new('RGBA', (width, 11), (0, 0, 0, 0))
+img = Image.new('RGBA', (width, height), (0, 0, 0, 0))
offset = 0
for ch in chars:
diff --git a/src/hammeraddons/__init__.py b/src/hammeraddons/__init__.py
index 39d760fba..cf7fbc54c 100644
--- a/src/hammeraddons/__init__.py
+++ b/src/hammeraddons/__init__.py
@@ -1,4 +1,8 @@
"""Postcompiler logic."""
+from pathlib import Path
+import sys
+
+
try:
from ._version import __version__
except ImportError:
@@ -8,3 +12,13 @@
import sys as _sys
del _sys.modules[_version.__name__] # type: ignore # noqa
del _version, _sys # type: ignore # noqa
+
+
+try:
+ # PyInstaller sets this attribute.
+ BINS_PATH = Path(sys._MEIPASS) # noqa
+ FROZEN = True
+except AttributeError:
+ # Root directory is up thrice from postcompiler.py.
+ BINS_PATH = Path(sys.argv[0], '..', '..', '..').resolve()
+ FROZEN = False
diff --git a/src/hammeraddons/bsp_transform/__init__.py b/src/hammeraddons/bsp_transform/__init__.py
index acf85bbe1..122a19174 100644
--- a/src/hammeraddons/bsp_transform/__init__.py
+++ b/src/hammeraddons/bsp_transform/__init__.py
@@ -1,39 +1,34 @@
"""Transformations that can be applied to the BSP file."""
+from typing import Awaitable, Callable, Dict, FrozenSet, List, Mapping, Optional, Tuple, Union
+from typing_extensions import TypeAlias
import warnings
-from typing import Awaitable, Callable, Dict, FrozenSet, List, Mapping, Optional, Tuple
from pathlib import Path
import inspect
-from srctools import FGD, VMF, EmptyMapping, Entity, FileSystem, Keyvalues, Output, conv_bool
+
+from srctools import FGD, VMF, EmptyMapping, Entity, FileSystem, Keyvalues, Output
from srctools.bsp import BSP
from srctools.game import Game
from srctools.logger import get_logger
from srctools.packlist import PackList
+from hammeraddons.bsp_transform.common import (
+ check_control_enabled,
+ parse_numeric_specifier, NumericSpecifier, NumericOp
+)
LOGGER = get_logger(__name__, 'bsp_trans')
+RemapFunc: TypeAlias = Callable[[Entity, Output], List[Output]]
__all__ = [
- 'check_control_enabled',
'Context', 'trans', 'run_transformations',
'TransFunc', 'TRANSFORMS',
+ # Utils:
+ 'check_control_enabled',
+ 'parse_numeric_specifier', 'NumericOp', 'NumericSpecifier',
]
-def check_control_enabled(ent: Entity) -> bool:
- """Implement the bahaviour of ControlEnables - control_type and control_value.
-
- This allows providing a fixup value, and optionally inverting it.
- """
- # If ctrl_type is 0, ctrl_value needs to be 1 to be enabled.
- # If ctrl_type is 1, ctrl_value needs to be 0 to be enabled.
- if 'ctrl_type' in ent:
- return conv_bool(ent['ctrl_type'], False) != conv_bool(ent['ctrl_value'], True)
- else:
- # Missing, assume true if ctrl_value also isn't present.
- return conv_bool(ent['ctrl_value'], True)
-
-
class Context:
"""Bundles information useful for each transformation.
@@ -47,8 +42,9 @@ def __init__(
bsp: BSP,
game: Game,
*,
- studiomdl_loc: Optional[Path]=None,
- tags: FrozenSet[str]=frozenset(),
+ studiomdl_loc: Optional[Path] = None,
+ tags: FrozenSet[str] = frozenset(),
+ modelcompile_dump: Optional[Path] = None,
) -> None:
self.sys = filesys
self.vmf = vmf
@@ -57,11 +53,13 @@ def __init__(
self.bsp_path = Path(bsp.filename)
self._fgd: Optional[FGD] = None
self.tags = tags
+ self.modelcompile_dump = modelcompile_dump
self.game = game
self.studiomdl = studiomdl_loc
self.config = Keyvalues.root()
- self._io_remaps: Dict[Tuple[str, str], Tuple[List[Output], bool]] = {}
+ self._io_remaps: Dict[Tuple[str, str], Tuple[List[Union[Output, RemapFunc]], bool]] = {}
+ self._allow_remaps = True
self._ent_code: Dict[Entity, str] = {}
@property
@@ -71,6 +69,24 @@ def fgd(self) -> FGD:
self._fgd = FGD.engine_dbase()
return self._fgd
+ def _add_io_remap(
+ self, name: str, inp_name: str,
+ value: Union[Output, RemapFunc],
+ remove: bool,
+ ) -> None:
+ if not self._allow_remaps:
+ raise RecursionError('Cannot add more remaps from a remap callback!')
+ key = (name, inp_name)
+ try:
+ out_list, old_remove = self._io_remaps[key]
+ except KeyError:
+ self._io_remaps[key] = ([value], remove)
+ else:
+ out_list.append(value)
+ # Only allow removing if all remaps have requested it.
+ if old_remove and not remove:
+ self._io_remaps[key] = (out_list, False)
+
def add_io_remap(self, name: str, *outputs: Output, remove: bool=True) -> None:
"""Register an output to be replaced.
@@ -87,19 +103,23 @@ def add_io_remap(self, name: str, *outputs: Output, remove: bool=True) -> None:
for out in outputs:
inp_name = out.output.casefold()
out.output = ''
- key = (name, inp_name)
- try:
- out_list, old_remove = self._io_remaps[key]
- except KeyError:
- self._io_remaps[key] = ([out], remove)
- else:
- out_list.append(out)
- # Only allow removing if all remaps have requested it.
- if old_remove and not remove:
- self._io_remaps[key] = (out_list, False)
+ self._add_io_remap(name, inp_name, out, remove)
+
+ def add_io_remap_func(self, name: str, inp_name: str, func: RemapFunc, remove: bool = True) -> None:
+ """Register an output to be dynamically replaced, using a function.
+
+ This allows varying the output for each input entity. The entity and the relevant output
+ are passed to the function for reference, but the output and entity should not be modified.
+ Instead, return new outputs from the function, which are merged with the original.
+ """
+ if name and inp_name:
+ self._add_io_remap(name.casefold(), inp_name.casefold(), func, remove)
def add_io_remap_removal(self, name: str, inp_name: str) -> None:
"""Special case of add_io_remap, request that this output should be removed."""
+ if not self._allow_remaps:
+ raise RecursionError('Cannot add more remaps from a remap callback!')
+
key = (name.casefold(), inp_name.casefold())
if key not in self._io_remaps:
self._io_remaps[key] = ([], True)
@@ -147,12 +167,17 @@ async def run_transformations(
pack: PackList,
bsp: BSP,
game: Game,
- studiomdl_loc: Optional[Path]=None,
- config: Mapping[str, Keyvalues]=EmptyMapping,
+ studiomdl_loc: Optional[Path] = None,
+ config: Mapping[str, Keyvalues] = EmptyMapping,
tags: FrozenSet[str] = frozenset(),
+ modelcompile_dump: Optional[Path] = None,
) -> None:
"""Run all transformations."""
- context = Context(filesys, vmf, pack, bsp, game, studiomdl_loc=studiomdl_loc, tags=tags)
+ context = Context(
+ filesys, vmf, pack, bsp, game,
+ studiomdl_loc=studiomdl_loc, tags=tags,
+ modelcompile_dump=modelcompile_dump,
+ )
for func_name, func in sorted(
TRANSFORMS.items(),
@@ -170,52 +195,72 @@ async def run_transformations(
LOGGER.info('Injecting VScript code...')
for ent, code in context._ent_code.items():
init_scripts = ent['vscripts'].split()
+ if init_scripts:
+ # If both a regular entity script and injected script are present,
+ # the call chaining mechanism used for Precache & OnPostSpawn can malfunction.
+ # If the entity script defines either, running the second script will make the
+ # chainer pick it up again, calling the function twice. So edit the script to
+ # first blank out the functions.
+ code = 'OnPostSpawn<-Precache<-function(){}\n' + code
init_scripts.append(pack.inject_vscript(code.replace('`', '"')))
ent['vscripts'] = ' '.join(init_scripts)
- if context._io_remaps:
- LOGGER.info('Remapping outputs...')
- for (name, inp_name), outs in context._io_remaps.items():
- LOGGER.debug('Remap {}.{} = {}', name, inp_name, outs)
- for ent in vmf.entities:
- todo = ent.outputs[:]
- # Recursively convert only up to 500 times.
- # Arbitrary limit, should be sufficient.
- for _ in range(500):
- if not todo:
- break
- deferred = []
- for out in todo:
- try:
- remaps, should_remove = context._io_remaps[
- out.target.casefold(),
- out.input.casefold(),
- ]
- except KeyError:
- continue
- if should_remove:
- ent.outputs.remove(out)
- for rep_out in remaps:
- new_out = Output(
- out.output,
- rep_out.target,
- rep_out.input,
- rep_out.params or out.params,
- out.delay + rep_out.delay,
- times=out.times if rep_out.times == -1
- else rep_out.times if out.times == -1
- else min(out.times, rep_out.times),
- )
- ent.outputs.append(new_out)
- deferred.append(new_out)
- todo = deferred
- else:
- LOGGER.error(
- 'Entity "{}" ({}) @ {} has infinite loop when expanding '
- ' compiler outputs to real ones! Final output list: \n{}',
- ent['targetname'], ent['classname'], ent['origin'],
- '\n'.join(['* {}\n'.format(out) for out in ent.outputs])
- )
+ apply_io_remaps(context)
+
+
+# noinspection PyProtectedMember
+def apply_io_remaps(context: Context) -> None:
+ """Apply all the IO remaps."""
+ # Always disallow remaps now.
+ context._allow_remaps = False
+
+ if not context._io_remaps:
+ return
+
+ LOGGER.info('Remapping outputs...')
+ for (name, inp_name), outs in context._io_remaps.items():
+ LOGGER.debug('Remap {}.{} = {}', name, inp_name, outs)
+
+ for ent in context.vmf.entities:
+ if not ent.outputs: # Early out.
+ continue
+ todo = ent.outputs[:]
+ # Recursively convert only up to 500 times.
+ # Arbitrary limit, should be sufficient.
+ for _ in range(500):
+ deferred = []
+ for out in todo:
+ try:
+ remaps, should_remove = context._io_remaps[
+ out.target.casefold(),
+ out.input.casefold(),
+ ]
+ except KeyError:
+ continue
+ if should_remove:
+ ent.outputs.remove(out)
+ collapsed_remaps: List[Output] = []
+ out_copy = out.copy() # Don't allow remapping functions to modify this.
+ for remap in remaps:
+ if isinstance(remap, Output):
+ collapsed_remaps.append(remap)
+ else:
+ collapsed_remaps.extend(remap(ent, out_copy))
+
+ for rep_out in collapsed_remaps:
+ new_out = Output.combine(out, rep_out)
+ ent.outputs.append(new_out)
+ deferred.append(new_out)
+ if not deferred:
+ break
+ todo = deferred
+ else:
+ LOGGER.error(
+ 'Entity "{}" ({}) @ {} has infinite loop when expanding '
+ ' compiler outputs to real ones! Final output list: \n{}',
+ ent['targetname'], ent['classname'], ent['origin'],
+ '\n'.join(['* {}\n'.format(out) for out in ent.outputs])
+ )
def _load() -> None:
diff --git a/src/hammeraddons/bsp_transform/common.py b/src/hammeraddons/bsp_transform/common.py
new file mode 100644
index 000000000..8314ff99d
--- /dev/null
+++ b/src/hammeraddons/bsp_transform/common.py
@@ -0,0 +1,76 @@
+"""Operations that can be reused across different transforms."""
+import operator
+import re
+from typing import Callable, Dict, Tuple
+from decimal import Decimal, InvalidOperation
+
+from typing_extensions import Literal, TypeAlias
+
+from srctools import Entity, conv_bool
+from srctools.logger import get_logger
+
+
+LOGGER = get_logger(__name__)
+NumericOp: TypeAlias = Callable[[Decimal, Decimal], bool]
+NumericSpecifier: TypeAlias = Tuple[NumericOp, Decimal]
+
+OPERATIONS: Dict[str, NumericOp] = {
+ '<': operator.lt,
+ '>': operator.gt,
+ '>=': operator.ge,
+ '<=': operator.le,
+ '=': operator.eq,
+ '==': operator.eq,
+ '!=': operator.ne,
+ '=!=': operator.ne,
+ '~=': operator.ne,
+ '=/=': operator.ne,
+}
+# Matches multiple characters present in OPERATIONS.
+# \s skips whitespace beforehand, so we have a capturing group to just grap the actual operation.
+OPERATION_RE = re.compile(r'\s*([{0}]+)'.format(''.join(map(re.escape, {
+ char for key in OPERATIONS for char in key
+}))))
+
+
+# noinspection PyUnusedLocal
+def op_always_fail(a: Decimal, b: Decimal, /) -> Literal[False]:
+ """NumericOp implementation which always fails."""
+ return False
+
+
+def parse_numeric_specifier(text: str, desc: str='') -> NumericSpecifier:
+ """Parse case values like "> 5" into the operation and number."""
+ operation: NumericOp
+ if (match := OPERATION_RE.match(text)) is not None:
+ try:
+ operation = OPERATIONS[match.group(1)]
+ except KeyError:
+ LOGGER.warning('Invalid numeric operator "{}"{}', match.group(1), desc)
+ operation = operator.eq
+ num_str = text[match.end():]
+ else:
+ operation = operator.eq
+ num_str = text
+ try:
+ num = Decimal(num_str)
+ except InvalidOperation:
+ LOGGER.warning('Invalid number "{}"{}', num_str, desc)
+ # Force this to always fail.
+ return (op_always_fail, Decimal())
+ else:
+ return (operation, num)
+
+
+def check_control_enabled(ent: Entity) -> bool:
+ """Implement the bahaviour of ControlEnables - control_type and control_value.
+
+ This allows providing a fixup value, and optionally inverting it.
+ """
+ # If ctrl_type is 0, ctrl_value needs to be 1 to be enabled.
+ # If ctrl_type is 1, ctrl_value needs to be 0 to be enabled.
+ if 'ctrl_type' in ent:
+ return conv_bool(ent['ctrl_type'], False) != conv_bool(ent['ctrl_value'], True)
+ else:
+ # Missing, assume true if ctrl_value also isn't present.
+ return conv_bool(ent['ctrl_value'], True)
diff --git a/src/hammeraddons/bsp_transform/packing.py b/src/hammeraddons/bsp_transform/packing.py
index 511cba893..f4c524369 100644
--- a/src/hammeraddons/bsp_transform/packing.py
+++ b/src/hammeraddons/bsp_transform/packing.py
@@ -4,7 +4,9 @@
from srctools import Entity
from srctools.logger import get_logger
-from srctools.packlist import FileType, unify_path
+from srctools.mdl import MDL_EXTS
+from srctools.packlist import FileType, strip_extension, unify_path
+from srctools.sndscript import SND_CHARS
from hammeraddons.bsp_transform import Context, check_control_enabled, trans
@@ -63,7 +65,8 @@ def make_precache_prop(ent: Entity) -> None:
@trans('comp_precache_sound', priority=100)
def comp_precache_sound(ctx: Context):
"""Force precaching a set of sounds."""
- sounds = set()
+ # Match normalised sound to the original filename.
+ sounds: Dict[str, str] = {}
for ent in ctx.vmf.by_class['comp_precache_sound']:
ent.remove()
if not check_control_enabled(ent):
@@ -72,29 +75,28 @@ def comp_precache_sound(ctx: Context):
for key, sound in ent.items():
if not key.startswith('sound'):
continue
- sound = sound.casefold().replace('\\', '/')
- if sound.endswith(('.wav', '.mp3')) and not sound.startswith('sound/'):
- sound = 'sound/' + sound
+ sound_key = sound.casefold().replace('\\', '/').lstrip(SND_CHARS)
+ if sound_key.endswith(('.wav', '.mp3')) and not sound_key.startswith('sound/'):
+ sound_key = 'sound/' + sound_key
# Precaching implies packing it.
- ctx.pack.pack_file(sound, FileType.GAME_SOUND)
+ ctx.pack.pack_file(sound_key, FileType.GAME_SOUND)
- sounds.add(sound)
+ sounds.setdefault(sound_key, sound)
if not sounds:
return
# This VScript function forces a script to be precached.
lines = SND_CACHE_FUNC % '\n'.join([
- f'\tself.PrecacheSoundScript("{snd}")'
- for snd in sorted(sounds)
+ f'\tself.PrecacheSoundScript("{snd.lstrip(SND_CHARS)}")'
+ for snd in sorted(sounds.values())
])
ctx.vmf.create_ent(
'info_target',
targetname='@precache',
origin='-15872 -15872 -15872', # Should be outside the map.
- # We don't include scripts/vscripts in the filename.
vscripts=ctx.pack.inject_vscript(lines),
)
@@ -195,16 +197,6 @@ def comp_pack_rename(ctx: Context):
name_dest = ent['filedest']
file_type_name = ent['filetype']
- try:
- file = ctx.sys[name_src]
- except FileNotFoundError:
- LOGGER.warning(
- 'File cannot be loaded to pack! \n{} -> {}',
- name_src,
- name_dest,
- )
- continue
-
try:
res_type = PACK_TYPES[file_type_name.casefold()]
except KeyError:
@@ -218,7 +210,44 @@ def comp_pack_rename(ctx: Context):
try:
data = file_data[name_src]
except KeyError:
- with ctx.sys, ctx.sys.open_bin(file) as f:
- data = file_data[name_src] = f.read()
+ try:
+ file = ctx.sys.open_bin(name_src)
+ except FileNotFoundError:
+ LOGGER.warning(
+ 'File cannot be loaded to pack! \n{} -> {}',
+ name_src,
+ name_dest,
+ )
+ continue
+ with file:
+ data = file_data[name_src] = file.read()
+ LOGGER.info('Force packing "{}" as "{}"...', name_src, name_dest)
ctx.pack.pack_file(name_dest, res_type, data)
+
+ if res_type is FileType.MODEL:
+ # Pack additional files.
+ name_src_stem = strip_extension(name_src)
+ name_dest_stem = strip_extension(name_dest)
+ for ext in MDL_EXTS:
+ if ext == '.mdl': # TODO use MDL_EXTS_EXTRA
+ continue
+
+ name_add = name_src_stem + ext
+
+ try:
+ data = file_data[name_add]
+ except KeyError:
+ try:
+ file = ctx.sys.open_bin(name_add)
+ except FileNotFoundError:
+ # Optional.
+ continue
+ with file:
+ data = file_data[name_add] = file.read()
+
+ LOGGER.info(
+ 'Force packing "{}" as "{}{}"...',
+ name_add, name_dest_stem, ext,
+ )
+ ctx.pack.pack_file(name_dest_stem + ext, FileType.GENERIC, data)
diff --git a/src/hammeraddons/config.py b/src/hammeraddons/config.py
index a65780d38..7f574b2b9 100644
--- a/src/hammeraddons/config.py
+++ b/src/hammeraddons/config.py
@@ -372,6 +372,13 @@ def packfile_filters(block: Keyvalues, kind: str) -> Iterator[re_Pattern[str]]:
""",
)
+MODEL_COMPILE_DUMP = Opt.string(
+ 'modelcompile_dump', '',
+ """If set, models will be compiled as subfolders of this folder, instead of in a
+ temporary directory. The specified folder will be emptied at the start of each compile, to
+ prevent it filling up with old model sources. Move things out that you want to keep.
+""")
+
USE_COMMA_SEP = Opt.boolean_or_none(
'use_comma_sep',
"""Before L4D, entity I/O used ',' to seperate the different parts.
@@ -409,15 +416,26 @@ def packfile_filters(block: Keyvalues, kind: str) -> Iterator[re_Pattern[str]]:
the combined version will be used. If negative, this will not be done.
"""
)
-PROPCOMBINE_AUTO_RANGE = Opt.integer(
+PROPCOMBINE_MIN_AUTO_RANGE = Opt.integer(
'propcombine_auto_range', 0,
"""If greater than zero, combine props at least this close together.""",
)
+PROPCOMBINE_MAX_AUTO_RANGE = Opt.integer_or_none(
+ 'propcombine_max_auto_range',
+ """If set, do not automatically combine props further away than this from each other.""",
+)
-PROPCOMBINE_MIN_CLLUSTER = Opt.integer(
+PROPCOMBINE_MIN_CLUSTER = Opt.integer(
'propcombine_min_cluster', 2,
"""The minimum number of props required before propcombine will
- bother merging them. Should be greater than 1.
+ bother merging them, in propcombine volumes. Should be greater than 1.
+ """,
+)
+
+PROPCOMBINE_MIN_CLUSTER_AUTO = Opt.integer(
+ 'propcombine_min_cluster_auto', 0,
+ """The minimum number of props required before the automatic propcombine clustering will
+ merge the props. If less than or equal to 1, `propcombine_min_cluster` is used.
""",
)
diff --git a/src/hammeraddons/mdl_compiler.py b/src/hammeraddons/mdl_compiler.py
index 1dc29bc72..5c150addb 100644
--- a/src/hammeraddons/mdl_compiler.py
+++ b/src/hammeraddons/mdl_compiler.py
@@ -3,12 +3,18 @@
Each comes with a key, used to identify a previously compiled version.
We can then reuse already compiled versions.
"""
-from typing import Any, Awaitable, Callable, Generic, Hashable, List, Set, Tuple, TypeVar
+import shutil
+from typing import (
+ Any, Awaitable, Callable, Generic, Hashable, List, Optional, Set, Tuple, TypeVar,
+ ContextManager, Union,
+)
+from typing_extensions import Self
from pathlib import Path
import os
import pickle
import random
import tempfile
+import contextlib
from srctools import AtomicWriter, logger
from srctools.game import Game
@@ -24,7 +30,7 @@
ModelKey = TypeVar('ModelKey', bound=Hashable)
InT = TypeVar('InT')
OutT = TypeVar('OutT')
-ModelCompilerT = TypeVar('ModelCompilerT', bound='ModelCompiler') # TODO: Replace by Self
+force_regen = False # If set, force every model to be regenerated.
class GenModel(Generic[OutT]):
@@ -52,6 +58,7 @@ def __init__(
folder_name: str,
version: object=0,
pack_models: bool=True,
+ compile_dir: Optional[Path] =None,
) -> None:
# The models already constructed.
self._built_models: ACache[ModelKey, GenModel[OutT]] = ACache()
@@ -65,6 +72,7 @@ def __init__(
self.pack: PackList = pack
self.version = version
self.studiomdl_loc = studiomdl_loc
+ self.compile_dir = (compile_dir / folder_name) if compile_dir is not None else None
self.limiter = trio.CapacityLimiter(8)
self.pack_models = pack_models
# For statistics, the number we built this compile
@@ -82,16 +90,21 @@ def from_ctx(cls, ctx: Context, folder_name: str, version: object=0) -> 'ModelCo
ctx.bsp_path.stem,
folder_name,
version,
+ compile_dir=ctx.modelcompile_dump,
)
def use_count(self) -> int:
"""Return the number of used models."""
return sum(1 for _, mdl in self._built_models if mdl.used)
- def __enter__(self: ModelCompilerT) -> ModelCompilerT:
+ def __enter__(self) -> Self:
"""Load the previously compiled models and prepare for compiles."""
# Ensure the folder exists.
os.makedirs(self.model_folder_abs, exist_ok=True)
+
+ if force_regen:
+ return self # Skip loading.
+
data: List[Tuple[ModelKey, str, OutT]]
version = 0
try:
@@ -111,6 +124,7 @@ def __enter__(self: ModelCompilerT) -> ModelCompilerT:
exc_info=True,
)
return self
+
if version != self.version:
# Different version, ignore the data.
return self
@@ -225,7 +239,20 @@ async def _compile(
self._mdl_names.add(mdl_name)
break
- with tempfile.TemporaryDirectory(prefix='mdl_compile') as folder:
+ # If compile dir is specified, create the folder/clear it, but don't delete once done.
+ ctx_man: ContextManager[Union[str, Path]]
+ if self.compile_dir is not None:
+ path = Path(self.compile_dir, mdl_name)
+ ctx_man = contextlib.nullcontext(path)
+ try:
+ shutil.rmtree(path)
+ except FileNotFoundError:
+ pass
+ path.mkdir(parents=True, exist_ok=True)
+ else: # If not specified, use a temporary directory.
+ ctx_man = tempfile.TemporaryDirectory(prefix='mdl_compile')
+
+ with ctx_man as folder:
path = Path(folder)
result = await compile_func(key, path, f'{self.model_folder}{mdl_name}.mdl', args)
studio_args = [
@@ -237,6 +264,8 @@ async def _compile(
LOGGER.debug("Execute {}", studio_args)
async with self.limiter:
res = await trio.run_process(studio_args, capture_stdout=True, check=False)
+ if self.compile_dir is not None:
+ (path / 'compile.log').write_bytes(res.stdout)
LOGGER.debug(
'Log for {}:\n{}',
str(path / 'model.qc'),
diff --git a/src/hammeraddons/postcompiler.py b/src/hammeraddons/postcompiler.py
index bcfd7906d..04a8ca007 100644
--- a/src/hammeraddons/postcompiler.py
+++ b/src/hammeraddons/postcompiler.py
@@ -13,18 +13,21 @@
from typing import Dict, List, Optional
from collections import defaultdict
-from logging import FileHandler
+from logging import FileHandler, StreamHandler
import argparse
+import math
import os
import re
+import shutil
from srctools import __version__ as version_lib, conv_bool
-from srctools.bsp import BSP
-from srctools.fgd import FGD
+from srctools.bsp import BSP, BSP_LUMPS
from srctools.filesys import ZipFileSystem
from srctools.packlist import PackList
-from hammeraddons import __version__ as version_haddons, config, propcombine
+from hammeraddons import (
+ BINS_PATH, __version__ as version_haddons, config, mdl_compiler, propcombine,
+)
from hammeraddons.bsp_transform import run_transformations
from hammeraddons.move_shim import install as install_depmodule_hook
@@ -32,6 +35,18 @@
install_depmodule_hook()
+def format_bytesize(val: float) -> str:
+ """Add mb, gb etc suffixes to a size in bytes."""
+ if val < 1024:
+ return f'{val} bytes' # No rounding.
+ val /= 1024.0
+ for size in ['kB', 'mB', 'gB']:
+ if val <= 1024.0:
+ return f'{val:.3f}{size}'
+ val /= 1024.0
+ return f'{val:.03f}tB'
+
+
async def main(argv: List[str]) -> None:
"""Run the postcompiler."""
parser = argparse.ArgumentParser(
@@ -54,6 +69,22 @@ async def main(argv: List[str]) -> None:
action="store_false",
help="Prevent packing of files found in the map."
)
+ parser.add_argument(
+ "--nosaving",
+ dest="allow_save",
+ action="store_false",
+ help="For testing purposes, allow skipping saving the BSP.",
+ )
+ parser.add_argument(
+ "--regenerate",
+ action="store_true",
+ help="Force models and similar resources to be regnerated.",
+ )
+ parser.add_argument(
+ '-v', '--verbose',
+ action="store_true",
+ help="Show DEBUG level messages.",
+ )
parser.add_argument(
"--propcombine",
action="store_true",
@@ -79,6 +110,16 @@ async def main(argv: List[str]) -> None:
if args.showgroups:
LOGGER.warning('--showgroups is not implemented. r_colorstaticprops does the same thing ingame.')
+ if args.verbose:
+ # Find the stdout handler, make it DEBUG mode.
+ for handler in LOGGER.handlers:
+ if isinstance(handler, StreamHandler) and handler.stream is sys.stdout:
+ handler.setLevel('DEBUG')
+ break
+ else:
+ LOGGER.warning('Could not set stdout handler to DEBUG mode.')
+
+ mdl_compiler.force_regen = args.regenerate
# The path is the last argument to the compiler.
# Hammer adds wrong slashes sometimes, so fix that.
@@ -139,6 +180,19 @@ async def main(argv: List[str]) -> None:
LOGGER.warning('No studiomdl path provided.')
studiomdl_loc = None
+ modelcompile_dump_str = conf.opts.get(config.MODEL_COMPILE_DUMP)
+ modelcompile_dump = conf.expand_path(modelcompile_dump_str) if modelcompile_dump_str else None
+ if modelcompile_dump is not None:
+ LOGGER.info('Clearing model compile dump folder {}', modelcompile_dump)
+ try:
+ for file in modelcompile_dump.iterdir():
+ if file.is_dir():
+ shutil.rmtree(file)
+ else:
+ file.unlink()
+ except FileNotFoundError:
+ pass # Already empty.
+
use_comma_sep = conf.opts.get(config.USE_COMMA_SEP)
if use_comma_sep is None:
# Guess the format, by checking existing outputs.
@@ -176,6 +230,7 @@ async def main(argv: List[str]) -> None:
studiomdl_loc,
transform_conf,
pack_tags,
+ modelcompile_dump=modelcompile_dump,
)
if studiomdl_loc is not None and args.propcombine:
@@ -193,11 +248,14 @@ async def main(argv: List[str]) -> None:
if 'CROWBAR_LOC' in os.environ:
crowbar_loc = Path(os.environ['CROWBAR_LOC']).resolve()
else:
- crowbar_loc = Path(sys.argv[0], '../Crowbar.exe').resolve()
+ crowbar_loc = Path(BINS_PATH, 'Crowbar.exe').resolve()
else:
crowbar_loc = None
LOGGER.info('Combining props...')
+ max_auto_range: Optional[float] = conf.opts.get(config.PROPCOMBINE_MAX_AUTO_RANGE)
+ if not max_auto_range:
+ max_auto_range = math.inf
await propcombine.combine(
bsp_file,
bsp_file.ents,
@@ -207,10 +265,13 @@ async def main(argv: List[str]) -> None:
qc_folders=conf.opts.get(config.PROPCOMBINE_QC_FOLDER).as_array(conv=conf.expand_path),
decomp_cache_loc=decomp_cache_loc,
crowbar_loc=crowbar_loc,
- auto_range=conf.opts.get(config.PROPCOMBINE_AUTO_RANGE),
- min_cluster=conf.opts.get(config.PROPCOMBINE_MIN_CLLUSTER),
+ min_auto_range=conf.opts.get(config.PROPCOMBINE_MIN_AUTO_RANGE),
+ max_auto_range=max_auto_range,
+ min_cluster=conf.opts.get(config.PROPCOMBINE_MIN_CLUSTER),
+ min_cluster_auto=conf.opts.get(config.PROPCOMBINE_MIN_CLUSTER_AUTO),
blacklist=conf.opts.get(config.PROPCOMBINE_BLACKLIST).as_array(),
volume_tolerance=conf.opts.get(config.PROPCOMBINE_VOLUME_TOLERANCE),
+ compile_dump=modelcompile_dump,
debug_dump=args.dumpgroups,
pack_models=conf.opts.get(config.PROPCOMBINE_PACK) or False,
)
@@ -280,13 +341,13 @@ def pack_callback(path: str) -> Optional[bool]:
# List out all the files, but group together files with the same extension.
ext_for_name: Dict[str, List[str]] = defaultdict(list)
- for file in bsp_file.pakfile.infolist():
- filename = Path(file.filename)
+ for zip_info in bsp_file.pakfile.infolist():
+ filename = Path(zip_info.filename)
if '.' in filename.name:
stem, ext = filename.name.split('.', 1)
file_path = str(filename.parent / stem)
else:
- file_path = file.filename
+ file_path = zip_info.filename
ext = ''
ext_for_name[file_path].append(ext)
@@ -299,8 +360,13 @@ def pack_callback(path: str) -> Optional[bool]:
for name, exts in sorted(ext_for_name.items())
])))
- LOGGER.info('Writing BSP...')
- bsp_file.save()
+ if args.allow_save:
+ LOGGER.info('Writing BSP...')
+ bsp_file.save()
+
+ LOGGER.info('Packfile size: {}', format_bytesize(
+ len(bsp_file.lumps[BSP_LUMPS.PAKFILE].data)
+ ))
try:
from srctools.fgd import _engine_db_stats # noqa
diff --git a/src/hammeraddons/propcombine.py b/src/hammeraddons/propcombine.py
index 676277bac..46672b88a 100644
--- a/src/hammeraddons/propcombine.py
+++ b/src/hammeraddons/propcombine.py
@@ -3,9 +3,11 @@
This merges static props together, so they can be drawn with a single
draw call.
"""
+import math
from typing import (
- Callable, Dict, FrozenSet, Iterable, Iterator, List, MutableMapping, Optional, Set, Tuple,
- Union,
+ Callable, Dict, FrozenSet, Iterable, Iterator, List, Literal, MutableMapping, Optional, Set,
+ Tuple,
+ Union, Sequence,
)
from collections import defaultdict
from enum import Enum
@@ -25,7 +27,7 @@
from srctools.game import Game
from srctools.logger import get_logger
from srctools.math import Angle, Matrix, Vec, quickhull
-from srctools.mdl import MDL_EXTS, Model
+from srctools.mdl import MDL_EXTS, Model, Flags as ModelFlags
from srctools.packlist import PackList
from srctools.smd import Bone, Mesh, Triangle, Vertex
from srctools.tokenizer import Token, Tokenizer
@@ -39,11 +41,22 @@
LOGGER = get_logger(__name__)
+class CollType(Enum):
+ """Collision types that static props can have."""
+ NONE = 0 # No collision
+ BSP = 1 # Treat the same as MODEL.
+ BBOX = 2
+ OBB = 3
+ OBB_YAW = 4
+ VPHYS = 6 # Collision model
+
+
@attrs.frozen
class QC:
+ """The relevant we need from a QC."""
path: str # QC path.
- ref_smd: str # Location of main visible geometry.
- phy_smd: Optional[str] # Relative location of collision model, or None
+ ref_smd: str # Absolute location of main visible geometry.
+ phy_smd: Optional[str] # Absolute location of collision model, or None
ref_scale: float # Scale of main model.
phy_scale: float # Scale of collision model.
is_concave: bool # If the collision model is known to be concave.
@@ -69,15 +82,15 @@ class QC:
'''
MAX_GROUP = 24 # StudioMDL doesn't allow more than this...
-# Exceed this and StudioMDL cuts into multiple bodygroups.
-# So at that point we should produce multiple grouped props.
-MAX_VERTS = 65536//3
+# Exceed 65k triangles and StudioMDL cuts into multiple bodygroups. So at that point we should
+# produce multiple grouped props. Shrink a little just for breathing room.
+MAX_VERTS = 65536//3 - 64
# Cache of the SMD models we have already parsed, so we don't need
# to parse them again. For the collision model, we store them pre-split.
_mesh_cache: ACache[Tuple[QC, int], Mesh] = ACache()
-_coll_cache: ACache[Optional[str], List[Mesh]] = ACache()
+_coll_cache: ACache[Tuple[Optional[str], CollType], List[Mesh]] = ACache()
# Limit the amount of decompile/recompiles we do simultaneously.
LIM_PROCESS = trio.CapacityLimiter(8)
@@ -102,20 +115,26 @@ def __init__(self, group_name: str, skinset: FrozenSet, origin: Vec) -> None:
# For sorting.
self.volume = 0.0
self.used = False
- self.mins = Vec()
- self.maxes = Vec()
+ self.mins: Optional[Vec] = None
+ self.maxes: Optional[Vec] = None
# Each volume in the group, specifying its collision behaviour.
self.collision: List[Callable[[Vec], bool]] = []
if group_name:
- self.desc = f'group "{group_name}"'
+ self._desc_start = f'group "{group_name}"'
else:
- self.desc = f'at {origin}'
+ self._desc_start = f'at {origin}'
def contains(self, point: Vec) -> bool:
"""Check if the volume contains this point."""
return any(coll(point) for coll in self.collision)
+ def __str__(self) -> str:
+ if self.mins is None or self.maxes is None:
+ return self._desc_start
+ else:
+ return f'{self._desc_start}, ({self.mins} : {self.maxes})'
+
def make_collision_bbox(origin: Vec, angles: Angle, mins: Vec, maxes: Vec) -> Callable[[Vec], bool]:
"""Produce a bounding box collision checker."""
@@ -133,10 +152,6 @@ def make_collision_brush(origin: Vec, angles: Angle, brush: BModel) -> Callable[
"""Produce a collision checker using a brush entity."""
# Transpose the angles, giving us the inverse transform.
inv_angles = Matrix.from_angle(angles).transpose()
- # brushes = {
- # br for leaf in brush.node.iter_leafs()
- # for br in leaf.brushes
- # }
def check(point: Vec) -> bool:
"""Check if the given position is inside the volume."""
@@ -146,16 +161,6 @@ def check(point: Vec) -> bool:
return check
-class CollType(Enum):
- """Collision types that static props can have."""
- NONE = 0 # No collision
- BSP = 1 # Treat the same as MODEL.
- BBOX = 2
- OBB = 3
- OBB_YAW = 4
- VPHYS = 6 # Collision model
-
-
@attrs.frozen
class PropPos:
"""Key used to match models to each other."""
@@ -170,7 +175,11 @@ class PropPos:
model: str
checksum: bytes
skin: int
- scale: float
+
+ scale_x: float
+ scale_y: float
+ scale_z: float
+
solidity: CollType
@@ -207,20 +216,24 @@ async def combine_group(
for prop in props:
avg_pos += prop.origin
- avg_yaw += prop.angles.yaw
+ yaw = prop.angles.yaw % 90
+ if yaw > 45.0:
+ avg_yaw -= 90.0 - yaw
+ else:
+ avg_yaw += yaw
visleafs.update(prop.visleafs)
- # Snap to nearest 45 degrees to keep the models themselves not
- # strangely rotated.
- avg_yaw = round(avg_yaw / (45 * len(props))) * 45.0
+ avg_yaw /= len(props)
avg_pos /= len(props)
yaw_rot = Matrix.from_yaw(-avg_yaw)
prop_pos = set()
for prop in props:
origin = round((prop.origin - avg_pos) @ yaw_rot, 7)
- angles = round(Vec(prop.angles), 7)
- angles.y -= avg_yaw
+ angles = prop.angles
+ angles.pitch = round(angles.pitch, 7)
+ angles.yaw = round(angles.yaw - avg_yaw, 7)
+ angles.roll = round(angles.roll, 7)
try:
coll = CollType(prop.solidity)
except ValueError:
@@ -234,13 +247,21 @@ async def combine_group(
)
qc, mdl = lookup_model(prop.model)
assert mdl is not None, prop.model
+
+ scale = prop.scaling
+ if isinstance(scale, float):
+ scale_x = scale_y = scale_z = scale
+ else:
+ scale_x, scale_y, scale_z = scale
prop_pos.add(PropPos(
origin.x, origin.y, origin.z,
- angles.x, angles.y, angles.z,
+ angles.pitch, angles.yaw, angles.roll,
prop.model,
mdl.checksum,
prop.skin,
- prop.scaling,
+ scale_x,
+ scale_y,
+ scale_z,
coll,
))
# We don't want to build collisions if it's not used.
@@ -281,6 +302,7 @@ async def compile_func(
surfprops: Set[str] = set()
cdmats: Set[str] = set()
contents: Set[int] = set()
+ combined_flags = ModelFlags(0)
for prop in prop_pos:
qc, mdl = lookup_model(prop.model)
@@ -289,6 +311,7 @@ async def compile_func(
surfprops.add(mdl.surfaceprop.casefold())
cdmats.update(mdl.cdmaterials)
contents.add(mdl.contents)
+ combined_flags |= mdl.flags
if len(surfprops) > 1:
raise ValueError('Multiple surfaceprops? Should be filtered out.')
@@ -311,24 +334,43 @@ async def compile_func(
assert mdl is not None, prop.model
child_ref = await _mesh_cache.fetch((qc, prop.skin), build_reference, prop, qc, mdl)
- child_coll = await _coll_cache.fetch(qc.phy_smd, build_collision, qc, prop, child_ref, volume_tolerance > 0)
+ child_coll = await _coll_cache.fetch((qc.phy_smd, prop.solidity), build_collision, qc, prop, child_ref, volume_tolerance > 0)
+ scale = Vec(prop.scale_x, prop.scale_y, prop.scale_z)
offset = Vec(prop.x, prop.y, prop.z)
- matrix = Matrix.from_angle(prop.pit, prop.yaw, prop.rol)
+ rot_matrix = Matrix.from_angle(prop.pit, prop.yaw, prop.rol)
- ref_mesh.append_model(child_ref, matrix, offset, prop.scale * qc.ref_scale)
+ ref_mesh.append_model(child_ref, rot_matrix, offset, scale * qc.ref_scale)
if has_coll and child_coll is not None:
- scale = prop.scale * qc.phy_scale
+ phy_scale = scale * qc.phy_scale
+
+ matrix = Matrix()
+
+ # Set the scale
+ matrix[0, 0] = phy_scale.x
+ matrix[1, 1] = phy_scale.y
+ matrix[2, 2] = phy_scale.z
+
+ # Rotate the matrix
+ matrix @= rot_matrix
+
+ # Secondary matrix for the normals
+ itm = matrix.inverse().transpose()
+
group = Mesh(coll_mesh.bones, coll_mesh.animation, [])
for part in child_coll:
for orig_tri in part.triangles:
new_tri = orig_tri.copy()
for vert in new_tri:
vert.links[:] = bone_link
- vert.norm @= matrix
- vert.pos *= scale
- vert.pos.localise(offset, matrix)
+
+ # Transform the vertex
+ vert.norm @= itm
+ vert.norm = vert.norm.norm()
+ vert.pos @= matrix
+ vert.pos += offset
+
group.triangles.append(new_tri)
if group.triangles:
coll_groups[group] = group.compute_volume()
@@ -373,6 +415,25 @@ async def compile_func(
# 0 needs to produce this value.
]) or '"notsolid"',
))
+ # According to studiomdl, $opaque overrides $mostlyopaque.
+ if ModelFlags.force_opaque in combined_flags:
+ f.write('$opaque\n')
+ if ModelFlags.translucent_twopass in combined_flags:
+ LOGGER.warning(
+ 'Both $mostlyopaque and $opaque set with models: {}',
+ {prop.model for prop in prop_pos}
+ )
+ elif ModelFlags.translucent_twopass in combined_flags:
+ f.write('$mostlyopaque\n')
+
+ if ModelFlags.no_forced_fade in combined_flags:
+ f.write('$noforcedfade\n')
+
+ if ModelFlags.ambient_boost in combined_flags:
+ f.write('$ambientboost\n')
+
+ if ModelFlags.do_not_cast_shadows in combined_flags:
+ f.write('$donotcastshadows\n')
for mat in sorted(cdmats):
f.write('$cdmaterials "{}"\n'.format(mat))
@@ -590,12 +651,12 @@ def parse_qc(qc_loc: Path, qc_path: Path) -> Optional[Tuple[
elif body_type is not Token.NEWLINE:
raise tok.error(body_type)
- elif token_value == '$collisionmodel':
+ elif token_value in ('$collisionmodel', '$collisionjoints'):
phy_smd = qc_loc / tok.expect(Token.STRING)
phy_scale = scale_factor
next_typ, next_val = next(tok.skipping_newlines())
if next_typ is Token.BRACE_OPEN:
- for body_value in tok.block('$collisionmodel', consume_brace=False):
+ for body_value in tok.block(token_value, consume_brace=False):
if body_value.casefold() == '$concave':
is_concave = True
else:
@@ -603,7 +664,6 @@ def parse_qc(qc_loc: Path, qc_path: Path) -> Optional[Tuple[
# We can't support this.
elif token_value in (
- '$collisionjoints',
'$ikchain',
'$weightlist',
'$poseparameter',
@@ -616,9 +676,14 @@ def parse_qc(qc_loc: Path, qc_path: Path) -> Optional[Tuple[
return None
elif token_type is Token.BRACE_OPEN:
# Skip other "compound" sections we don't care about.
+ depth = 1
for body_type, body_value in tok:
if body_type is Token.BRACE_CLOSE:
- break
+ depth -= 1
+ if not depth:
+ break
+ elif body_type is Token.BRACE_OPEN:
+ depth += 1
else:
raise tok.error("EOF reached without closing brace (})!")
@@ -793,6 +858,15 @@ def group_props_ent(
Vec.from_str(ent['mins']),
Vec.from_str(ent['maxs']),
)
+ if combine_set.mins is None:
+ combine_set.mins = origin + mins
+ else:
+ combine_set.mins.min(origin + mins)
+ if combine_set.maxes is None:
+ combine_set.maxes = origin + maxes
+ else:
+ combine_set.maxes.max(origin + maxes)
+
size = maxes - mins
# Enlarge slightly to ensure it never has a zero area.
# This ensures items on the edge are included.
@@ -813,6 +887,14 @@ def group_props_ent(
size = brush.maxes - brush.mins
combine_set.volume += size.x * size.y * size.z
combine_set.collision.append(make_collision_brush(origin, angles, brush))
+ if combine_set.mins is None:
+ combine_set.mins = brush.origin + brush.mins
+ else:
+ combine_set.mins.min(brush.origin + brush.mins)
+ if combine_set.maxes is None:
+ combine_set.maxes = brush.origin + brush.maxes
+ else:
+ combine_set.maxes.max(brush.origin + brush.maxes)
else:
raise AssertionError(ent['classname'])
@@ -841,7 +923,29 @@ def group_props_ent(
found.append(prop)
combine_set.used = True
- actual = set(found).intersection(group)
+ if not found: # No point checking an empty list.
+ continue
+
+ actual: List[StaticProp] = []
+ total_verts = 0
+ for prop in found:
+ qc, mdl = get_model(prop.model)
+ assert mdl is not None
+ total_verts += mdl.total_verts
+ if total_verts > MAX_VERTS:
+ # Warn for groups since these were intentionally built.
+ LOGGER.warning(
+ 'Hit vert limit in group {} with models {}', combine_set,
+ {prop.model for prop in found},
+ )
+ # Output this prop, then start a new group.
+ if len(actual) >= min_cluster:
+ yield list(actual)
+ for sub_prop in actual:
+ group.remove(sub_prop)
+ actual.clear()
+ total_verts = mdl.total_verts
+ actual.append(prop)
if len(actual) >= min_cluster:
yield list(actual)
for prop in actual:
@@ -851,59 +955,128 @@ def group_props_ent(
for combine_set_list in sets_by_skin.values():
for combine_set in combine_set_list:
if not combine_set.used:
- LOGGER.warning('Unused comp_propcombine_set {}', combine_set.desc)
+ LOGGER.warning('Unused comp_propcombine_volume/_set {}', combine_set)
def group_props_auto(
prop_groups: Dict[Optional[tuple], List[StaticProp]],
- dist: float,
+ get_model: Callable[[str], Tuple[Optional[QC], Optional[Model]]],
+ min_dist: float,
+ max_dist: float,
min_cluster: int,
) -> Iterator[List[StaticProp]]:
"""Given the groups of props, automatically find close props to merge."""
- # Each of these groups cannot be merged with other ones.
+ min_dist_sq = min_dist * min_dist
+ max_dist_sq = max_dist * max_dist
+ neighbours: Dict[StaticProp, Sequence[StaticProp]] = {}
- dist_sq = dist * dist
- large_dist_sq = 4 * dist_sq
+ def find_neighbours(start: StaticProp) -> Sequence[StaticProp]:
+ """Find props within dist from the specified one."""
+ try:
+ return neighbours[start]
+ except KeyError:
+ pass
+ neigh = [
+ prop for prop in group
+ if (prop.origin - start.origin).mag_sq() <= min_dist_sq
+ ]
+ neighbours[start] = neigh
+ return neigh
+ UNSET: Literal['unset'] = 'unset'
+ NOISE: Literal['noise'] = 'noise'
+
+ # Each of these groups cannot be merged with other ones.
for group in prop_groups.values():
# No point merging single/empty groups.
if len(group) < 2:
continue
- todo = set(group)
- while todo:
- center = todo.pop()
- cluster = {center}
+ # DBSCAN algorithm.
+ labels: Dict[StaticProp, Union[int, Literal['noise', 'unset']]] = dict.fromkeys(group, UNSET)
+ neighbours.clear()
+ cluster_ind = 0
- for prop in todo:
- if (center.origin - prop.origin).mag_sq() <= large_dist_sq:
- cluster.add(prop)
- if len(cluster) > MAX_GROUP:
- # Limit the number of maximum props that can be used.
- break
+ LOGGER.debug('Grouping {} props', len(group))
- if len(cluster) < min_cluster:
+ for prop in group:
+ if labels[prop] is not UNSET:
continue
-
- bbox_min, bbox_max = Vec.bbox(prop.origin for prop in cluster)
- center_pos = (bbox_min + bbox_max) / 2
-
- cluster_list: List[Tuple[StaticProp, float]] = []
-
- for prop in cluster:
- prop_off = (center_pos - prop.origin).mag_sq()
- if prop_off <= dist_sq:
- cluster_list.append((prop, prop_off))
-
- cluster_list.sort(key=operator.itemgetter(1))
- selected_props = [
- prop for prop, off in
- cluster_list[:MAX_GROUP]
- ]
- todo.difference_update(selected_props)
-
- if len(selected_props) >= min_cluster:
- yield selected_props
+ neigh = find_neighbours(prop)
+ if len(neigh) < min_cluster:
+ labels[prop] = NOISE
+ continue
+ cluster_ind += 1
+ labels[prop] = cluster_ind
+ todo = set(neigh)
+
+ while todo:
+ sub_prop = todo.pop()
+ if labels[sub_prop] is NOISE:
+ labels[sub_prop] = cluster_ind
+ elif labels[sub_prop] != UNSET:
+ continue # Already handled.
+ labels[sub_prop] = cluster_ind
+ neigh = find_neighbours(sub_prop)
+ if len(neigh) > min_cluster:
+ todo.update(neigh)
+
+ neighbours.clear() # Discard, no longer useful.
+
+ clusters: Dict[int, List[StaticProp]] = defaultdict(list)
+ for prop, key in labels.items():
+ if type(key) is int:
+ clusters[key].append(prop)
+
+ # We now have many potential groups, which may be extremely large.
+ # We want to split these up, so they don't extend too far.
+ for cluster in clusters.values():
+ warned: bool = False
+ todo = set(cluster)
+ while len(todo) > min_cluster:
+ # First find the prop the furthest from the center-point.
+ average_pos = sum((prop.origin for prop in todo), Vec()) / len(todo)
+ central_prop = max(todo, key=lambda prop: (prop.origin - average_pos).mag_sq())
+
+ total_verts = 0
+ selected_props: List[StaticProp] = []
+ found_matches = False
+ for prop in list(todo):
+ # Exceeds the max radius?
+ if (prop.origin - central_prop.origin).mag_sq() > max_dist_sq:
+ continue
+ qc, mdl = get_model(prop.model)
+ assert mdl is not None
+ total_verts += mdl.total_verts
+ if total_verts > MAX_VERTS:
+ # Make this just info level, just might be props nearby.
+ if not warned:
+ bb_min, bb_max = Vec.bbox(prop.origin for prop in cluster)
+ LOGGER.info(
+ 'Hit vert limit for auto group @ ({} - {}) with models {}' ,
+ bb_min, bb_max,
+ {prop.model for prop in cluster},
+ )
+ warned = True
+ # Split the group here, create a new prop.
+ if len(selected_props) >= min_cluster:
+ found_matches = True
+ todo.difference_update(selected_props)
+ yield selected_props
+ selected_props = []
+ total_verts = mdl.total_verts
+ selected_props.append(prop)
+
+ if len(selected_props) >= min_cluster:
+ yield selected_props
+ todo.difference_update(selected_props)
+ found_matches = True
+ if not found_matches:
+ # The selected prop was too far away to cluster. Discard it, so we pick a
+ # different one. It should be added by itself, it's on its own mostly.
+ todo.discard(central_prop)
+ # Once the while loop terminates, our group is too small to actually cluster any more.
+ # The main combine() function will re-add them to the map automatically.
async def combine(
@@ -916,9 +1089,12 @@ async def combine(
qc_folders: Optional[List[Path]]=None,
crowbar_loc: Optional[Path]=None,
decomp_cache_loc: Optional[Path]=None,
+ compile_dump: Optional[Path]=None,
blacklist: Iterable[str]=(),
- auto_range: float=0,
+ min_auto_range: float=0.0,
+ max_auto_range: float=math.inf,
min_cluster: int=2,
+ min_cluster_auto: int=0,
volume_tolerance: float=1.0,
debug_dump: bool=False,
pack_models: bool=True,
@@ -1034,8 +1210,9 @@ def get_grouping_key(prop: StaticProp) -> Optional[tuple]:
for tex in
model.iter_textures([prop.skin])
}),
- model.flags.value,
(prop.flags & relevant_flags).value,
+ # Do not allow combining across an areaportal boundary.
+ frozenset({leaf.area for leaf in prop.visleafs}),
model.contents,
model.surfaceprop,
prop.renderfx,
@@ -1054,7 +1231,9 @@ def get_grouping_key(prop: StaticProp) -> Optional[tuple]:
final_props: List[StaticProp] = []
grouper: Iterator[List[StaticProp]]
grouper_ents = list(bsp_ents.by_class['comp_propcombine_set'] | bsp_ents.by_class['comp_propcombine_volume'])
- if grouper_ents and auto_range > 0:
+ if min_cluster_auto <= 2:
+ min_cluster_auto = min_cluster
+ if grouper_ents and min_auto_range > 0:
LOGGER.info('{} propcombine sets present and auto-grouping enabled, combining...', len(grouper_ents))
# Do ents first, that removes values from the lists in prop_groups,
# then the auto grouper handles that.
@@ -1067,8 +1246,9 @@ def get_grouping_key(prop: StaticProp) -> Optional[tuple]:
),
group_props_auto(
prop_groups,
- auto_range,
- min_cluster,
+ get_model,
+ min_auto_range, max_auto_range,
+ min_cluster_auto or min_cluster,
)
)
elif grouper_ents:
@@ -1079,16 +1259,17 @@ def get_grouping_key(prop: StaticProp) -> Optional[tuple]:
bsp.bmodels, grouper_ents,
min_cluster,
)
- elif auto_range > 0:
+ elif min_auto_range > 0:
LOGGER.info('Automatically finding propcombine sets...')
grouper = group_props_auto(
prop_groups,
- auto_range,
- min_cluster,
+ get_model,
+ min_auto_range, max_auto_range,
+ min_cluster_auto or min_cluster,
)
else:
# No way provided to choose props.
- LOGGER.info('No propcombine groups provided.')
+ LOGGER.info('No propcombine groups or range provided.')
return
# These are models we cannot merge no matter what -
@@ -1114,21 +1295,22 @@ def get_grouping_key(prop: StaticProp) -> Optional[tuple]:
map_name,
folder_name='propcombine',
version={
- 'ver': 1,
+ 'ver': 2,
'vol_tolerance': volume_tolerance,
},
+ compile_dir=compile_dump,
pack_models=pack_models,
) as compiler:
async def do_combine(group: List[StaticProp]) -> None:
- nonlocal group_count
+ """Task run to combine one prop."""
grouped_prop = await combine_group(compiler, group, get_model, volume_tolerance)
rejected.difference_update(group)
final_props.append(grouped_prop)
- group_count += 1
async with trio.open_nursery() as nursery:
for group_ in grouper:
nursery.start_soon(do_combine, group_)
+ group_count += 1
final_props.extend(rejected)
diff --git a/src/hammeraddons/props_config.py b/src/hammeraddons/props_config.py
index 8ebf7b130..31f9ce4ee 100644
--- a/src/hammeraddons/props_config.py
+++ b/src/hammeraddons/props_config.py
@@ -120,8 +120,8 @@ def vector(cls, opt_id: str, default: Vec, doc: str, *, fallback: Optional[str]
return OptWithDefault(opt_id, Vec, default, doc, fallback)
-@attrs.define(init=False)
-class OptWithDefault(Opt[OptionT], Generic[OptionT]):
+@attrs.define(init=False) # __attrs_init__() is incompatible with the superclass.
+class OptWithDefault(Opt[OptionT], Generic[OptionT]): # type: ignore[override]
"""An option, with a default."""
default: OptionT
def __init__(
@@ -254,8 +254,8 @@ def get(self, option: Opt[OptionT]) -> Optional[Option]:
raise TypeError(f'Option "{option.name}" does not exist!') from None
if val is None:
- if option.kind is Keyvalues: # Type checker doesn't understand isinstance here.
- return Keyvalues(option.name, []) # type: ignore
+ if option.kind is Keyvalues:
+ return Keyvalues(option.name, [])
else:
return None
diff --git a/src/hammeraddons/splines.py b/src/hammeraddons/splines.py
new file mode 100644
index 000000000..fafd679b7
--- /dev/null
+++ b/src/hammeraddons/splines.py
@@ -0,0 +1,21 @@
+"""Math related to spline generation."""
+import math
+from typing import Generator
+
+from srctools import Matrix, Vec
+
+
+def parallel_transport(orient1: Matrix, tanj1: Vec, tanj2: Vec) -> Matrix:
+ """Given a series of vectors along a path, produce a corresponding set of orientations.
+
+ This allows creating geometry which smoothly follows a curve.
+ The code is based on the info at: https://janakiev.com/blog/framing-parametric-curves/.
+ """
+ b = Vec.cross(tanj1, tanj2)
+ if b.mag_sq() < 0.001:
+ # Aligned, yield the same orientation.
+ return orient1.copy()
+ else:
+ phi = math.acos(Vec.dot(tanj1, tanj2))
+ up = orient1.up() @ Matrix.axis_angle(b.norm(), math.degrees(phi))
+ return Matrix.from_basis(x=tanj2, z=up)
diff --git a/src/hammeraddons/unify_fgd.py b/src/hammeraddons/unify_fgd.py
index 58638de9a..6085c842a 100644
--- a/src/hammeraddons/unify_fgd.py
+++ b/src/hammeraddons/unify_fgd.py
@@ -14,7 +14,7 @@
from srctools import fgd
from srctools.fgd import (
FGD, AutoVisgroup, EntAttribute, EntityDef, EntityTypes, Helper, HelperExtAppliesTo,
- HelperWorldText, KVDef, ValueTypes, match_tags, validate_tags,
+ HelperTypes, HelperWorldText, KVDef, ValueTypes, match_tags, validate_tags,
)
from srctools.filesys import RawFileSystem
@@ -24,8 +24,8 @@
# If 'until_l4d' etc is used in FGD, only games before include it.
GAMES_CHRONO: List[Tuple[str, str]] = [
('HL2', 'Half-Life 2'),
- ('EP1', 'Half-Life 2 Episode 1'),
- ('EP2', 'Half-Life 2 Episode 2'),
+ ('EP1', 'Half-Life 2: Episode One'),
+ ('EP2', 'Half-Life 2: Episode Two'),
('TF2', 'Team Fortress 2'),
('P1', 'Portal'),
@@ -33,7 +33,7 @@
('L4D2', 'Left 4 Dead 2'),
('ASW', 'Alien Swarm'),
('P2', 'Portal 2'),
- ('CSGO', 'Counter-Strike Global Offensive'),
+ ('CSGO', 'Counter-Strike: Global Offensive'),
('SFM', 'Source Filmmaker'),
('DOTA2', 'Dota 2'),
@@ -48,11 +48,14 @@
],
'EP2': [
('MESA', 'Black Mesa'),
- ('GMOD', "Gary's Mod"),
- ('EZ1', 'Entropy Zero'),
- ('EZ2', 'Entropy Zero 2'),
+ ('GMOD', "Garry's Mod"),
+ ('EZ1', 'Entropy: Zero'),
+ ('EZ2', 'Entropy: Zero 2'),
('KZ', 'Kreedz Climbing'),
],
+ 'ASW': [
+ ('ASRD', 'Alien Swarm: Reactive Drop'),
+ ],
'P2': [
('P2SIXENSE', 'Portal 2 Sixense MotionPack'),
('P2EDU', 'Portal 2 Educational Version'),
@@ -82,10 +85,10 @@
'EP2': {'HL2', 'EP1'},
'MBASE': {'VSCRIPT'},
- 'MESA': {'INST_IO'},
+ 'MESA': {'HL2', 'INST_IO'},
'GMOD': {'HL2', 'EP1', 'EP2'},
- 'EZ1': {'MBASE', 'VSCRIPT'},
- 'EZ2': {'MBASE', 'VSCRIPT'},
+ 'EZ1': {'HL2', 'EP1', 'EP2', 'MBASE', 'VSCRIPT'},
+ 'EZ2': {'HL2', 'EP1', 'EP2', 'MBASE', 'VSCRIPT'},
'KZ': {'HL2'},
'L4D2': {'INST_IO', 'VSCRIPT'},
@@ -93,7 +96,7 @@
'ASW': {'INST_IO', 'VSCRIPT'},
'P2': {'INST_IO', 'VSCRIPT'},
'CSGO': {'INST_IO', 'PROP_SCALING', 'VSCRIPT', 'PROPCOMBINE'},
- 'P2DES': {'P2'},
+ 'P2DES': {'P2', 'INST_IO', 'PROP_SCALING', 'VSCRIPT', 'PROPCOMBINE'},
}
ALL_FEATURES = {
@@ -135,6 +138,8 @@
# Special classname which has all the keyvalues and IO of CBaseEntity.
BASE_ENTITY = '_CBaseEntity_'
+MAP_SIZE_DEFAULT = 16384 # Default grid bounds.
+
# Helpers which are only used by one or two entities each.
UNIQUE_HELPERS = {
@@ -213,17 +218,6 @@ def _polyfill_scripts(fgd: FGD) -> None:
inp.type = ValueTypes.STRING
-@_polyfill('until_csgo')
-def _polyfill_worldtext(fgd: FGD):
- """Strip worldtext(), since this is not available."""
- for ent in fgd:
- ent.helpers[:] = [
- helper
- for helper in ent.helpers
- if not isinstance(helper, HelperWorldText)
- ]
-
-
@_polyfill()
def _polyfill_ext_valuetypes(fgd: FGD) -> None:
# Convert extension types to their real versions.
@@ -259,30 +253,40 @@ def expand_tags(tags: FrozenSet[str]) -> FrozenSet[str]:
This adds since_/until_ tags, and values in FEATURES.
"""
exp_tags = set(tags)
+
+ # Figure out the game branch, for adding since/until tags.
+ # For games, pick the most recent one. For mods, pick the associated branch,
+ # but don't add the branch itself - they can do that via FEATURES.
+ pos = -1
for tag in tags:
- try:
- exp_tags.add(MOD_TO_BRANCH[tag.upper()])
- except KeyError:
- pass
+ tag = tag.upper()
+ if tag in ALL_GAMES:
+ pos = max(pos, GAME_ORDER.index(tag))
+ break
+ else:
+ try:
+ pos = GAME_ORDER.index(MOD_TO_BRANCH[tag])
+ except (KeyError, ValueError):
+ pass
+ else:
+ break
+
+ if pos != -1:
+ exp_tags.update(
+ 'SINCE_' + tag
+ for tag in GAME_ORDER[:pos + 1]
+ )
+ exp_tags.update(
+ 'UNTIL_' + tag
+ for tag in GAME_ORDER[pos + 1:]
+ )
for tag in list(exp_tags):
try:
exp_tags.update(FEATURES[tag.upper()])
except KeyError:
pass
- try:
- pos = GAME_ORDER.index(tag.upper())
- except ValueError:
- pass
- else:
- exp_tags.update(
- 'SINCE_' + tag
- for tag in GAME_ORDER[:pos+1]
- )
- exp_tags.update(
- 'UNTIL_' + tag
- for tag in GAME_ORDER[pos+1:]
- )
+
return frozenset(exp_tags)
@@ -306,13 +310,18 @@ def ent_path(ent: EntityDef) -> str:
return '{}/{}.fgd'.format(folder, ent.classname)
-def load_database(dbase: Path, extra_loc: Optional[Path]=None, fgd_vis: bool=False) -> Tuple[FGD, EntityDef]:
+def load_database(
+ dbase: Path,
+ extra_loc: Optional[Path]=None,
+ fgd_vis: bool=False,
+ map_size: int=MAP_SIZE_DEFAULT,
+) -> Tuple[FGD, EntityDef]:
"""Load the entire database from disk. This returns the FGD, plus the CBaseEntity definition."""
print(f'Loading database {dbase}:')
fgd = FGD()
- fgd.map_size_min = -16384
- fgd.map_size_max = 16384
+ fgd.map_size_min = -map_size
+ fgd.map_size_max = map_size
# Classname -> filename
ent_source: Dict[str, str] = {}
@@ -819,6 +828,7 @@ def action_export(
output_path: Path,
as_binary: bool,
engine_mode: bool,
+ map_size: int=MAP_SIZE_DEFAULT,
) -> None:
"""Create an FGD file using the given tags."""
@@ -829,7 +839,9 @@ def action_export(
print('Tags expanded to: {}'.format(', '.join(tags)))
- fgd, base_entity_def = load_database(dbase, extra_db)
+ fgd, base_entity_def = load_database(dbase, extra_loc=extra_db, map_size=map_size)
+
+ print(f'Map size: ({fgd.map_size_min}, {fgd.map_size_max})')
if engine_mode:
# In engine mode, we don't care about specific games.
@@ -908,7 +920,7 @@ def action_export(
key,
', '.join([typ.value for typ in types])
))
- # Pick the one with shortest tags arbitrarily.
+ # Pick the one with the shortest tags arbitrarily.
_, value = min(
tag_map.items(),
key=lambda t: len(t[0]),
@@ -1004,38 +1016,48 @@ def action_export(
ent.bases.remove(base)
if not engine_mode:
+ print('Applying polyfills:')
for poly_tag, polyfill in POLYFILLS:
if match_tags(tags, poly_tag):
+ print(f' - {polyfill.__name__[10:]}: Applying')
polyfill(fgd)
+ else:
+ print(f' - {polyfill.__name__[10:]}: Not required')
print('Applying helpers to child entities and optimising...')
for ent in fgd.entities.values():
# Merge them together.
- helpers: List[Helper] = []
+ base_helpers: List[Helper] = []
for base in ent.bases:
assert isinstance(base, EntityDef)
- helpers.extend(base.helpers)
- helpers.extend(ent.helpers)
+ base_helpers.extend(base.helpers)
+
+ # Then optimise this list, by re-assembling in reverse.
+ rev_helpers: List[Helper] = []
+ overrides: Set[HelperTypes] = set()
- # Then optimise this list.
- ent.helpers.clear()
- for helper in helpers:
- if helper in ent.helpers: # No duplicates
+ # Add the entity's own helpers to the end, but do not override within that.
+ for helper in reversed(ent.helpers):
+ if helper in rev_helpers: # No duplicates here.
continue
- # Strip applies-to helper.
- if isinstance(helper, HelperExtAppliesTo):
+ if helper.IS_EXTENSION:
continue
- # For each, check if it makes earlier ones obsolete.
- overrides = helper.overrides()
- if overrides:
- ent.helpers[:] = [
- helper for helper in ent.helpers
- if helper.TYPE not in overrides
- ]
+ # For each, it may make earlier definitions obsolete.
+ overrides.update(helper.overrides())
+ # But the last of any type is always included.
+ rev_helpers.append(helper)
- # But it itself should be added to the end regardless.
- ent.helpers.append(helper)
+ # Add in all the base entity helpers.
+ for helper in reversed(base_helpers):
+ # No duplicates or overridden helpers.
+ if helper in rev_helpers or helper.TYPE in overrides:
+ continue
+ if helper.IS_EXTENSION:
+ continue
+ overrides.update(helper.overrides())
+ rev_helpers.append(helper)
+ ent.helpers = rev_helpers[::-1]
print('Culling unused bases...')
used_bases: Set[EntityDef] = set()
@@ -1055,7 +1077,7 @@ def action_export(
del fgd.entities[classname]
continue
else:
- # Helpers aren't inherited, so this isn't useful anymore.
+ # Helpers aren't inherited, so this isn't useful any more.
ent.helpers.clear()
# Cull all base classes we don't use.
# Ents that inherit from each other always need to exist.
@@ -1226,6 +1248,12 @@ def main(args: Optional[List[str]]=None):
help="Tags to include in the output.",
default=None,
)
+ parser_exp.add_argument(
+ "--map-size",
+ default=MAP_SIZE_DEFAULT,
+ dest="map_size",
+ type=int,
+ )
parser_imp = subparsers.add_parser(
"import",
@@ -1301,6 +1329,7 @@ def main(args: Optional[List[str]]=None):
result.output,
result.binary,
result.engine,
+ result.map_size,
)
elif result.mode in ("c", "count"):
action_count(dbase, extra_db, factories_folder=Path(repo_dir, 'db', 'factories'))
diff --git a/tests/test_transforms/test_core_io_remap.py b/tests/test_transforms/test_core_io_remap.py
new file mode 100644
index 000000000..79ab688c8
--- /dev/null
+++ b/tests/test_transforms/test_core_io_remap.py
@@ -0,0 +1,38 @@
+"""Test the IO remapping behaviour."""
+from srctools import Output
+from . import blank_ctx, Context
+
+from hammeraddons.bsp_transform import apply_io_remaps # noqa
+
+
+def test_simple_remap(blank_ctx: Context, file_regression) -> None:
+ """Test some basic remaps."""
+ rl_source = blank_ctx.vmf.create_ent('some_ent', targetname='rl_source')
+ rl_source.add_out(
+ Output('OnMulti', 'some_dest', 'Trigger', delay=0.5),
+ Output('OnSingle', 'some_dest', 'Trigger', only_once=True),
+ Output('OnTrigger', 'some_dest', 'WillBeRemoved'),
+ Output('OnTrigger', 'regular_output', 'SetAnimation', 'dance', 0.125),
+ Output('OnSpawn', 'basic_dest', 'NeedsParam', '1'),
+ Output('OnSpawn', 'overrides', 'Skin', '5'),
+ )
+
+ blank_ctx.add_io_remap(
+ 'some_dest',
+ Output('Trigger', 'model_1', 'Skin', '1'),
+ Output('Trigger', 'model_1', 'Skin', '0', delay=1.0, times=3),
+ )
+ blank_ctx.add_io_remap(
+ 'some_dest',
+ Output('Trigger', 'pfx', 'Start'),
+ Output('Trigger', 'pfx', 'Stop', delay=0.5),
+ )
+ blank_ctx.add_io_remap(
+ 'overrides',
+ Output('Skin', 'another_model', 'Bodygroup', '256'),
+ )
+ blank_ctx.add_io_remap_removal('some_dest', 'WillBeRemoved')
+
+ apply_io_remaps(blank_ctx)
+
+ file_regression.check(blank_ctx.vmf.export(), encoding='utf8', extension='.vmf')
diff --git a/tests/test_transforms/test_core_io_remap/test_simple_remap.vmf b/tests/test_transforms/test_core_io_remap/test_simple_remap.vmf
new file mode 100644
index 000000000..f682205e4
--- /dev/null
+++ b/tests/test_transforms/test_core_io_remap/test_simple_remap.vmf
@@ -0,0 +1,116 @@
+versioninfo
+{
+ "editorversion" "400"
+ "editorbuild" "5304"
+ "mapversion" "6"
+ "formatversion" "100"
+ "prefab" "0"
+}
+visgroups
+{
+}
+viewsettings
+{
+ "bSnapToGrid" "1"
+ "bShowGrid" "1"
+ "bShowLogicalGrid" "0"
+ "nGridSpacing" "64"
+ "bShow3DGrid" "0"
+}
+world
+{
+ "id" "1"
+ "classname" "worldspawn"
+ "detailmaterial" "detail/detailsprites"
+ "detailvbsp" "detail.vbsp"
+ "hammerid" "1"
+ "mapversion" "6"
+ "maxpropscreenwidth" "-1"
+ "skyname" "sky_day01_01"
+ "world_maxs" "128 128 128"
+ "world_mins" "0 0 0"
+ editor
+ {
+ "color" "255 255 255"
+ }
+}
+entity
+{
+ "id" "2"
+ "angles" "0 0 0"
+ "classname" "info_player_start"
+ "hammerid" "30"
+ "origin" "64 64 0"
+ editor
+ {
+ "color" "255 255 255"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 2]"
+ }
+}
+entity
+{
+ "id" "3"
+ "_cone" "80"
+ "_constant_attn" "0"
+ "_distance" "0"
+ "_exponent" "1"
+ "_fifty_percent_distance" "0"
+ "_hardfalloff" "0"
+ "_inner_cone" "40"
+ "_light" "187 240 255 200"
+ "_lighthdr" "-1 -1 -1 1"
+ "_lightscalehdr" "1"
+ "_linear_attn" "0"
+ "_quadratic_attn" "1"
+ "_zero_percent_distance" "0"
+ "angles" "-90 0 0"
+ "classname" "light_spot"
+ "hammerid" "36"
+ "origin" "64 64 120"
+ "pitch" "-90"
+ "style" "0"
+ editor
+ {
+ "color" "255 255 255"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 3]"
+ }
+}
+entity
+{
+ "id" "4"
+ "classname" "some_ent"
+ "targetname" "rl_source"
+ connections
+ {
+ "OnTrigger" "regular_outputSetAnimationdance0.125-1"
+ "OnSpawn" "basic_destNeedsParam10-1"
+ "OnMulti" "model_1Skin10.5-1"
+ "OnMulti" "model_1Skin01.53"
+ "OnMulti" "pfxStart0.5-1"
+ "OnMulti" "pfxStop1-1"
+ "OnSingle" "model_1Skin101"
+ "OnSingle" "model_1Skin011"
+ "OnSingle" "pfxStart01"
+ "OnSingle" "pfxStop0.51"
+ "OnSpawn" "another_modelBodygroup2560-1"
+ }
+ editor
+ {
+ "color" "255 255 255"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 4]"
+ }
+}
+cameras
+{
+ "activecamera" "-1"
+}
+cordons
+{
+ "active" "0"
+}
diff --git a/tests/test_transforms/test_utils.py b/tests/test_transforms/test_utils.py
new file mode 100644
index 000000000..463008def
--- /dev/null
+++ b/tests/test_transforms/test_utils.py
@@ -0,0 +1,81 @@
+"""Test utilty transform logic."""
+import logging
+from decimal import Decimal
+import operator
+
+from srctools import VMF, Entity
+
+from hammeraddons.bsp_transform.common import check_control_enabled, parse_numeric_specifier, op_always_fail
+
+
+def test_check_control_start_enabled() -> None:
+ """Test the control-enabled options functions, for the start-enabled mode."""
+ vmf = VMF()
+ assert not check_control_enabled(Entity(vmf, {
+ 'ctrl_type': '0', # Start enabled.
+ 'ctrl_value': '0',
+ }))
+ assert check_control_enabled(Entity(vmf, {
+ 'ctrl_type': '0',
+ 'ctrl_value': '1',
+ }))
+
+
+def test_check_control_start_disabled() -> None:
+ """Test the control-enabled options functions, for the start-disabled mode."""
+ vmf = VMF()
+ assert check_control_enabled(Entity(vmf, {
+ 'ctrl_type': '1', # Start disabled
+ 'ctrl_value': '0',
+ }))
+ assert not check_control_enabled(Entity(vmf, {
+ 'ctrl_type': '1',
+ 'ctrl_value': '1',
+ }))
+
+
+def test_check_control_backward_compatiblity() -> None:
+ """Test the control-enabled options functions, when the mode is missing."""
+ vmf = VMF()
+ # Backwards compatibility, if ctrl_type is missing assume Start Enabled.
+ assert not check_control_enabled(Entity(vmf, {
+ 'ctrl_value': '0',
+ }))
+ assert check_control_enabled(Entity(vmf, {
+ 'ctrl_value': '1',
+ }))
+
+
+def test_numeric_parsing_good(caplog) -> None:
+ """Test the numeric parsing function, with good values."""
+ caplog.set_level(logging.WARNING)
+ assert parse_numeric_specifier(' 42 ') == (operator.eq, Decimal('42'))
+ assert parse_numeric_specifier('<3') == (operator.lt, Decimal('3'))
+ assert parse_numeric_specifier(' > 45.872_67') == (operator.gt, Decimal('45.87267'))
+ assert parse_numeric_specifier('>= -0892.930') == (operator.ge, Decimal('-892.93'))
+ assert parse_numeric_specifier('=4') == (operator.eq, Decimal(4))
+ assert parse_numeric_specifier('== -17') == (operator.eq, Decimal(-17))
+ assert parse_numeric_specifier(' != 909') == (operator.ne, Decimal(909))
+ assert parse_numeric_specifier(' =!= 87') == (operator.ne, Decimal(87))
+ assert parse_numeric_specifier('~= 38') == (operator.ne, Decimal(38))
+ assert parse_numeric_specifier(' =/= 24.5') == (operator.ne, Decimal('24.5'))
+ # No warnings caught.
+ assert caplog.record_tuples == []
+
+
+def test_numeric_parsing_bad_op(caplog) -> None:
+ """Test the numeric parsing function, when given an illegal operator."""
+ assert parse_numeric_specifier(' <> 34.83') == (operator.eq, Decimal('34.83'))
+ assert parse_numeric_specifier(' >!> 34.83') == (operator.eq, Decimal('34.83'))
+ assert caplog.record_tuples == [
+ ('srctools.hammeraddons.bsp_transform.common', logging.WARNING, 'Invalid numeric operator "<>"'),
+ ('srctools.hammeraddons.bsp_transform.common', logging.WARNING, 'Invalid numeric operator ">!>"'),
+ ]
+
+
+def test_numeric_parsing_bad_number(caplog) -> None:
+ """Test the numeric parsing function, when given a totally invalid number."""
+ assert parse_numeric_specifier('hello') == (op_always_fail, Decimal())
+ assert caplog.record_tuples == [
+ ('srctools.hammeraddons.bsp_transform.common', logging.WARNING, 'Invalid number "hello"')
+ ]
diff --git a/transforms/areaportals.py b/transforms/areaportals.py
new file mode 100644
index 000000000..218437937
--- /dev/null
+++ b/transforms/areaportals.py
@@ -0,0 +1,28 @@
+"""Optimise brushes used for areaportal windows."""
+from hammeraddons.bsp_transform import Context, trans
+from srctools.logger import get_logger
+
+LOGGER = get_logger(__name__)
+
+
+@trans('Optimise Areaportals')
+def optimise_areaportals(ctx: Context) -> None:
+ """Optimise brushes used for areaportal windows.
+
+ This forces off solidity for func_brush, and clears the physics data.
+ """
+ for ap_ent in ctx.vmf.by_class['func_areaportalwindow']:
+ if ap_ent['target']:
+ for fade_ent in ctx.vmf.search(ap_ent['target']):
+ if fade_ent['classname'] in ['prop_dynamic', 'prop_dynamic_override']:
+ fade_ent['solid'] = '0'
+ elif fade_ent['classname'] in ['func_brush']:
+ fade_ent['solidity'] = '1' # Never Solid
+
+ try:
+ bmodel = ctx.bsp.bmodels[fade_ent]
+ except KeyError:
+ continue # Model ent?
+ else:
+ # For brush models, delete the VPhysics data.
+ bmodel.clear_physics()
diff --git a/transforms/client_target.py b/transforms/client_target.py
new file mode 100644
index 000000000..84df4628d
--- /dev/null
+++ b/transforms/client_target.py
@@ -0,0 +1,28 @@
+"""Automatically enable the clientside flag on info_target entities."""
+from hammeraddons.bsp_transform import Context, trans
+from srctools import Entity, conv_int
+from srctools.logger import get_logger
+
+LOGGER = get_logger(__name__)
+
+KEYVALUES = [
+ ('info_particle_system', [f'cpoint{x}' for x in range(1, 64)]),
+ ('env_instructor_hint', ['hint_target']),
+]
+
+
+@trans('Enable info_target clientside')
+def clientside_info_target(ctx: Context) -> None:
+ """Automatically enable the clientside flag on info_target entities.
+ """
+ for clsname, keys in KEYVALUES:
+ ent: Entity
+ for ent in ctx.vmf.by_class[clsname]:
+ for key in keys:
+ value = ent[key]
+ if not value:
+ continue
+ for target in ctx.vmf.search(value):
+ if target['classname'].casefold() == 'info_target':
+ spawnflags = conv_int(target['spawnflags'])
+ target['spawnflags'] = spawnflags | 1 # Transmit to client (respect PVS)
diff --git a/transforms/comp_adv_output.py b/transforms/comp_adv_output.py
new file mode 100644
index 000000000..c7b9f93d8
--- /dev/null
+++ b/transforms/comp_adv_output.py
@@ -0,0 +1,98 @@
+"""Adds a single output to an entity, with precise control over fixup behaviour.
+
+"""
+import itertools
+import string
+from typing import Any, List, Mapping, Sequence, Union
+
+from srctools import EmptyMapping, conv_float, conv_int
+from srctools.vmf import Output, Entity
+from srctools.logger import get_logger
+
+from hammeraddons.bsp_transform import trans, Context, check_control_enabled
+
+
+class SimpleFormatter(string.Formatter):
+ """Use 1-based indexes for the args, instead of 0-based."""
+ def get_value(self, key: Union[int, str], args: Sequence[Any], kwargs: Mapping[str, Any]) -> Any:
+ """Adjust the key."""
+ if isinstance(key, int) and key > 0:
+ return args[key - 1]
+ raise KeyError(key)
+
+
+LOGGER = get_logger(__name__)
+FORMATTER = SimpleFormatter()
+
+
+@trans('comp_adv_output')
+def advanced_output(ctx: Context) -> None:
+ """Adds a single output to an entity, with precise control over fixup behaviour."""
+ adv_out: Entity
+ for adv_out in ctx.vmf.by_class['comp_adv_output']:
+ adv_out.remove()
+ if not check_control_enabled(adv_out):
+ continue
+
+ output_name = adv_out['out_name']
+ input_name = adv_out['inp_name']
+ target_name = adv_out['target_local'] or adv_out['target_global']
+ times = conv_int(adv_out['times'], -1)
+ if not target_name:
+ LOGGER.warning(
+ 'No target entity for conv_adv_output at ({})!',
+ adv_out['origin'],
+ )
+ continue
+
+ if target_instname := adv_out['target_instname']:
+ target_name = f'{target_name}-{target_instname}'
+
+ delay = conv_float(adv_out['delay'])
+ delay += conv_float(adv_out['delay2'])
+ if delay < 0.0:
+ LOGGER.warning(
+ 'conv_adv_output at ({}) has a negative delay!',
+ adv_out['origin'],
+ )
+ delay = 0.0
+
+ param_args: List[str] = []
+ for ind in itertools.count(1):
+ val = (
+ adv_out[f'params_pos{ind}']
+ or adv_out[f'params_local{ind}']
+ or adv_out[f'params_global{ind}']
+ )
+ if not val:
+ break
+ param_args.append(val)
+
+ parameter = adv_out['params_fmt']
+ if parameter:
+ try:
+ parameter = FORMATTER.vformat(parameter, param_args, EmptyMapping)
+ except Exception:
+ LOGGER.exception(
+ 'Failed to format comp_adv_output at ({}) using format "{}" and parameters {!r}',
+ adv_out['origin'], parameter, param_args
+ )
+ continue
+
+ found_ent = None
+
+ for found_ent in ctx.vmf.search(adv_out['out_ent']):
+ found_ent.add_out(Output(
+ output_name,
+ target_name,
+ input_name,
+ parameter,
+ delay,
+ times=times,
+ ))
+
+ if found_ent is None:
+ LOGGER.warning(
+ 'No entities found named "{}" for comp_adv_output at ({})!',
+ adv_out['target'], adv_out['origin'],
+ )
diff --git a/transforms/comp_case.py b/transforms/comp_case.py
new file mode 100644
index 000000000..466dfaa97
--- /dev/null
+++ b/transforms/comp_case.py
@@ -0,0 +1,218 @@
+"""comp_case is a compile-time collapsible version of logic_case."""
+import math
+from typing import Dict, Iterator, List, Tuple
+
+import hashlib
+import re
+import struct
+import random
+from decimal import Decimal
+from collections import defaultdict
+
+from srctools import Entity, Output, conv_bool, conv_float
+from srctools.math import parse_vec_str
+from srctools.logger import get_logger
+
+from hammeraddons.bsp_transform import (
+ trans, Context,
+ check_control_enabled,
+ NumericSpecifier, parse_numeric_specifier,
+)
+
+
+LOGGER = get_logger(__name__)
+CASES = [f'case{x:02}' for x in range(1, 17)]
+
+
+def collapse_case(ctx: Context, case: Entity) -> None:
+ """Collapse a single case."""
+ multi_cases = conv_bool(case['multiplecasesallowed'])
+ case_name = case['targetname']
+ mode = case['mode'].casefold()
+ default_value = case['value']
+ miss_chance = conv_float(case['misschance'], 0.0) / 100.0
+ desc = f'for comp_case "{case_name}" @ ({case["origin"]})'
+
+ hasher_template = hashlib.sha512()
+ hasher_template.update(f"{case['seed']};{case_name}".encode('utf-8'))
+ hasher_template.update(struct.pack(' random.Random:
+ """Create a seeded RNG, based on the input source."""
+ hasher = hasher_template.copy()
+ hasher.update((source['targetname'] or source['classname']).encode('utf8'))
+ hasher.update(struct.pack(' Iterator[int]:
+ """Find string-based matches."""
+ for case_num in key_params:
+ if param == case_params[case_num]:
+ yield case_num
+ elif mode == 'casefold':
+ def find_matches(param: str) -> Iterator[int]:
+ """Find string-based matches, ignoring cases."""
+ for case_num in key_params:
+ if param.casefold() == case_params[case_num].casefold():
+ yield case_num
+ elif mode == 'numeric':
+ # Pre-parse "< 5" style values.
+ numeric_cases: List[Tuple[NumericSpecifier, int]] = [
+ (parse_numeric_specifier(
+ case_params[case_num],
+ f' for case #{case_num} in {desc}'
+ ), case_num)
+ for case_num in key_params
+ ]
+
+ def find_matches(param: str) -> Iterator[int]:
+ """Find numeric matches, using a configurable operator."""
+ try:
+ num_a = Decimal(param)
+ except ValueError:
+ return # Matches nothing.
+ for (operation, num_b), case_num in numeric_cases:
+ if operation(num_a, num_b):
+ yield case_num
+ elif mode == 'randweight': # Weighted Random, rather different.
+ warned_rand_weight = False
+ weight_outs: List[List[Output]] = [
+ # Pre-concatenate, so we don't have to do it each time.
+ [*out_cases[case_num], *out_used, *out_matched]
+ for case_num in key_out
+ ]
+ cur_val = 0.0
+ cum_weights: List[float] = [
+ cur_val := cur_val + conv_float(case_params.get(case_num, 0.0))
+ for case_num in key_out
+ ]
+ # If we missed, it was used too.
+ out_missed += out_used
+
+ def handle_rand_weight(source: Entity, out: Output) -> List[Output]:
+ """Pick a weighted-random case."""
+ rng = make_rng(source)
+ if 0.0 < miss_chance < rng.random():
+ return out_missed
+ [chosen] = make_rng(source).choices(weight_outs, cum_weights=cum_weights)
+ return chosen
+
+ def warn_rand_weight(source: Entity, out: Output) -> List[Output]:
+ """Warn about invalid use of InValue."""
+ nonlocal warned_rand_weight
+ if not warned_rand_weight:
+ warned_rand_weight = True
+ LOGGER.warning(
+ '{} @ ({}) fired InValue input to comp_case "{}" @ ({}), which is in '
+ 'weighted random mode! Use PickRandom instead, parameters are ignored.',
+ source['targetname'] or source['classname'],
+ source['origin'],
+ case_name, case['origin'],
+ )
+ return []
+
+ ctx.add_io_remap_func(case_name, 'InValue', warn_rand_weight)
+ ctx.add_io_remap_func(case_name, 'Trigger', handle_rand_weight)
+ ctx.add_io_remap_func(case_name, 'PickRandom', handle_rand_weight)
+ return
+ else:
+ LOGGER.error(
+ 'Invalid mode "{}" for comp_case "{}" @ ({})',
+ case['mode'], case_name, case['origin']
+ )
+ return
+
+ def compute_outputs(source: Entity, param: str) -> Iterator[Output]:
+ """Compute the matching cases, then yield the outputs."""
+ yield from out_used # Always used.
+
+ if 0.0 < miss_chance < make_rng(source).random():
+ yield from out_missed
+ return
+
+ matching = find_matches(param)
+ try:
+ first_match = next(matching)
+ except StopIteration:
+ # No match, use defaults.
+ yield from out_default
+ return
+ yield from out_cases[first_match]
+ yield from out_matched
+ if multi_cases: # Include all matches.
+ for match in matching:
+ yield from out_cases[match]
+
+ def handle_pick_random(source: Entity, out: Output) -> List[Output]:
+ """Handle the PickRandom input."""
+ rng = make_rng(source)
+ if 0.0 < miss_chance < rng.random():
+ return out_missed + out_used
+ else:
+ return out_cases[rng.choice(key_out)] + out_used
+
+ ctx.add_io_remap_func(
+ case_name, 'InValue',
+ lambda source, out: list(compute_outputs(source, out.params or default_value)),
+ )
+ ctx.add_io_remap_func(
+ case_name, 'Trigger',
+ lambda source, out: list(compute_outputs(source, default_value)),
+ )
+ ctx.add_io_remap_func(case_name, 'PickRandom', handle_pick_random)
+
+
+@trans('comp_case', priority=10)
+def comp_case(ctx: Context) -> None:
+ """A version of logic_case which is collapsed at compile time."""
+ ent: Entity
+ for ent in ctx.vmf.by_class['comp_case']:
+ ent.remove()
+ if check_control_enabled(ent):
+ collapse_case(ctx, ent)
+ else:
+ # If any entities exist with the same name that aren't comp_case, we need to
+ # keep the inputs.
+ case_name = ent['targetname']
+ if not any(ent['classname'].casefold() != 'comp_case' for ent in ctx.vmf.by_target[case_name]):
+ ctx.add_io_remap_removal(case_name, 'InValue')
+ ctx.add_io_remap_removal(case_name, 'Trigger')
+ ctx.add_io_remap_removal(case_name, 'PickRandom')
diff --git a/transforms/comp_cubemap_parallax.py b/transforms/comp_cubemap_parallax.py
new file mode 100644
index 000000000..667f4bd4b
--- /dev/null
+++ b/transforms/comp_cubemap_parallax.py
@@ -0,0 +1,176 @@
+"""Adds keys to generated cubemap materials to map them to the bounds of a cubeoid."""
+from typing import List, Optional, Tuple
+
+import attrs
+
+from srctools import Matrix, Vec, conv_float
+from srctools.vmt import Material
+from srctools.logger import get_logger
+
+from hammeraddons.bsp_transform import trans, Context
+
+import io
+import re
+
+
+LOGGER = get_logger(__name__)
+# 4x4 matrix, including translation.
+Matrix4 = Tuple[
+ float, float, float, float,
+ float, float, float, float,
+ float, float, float, float,
+ float, float, float, float,
+]
+
+
+def matmul(a: Matrix4, b: Matrix4) -> Matrix4:
+ """Multiply two 4x4 matrixes."""
+ def helper(a: Matrix4, b: Matrix4, x: int, y: int) -> float:
+ """Calculate a single result value."""
+ return a[x] * b[y * 4] + a[x + 4] * b[y * 4 + 1] + a[x + 8] * b[y * 4 + 2] + a[x + 12] * b[y * 4 + 3]
+
+ return (
+ helper(a, b, 0, 0), helper(a, b, 1, 0), helper(a, b, 2, 0), helper(a, b, 3, 0),
+ helper(a, b, 0, 1), helper(a, b, 1, 1), helper(a, b, 2, 1), helper(a, b, 3, 1),
+ helper(a, b, 0, 2), helper(a, b, 1, 2), helper(a, b, 2, 2), helper(a, b, 3, 2),
+ helper(a, b, 0, 3), helper(a, b, 1, 3), helper(a, b, 2, 3), helper(a, b, 3, 3),
+ )
+
+
+@attrs.define
+class Config:
+ """Configuration of a parallax entity."""
+ origin: Vec
+ radius: float
+ radius_sqr: float
+ used: int
+ obb1: str
+ obb2: str
+ obb3: str
+
+
+@trans('comp_cubemap_parallax')
+def comp_cubemap_parallax(ctx: Context):
+ """Modify cubemap materials to contain parallax information."""
+ parallax_cubemap_configs: List[Config] = []
+ for parallax in ctx.vmf.by_class['comp_cubemap_parallax']:
+ parallax.remove()
+
+ origin = Vec.from_str(parallax['origin'])
+ angles = Matrix.from_angstr(parallax['angles'])
+ radius = conv_float(parallax['radius'])
+ mins, maxs = Vec.bbox(
+ Vec.from_str(parallax['mins']),
+ Vec.from_str(parallax['maxs'])
+ )
+ size = maxs - mins
+
+ # ensure bounding box has volume
+ size.max((1.0, 1.0, 1.0))
+
+ # We need a 4-component matrix here because we need to translate
+ translate1_matrix = (
+ 1.0, 0.0, 0.0, -origin[0],
+ 0.0, 1.0, 0.0, -origin[1],
+ 0.0, 0.0, 1.0, -origin[2],
+ 0.0, 0.0, 0.0, 1.0,
+ )
+
+ rotation_matrix = matmul(translate1_matrix, (
+ angles[0, 0], angles[0, 1], angles[0, 2], 0.0,
+ angles[1, 0], angles[1, 1], angles[1, 2], 0.0,
+ angles[2, 0], angles[2, 1], angles[2, 2], 0.0,
+ 0.0, 0.0, 0.0, 1.0,
+ ))
+
+ translate2_matrix = matmul(rotation_matrix, (
+ 1.0, 0.0, 0.0, -mins.x,
+ 0.0, 1.0, 0.0, -mins.y,
+ 0.0, 0.0, 1.0, -mins.z,
+ 0.0, 0.0, 0.0, 1.0,
+ ))
+
+ scale_matrix = matmul(translate2_matrix, (
+ 1.0 / size.x, 0.0, 0.0, 0.0,
+ 0.0, 1.0 / size.y, 0.0, 0.0,
+ 0.0, 0.0, 1.0 / size.z, 0.0,
+ 0.0, 0.0, 0.0, 1.0,
+ ))
+
+ parallax_cubemap_configs.append(Config(
+ origin=origin,
+ radius=radius,
+ radius_sqr=radius**2,
+ used=0,
+ obb1=f"[{scale_matrix[0]:f} {scale_matrix[1]:f} {scale_matrix[2]:f} {scale_matrix[3]:f}]",
+ obb2=f"[{scale_matrix[4]:f} {scale_matrix[5]:f} {scale_matrix[6]:f} {scale_matrix[7]:f}]",
+ obb3=f"[{scale_matrix[8]:f} {scale_matrix[9]:f} {scale_matrix[10]:f} {scale_matrix[11]:f}]",
+ ))
+
+ cubemap_material_name_pattern = re.compile(r"materials/maps/.*_(-?[0-9]+)_(-?[0-9]+)_(-?[0-9]+)\.vmt")
+ for name in ctx.bsp.pakfile.namelist():
+ match = cubemap_material_name_pattern.fullmatch(name)
+ if match is None:
+ continue
+
+ cubemap_origin = Vec(int(match.group(1)), int(match.group(2)), int(match.group(3)))
+
+ best_match: Optional[Config] = None
+ best_match_distance_sqr = -1.0
+ for config in parallax_cubemap_configs:
+ distance_sqr = (cubemap_origin - config.origin).len_sq()
+ if distance_sqr > config.radius_sqr:
+ continue
+ if best_match is None or best_match_distance_sqr > distance_sqr:
+ best_match = config
+ best_match_distance_sqr = distance_sqr
+
+ if best_match is None:
+ continue
+
+ try:
+ material = Material.parse(ctx.bsp.pakfile.read(name).decode('utf-8'), filename=name)
+ except Exception as exc:
+ LOGGER.exception(
+ "Could not parse packed cubemap patch material {}!",
+ name,
+ exc_info=exc,
+ )
+ continue
+
+ if material.shader != 'patch':
+ LOGGER.error(
+ 'Expected cubemap material to have the "patch" shader, but shader is "{}" for {}',
+ material.shader,
+ name
+ )
+ continue
+
+ if len(material.blocks) != 1 or (material.blocks[0].name != 'replace' and material.blocks[0].name != 'insert'):
+ LOGGER.error(
+ 'Expected cubemap material to have exactly one block named either "replace" or "insert" for {}',
+ name
+ )
+ continue
+
+ best_match.used += 1
+
+ material.blocks[0].name = 'insert'
+ with material.blocks[0].build() as builder:
+ builder['$envmapparallax']('1')
+ builder['$envmapparallaxobb1'](best_match.obb1)
+ builder['$envmapparallaxobb2'](best_match.obb2)
+ builder['$envmapparallaxobb3'](best_match.obb3)
+ builder['$envmaporigin'](f'[{cubemap_origin}]')
+
+ encoded = io.StringIO()
+ material.export(encoded)
+ ctx.pack.pack_file(name, data=encoded.getvalue().encode('utf8'))
+
+ for config in parallax_cubemap_configs:
+ if config.used == 0:
+ LOGGER.warning(
+ 'No materials found affected by a cubemap within {} units for comp_cubemap_parallax at ({})!',
+ config.radius,
+ config.origin,
+ )
diff --git a/transforms/comp_entity_finder.py b/transforms/comp_entity_finder.py
index 1aaff6819..198d50e10 100644
--- a/transforms/comp_entity_finder.py
+++ b/transforms/comp_entity_finder.py
@@ -2,6 +2,8 @@
import itertools
import math
from enum import Enum
+from typing import Dict, Optional, Set
+
from srctools import FrozenVec, conv_bool, conv_float, Vec, Entity, Angle
from srctools.logger import get_logger
@@ -32,7 +34,7 @@ class FinderModes(Enum):
@trans('comp_entity_finder')
def entity_finder(ctx: Context):
"""Finds the closest entity of a given type."""
- target_cache: dict[tuple, Entity] = {}
+ target_cache: Dict[tuple, Entity] = {}
for finder in ctx.vmf.by_class['comp_entity_finder']:
finder.remove()
@@ -74,6 +76,7 @@ def entity_finder(ctx: Context):
continue
key = (targ_classes, targ_radius, blacklist, targ_fov, targ_pos)
+ found_ent: Optional[Entity]
try:
found_ent = target_cache[key]
except KeyError:
@@ -98,6 +101,7 @@ def blacklist_func(name: str) -> bool:
# If multiple, it's the union of the sets. If there's a single one
# we don't need to copy by_class[].
+ ent_set: Set[Entity]
if len(targ_classes) == 1:
[single_class] = targ_classes
ent_set = ctx.vmf.by_class[single_class]
@@ -186,7 +190,7 @@ def blacklist_func(name: str) -> bool:
needs_src, needs_known = NEEDS[kv_mode]
- known_ent = None
+ known_ent: Optional[Entity] = None
if needs_known:
known_ent_name = finder['kv{}_known'.format(ind)]
if not known_ent_name:
@@ -222,13 +226,17 @@ def blacklist_func(name: str) -> bool:
found_ent[kv_dest] = kv_src
elif kv_mode is FinderModes.CONST_KNOWN:
# Set constant value on known entity.
+ assert needs_known and known_ent is not None
known_ent[kv_dest] = kv_src
elif kv_mode is FinderModes.TARG_TO_KNOWN:
+ assert needs_known and known_ent is not None
known_ent[kv_dest] = found_ent[kv_src]
elif kv_mode is FinderModes.KNOWN_TO_TARG:
+ assert needs_known and known_ent is not None
found_ent[kv_dest] = known_ent[kv_src]
elif kv_mode is FinderModes.OUTPUT_MERGE:
output_name = '!' + kv_dest.lstrip('!').casefold()
+ assert needs_known and known_ent is not None
for out in known_ent.outputs:
if out.target.casefold() == output_name:
out.target = found_ent['targetname']
diff --git a/transforms/comp_flicker.py b/transforms/comp_flicker.py
index d5804af2e..7d2b17394 100644
--- a/transforms/comp_flicker.py
+++ b/transforms/comp_flicker.py
@@ -1,4 +1,5 @@
"""Fires on/off inputs repeatedly to simulate a flicker-on effect."""
+from typing_extensions import Final
import random
from srctools import Output, lerp, logger, conv_float
@@ -6,15 +7,15 @@
from hammeraddons.bsp_transform import trans, Context
LOGGER = logger.get_logger(__name__)
-INP_TURN_OFF = 'FireUser1'
-OUT_TURN_OFF = 'OnUser1'
-INP_TURN_ON = 'FireUser2'
-OUT_TURN_ON = 'OnUser2'
+INP_TURN_OFF: Final = 'FireUser1'
+OUT_TURN_OFF: Final = 'OnUser1'
+INP_TURN_ON: Final = 'FireUser2'
+OUT_TURN_ON: Final = 'OnUser2'
-INP_FLICK_OFF = 'FireUser3'
-OUT_FLICK_OFF = 'OnUser3'
-INP_FLICK_ON = 'FireUser4'
-OUT_FLICK_ON = 'OnUser4'
+INP_FLICK_OFF: Final = 'FireUser3'
+OUT_FLICK_OFF: Final = 'OnUser3'
+INP_FLICK_ON: Final = 'FireUser4'
+OUT_FLICK_ON: Final = 'OnUser4'
@trans('comp_flicker')
@@ -60,7 +61,10 @@ def comp_flicker(ctx: Context) -> None:
out.output = OUT_FLICK_ON
out.delay += total_time
else:
- LOGGER.warning('Unknown comp_flicker output "{}" for "{}"', out.output, ent_name)
+ LOGGER.warning(
+ 'Unknown comp_flicker output "{}" for "{}"',
+ out.output, ent_name,
+ )
mdl_name = ent['target_mdl']
if mdl_name:
@@ -73,12 +77,16 @@ def comp_flicker(ctx: Context) -> None:
(OUT_FLICK_ON, False, 0.0, total_time),
(OUT_FLICK_OFF, True, total_time, 0.0),
]:
- time = 0
+ time = 0.0
state = start_state
limit = 0
while time < total_time:
state = not state
- ent.add_out(Output(out_name, '!self', INP_TURN_ON if state else INP_TURN_OFF, delay=time))
+ ent.add_out(Output(
+ out_name, '!self',
+ INP_TURN_ON if state else INP_TURN_OFF,
+ delay=time,
+ ))
delay = lerp(time, min_point, max_point, flicker_min, flicker_max)
time += delay + random.uniform(-variance, variance)
@@ -105,4 +113,8 @@ def comp_flicker(ctx: Context) -> None:
break
# Force on exactly at the end time.
- ent.add_out(Output(out_name, '!self', INP_TURN_OFF if start_state else INP_TURN_ON, delay=time))
+ ent.add_out(Output(
+ out_name, '!self',
+ INP_TURN_OFF if start_state else INP_TURN_ON,
+ delay=time,
+ ))
diff --git a/transforms/comp_kv_setter.py b/transforms/comp_kv_setter.py
index 563985ad6..679be83ac 100644
--- a/transforms/comp_kv_setter.py
+++ b/transforms/comp_kv_setter.py
@@ -34,7 +34,7 @@ def kv_setter(ctx: Context) -> None:
kv_name = setter['kv_name']
# Use fixup name if actually set.
- kv_value = setter['kv_value_local'] or setter['kv_value_global']
+ kv_value = setter['kv_value_pos'] or setter['kv_value_local'] or setter['kv_value_global']
if conv_bool(setter['invert']):
kv_value = '0' if conv_bool(kv_value) else '1'
@@ -55,7 +55,7 @@ def kv_setter(ctx: Context) -> None:
except (TypeError, ValueError):
LOGGER.warning(
'Invalid spawnflags mask for comp_kv_setter at ({})!\n'
- 'Provide an integer, 0x45 hex or 0b01101 binary value.',
+ 'Provide an decimal integer, 0x45 hex or 0b01101 binary value.',
mode,
setter['origin'],
)
@@ -66,7 +66,6 @@ def kv_setter(ctx: Context) -> None:
flag_enabled = False
kv_name = kv_name.strip()
- found_ent = None
if not is_flags and not kv_name and not setter.outputs:
# We have nothing to do?
@@ -77,6 +76,8 @@ def kv_setter(ctx: Context) -> None:
setter['origin'],
)
+ found_ent = None
+
for found_ent in ctx.vmf.search(setter['target']):
if is_flags:
spawnflags = conv_int(found_ent['spawnflags', '0'])
diff --git a/transforms/comp_numeric_transition.py b/transforms/comp_numeric_transition.py
index 626345dcb..b44c28cdd 100644
--- a/transforms/comp_numeric_transition.py
+++ b/transforms/comp_numeric_transition.py
@@ -1,14 +1,16 @@
"""Implements an entity which transitions a value from one to another."""
-import math
+from typing import Callable, Dict, Iterator, Optional, Union
from string import ascii_lowercase
-from typing import Callable, Dict, Optional
+import math
-from srctools import conv_float, Output
+from srctools import Entity, conv_float, Output
from srctools.fgd import EntityDef
from srctools.logger import get_logger
+from srctools.vmf import conv_kv
from hammeraddons.bsp_transform import trans, Context
+
LOGGER = get_logger(__name__)
halfpi = math.pi / 2.0
@@ -17,7 +19,7 @@
EPSILON = 1e-6
BRIGHT_LETTERS = {
- let : i/25
+ let: i/25
for i, let in enumerate(ascii_lowercase)
}
@@ -43,6 +45,7 @@ def lerp(x: float, in_min: float, in_max: float, out_min: float, out_max: float)
@trans('comp_numeric_transition')
def numeric_transition(ctx: Context) -> None:
"""When triggered, animates a keyvalue/input over time with various options."""
+ ent: Entity
for ent in ctx.vmf.by_class['comp_numeric_transition']:
ent['classname'] = 'logic_relay'
@@ -59,7 +62,8 @@ def numeric_transition(ctx: Context) -> None:
# Special case - if the transform type is "light", allow parsing these
# as A-Z values.
- value_start = value_end = None # type: Optional[float]
+ value_start: Optional[float] = None
+ value_end: Optional[float] = None
if transform_type == 'light':
value_start = BRIGHT_LETTERS.get(ent['startval'].lower(), None)
value_end = BRIGHT_LETTERS.get(ent['endval'].lower(), None)
@@ -128,6 +132,7 @@ def numeric_transition(ctx: Context) -> None:
ease_end_func = ease_func_linear
def compute_point(x: float) -> float:
+ """Apply the easing equations to compute the value."""
pos = x * ease_start_func(x) + (1.0 - x) * ease_end_func(x)
if pos < 0.0:
pos = 0.0
@@ -141,6 +146,7 @@ def compute_point(x: float) -> float:
point_count = 1
points = [i / point_count for i in range(int(point_count))]
+ result: Iterator[Union[str, float]]
if transform_type == 'speed':
# Compute the speed from x to x+1
result = (
@@ -172,6 +178,12 @@ def compute_point(x: float) -> float:
# Directly sets the location at every point.
result = map(compute_point, points)
+ # Add the duration so the output fires after the transition finishes.
+ for out in ent.outputs:
+ if out.output.casefold() == 'onfinished':
+ out.output = 'OnTrigger'
+ out.delay += duration
+
last_inp = None
for i, point in enumerate(result):
if io_type == 'kv':
@@ -179,7 +191,7 @@ def compute_point(x: float) -> float:
param = '{} {}'.format(input_name, point)
else: # input
io_input = input_name
- param = format(point)
+ param = conv_kv(point)
if param != last_inp:
ent.add_out(Output(
@@ -226,18 +238,18 @@ def ease_func_sine_end(x: float) -> float:
return 1.0 - math.cos(x * halfpi)
-EASE_START_FUNC = {
+EASE_START_FUNC: Dict[str, Callable[[float], float]] = {
'linear': ease_func_linear,
'quad': ease_func_power_start(2),
'cubic': ease_func_power_start(3),
'quartic': ease_func_power_start(4),
'sine': ease_func_sine_start,
-} # type: Dict[str, Callable[[float], float]]
+}
-EASE_END_FUNC = {
+EASE_END_FUNC: Dict[str, Callable[[float], float]] = {
'linear': ease_func_linear,
'quad': ease_func_power_end(2),
'cubic': ease_func_power_end(3),
'quartic': ease_func_power_end(4),
'sine': ease_func_sine_end,
-} # type: Dict[str, Callable[[float], float]]
+}
diff --git a/transforms/comp_scriptvar_setter.py b/transforms/comp_scriptvar_setter.py
index 7d25cc7b7..42c1bc9bb 100644
--- a/transforms/comp_scriptvar_setter.py
+++ b/transforms/comp_scriptvar_setter.py
@@ -2,7 +2,9 @@
from __future__ import annotations
import re
from collections import defaultdict
-from typing import Type, Optional, Callable, Union
+from typing import Dict, TYPE_CHECKING, Optional, Callable, Union
+
+from typing_extensions import TypeAlias
from srctools.fgd import EntityDef, ValueTypes
from srctools.logger import get_logger
@@ -14,6 +16,10 @@
LOGGER = get_logger(__name__)
MODES: dict[str, Callable[[Entity, Entity], str]] = {}
+if TYPE_CHECKING:
+ EllipsisType: TypeAlias = ellipsis # Fake name before 3.10
+else:
+ EllipsisType = type(...)
def vs_vec(vec: Vec) -> str:
@@ -68,7 +74,7 @@ def make_code(self) -> str:
for x in array
]))
else:
- return self.scalar
+ return self.scalar if self.scalar is not None else 'null'
@trans('comp_scriptvar_setter')
@@ -78,12 +84,12 @@ def comp_scriptvar(ctx: Context):
set_vars: dict[Entity | None, dict[str, VarData]] = defaultdict(lambda: defaultdict(VarData))
# If the index is None, there's no index.
# If an int, that specific one.
- # If ..., blank index and it's inserted anywhere that fits.
+ # If ..., blank index, and it's inserted anywhere that fits.
for comp_ent in ctx.vmf.by_class['comp_scriptvar_setter']:
comp_ent.remove()
var_name = comp_ent['variable']
- index: Union[int, Type[Ellipsis], None] = None
+ index: Union[int, EllipsisType, None] = None
if not check_control_enabled(comp_ent):
continue
@@ -339,7 +345,7 @@ def mode_func(comp_ent: Entity, ent: Entity) -> str:
)
# Keyvalue types -> equivalent Squirrel code, if not just stringified.
-KEYVALUES = {
+KEYVALUES: Dict[ValueTypes, Callable[[str], str]] = {
ValueTypes.VOID: lambda val: 'null',
ValueTypes.SPAWNFLAGS: str,
diff --git a/transforms/comp_sequential_call.py b/transforms/comp_sequential_call.py
index 13850d7f5..d55062528 100644
--- a/transforms/comp_sequential_call.py
+++ b/transforms/comp_sequential_call.py
@@ -1,7 +1,7 @@
+from typing import Iterable, List, Dict, Iterator, Tuple
import itertools
import random
import re
-from collections.abc import Iterator
from srctools import Vec, Entity, Output, conv_bool, conv_float, lerp
import srctools.logger
@@ -27,7 +27,7 @@ def sequential_call(ctx: Context) -> None:
for seq_call in ctx.vmf.by_class['comp_sequential_call']:
seq_call['classname'] = 'logic_relay'
- target_ents: list[Entity] = list(ctx.vmf.search(seq_call['target']))
+ target_ents: List[Entity] = list(ctx.vmf.search(seq_call['target']))
if not target_ents:
LOGGER.warning(
'Sequential call "{}" at {} could find no target entities named "{}"!',
@@ -43,7 +43,7 @@ def sequential_call(ctx: Context) -> None:
origin = Vec.from_str(seq_call['origin'])
if order_mode.startswith('dist'):
- dist_to_ent: dict[Entity, float] = {
+ dist_to_ent: Dict[Entity, float] = {
ent: (Vec.from_str(ent['origin']) - origin).mag()
for ent in target_ents
}
@@ -62,10 +62,10 @@ def sequential_call(ctx: Context) -> None:
f'"{seq_call["targetname"]}" at ({seq_call["origin"]}).'
)
- ent_and_delay: Iterator[tuple[Entity, float]] = []
+ ent_and_delay: Iterable[Tuple[Entity, float]] = []
if max_dist < 1e-6 or time_val == 0.0:
# No total delay, skip computation and any divide by zero.
- ent_and_delay[:] = zip(target_ents, itertools.repeat(0.0))
+ ent_and_delay = zip(target_ents, itertools.repeat(0.0))
elif time_mode == 'total':
time_start, time_end = (time_val, 0.0) if order_mode.endswith('_inv') else (0.0, time_val)
# Special case, if total and dist selected, lerp by distance, not evenly spaced.
@@ -88,9 +88,9 @@ def sequential_call(ctx: Context) -> None:
f'"{seq_call["targetname"]}" at ({seq_call["origin"]}).'
)
- outputs_rep: list[Output] = []
- outputs_final: list[Output] = []
- outputs_other: list[Output] = []
+ outputs_rep: List[Output] = []
+ outputs_final: List[Output] = []
+ outputs_other: List[Output] = []
for out in seq_call.outputs:
out_name = out.output.casefold()
if out_name == 'onseq':
diff --git a/transforms/fgd_tweaks/func_physbox.py b/transforms/fgd_tweaks/func_physbox.py
new file mode 100644
index 000000000..4d1cf1a6e
--- /dev/null
+++ b/transforms/fgd_tweaks/func_physbox.py
@@ -0,0 +1,29 @@
+"""Allow physboxes to completely override the mass of physics brushes."""
+from srctools import conv_float, logger
+
+from hammeraddons.bsp_transform import trans, Context
+from srctools.bsp import BModel
+
+
+LOGGER = logger.get_logger(__name__)
+
+
+@trans('FGD - func_physbox mass override')
+def mass_override(ctx: Context) -> None:
+ """Allow overriding the mass entirely for physboxes."""
+ for ent in iter(ctx.vmf.by_class['func_physbox']):
+ override = ent.pop('ha_override_mass')
+ if conv_float(override) <= 0.0:
+ continue
+ try:
+ bmodel: BModel = ctx.bsp.bmodels[ent]
+ except KeyError:
+ LOGGER.warning(
+ 'func_physbox "{}" @ {} is not a brush?',
+ ent['targetname'], ent['origin'],
+ )
+ continue
+ if bmodel.phys_keyvalues is None:
+ continue
+ for solid in bmodel.phys_keyvalues.find_all('solid'):
+ solid['mass'] = override
diff --git a/transforms/fgd_tweaks/mat_modify_control.py b/transforms/fgd_tweaks/mat_modify_control.py
new file mode 100644
index 000000000..989645bd9
--- /dev/null
+++ b/transforms/fgd_tweaks/mat_modify_control.py
@@ -0,0 +1,133 @@
+"""Tweak material_modify_control to avoid the variable showing up in instances."""
+from collections.abc import Iterable
+from typing import Counter, Dict, Set, Tuple
+
+import srctools.logger
+from hammeraddons.bsp_transform import trans, Context
+from srctools import Entity, conv_bool
+from srctools.bsp import BModel
+from srctools.mdl import Model
+from srctools.tokenizer import TokenSyntaxError
+from srctools.vmt import Material
+
+
+LOGGER = srctools.logger.get_logger(__name__)
+
+
+@trans('FGD - material_modify_control')
+def material_modify_control(ctx: Context) -> None:
+ """Prepend $ to mat-mod-control variable keyvalues if required.
+
+ This allows Hammer to not detect this as a fixup variable.
+ """
+ # Material name -> does it have either materialmodify or materialmodifyanimated proxies.
+ mat_has_proxy: Dict[str, bool] = {}
+ # Model or "*xx" index -> list of relevant materials.
+ model_mats: Dict[str, Iterable[str]] = {}
+ fsys = ctx.pack.fsys # Close over just filesystem.
+
+ def material_has_proxy(mat_name: str) -> bool:
+ """Check if this material has the proxy."""
+ lowered = mat_name.casefold()
+ if not lowered.startswith(('materials/', 'materials\\')):
+ mat_name = f'materials/{mat_name}'
+ lowered = f'materials/{lowered}'
+ if not lowered.endswith('.vmt'):
+ mat_name += '.vmt'
+ lowered += '.vmt'
+ try:
+ return mat_has_proxy[lowered]
+ except KeyError:
+ pass
+ try:
+ file = fsys[mat_name]
+ except FileNotFoundError:
+ LOGGER.warning('Material "{}" does not exist!', mat_name)
+ mat_has_proxy[lowered] = False
+ return False
+ with file.open_str() as f:
+ try:
+ mat = Material.parse(f, mat_name)
+ mat = mat.apply_patches(fsys)
+ except (TokenSyntaxError, ValueError) as exc:
+ LOGGER.warning('Material "{}" is not valid: ', exc_info=exc)
+ for proxy in mat.proxies:
+ if proxy.name in ('materialmodify', 'materialmodifyanimated'):
+ mat_has_proxy[lowered] = True
+ return True
+ mat_has_proxy[lowered] = False
+ return False
+
+ matmod: Entity
+ for matmod in ctx.vmf.by_class['material_modify_control']:
+ var_name = matmod['materialvar']
+ if var_name and not var_name.startswith(('$', '%')):
+ matmod['materialvar'] = '$' + var_name
+
+ if not conv_bool(matmod.pop('srctools_search_parent')):
+ continue
+ filter_mat = matmod['materialname'].casefold()
+
+ targets: Set[Tuple[str, str]] = set()
+ ent_materials: Iterable[str]
+ found_count = Counter[str]()
+ for parent in ctx.vmf.search(matmod['parentname']):
+ found_count[parent['targetname']] += 1
+ try:
+ bsp_model: BModel = ctx.bsp.bmodels[parent]
+ except KeyError: # It must be a prop?
+ prop_model = parent['model']
+ if not prop_model:
+ LOGGER.warning(
+ 'Parent "{}" of mat-mod-control "{}" has no model?',
+ parent['targetname'], matmod['targetname'],
+ )
+ continue
+ try:
+ ent_materials = model_mats[prop_model]
+ except KeyError:
+ # Get all the materials this model uses.
+ try:
+ mdl = Model(fsys, fsys[prop_model])
+ except FileNotFoundError:
+ LOGGER.warning(
+ 'Model "{}" does not exist for "{}"',
+ prop_model, parent['targetname'],
+ )
+ model_mats[prop_model] = ()
+ continue
+ except ValueError:
+ LOGGER.warning('Invalid model "{}"', prop_model)
+ model_mats[prop_model] = ()
+ continue
+ ent_materials = model_mats[prop_model] = list(mdl.iter_textures())
+ del mdl # Complicated.
+ else: # A BSP model.
+ ent_materials = {
+ texinfo.mat
+ for face in bsp_model.faces
+ if (texinfo := face.texinfo) is not None
+ }
+ for mat in ent_materials:
+ if material_has_proxy(mat) and (not filter_mat or filter_mat in mat.casefold()):
+ targets.add((parent['targetname'], mat))
+ duplicates = found_count.most_common(2)
+ if duplicates:
+ LOGGER.warning(
+ '"{}" has multiple entities with the same name in parents! '
+ 'Only one with each name will be affected:\n{}',
+ matmod['targetname'],
+ '\n'.join([f'- {name}' for name, count in duplicates]),
+ )
+ LOGGER.debug('"{}": {} ents to generate', matmod['targetname'], len(targets))
+ if not targets:
+ LOGGER.warning('"{}"\'s parent has no valid materials!', matmod['targetname'])
+ # Leave it unchanged, in case the material name happens to actually be correct.
+ else:
+ targ_iter = iter(targets)
+ matmod['parentname'], matmod['materialname'] = next(targ_iter)
+ for parent_name, extra_mat in targ_iter:
+ matmod_extra = matmod.copy()
+ ctx.vmf.add_ent(matmod_extra)
+ matmod_extra['parentname'] = parent_name
+ matmod_extra['materialname'] = extra_mat
diff --git a/transforms/geocable.py b/transforms/geocable.py
index babba5381..4c816fe41 100644
--- a/transforms/geocable.py
+++ b/transforms/geocable.py
@@ -1,4 +1,9 @@
"""Compile static prop cables, instead of sprites."""
+from typing import (
+ Optional, List, Tuple, FrozenSet, Callable,
+ TypeVar, MutableMapping, NewType, Set, Iterable, Dict, Iterator, cast,
+)
+from typing_extensions import Final, Self
import itertools
import math
import struct
@@ -6,16 +11,12 @@
from collections import defaultdict
from enum import Enum
from pathlib import Path
-from typing import (
- Optional, List, Tuple, FrozenSet,
- TypeVar, MutableMapping, NewType, Set, Iterable, Dict, Iterator,
-)
import attrs
import trio
from srctools import (
- logger, conv_int, conv_float, conv_bool,
+ FrozenVec, logger, conv_int, conv_float, conv_bool,
Vec, Entity, Matrix, Angle, lerp, FileSystem,
)
from srctools.bsp import StaticProp, StaticPropFlags, VisLeaf, VisTree
@@ -23,6 +24,7 @@
from hammeraddons.mdl_compiler import ModelCompiler
from hammeraddons.bsp_transform import Context, trans
+from hammeraddons.splines import parallel_transport
LOGGER = logger.get_logger(__name__)
NodeID = NewType('NodeID', str)
@@ -62,6 +64,23 @@ class InterpType(Enum):
STRAIGHT = 0
CATMULL_ROM = 1
ROPE = 2
+ BEZIER = 3
+
+
+class VactubeGenType(Enum):
+ """How vactube models should be generated.
+
+ Splitting the glass and frame parts produces better lighting.
+ """
+ COMBINE = 0
+ SEPARATE = 1
+
+
+class VactubeGenPartType(Enum):
+ """What part of the vactube model to generate."""
+ ALL = 0 # Both glass + frame, or not a vactube.
+ GLASS = 1 # Glass only + collision.
+ FRAME = 2 # Frame only.
class RopeType(Enum):
@@ -85,7 +104,6 @@ class SegPropOrient(Enum):
RAND_YAW = 'rand_yaw'
RAND_FULL = 'rand'
-
@attrs.define
class RopePhys:
"""Holds the data for move_rope simulation."""
@@ -97,12 +115,12 @@ class RopePhys:
radius: float # Just to transfer to the node.
-ROPE_GRAVITY = -1500
-SIM_TIME = 5.00
-TIME_STEP = 1/50
+ROPE_GRAVITY: Final = -1500
+SIM_TIME: Final = 5.00
+TIME_STEP: Final = 1/50
-@attrs.frozen(hash=False)
+@attrs.frozen
class SegPropConf:
"""Defines configuration for a set of props placed across the rope."""
weight: int
@@ -133,7 +151,8 @@ def __hash__(self) -> int:
VAC_RADIUS = 45.0
VAC_COLL_RADIUS = 52.0
VAC_MAT = 'models/props_backstage/vacum_pipe'
-
+# Pos/radius pairs defining cylinders, for visleaf computation.
+CollData = List[Tuple[Vec, float, Vec, float]]
@attrs.define
class SegProp:
@@ -143,6 +162,16 @@ class SegProp:
orient: Matrix
+@attrs.define
+class ModelContainer:
+ """Temporary container for static props generated."""
+ model_name: str
+ light_origin: Vec
+ coll_data: CollData
+ seg_props: List[SegProp]
+ flags: StaticPropFlags
+
+
@attrs.frozen
class Config:
"""Configuration specified in rope entities. This can be shared to reduce duplication."""
@@ -160,7 +189,7 @@ class Config:
coll_segments: int
coll_side_count: int
seg_props: FrozenSet[SegPropConf]
- prop_rendercolor: Tuple[float, float, float]
+ prop_rendercolor: FrozenVec
prop_renderalpha: int
prop_no_shadows: bool
prop_no_vert_light: bool
@@ -169,11 +198,15 @@ class Config:
prop_fade_min_dist: float
prop_fade_max_dist: float
prop_fade_scale: float
+ vac_separate_glass: VactubeGenType
@staticmethod
def _parse_min(ent: Entity, keyvalue: str, minimum: Number, message: str) -> Number:
"""Helper for passing all the numeric keys."""
- value = (conv_float if isinstance(minimum, float) else conv_int)(ent[keyvalue], minimum)
+ value: Number = cast(
+ 'Callable[[str, Number], Number]',
+ (conv_float if isinstance(minimum, float) else conv_int),
+ )(ent[keyvalue], minimum)
if value < minimum:
LOGGER.warning(message, ent['origin'])
return minimum
@@ -185,7 +218,7 @@ def is_vactube(self) -> bool:
return self.type.is_vactube
@classmethod
- def parse(cls, ent: Entity, name_to_segprops: Dict[str, FrozenSet[SegPropConf]]) -> 'Config':
+ def parse(cls, ent: Entity, name_to_segprops: Dict[str, FrozenSet[SegPropConf]]) -> Self:
"""Parse from an entity."""
segments = cls._parse_min(
ent, 'segments', 0,
@@ -202,6 +235,22 @@ def parse(cls, ent: Entity, name_to_segprops: Dict[str, FrozenSet[SegPropConf]])
else:
material = 'models/props_backstage/vacum_pipe_glass'
+ try:
+ interp_type = InterpType(int(ent['positioninterpolator', '1']))
+ except ValueError:
+ LOGGER.warning(
+ 'Unknown interpolation type "{}" '
+ 'for vactube at {}!',
+ ent['interpolationtype'],
+ ent['origin'],
+ )
+ interp_type = InterpType.CATMULL_ROM
+
+ if conv_bool(ent['vac_separateglass']):
+ vac_separate_glass = VactubeGenType.SEPARATE
+ else:
+ vac_separate_glass = VactubeGenType.COMBINE
+
# Side counts are the same as the original models.
side_count = 24
if conv_bool(ent['collisions']):
@@ -211,13 +260,13 @@ def parse(cls, ent: Entity, name_to_segprops: Dict[str, FrozenSet[SegPropConf]])
coll_side_count = 0
coll_segments = -1
radius = VAC_RADIUS
- slack = 0 # Unused.
- interp_type = InterpType.CATMULL_ROM
+ slack = 0.0 # Unused.
u_min = 0.0
u_max = 1.0
v_scale = 1.0
flip_uv = False
seg_props = VAC_SEG_CONF_SET
+
else:
rope_type = RopeType.ROPE
# There's not really a vanilla material we can use for cables.
@@ -258,6 +307,7 @@ def parse(cls, ent: Entity, name_to_segprops: Dict[str, FrozenSet[SegPropConf]])
u_min = abs(conv_float(ent['u_min'], 0.0))
u_max = abs(conv_float(ent['u_max'], 1.0))
flip_uv = conv_bool(ent['mat_rotate'])
+ vac_separate_glass = VactubeGenType.COMBINE
try:
seg_props = name_to_segprops[ent['bunting'].casefold()]
@@ -282,7 +332,7 @@ def parse(cls, ent: Entity, name_to_segprops: Dict[str, FrozenSet[SegPropConf]])
coll_segments,
coll_side_count,
seg_props,
- tuple(Vec.from_str(ent['rendercolor'], 255, 255, 255)),
+ FrozenVec.from_str(ent['rendercolor'], 255, 255, 255),
alpha,
conv_bool(ent['disableshadows']),
conv_bool(ent['disablevertexlighting']),
@@ -291,9 +341,10 @@ def parse(cls, ent: Entity, name_to_segprops: Dict[str, FrozenSet[SegPropConf]])
conv_float(ent['fademindist'], -1.0),
conv_float(ent['fademaxdist'], 0.0),
conv_float(ent['fadescale'], 0.0),
+ vac_separate_glass
)
- def coll(self) -> Optional['Config']:
+ def coll(self) -> Self:
"""Extract the collision options from the ent."""
return attrs.evolve(
self,
@@ -316,12 +367,7 @@ class NodeEnt:
def relative_to(self, off: Vec) -> 'NodeEnt':
"""Return a copy relative to the specified origin."""
- return NodeEnt(
- self.pos - off,
- self.config,
- self.id,
- self.group,
- )
+ return attrs.evolve(self, pos=self.pos - off)
def __hash__(self) -> int:
"""Hash the vector with the rest of the values."""
@@ -332,7 +378,7 @@ def __hash__(self) -> int:
))
-@attrs.define(eq=False)
+@attrs.define(eq=False, repr=False)
class Node:
"""All the data for a node, used during construction of the geo.
@@ -385,14 +431,14 @@ def __repr__(self) -> str:
async def build_rope(
- nodes_and_conn: Tuple[FrozenSet[NodeEnt], FrozenSet[Tuple[NodeID, NodeID]]],
+ rope_key: Tuple[FrozenSet[NodeEnt], FrozenSet[Tuple[NodeID, NodeID]], Tuple[str, ...], VactubeGenPartType],
temp_folder: Path,
mdl_name: str,
args: Tuple[Vec, FileSystem],
-) -> Tuple[Vec, List[Tuple[Vec, float, Vec, float]], List[SegProp], List[List[Vec]]]:
- """Construct the geometry for a rope."""
+) -> Tuple[Vec, CollData, List[SegProp], List[List[Vec]]]:
+ """Construct the geometry for a rope. nodes_and_conn is saved into file system to check if the model needs to be recompiled. args is for information that can be lost after the compile"""
LOGGER.info('Building rope {}', mdl_name)
- ents, connections = nodes_and_conn
+ ents, connections, skins, vacgentype = rope_key
offset, fsys = args
mesh = Mesh.blank('root')
@@ -405,16 +451,24 @@ async def build_rope(
compute_orients(nodes)
compute_verts(nodes, bone, is_coll=False)
- mesh.triangles.extend(generate_straights(nodes))
+ # compile_rope uses VactubeGenPartType.ALL for all other rope generation
+ # skip this when only generating frame
+ if vacgentype != VactubeGenPartType.FRAME:
+ mesh.triangles.extend(generate_straights(nodes))
generate_caps(nodes, mesh, is_coll=False)
# All or nothing.
is_vactube = next(iter(nodes)).config.is_vactube
vac_points: List[List[Vec]] = []
- if is_vactube:
+ if is_vactube and (vacgentype == VactubeGenPartType.FRAME or vacgentype == VactubeGenPartType.ALL):
mesh.triangles.extend(generate_vac_beams(nodes, bone, vac_points))
- seg_props = list(place_seg_props(nodes, fsys, mesh))
+ # appends rings to the tube model
+ # skip this when only generating glass
+ if vacgentype != VactubeGenPartType.GLASS:
+ seg_props = list(place_seg_props(nodes, fsys, mesh))
+ else:
+ seg_props = []
if coll_nodes:
# Generate the collision mesh.
@@ -425,7 +479,7 @@ async def build_rope(
coll_mesh.triangles.extend(generate_straights(coll_nodes))
generate_caps(coll_nodes, coll_mesh, is_coll=True)
- # Move the UVs around so they don't extend too far.
+ # Move the UVs around, so they don't extend too far.
for tri in mesh.triangles:
u = math.floor(min(point.tex_u for point in tri))
v = math.floor(min(point.tex_v for point in tri))
@@ -439,19 +493,47 @@ async def build_rope(
# the whole model.
light_origin = min((node.pos for node in nodes), key=Vec.mag_sq)
+ # Studiomdl seems to rotate everything 90 degrees...
+ orient_fix = Matrix.from_yaw(270)
+
+ fixed_visual_mesh = Mesh.blank('root')
+ fixed_visual_mesh.append_model(mesh, rotation=orient_fix)
+
with (temp_folder / 'cable.smd').open('wb') as fb:
- mesh.export(fb)
+ fixed_visual_mesh.export(fb)
if coll_nodes:
+ fixed_coll_mesh = Mesh.blank('root')
+ fixed_coll_mesh.append_model(coll_mesh, rotation=orient_fix)
with (temp_folder / 'cable_phy.smd').open('wb') as fb:
- coll_mesh.export(fb)
+ fixed_coll_mesh.export(fb)
+ del coll_mesh, fixed_coll_mesh
+
+ del mesh, fixed_visual_mesh
with (temp_folder / 'model.qc').open('w') as f:
- # Desolation needs this hint.
- if is_vactube and hasattr(Mesh, 'NEED_TRANSLUCENT_MOSTLYOPAQUE'):
- f.write('$mostlyopaque\n')
+ if is_vactube:
+ # Desolation needs this hint.
+ if hasattr(Mesh, 'NEED_TRANSLUCENT_MOSTLYOPAQUE') and vacgentype is VactubeGenPartType.ALL:
+ f.write('$mostlyopaque\n')
+ elif vacgentype is VactubeGenPartType.FRAME:
+ f.write('$opaque\n')
+
f.write(QC_TEMPLATE.format(path=mdl_name, light_origin=light_origin))
+ if skins:
+ f.write('$texturegroup "skinfamilies" {\n')
+ try:
+ [first_mat] = {node.config.material for node in nodes}
+ except ValueError:
+ raise NotImplementedError(
+ 'Using multiple skins for a rope using different materials '
+ 'for different segments is not supported.'
+ ) from None
+ f.write(f' {{ "{first_mat}" }}\n')
+ for mat in skins:
+ f.write(f' {{ "{mat}" }}\n')
+ f.write('}\n')
if coll_nodes:
- f.write(QC_TEMPLATE_PHYS.format(count=sum(node.next is not None for node in coll_nodes)))
+ f.write(QC_TEMPLATE_PHYS.format(count=sum(node.next is not None for node in coll_nodes) + 8))
# For visleaf computation, build a list of all the actual segments generated.
coll_data = [
@@ -469,18 +551,18 @@ def build_node_tree(
) -> Tuple[Set[Node], Set[Node]]:
"""Convert the ents/connections definitions into a node tree."""
# Convert them all into the real node objects.
- id_to_node: dict[str, tuple[Node, Optional[Node]]] = {}
- vis_nodes: set[Node] = set()
+ id_to_node: Dict[str, Tuple[Node, Optional[Node]]] = {}
+ vis_nodes: Set[Node] = set()
coll_nodes: Set[Node] = set()
- for node in ents:
- vis_node = Node(node.pos.copy(), node.config)
+ for node_ent in ents:
+ vis_node = Node(node_ent.pos.copy(), node_ent.config)
vis_nodes.add(vis_node)
- if node.config.coll_side_count >= 3:
- coll_node = Node(node.pos.copy(), node.config.coll())
+ if node_ent.config.coll_side_count >= 3:
+ coll_node = Node(node_ent.pos.copy(), node_ent.config.coll())
coll_nodes.add(coll_node)
else:
coll_node = None
- id_to_node[node.id] = (vis_node, coll_node)
+ id_to_node[node_ent.id] = (vis_node, coll_node)
def maybe_split(nodes: Set[Node], node: Node, direction: str) -> Node:
"""Split nodes to ensure they only have 1 or 2 connections.
@@ -561,7 +643,7 @@ def interpolate_catmull_rom(node1: Node, node2: Node, seg_count: int) -> List[No
t1 = t0 + (p1-p0).mag()
t2 = t1 + (p2-p1).mag()
t3 = t2 + (p3-p2).mag()
- points: list[Node] = []
+ points: List[Node] = []
for i in range(1, seg_count + 1):
t = lerp(i, 0, seg_count + 1, t1, t2)
A1 = (t1-t)/(t1-t0)*p0 + (t-t0)/(t1-t0)*p1
@@ -603,7 +685,7 @@ def interpolate_rope(node1: Node, node2: Node, seg_count: int) -> List[Node]:
]
springs = list(zip(points, points[1:]))
- time = 0
+ time = 0.0
step = TIME_STEP
gravity = Vec(z=ROPE_GRAVITY) * step**2
# Valve uses 3 iterations, but they only ever have 10 subdivisions.
@@ -646,40 +728,122 @@ def interpolate_rope(node1: Node, node2: Node, seg_count: int) -> List[Node]:
]
+def interpolate_bezier(first_node: Node, last_node: Node, curve_segment_count: int) -> List[Node]:
+ """Interpolate a bezier curve, for better 90 degrees turn."""
+ # reference:
+ # https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm
+ points: List[Node] = []
+ increment = 1 / curve_segment_count
+ # Only the segment count set in the first spline object counts
+ curve_x = []
+ curve_y = []
+ curve_z = []
+ curnode: Optional[Node] = first_node
+ while curnode is not None:
+ curve_x.append(curnode.pos.x)
+ curve_y.append(curnode.pos.y)
+ curve_z.append(curnode.pos.z)
+ curnode = curnode.next
+ # We do not calculate the first and last node of this curve
+ for l in range(1,curve_segment_count-1):
+ t = l * increment
+ x = de_casteljau(t,curve_x)
+ y = de_casteljau(t,curve_y)
+ z = de_casteljau(t,curve_z)
+ n = Node(Vec(x,y,z), first_node.config, first_node.radius)
+ points.append(n)
+
+ last_node.config = first_node.config
+
+ LOGGER.debug("Bezier Nodes Generated: ",points)
+ return points
+
+def de_casteljau(t, coefs):
+ beta = [c for c in coefs] # values in this list are overridden
+ n = len(beta)
+ for j in range(1, n):
+ for k in range(n - j):
+ beta[k] = beta[k] * (1 - t) + beta[k + 1] * t
+ return beta[0]
+
+def find_all_connected_exclude_firstlast(node: Node) -> Tuple[List[Node], Optional[Node], Optional[Node]]:
+ node_list: List[Node] = [node]
+ cur_back: Optional[Node] = node
+ cur_forward: Optional[Node] = node
+
+ while cur_back.prev is not None:
+ cur_back = cur_back.prev
+ node_list.append(cur_back)
+ assert cur_back.prev != node, 'Circular Node Detected'
+
+ while cur_forward.next is not None:
+ cur_forward = cur_forward.next
+ node_list.append(cur_forward)
+ assert cur_forward.next != node, 'Circular Node Detected'
+
+ if cur_back.prev is None:
+ node_list.remove(cur_back)
+ if cur_forward.next is None:
+ node_list.remove(cur_forward)
+ return node_list, cur_back, cur_forward
+
+
def interpolate_all(nodes: Set[Node]) -> None:
"""Produce nodes in-between each user-made node."""
- # Create the nodes and put them in a seperate list, then add them
+ # Create the nodes and put them in a separate list, then add them
# to the actual nodes list second. This way sections that have been interpolated
# don't affect the interpolation of neighbouring sections.
+ seen_bezier_nodes: Set[Node] = set()
+ # Add None in here to make code simpler to handle - we always ignore missing endpoints.
+ seen_bezier_nodes_ignore: Set[Optional[Node]] = {None}
+
segments: List[List[Node]] = []
for node1 in nodes:
if node1.next is None or node1.config.segments <= 0:
continue
- node2 = node1.next
+
interp_type = node1.config.interp
+
+ if interp_type is InterpType.BEZIER:
+ if node1 in seen_bezier_nodes or node1 in seen_bezier_nodes_ignore:
+ continue
+ b_curve, first, last = find_all_connected_exclude_firstlast(node1)
+ LOGGER.debug("Curve Keyframes: ",first, b_curve, last)
+ seen_bezier_nodes.update(b_curve)
+ seen_bezier_nodes_ignore.add(first)
+ seen_bezier_nodes_ignore.add(last)
+ node1 = first
+ node2 = last
+ else:
+ node2 = node1.next
func = globals()['interpolate_' + interp_type.name.casefold()]
points = func(node1, node2, node1.config.segments)
for a, b in zip(points, points[1:]):
a.next = b
b.prev = a
- points[0].prev = node1
+ points[0].prev = node1 # if segment count is low (like 2) for bezier curve, this will cause error. TODO: Fix this?
points[-1].next = node2
segments.append(points)
+ for removenode in seen_bezier_nodes:
+ LOGGER.debug("Removing Bezier Keyframe Node ",removenode)
+ nodes.remove(removenode)
+
for points in segments:
nodes.update(points)
points[0].prev.next = points[0]
points[-1].next.prev = points[-1]
# Finally, split nodes with too much of an angle between them - we can't smooth.
+ # Don't bother if they're real small angles though, that's fine.
for node in list(nodes):
if node.prev is None or node.next is None:
continue
off1 = node.pos - node.prev.pos
off2 = node.next.pos - node.pos
- if Vec.dot(off1, off2) < 0.7:
+ if Vec.dot(off1, off2) < 0.7 and off1.mag_sq() > 8 and off2.mag_sq() > 8:
new_node = Node(node.pos.copy(), node.config, node.radius)
nodes.add(new_node)
new_node.next = node.next
@@ -691,8 +855,8 @@ def compute_orients(nodes: Iterable[Node]) -> None:
"""Compute the appropriate orientation for each node."""
# This is based on the info at:
# https://janakiev.com/blog/framing-parametric-curves/
- tangents: dict[Node, Vec] = {}
- all_nodes: set[Node] = set()
+ tangents: Dict[Node, Vec] = {}
+ all_nodes: Set[Node] = set()
for node in nodes:
if node.prev is node.next is None:
continue
@@ -710,16 +874,7 @@ def compute_orients(nodes: Iterable[Node]) -> None:
while node1.next is not None:
node2 = node1.next
all_nodes.discard(node2)
- tanj1 = tangents[node1]
- tanj2 = tangents[node2]
- b = Vec.cross(tanj1, tanj2)
- if b.mag_sq() < 0.001:
- node2.orient = node1.orient.copy()
- else:
- b = b.norm()
- phi = math.acos(Vec.dot(tanj1, tanj2))
- up = node1.orient.up() @ Matrix.axis_angle(b, math.degrees(phi))
- node2.orient = Matrix.from_basis(x=tanj2, z=up)
+ node2.orient = parallel_transport(node1.orient, tangents[node1], tangents[node2])
node1 = node2
@@ -854,7 +1009,7 @@ def generate_vac_beams(nodes: Iterable[Node], bone: Bone, vac_points: List[List[
BEAM_WID = 2.17316
node_pos: Vec
- def vert_node1(y: float, z: float, norm: tuple[float, float, float], u: float) -> Vertex:
+ def vert_node1(y: float, z: float, norm: Tuple[float, float, float], u: float) -> Vertex:
"""Helper for generating at the first node."""
return Vertex(
pos1 + (0.0, y, z) @ orient1,
@@ -967,8 +1122,8 @@ def vert_node2(y: float, z: float, norm: Tuple[float, float, float], u: float) -
def place_seg_props(nodes: Iterable[Node], fsys: FileSystem, mesh: Mesh) -> Iterator[SegProp]:
"""Place segment props, across the nodes."""
- mesh_cache: dict[str, Mesh] = {}
- prop_dists: dict[SegPropConf, float] = {}
+ mesh_cache: Dict[str, Mesh] = {}
+ prop_dists: Dict[SegPropConf, float] = {}
for start_node in nodes:
# Find start nodes, we then loop in order over the nodes.
if start_node.prev is not None:
@@ -997,6 +1152,9 @@ def place_seg_props(nodes: Iterable[Node], fsys: FileSystem, mesh: Mesh) -> Iter
))
conf = rand.choice(weights)
+ if not conf.model:
+ # Deliberately skip placing a prop.
+ continue
if conf.orient is SegPropOrient.RAND_FULL:
# We cover all orientations, so pre-rotation value is irrelevant.
angles = Matrix.from_angle(
@@ -1077,86 +1235,116 @@ async def compile_rope(
"""Compile a single rope group."""
for ent in dyn_ents:
origin = Vec.from_str(ent['origin'])
- dyn_nodes = frozenset({
+ dyn_nodes: FrozenSet[NodeEnt] = frozenset({
node.relative_to(origin)
for node in nodes
})
+
+ skins = []
+ for i in itertools.count(1):
+ skin_str = ent[f'skin{i}']
+ if not skin_str:
+ break
+ skins.append(skin_str)
+
+ if any(node.config.vac_separate_glass is VactubeGenType.SEPARATE for node in nodes):
+ LOGGER.warning(
+ "Vactube at {} is requesting separate models, which is not allowed for "
+ "prop_dynamic. Ignoring.",
+ origin,
+ )
model_name, _ = await compiler.get_model(
- (dyn_nodes, frozenset(connections)),
+ (dyn_nodes, frozenset(connections), tuple(skins), VactubeGenPartType.ALL),
build_rope,
(origin, ctx.pack.fsys),
)
ent['model'] = model_name
- ang = Angle.from_str(ent['angles'])
- ang.yaw -= 90.0
- ent['angles'] = ang
if not dyn_ents: # Static prop.
bbox_min, bbox_max = Vec.bbox(node.pos for node in nodes)
center = (bbox_min + bbox_max) / 2
node: Optional[NodeEnt] = None
has_coll = False
- local_nodes: set[NodeEnt] = set()
+ local_nodes: Set[NodeEnt] = set()
for node in nodes:
local_nodes.add(attrs.evolve(node, pos=node.pos - center))
if node.config.coll_side_count >= 3:
has_coll = True
+ # All the configs should be the same, so just use the last node in the set.
+ conf = node.config
+
+ # If separate models are enabled, call get_model twice to get models for the frame and
+ # glass individually.
+ is_sep = conf.vac_separate_glass == VactubeGenType.SEPARATE
+ # First do the frame, or everything if we're not separating them.
model_name, (light_origin, coll_data, seg_props, vac_points) = await compiler.get_model(
- (frozenset(local_nodes), frozenset(connections)),
+ (frozenset(local_nodes), frozenset(connections), (), VactubeGenPartType.FRAME if is_sep else VactubeGenPartType.ALL),
build_rope,
(center, ctx.pack.fsys),
)
+ modellist = [ModelContainer(model_name, light_origin, coll_data, seg_props, StaticPropFlags.NONE)]
+
+ if is_sep:
+ # Generate the glass only
+ model_name, (light_origin, coll_data, seg_props, _) = await compiler.get_model(
+ (frozenset(local_nodes), frozenset(connections), (), VactubeGenPartType.GLASS),
+ build_rope,
+ (center, ctx.pack.fsys),
+ )
+ modellist.append(ModelContainer(model_name, light_origin, coll_data, seg_props, StaticPropFlags.NO_SHADOW))
if vac_points and vac_node_mod is not None:
for track in vac_points:
vac_node_mod.SPLINES.append(vac_node_mod.Spline(center, track))
# Compute the flags. Just pick a random node, from above.
- conf = node.config
flags = StaticPropFlags.NONE
if conf.prop_light_bounce:
flags |= StaticPropFlags.BOUNCED_LIGHTING
- if conf.prop_no_shadows:
- flags |= StaticPropFlags.NO_SHADOW
if conf.prop_no_vert_light:
flags |= StaticPropFlags.NO_PER_VERTEX_LIGHTING
if conf.prop_no_self_shadow:
flags |= StaticPropFlags.NO_SELF_SHADOWING
+ if conf.prop_no_shadows:
+ flags |= StaticPropFlags.NO_SHADOW
- leafs = compute_visleafs(coll_data, ctx.bsp.vis_tree())
- ctx.bsp.props.append(StaticProp(
- model=model_name,
- origin=center,
- angles=Angle(0, 270, 0),
- scaling=1.0,
- visleafs=leafs,
- solidity=6 if has_coll else 0,
- flags=flags,
- tint=Vec(conf.prop_rendercolor),
- renderfx=conf.prop_renderalpha,
- lighting=center + light_origin,
- min_fade=conf.prop_fade_min_dist,
- max_fade=conf.prop_fade_max_dist,
- fade_scale=conf.prop_fade_scale,
- ))
- for seg_prop in seg_props:
+ for m in modellist:
+ new_flags = flags | m.flags # For the glass, we force shadows off
+ leafs = compute_visleafs(m.coll_data, ctx.bsp.vis_tree())
ctx.bsp.props.append(StaticProp(
- model=seg_prop.model,
- origin=center + seg_prop.offset,
- angles=(seg_prop.orient @ Matrix.from_yaw(270)).to_angle(),
+ model=m.model_name,
+ origin=center,
+ angles=Angle(0, 0, 0),
scaling=1.0,
visleafs=leafs, # TODO: compute individual leafs here?
- solidity=6,
- flags=flags,
+ solidity=6 if has_coll else 0,
+ flags=new_flags,
tint=Vec(conf.prop_rendercolor),
renderfx=conf.prop_renderalpha,
- lighting=center + seg_prop.offset,
+ lighting=center + m.light_origin,
min_fade=conf.prop_fade_min_dist,
max_fade=conf.prop_fade_max_dist,
fade_scale=conf.prop_fade_scale,
))
+ for seg_prop in m.seg_props:
+ ctx.bsp.props.append(StaticProp(
+ model=seg_prop.model,
+ origin=center + seg_prop.offset,
+ angles=seg_prop.orient.to_angle(),
+ scaling=1.0,
+ visleafs=leafs,
+ solidity=6,
+ flags=new_flags,
+ tint=Vec(conf.prop_rendercolor),
+ renderfx=conf.prop_renderalpha,
+ lighting=center + seg_prop.offset,
+ min_fade=conf.prop_fade_min_dist,
+ max_fade=conf.prop_fade_max_dist,
+ fade_scale=conf.prop_fade_scale,
+ ))
+
@trans('Model Ropes', priority=-10) # Needs to be before vactubes.
async def comp_prop_rope(ctx: Context) -> None:
@@ -1172,7 +1360,7 @@ async def comp_prop_rope(ctx: Context) -> None:
# Dynamic ents which will be given the static props.
group_dyn_ents: Dict[str, List[Entity]] = defaultdict(list)
# Name -> segprop configurations.
- name_to_segprops_lst: dict[str, list[SegPropConf]] = defaultdict(list)
+ name_to_segprops_lst: Dict[str, List[SegPropConf]] = defaultdict(list)
for ent in ctx.vmf.by_class['comp_prop_rope_bunting']:
ent.remove()
@@ -1187,7 +1375,7 @@ async def comp_prop_rope(ctx: Context) -> None:
# Put into a set, so they're immutable and have no ordering.
# We use that to identify the same config in previous compiles.
- name_to_segprops_set: dict[str, frozenset[SegPropConf]] = {
+ name_to_segprops_set: Dict[str, FrozenSet[SegPropConf]] = {
name: frozenset(lst)
for name, lst in name_to_segprops_lst.items()
}
@@ -1241,9 +1429,9 @@ async def comp_prop_rope(ctx: Context) -> None:
found: List[NodeEnt] = []
if target.endswith('*'):
search = target[:-1]
- for name, nodes in name_to_nodes.items():
+ for name, node_list in name_to_nodes.items():
if name.startswith(search):
- found.extend(nodes)
+ found.extend(node_list)
else:
found.extend(name_to_nodes.get(target, ()))
for dest in found:
@@ -1253,7 +1441,7 @@ async def comp_prop_rope(ctx: Context) -> None:
# To group nodes, take each group out, then search recursively through
# all connections from it to other nodes.
todo = set(all_nodes.values())
- with ModelCompiler.from_ctx(ctx, 'ropes', version=2) as compiler:
+ with ModelCompiler.from_ctx(ctx, 'ropes', version=3) as compiler:
async with trio.open_nursery() as nursery:
while todo:
dyn_ents: List[Entity] = []
diff --git a/transforms/p2_antline.py b/transforms/p2_antline.py
index 961715d34..8dd20ef02 100644
--- a/transforms/p2_antline.py
+++ b/transforms/p2_antline.py
@@ -48,15 +48,15 @@ def comp_antlines(ctx: Context):
# These are the names, not the ents themselves.
# Or brush ents holding overlays.
- ind_overlays = set() # type: Set[str]
- ind_toggles = set() # type: Set[str]
+ ind_overlays: Set[str] = set()
+ ind_toggles: Set[str] = set()
# These need the right inputs.
- ind_panel_tim = set() # type: Set[str]
- ind_panel_check = set() # type: Set[str]
+ ind_panel_tim: Set[str] = set()
+ ind_panel_check: Set[str] = set()
# Panels without an indicator set - we can use
# these instead of a texturetoggle.
- unused_panels = [] # type: List[Entity]
+ unused_panels: List[Entity] = []
for ind_ent in ctx.vmf.search(ind_name):
cls = ind_ent['classname']
diff --git a/transforms/p2_brush_ents.py b/transforms/p2_brush_ents.py
index 7585a305f..175217baa 100644
--- a/transforms/p2_brush_ents.py
+++ b/transforms/p2_brush_ents.py
@@ -54,7 +54,7 @@ def comp_trigger_coop(ctx: Context):
)
# Only keep OnChangeToAllTrue outputs, and remove
# them once they've fired.
- for out in list(manager):
+ for out in list(manager.outputs):
if out.output.casefold() == 'onchangetoalltrue':
out.only_once = True
else:
diff --git a/transforms/p2_custom_models.py b/transforms/p2_custom_models.py
new file mode 100644
index 000000000..6dec99178
--- /dev/null
+++ b/transforms/p2_custom_models.py
@@ -0,0 +1,63 @@
+"""Add keyvalues to Portal 2 test element entities to automatically handle custom models."""
+
+from srctools import conv_int
+
+from hammeraddons.bsp_transform import trans, Context
+
+SUPPORTED_ENTS = [
+ "prop_weighted_cube",
+ "prop_button",
+ "prop_floor_cube_button",
+ "prop_floor_ball_button",
+ "prop_under_button",
+ "prop_under_floor_button",
+ "prop_wall_projector",
+ "prop_glados_core",
+ # TODO: needs extra VScript for the sprite, otherwise should work
+ # "npc_security_camera",
+ "npc_rocket_turret",
+ "npc_personality_core",
+ "prop_exploding_futbol",
+ "prop_glass_futbol",
+ "hot_potato",
+
+ # Not supported:
+ # prop_testchamber_door - reverses animations
+ # prop_tractor_beam - breaks animations
+ # prop_linked_portal_door - breaks animations
+ # prop_monster_box - swaps models dynamically
+
+ # Not tested:
+ # prop_glass_futbol_spawner
+ # hot_potato_spawner
+ # prop_portal_stats_display
+ # prop_rocket_tripwire
+ # prop_telescopic_arm
+ # prop_scaled_cube (Sixense)
+ # prop_contraption_cube (Edu)
+ # prop_contraption_cube_button (Edu)
+]
+
+@trans('Portal 2 Custom Models')
+def p2_custom_models(ctx: Context) -> None:
+ """Add keyvalues to Portal 2 test element entities to automatically handle custom models."""
+ for classname in SUPPORTED_ENTS:
+ for ent in ctx.vmf.by_class[classname]:
+ model_type = conv_int(ent['comp_custom_model_type'])
+
+ if model_type == 0: # none
+ continue
+ elif model_type == 1: # script override
+ cust_model = ent['model']
+ # Make a comp_precache_model
+ ctx.vmf.create_ent(
+ classname = 'comp_precache_model',
+ model = cust_model,
+ )
+ ctx.add_code(ent, 'function OnPostSpawn() { self.SetModel("' + cust_model + '") }')
+ elif model_type == 2 and ent['classname'] == 'prop_weighted_cube': # cube type 6, for prop_weighted_cube only
+ orig_cube_type = ent['CubeType']
+ ent['CubeType'] = '6'
+ # Revert to the original type on spawn
+ ctx.add_code(ent, 'function OnPostSpawn() { EntFireByHandle(self, "AddOutput", "CubeType ' + orig_cube_type + '", 0, self, self) }')
+
\ No newline at end of file
diff --git a/transforms/portal2.py b/transforms/portal2.py
index ec3f3c10e..b5f96226c 100644
--- a/transforms/portal2.py
+++ b/transforms/portal2.py
@@ -11,7 +11,7 @@ def laser_catcher_skins(ctx: Context):
if not conv_bool(ent['src_fix_skins'], True):
continue
- deact_skin, act_skin = '23' if ent['SkinType'] == '1' else '01'
+ deact_skin, act_skin = ('2', '3') if ent['SkinType'] == '1' else ('0', '1')
# Look for outputs which do this already.
name = ent['targetname']
@@ -57,6 +57,7 @@ def needs_paint(vmf: VMF) -> bool:
# If the cube is bouncy, enable paint.
if conv_int(ent['paintpower', '4'], 4) != 4:
return True
+ return False
@trans('Force Paint in Map')
diff --git a/transforms/sceneset.py b/transforms/sceneset.py
index 2e5fc5309..bc17e3ef1 100644
--- a/transforms/sceneset.py
+++ b/transforms/sceneset.py
@@ -1,5 +1,7 @@
"""Implement comp_choreo_sceneset."""
-from srctools import Output, conv_bool, conv_float
+from typing import List
+
+from srctools import Entity, Output, conv_bool, conv_float
from srctools.logger import get_logger
from hammeraddons.bsp_transform import trans, Context
@@ -10,6 +12,7 @@
@trans('comp_choreo_sceneset')
def sceneset(ctx: Context):
"""Chains a set of choreographed scenes together."""
+ ent: Entity
for ent in ctx.vmf.by_class['comp_choreo_sceneset']:
scenes = [
ent['scene{:02}'.format(i)]
@@ -32,43 +35,45 @@ def sceneset(ctx: Context):
ent.remove()
- start_ent = None
+ scene_ents: List[Entity] = []
- name = ent['targetname'] or '_choreo_{}'.format(ent.id)
+ name = ent.make_unique('_choreo')['targetname']
for i, scene in enumerate(scenes):
part = ctx.vmf.create_ent(
classname='logic_choreographed_scene',
targetname=(
- '{}_{}'.format(name, i)
+ f'{name}_{i}'
if i > 0 else
name
),
origin=ent['origin'],
scenefile=scene,
)
+ scene_ents.append(part)
if i + 1 < len(scenes):
part.add_out(Output(
'OnCompletion',
- '{}_{}'.format(name, i+1),
+ f'{name}_{i + 1}',
'Start',
delay=delay,
))
if only_once:
- # When started blank the name so it can't be triggered,
- # then clean up after finished
+ # When started blank the name so that it can't be triggered, then clean up after
+ # it's finished
part.add_out(
Output('OnStart', '!self', 'AddOutput', 'targetname '),
Output('OnCompletion', '!self', 'Kill'),
)
- if start_ent is None:
- start_ent = part
-
- assert start_ent is not None, "Has scenes but none made?"
for out in ent.outputs:
if out.output.casefold() == 'onstart':
- start_ent.add_out(out)
+ scene_ents[0].add_out(out)
elif out.output.casefold() == 'onfinish':
- # Part is the last in the loop.
out.output = 'OnCompletion'
- part.add_out(out)
+ scene_ents[-1].add_out(out)
+
+ # Make firing cancel at the first scene also cancel the others.
+ ctx.add_io_remap(name, *[
+ Output('Cancel', ent, 'Cancel')
+ for ent in scene_ents[1:]
+ ], remove=False)
diff --git a/transforms/tf2.py b/transforms/tf2.py
new file mode 100644
index 000000000..a34375efc
--- /dev/null
+++ b/transforms/tf2.py
@@ -0,0 +1,22 @@
+"""Team Fortress 2 specific transformations"""
+
+from srctools import Output
+
+from hammeraddons.bsp_transform import trans, Context
+
+# Modified from the portal 2 indicator name transform, this might be able to be slightly cleaner
+@trans('TF2 Control Point Props')
+def comp_control_points(ctx: Context):
+ """Adds key to TF2 Control Points to automatically set the skin of the base (or another prop)."""
+ for ent in ctx.vmf.entities:
+ prop_name = ent['src_propname']
+ if not prop_name:
+ continue
+
+ ent['src_propname'] = ''
+
+ ent.add_out(
+ Output('OnCapTeam1' , prop_name, 'Skin', '1'),
+ Output('OnCapTeam2', prop_name, 'Skin', '2'),
+ Output('OnCapReset', prop_name, 'Skin', '0'),
+ )
\ No newline at end of file
diff --git a/transforms/vactubes/__init__.py b/transforms/vactubes/__init__.py
index 49279ff3d..324a87ed7 100644
--- a/transforms/vactubes/__init__.py
+++ b/transforms/vactubes/__init__.py
@@ -205,7 +205,7 @@ async def vactube_transform(ctx: Context) -> None:
LOGGER.info('Generating animations...')
all_anims = animations.generate(sources)
# Sort the animations by their start and end, so they ideally are consistent.
- all_anims.sort(key=lambda a: (a.start_node.origin, a.end_node.origin))
+ all_anims.sort(key=lambda a: (a.start_node.origin, a.end_node.origin if a.end_node is not None else Vec()))
anim_mdl_name = Path('maps', ctx.bsp_path.stem, f'vac_anim_{random.randrange(0xffffff):06x}.mdl')
@@ -227,18 +227,18 @@ async def vactube_transform(ctx: Context) -> None:
for tri in mesh.triangles:
for point in tri:
point.tex_u, point.tex_v = U[point.tex_u], V[point.tex_v]
- with open(temp_dir + '/ref.smd', 'wb') as f:
- mesh.export(f)
+ with open(temp_dir + '/ref.smd', 'wb') as mesh_file:
+ mesh.export(mesh_file)
with open(temp_dir + '/prop.qc', 'w') as qc_file:
- qc_file.write(QC_TEMPLATE.format(path=anim_mdl_name))
+ qc_file.write(QC_TEMPLATE.format(path=anim_mdl_name.as_posix()))
for i, anim in enumerate(all_anims):
anim.name = anim_name = f'anim_{i:03x}'
qc_file.write(SEQ_TEMPLATE.format(name=anim_name, fps=animations.FPS))
- with open(temp_dir + f'/{anim_name}.smd', 'wb') as f:
- anim.mesh.export(f)
+ with open(temp_dir + f'/{anim_name}.smd', 'wb') as mesh_file:
+ anim.mesh.export(mesh_file)
args = [
str(ctx.studiomdl),
@@ -258,12 +258,15 @@ async def vactube_transform(ctx: Context) -> None:
# Ensure they're all packed.
for ext in MDL_EXTS:
try:
- f = full_loc.with_suffix(ext).open('rb')
+ mdl_file = full_loc.with_suffix(ext).open('rb')
except FileNotFoundError:
pass
else:
- with f:
- ctx.pack.pack_file(Path('models', anim_mdl_name.with_suffix(ext)), data=f.read())
+ with mdl_file:
+ ctx.pack.pack_file(
+ Path('models', anim_mdl_name.with_suffix(ext)),
+ data=mdl_file.read(),
+ )
LOGGER.info('Setting up vactube ents...')
# Generate the shared template.
@@ -272,7 +275,7 @@ async def vactube_transform(ctx: Context) -> None:
targetname='_vactube_temp_mover',
angles='0 270 0',
origin='-16384 0 1024',
- model=str(Path('models', anim_mdl_name)),
+ model=Path('models', anim_mdl_name).as_posix(),
rendermode=10,
solid=0,
spawnflags=64 | 256, # Use Hitboxes for Renderbox, collision disabled.
@@ -318,7 +321,7 @@ async def vactube_transform(ctx: Context) -> None:
'logic_timer',
targetname=spawn_name + '_timer',
origin=start_node.origin,
- startdisabled='0',
+ startdisabled=start_node.timer_start_disabled,
userandomtime='1',
lowerrandombound=start_node.time_min,
upperrandombound=start_node.time_max,
@@ -337,7 +340,7 @@ async def vactube_transform(ctx: Context) -> None:
# Now, generate the code so the VScript knows about the animations.
code = [f'// Node: {start_node.ent["targetname"]}, {start_node.origin}']
for anim in anims:
- target = anim.end_node
+ anim_dest = anim.end_node
anim_speed = anim.start_node.speed
pass_code = ','.join([
f'Output({time:.2f}, "{node.ent["targetname"]}", '
@@ -345,23 +348,23 @@ async def vactube_transform(ctx: Context) -> None:
for time, node in anim.pass_points
])
cube_name = 'null'
- if isinstance(target, nodes.Dropper):
- cube_model = target.cube['model'].replace('\\', '/')
- cube_skin = conv_int(target.cube['skin'])
+ if isinstance(anim_dest, nodes.Dropper):
+ cube_model = anim_dest.cube['model'].replace('\\', '/')
+ cube_skin = conv_int(anim_dest.cube['skin'])
try:
- cube_name = vac_objects[start_node.group, cube_model, cube_skin].id
- except KeyError:
+ cube_name = objects.find_for_cube(vac_objects, start_node.group, anim_dest.cube).id
+ except LookupError:
LOGGER.warning(
'Cube model "{}", skin {} is not a type of cube travelling '
'in this vactube!\n\n'
- 'Add a comp_vactube_object entity with this cube model'
- # Mention groups if they're used, otherwise it's not important.
- + (f' with the group "{start_node.group}".' if start_node.group else '.'),
+ 'Add a comp_vactube_object entity with this cube model{}',
cube_model, cube_skin,
+ # Mention groups if they're used, otherwise it's not important.
+ f' with the group "{start_node.group}".' if start_node.group else '.',
)
continue # Skip this animation so it's not broken.
else:
- dropper_to_anim[target] = anim
+ dropper_to_anim[anim_dest] = anim
code.append(
f'{anim.name} <- anim("{anim.name}", {anim.duration}, '
f'{cube_name}, [{pass_code}]);'
diff --git a/transforms/vactubes/animations.py b/transforms/vactubes/animations.py
index e78df94cc..6ad00fdbb 100644
--- a/transforms/vactubes/animations.py
+++ b/transforms/vactubes/animations.py
@@ -3,7 +3,7 @@
from typing import Tuple, List, Optional, Union
from . import nodes
-from .nodes import DestType
+from .nodes import Node, DestType
from srctools import Vec, Angle
from srctools.smd import BoneFrame, Mesh
from random import Random
@@ -74,22 +74,22 @@ def __init__(self, start_node: nodes.Spawner) -> None:
[self.move_bone] = self.mesh.bones.values()
self.cur_frame = 0
# For nodes with OnPass outputs, the time to fire each of those.
- self.pass_points: list[tuple[float, nodes.Node]] = []
+ self.pass_points: List[Tuple[float, nodes.Node]] = []
# Set of nodes in this animation, to prevent loops.
- self.history: list[nodes.Node] = [start_node]
+ self.history: List[nodes.Node] = [start_node]
# The kind of curve used for the current node.
self.curve_type = DestType.PRIMARY
# The source of the cubes on this animation.
self.start_node = start_node
# Either the start point, or the splitter to move in the secondary direction.
- self.cur_node: Union[nodes.Spawner, nodes.Splitter] = start_node
- # Once done, the ending node so we can determine if it's a dropper or not.
+ self.cur_node: nodes.Node = start_node
+ # Once done, this is the ending node so that we can determine if it's a dropper or not.
self.end_node: Optional[nodes.Destroyer] = None
# When branching, the amount we overshot into this node from last time.
self.start_overshoot = 0.0
- def tee(self, split: nodes.Splitter, split_type: DestType, overshoot: float) -> 'Animation':
+ def tee(self, split: nodes.Node, split_type: DestType, overshoot: float) -> 'Animation':
"""Duplicate this animation so additional frames can be added.
Note: Does not fully copy, the existing frame data is shared so
@@ -133,7 +133,7 @@ def generate(sources: List[nodes.Spawner]) -> List[Animation]:
anims = [Animation(node) for node in sources]
for anim in anims:
- node = anim.cur_node
+ node: Node = anim.cur_node
speed = anim.start_node.speed / FPS
offset = anim.start_node.origin.copy()
@@ -160,12 +160,12 @@ def generate(sources: List[nodes.Spawner]) -> List[Animation]:
seg_frames = math.ceil((seg_len - overshoot) / speed)
for i in range(int(seg_frames)):
# Make each frame.
- pos = (overshoot + speed * i) / seg_len
- if needs_out and pos > 0.5:
+ fraction = (overshoot + speed * i) / seg_len
+ if needs_out and fraction > 0.5:
anim.pass_points.append((anim.duration, node))
needs_out = False
# Place the point.
- last_loc = node.vec_point(pos, anim.curve_type)
+ last_loc = node.vec_point(fraction, anim.curve_type)
anim.add_point(last_loc - offset)
# If short, we might not have placed the output.
@@ -183,6 +183,7 @@ def generate(sources: List[nodes.Spawner]) -> List[Animation]:
# Now generate the straight part between this node and the next.
next_node = node.outputs[anim.curve_type]
+ assert next_node is not None
cur_end = node.vec_point(1.0, anim.curve_type)
straight_off = next_node.vec_point(0.0) - cur_end
@@ -199,7 +200,7 @@ def generate(sources: List[nodes.Spawner]) -> List[Animation]:
for i in range(int(seg_frames)):
# Make each frame.
- pos = cur_end + ((overshoot + speed * i) / straight_dist) * straight_off
+ pos = cur_end + straight_off * ((overshoot + speed * i) / straight_dist)
anim.add_point(pos - offset)
overshoot += (speed * seg_frames) - straight_dist
@@ -207,7 +208,8 @@ def generate(sources: List[nodes.Spawner]) -> List[Animation]:
overshoot += straight_off.mag()
# And advance to the next node.
- anim.cur_node = node = next_node
+ anim.cur_node = next_node
+ node = next_node
anim.history.append(node)
# We only do secondary for the first node, we always continue
diff --git a/transforms/vactubes/nodes.py b/transforms/vactubes/nodes.py
index 1df8990a3..961d96b88 100644
--- a/transforms/vactubes/nodes.py
+++ b/transforms/vactubes/nodes.py
@@ -205,10 +205,11 @@ def __init__(self, ent: Entity) -> None:
super().__init__(ent)
self.group = ent['group'].casefold().strip()
self.speed = srctools.conv_float(ent['speed'], 800.0)
- self.is_auto = srctools.conv_bool(ent['timer'])
+ timer_int = srctools.conv_int(ent['timer'], 1)
+ self.is_auto = timer_int != 0
self.seed = ent['seed']
if not self.seed:
- # Generate a new seed, and notify the user so they can copy it down
+ # Generate a new seed, and notify the user, so they can copy it down
# if they want to use it themselves.
self.seed = format(random.getrandbits(64), '08X')
LOGGER.info('Spawner "{}" using random seed "{}"', self.name, self.seed)
@@ -216,8 +217,10 @@ def __init__(self, ent: Entity) -> None:
if self.is_auto:
self.time_min = srctools.conv_float(ent['time_min'], 0.5)
self.time_max = srctools.conv_float(ent['time_max'], 1.0)
+ self.timer_start_disabled = timer_int == 2
else:
self.time_min = self.time_max = 0.0
+ self.timer_start_disabled = True
# Strip these keyvalues.
del ent['speed'], ent['timer'], ent['time_min'], ent['time_max']
diff --git a/transforms/vactubes/objects.py b/transforms/vactubes/objects.py
index bbc81528d..158e70fdb 100644
--- a/transforms/vactubes/objects.py
+++ b/transforms/vactubes/objects.py
@@ -1,10 +1,13 @@
+"""Handles configuration for the objects appearing inside vactubes."""
+from typing import Optional, Tuple, List, Dict, Union
+from typing_extensions import TypeAlias
from collections import defaultdict
-from typing import Optional, Tuple, List, Dict
+from fractions import Fraction
import os.path
import math
from srctools.packlist import PackList, FileType
-from srctools import Vec, VMF
+from srctools import Entity, Vec, VMF, conv_bool, conv_int
import srctools.logger
from hammeraddons.bsp_transform.packing import make_precache_prop
@@ -12,6 +15,23 @@
LOGGER = srctools.logger.get_logger(__name__)
+# For prop_weighted_cube, cube type -> model, clean skin, dirty skin
+_CUBE_STANDARD = ('models/props/metal_box.mdl', 0, 3)
+_CUBE_COMPANION = ('models/props/metal_box.mdl', 1, 1)
+_CUBE_REFLECT = ('models/props/reflection_cube.mdl', 0, 1)
+_CUBE_SPHERE = ('models/props_gameplay/mp_ball.mdl', 0, 0)
+_CUBE_ANTIQUE = ('models/props_underground/underground_weighted_cube.mdl', 0, 0)
+CUBE_MODELS_FOR_TYPE = [
+ _CUBE_STANDARD, _CUBE_COMPANION,
+ _CUBE_REFLECT, _CUBE_SPHERE, _CUBE_ANTIQUE,
+]
+# The same, but using the old skin property.
+CUBE_MODELS_FOR_SKIN = [
+ _CUBE_STANDARD, _CUBE_COMPANION,
+ _CUBE_STANDARD, # Standard Activated -> just regular.
+ _CUBE_REFLECT, _CUBE_SPHERE, _CUBE_ANTIQUE,
+]
+
class VacObject:
"""An object that can appear in vactubes."""
@@ -22,7 +42,7 @@ def __init__(
model_vac: str,
model_drop: Optional[str],
offset: Vec,
- weight: int=1,
+ weight: Union[Fraction, int] = 1,
skin_tv: int=0,
skin_drop: int=0,
skin_vac: int=0,
@@ -38,7 +58,7 @@ def __init__(
self.skin_drop = skin_drop
def __repr__(self) -> str:
- return ''.format(os.path.basename(self.model_vac))
+ return f''
def make_code(self) -> str:
"""Generate the code to construct this object in VScript."""
@@ -52,11 +72,10 @@ def make_code(self) -> str:
)
-def parse(vmf: VMF, pack: PackList) -> Tuple[
- int,
- Dict[Tuple[str, str, int], VacObject],
- Dict[str, str],
-]:
+VacObjectDict: TypeAlias = Dict[Tuple[str, str, int], VacObject]
+
+
+def parse(vmf: VMF, pack: PackList) -> Tuple[int, VacObjectDict, Dict[str, str]]:
"""Parse out the cube objects from the map.
The return value is the number of objects, a dict of objects, and the
@@ -65,21 +84,33 @@ def parse(vmf: VMF, pack: PackList) -> Tuple[
"""
cube_objects: Dict[Tuple[str, str, int], VacObject] = {}
vac_objects: Dict[str, List[VacObject]] = defaultdict(list)
+ # To allow decimal weights, parse them as fractions, then multiply them all by every denominator.
+ # That'll cancel out the fraction, making them all integer. We then compute the common multiple
+ # and reduce down.
+ group_multipliers: Dict[str, int] = defaultdict(lambda: 1)
for i, ent in enumerate(vmf.by_class['comp_vactube_object']):
offset = Vec.from_str(ent['origin']) - Vec.from_str(ent['offset'])
+ group = ent['group']
+ try:
+ weight = Fraction(ent['weight', '1'])
+ except ValueError:
+ weight = Fraction(1)
+ else:
+ group_multipliers[group] *= weight.denominator
+
obj = VacObject(
f'obj_{i:x}',
- ent['group'],
+ group,
ent['model'],
ent['cube_model'],
offset,
- srctools.conv_int(ent['weight']),
+ weight,
srctools.conv_int(ent['tv_skin']),
srctools.conv_int(ent['cube_skin']),
srctools.conv_int(ent['skin']),
)
- vac_objects[obj.group].append(obj)
+ vac_objects[group].append(obj)
# Convert the ent into a precache ent, stripping the other keyvalues.
mdl_name = ent['model']
ent.clear()
@@ -89,7 +120,7 @@ def parse(vmf: VMF, pack: PackList) -> Tuple[
if obj.model_drop:
cube_objects[
- obj.group,
+ group,
obj.model_drop.replace('\\', '/'),
obj.skin_drop,
] = obj
@@ -98,17 +129,70 @@ def parse(vmf: VMF, pack: PackList) -> Tuple[
# Each group is the same, so it can be shared among them all.
codes = {}
for group, objects in sorted(vac_objects.items(), key=lambda t: t[0]):
- # First, see if there's a common multiple among the weights, allowing
- # us to simplify.
- multiple = objects[0].weight
+ if (group_mult := group_multipliers[group]) != 1:
+ for obj in objects:
+ obj.weight *= group_mult
+ # The fractions should be integral now.
+
+ # Now see if there's a common multiple among the weights, allowing us to simplify.
+ multiple = int(objects[0].weight)
for obj in objects[1:]:
- multiple = math.gcd(multiple, obj.weight)
+ multiple = math.gcd(multiple, int(obj.weight))
if multiple > 1:
LOGGER.info('Group "{}" has common factor of {}, simplifying.', group, multiple)
code = []
for obj in objects:
- obj.weight /= multiple
+ obj.weight //= multiple
code.append(obj.make_code())
codes[group] = pack.inject_vscript('\n'.join(code))
return sum(map(len, vac_objects.values())), cube_objects, codes
+
+
+def find_for_cube(vac_objects: VacObjectDict, group: str, cube: Entity) -> VacObject:
+ """Find an object that matches the specified cube entity."""
+ potentials: List[Tuple[str, int]] = []
+ # Try what's set in the keyvalues first. But if it's a default value, skip so that we use
+ # the cube type first.
+ model = cube['model'].replace('\\', '/')
+ if model not in ('', 'models/props/metal_box.mdl'):
+ potentials.append((model, conv_int(cube['skin'])))
+
+ if cube['classname'] == 'prop_weighted_cube':
+ model = ''
+ clean = rusty = 0
+ if conv_bool(cube['newskins']):
+ cube_type = conv_int(cube['cubetype'])
+ if cube_type != 6: # Used for custom cubes, no error.
+ try:
+ model, clean, rusty = CUBE_MODELS_FOR_TYPE[cube_type]
+ except KeyError:
+ LOGGER.warning(
+ 'Cube "{}" at ({}) has unknown cube type {}!',
+ cube['targetname'], cube['origin'], cube_type,
+ )
+ else:
+ # Old skin-based lookup
+ cube_skin = conv_int(cube['skin'])
+ try:
+ model, clean, rusty = CUBE_MODELS_FOR_SKIN[cube_skin]
+ except KeyError:
+ LOGGER.warning(
+ 'Cube "{}" at ({}) has unknown old-style cube skin {}!',
+ cube['targetname'], cube['origin'], cube_skin,
+ )
+ if model:
+ potentials.append((model, rusty if conv_bool(cube['skintype']) else clean))
+ elif cube['classname'] == 'prop_monster_box':
+ # Hardcoded model. Prefer box form.
+ potentials += [
+ ('models/npcs/monsters/monster_a_box.mdl', 0),
+ ('models/npcs/monsters/monster_a.mdl', 0),
+ ]
+
+ for model, skin in potentials:
+ try:
+ return vac_objects[group, model, skin]
+ except KeyError:
+ pass
+ raise LookupError('No matching object!')