Skip to content

Commit

Permalink
Fix usage of frustum FGD helpers
Browse files Browse the repository at this point in the history
This must use keyvalues, not literal strings. Make unify_fgd
automatically create keyvalues if necessary.
  • Loading branch information
TeamSpen210 committed Jan 29, 2024
1 parent 78c8e17 commit e4e031a
Show file tree
Hide file tree
Showing 13 changed files with 53 additions and 32 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Boolean keyvalues (yes/no) can now be set to `!$var`, to invert the value of the variable.
* Propcombine will now preserve prop fade distances, by calculating a new distance which encloses the original fade spheres.
* Allow comp_entity_finder to rotate the target in addition to teleporting.
* Fix various incorrect usages of the FGD `frustum()` helper.


--------------------
Expand Down
2 changes: 1 addition & 1 deletion fgd/point/camera_satellite.fgd
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@PointClass base(BaseEntityPoint) appliesto(Mesa)
studioprop("models/editor/camera.mdl")
frustum(FOV,fogstart,fogend,_frustum_color,-1)
frustum(FOV, fogstart, fogend, 255 255 255, -1)
= camera_satellite: "Satellite Camera"
[
spawnflags(flags) : "spawnflags" =
Expand Down
2 changes: 1 addition & 1 deletion fgd/point/env/env_steam.fgd
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
color(200 200 0)
studioprop("models/editor/spot_cone_fixed.mdl")
// Frustum is actually fairly accurate for this
frustum(spreadspeed, _frustum_near, jetlength, rendercolor, -1)
frustum(spreadspeed, 1, jetlength, rendercolor, -1)
= env_steam: "An entity used to create a jet of steam."
[
spawnflags(flags) =
Expand Down
2 changes: 1 addition & 1 deletion fgd/point/npc/npc_arbeit_turret_floor.fgd
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@PointClass base(npc_turret_floor, EZ2Variant, ResponseContext)
appliesto(EZ2)
studioprop( "models/props/turret_01.mdl")
frustum(FOV, _frustum_near, Range, _frustum_color, -1)
frustum(FOV, 1, Range, 255 0 0, -1)
autovis(Entities, NPCs, Arbeit, Floor Turret)
= npc_arbeit_turret_floor: "Arbeit Floor Turret"
[
Expand Down
9 changes: 3 additions & 6 deletions fgd/point/npc/npc_hover_turret.fgd
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
autovis(Entities, NPCs, Hover Turret)
studioprop("models/npcs/hover_turret.mdl")
line(255 255 255, targetname, attachtarget)
frustum(_frustum_fov, _frustum_near, _frustum_far, _frustum_color, -1)
// We can't check the code to see what hover turrets' range is, it seems to be about 2048.
frustum(90, 1, 2048, 0 255 255, -1)
= npc_hover_turret: "The cut Hover Turret, which hangs from the ceiling and fires a laser at the player. Missing its model by default, and somewhat buggy."
[
canPushPlayer(boolean) : "Laser Pushes Player" : 0 : "Should the hover turret's laser deal knockback? Usually only works while the player is in the air."
sentryRotateSpeed(float) : "Idle Rotation Speed" : "10" : "While idle, the hover turret will rotate at this speed."
attachTarget(target_destination) : "Tether Attach Target" : : "An entity (usually info_target) which the hover turret should hang from."

// We can't check the code to see what hover turrets' range is, it seems to be about 2048.
_frustum_far[!engine](integer) readonly : "<Maximum Range>" : 2048 : "How far the turret will be able to see targets. Always 2048, but this keyvalue is needed to display the preview."
_frustum_color[!engine](string) readonly : "<Frustum Color>" : "0 255 255" : "Ignore, needed to color the range preview."
]
]
3 changes: 1 addition & 2 deletions fgd/point/npc/npc_portal_turret_floor.fgd
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@PointClass base(BaseNPC, _npc_portal_turret_floor_p1_mdl, _npc_portal_turret_floor_p2_mdl)
appliesto(P1, P2, -STANLEY)
autovis(Entities, NPCs, Portal Turret)
frustum(_frustum_fov, _frustum_near, TurretRange, _frustum_color, -1)
frustum(90, 1, TurretRange, 255 0 0, -1)
= npc_portal_turret_floor: "Aperture Science Sentry Turret."
[
damageforce(boolean) : "Damage Pushes Player" : 0 : "Being hit by this turret will push the player back."
Expand Down Expand Up @@ -68,7 +68,6 @@
skin[P2](integer) : "[H] Skin" : 0 : "The skin to show, mainly for the normal model."

turretrange[P1, !engine](integer) readonly : "<Maximum Range>" : 1500 : "How far the turret will be able to see targets. Always 1500 in Portal 1, but this keyvalue is needed to display the preview."
_frustum_color[!engine](string) readonly : "<Frustum Color>" : "255 0 0" : "Ignore, needed to color the range preview."

// Inputs
input FireBullet(string) : "Causes the turret to instantly fire at the specified entity."
Expand Down
5 changes: 1 addition & 4 deletions fgd/point/npc/npc_turret_floor.fgd
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@PointClass base(BaseNPC)
appliesto(EP1, EP2, HL2, P1, P2)
studioprop("models/combine_turrets/floor_turret.mdl")
frustum(_frustum_fov, _frustum_near, _frustum_far, 255 0 0, -1)
frustum(90, 1, 1200, 255 0 0, -1)
autovis(Entities, NPCs, Combine, Floor Turret)
= npc_turret_floor: "Combine Floor Turret"
[
Expand All @@ -26,9 +26,6 @@
skinnumber[!Mbase](integer) : "Skin Number" : 0 : "Which skin to use for this turret. Set to 0 to select randomly."
skin[MBase](integer) : "Skin Number" : 0 : "Which skin to use for this turret. If a citizen turret, set to 0 to select randomly."

_frustum_far[!engine](integer) readonly : "<Maximum Range>" : 1200 : "How far the turret will be able to see targets. Always 1200, but this keyvalue is needed to display the preview."
_frustum_color[!engine](string) readonly : "<Frustum Color>" : "255 0 0" : "Ignore, needed to color the range preview."

// Inputs
input Toggle(void) : "Toggle - If open, close. If closed, open."
input Enable(void) : "Enable the turret."
Expand Down
3 changes: 1 addition & 2 deletions fgd/point/point/point_camera.fgd
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
@PointClass base(BaseEntityPoint)
studioprop("models/editor/camera.mdl")
// Frustum color must be a KV name, not a raw RGB value
frustum(FOV,fogstart,fogend,_frustum_color,-1)
frustum(fov, fogstart, fogend, 255 255 255, -1)
= point_camera: "Camera"
[
spawnflags(flags) : "spawnflags" =
Expand Down
4 changes: 1 addition & 3 deletions fgd/point/point/point_devshot_camera.fgd
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
@PointClass base(BaseEntityPoint)
studioprop("models/editor/camera.mdl")
iconsprite("editor/point_devshot_camera.vmt")
frustum(fov, _frustum_near, _frustum_far, _frustum_color, -1)
frustum(fov, 1, 1024, 255 255 255, -1)
= point_devshot_camera: "An entity used by the -makedevshots system, which automatically takes screenshots at the position of every devshot camera in the level."
[
cameraname(string) : "Camera Name" : : "Used as the name of the directory to store screenshots from this camera. Must be unique within the level."
fov(integer) : "Camera FOV" : 75 : "FOV of this camera."

_frustum_far[!engine](integer) readonly : "<Far Plane>" : 1024 : "Ignore, needed to display the view frustum preview."
]
2 changes: 1 addition & 1 deletion fgd/point/point/point_push.fgd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
sphere(inner_radius)
studio("models/editor/cone_helper.mdl")
iconsprite("editor/ficool2/point_push")
frustum(influence_cone, inner_radius, radius, _frustum_color, -1)
frustum(influence_cone, inner_radius, radius, 255 255 255, -1)
= point_push: "Pulls objects to, or pushes them away from a point. " +
"In Portal 2, if a portal is placed nearby it will transfer the suction and " +
"produce a 'broken_tube_suck' effect for Diversity Vents."
Expand Down
5 changes: 1 addition & 4 deletions fgd/point/point/point_viewcontrol.fgd
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
@PointClass base(BaseEntityPoint)
studioprop("models/editor/camera.mdl")
color(200 0 0)
// Frustum color must be a keyvalue name, not a raw RGB value
frustum(fov, 4, _frustum_far, _frustum_color, -1)
frustum(fov, 4, 1024, 255 255 255, -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."
Expand Down Expand Up @@ -53,8 +52,6 @@
teleportplayertoend[INFRA](boolean) : "Teleport Player to End" : 0 : "Should the player be teleported to the end once the camera reaches the end of its path?"
pathlengthinseconds[INFRA](float) : "Path Length in Seconds" : 5 : "How long does this path last? Smaller numbers means faster camera."

_frustum_far[!engine](integer) readonly : "<Far Plane>" : 1024 : "Ignore, needed to display the view frustum preview."

// Inputs
input Enable(void) : "Enable the point_viewcontrol, and start controlling the player's view."
input Disable(void) : "Disable the point_viewcontrol, and stop controlling the player's view."
Expand Down
4 changes: 1 addition & 3 deletions fgd/point/point/point_viewcontrol_multiplayer.fgd
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
appliesto(since_L4D, -ASW)
color(200 0 0)
studioprop("models/editor/camera.mdl")
frustum(fov, _frustum_near, _frustum_far, _frustum_color, -1)
frustum(fov, 1, 1024, 255 255 255, -1)
line(255 255 0, targetname, target_entity)
= 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."
Expand Down Expand Up @@ -37,8 +37,6 @@
2: "Set FOV" : 0
]

_frustum_far[!engine](integer) readonly : "<Far Plane>" : 1024 : "Ignore, needed to display the view frustum preview."

// Inputs
input Enable(void) : "Enable the point_viewcontrol_multiplayer, and start controlling the players' view."
input Disable(void) : "Disable the point_viewcontrol_multiplayer, and stop controlling the players' view."
Expand Down
43 changes: 39 additions & 4 deletions src/hammeraddons/unify_fgd.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
Callable, Dict, FrozenSet, List, MutableMapping, Optional, Set, Tuple, TypeVar, Union,
)
from collections import Counter, defaultdict
from lzma import LZMAFile
from pathlib import Path
import argparse
import sys

from srctools import fgd
from srctools.fgd import (
FGD, AutoVisgroup, EntAttribute, EntityDef, EntityTypes, Helper, HelperExtAppliesTo,
HelperTypes, HelperWorldText, KVDef, ValueTypes, match_tags, validate_tags,
HelperTypes, KVDef, ValueTypes, match_tags, validate_tags,
)
from srctools.filesys import RawFileSystem
from srctools.math import Vec, format_float


# Chronological order of games.
Expand Down Expand Up @@ -234,6 +234,41 @@ def _polyfill_ext_valuetypes(fgd: FGD) -> None:
kv.type = decay.get(kv.type, kv.type)


@_polyfill('!P2DES') # Fixed in VitaminSource.
def _polyfill_frustum_literals(fgd: FGD) -> None:
"""The frustum() helper does not support literal values, only keyvalues."""
keys = [
('fov', '_frustum_fov', '<Frustum FOV>'),
('near_z', '_frustum_near', '<Frustum Near>'),
('far_z', '_frustum_far', '<Frustum Far>'),
('color', '_frustum_color', '<Frustum Color>'),
]
for ent in fgd.entities.values():
for helper in ent.helpers:
if helper.TYPE is not HelperTypes.FRUSTUM:
continue
for attr, name_base, disp_name in keys:
value: str | int | tuple[int, int, int] = getattr(helper, attr)
if isinstance(value, str):
continue
# This is a literal, synthesize a keyvalue.
i = 0
name = name_base
while name in ent.keyvalues:
i += 1
name = f'{name_base}{i}'
# This should be !ENGINE, but we don't run polyfills in engine mode.
ent.keyvalues[name] = {frozenset(): KVDef(
name,
type=ValueTypes.COLOR_255 if attr == 'color' else ValueTypes.FLOAT,
disp_name=disp_name,
default=str(Vec(value)) if isinstance(value, tuple) else format_float(value),
desc='Ignore, this is necessary to display the preview frustum.',
readonly=True,
)}
setattr(helper, attr, name)


def format_all_tags() -> str:
"""Append a formatted description of all allowed tags to a message."""

Expand Down Expand Up @@ -1122,7 +1157,7 @@ def action_export(
for tag, classnames in res_tags.items():
print(f'- {tag}: {len(classnames)} ents')

print('Exporting...')
print(f'Exporting {output_path}...')

if as_binary:
with open(output_path, 'wb') as bin_f:
Expand Down Expand Up @@ -1326,7 +1361,7 @@ def main(args: Optional[List[str]]=None):
dbase,
extra_db,
tags,
result.output,
Path(result.output).resolve(),
result.binary,
result.engine,
result.map_size,
Expand Down

0 comments on commit e4e031a

Please sign in to comment.