'Base'- and 'Nazi'-Class Actor Configuration

There are two ZScript classes in Blade of Agony that define additional enemy behavior. The 'Base' class is used directly as a base for non-human enemies, such as sharks, rats, and the non-human bosses. The 'Nazi' class inherits all of the functionality of the 'Base' class, but adds additional capabilities that are used by human and human-like actors.

Custom UDMF Attributes

'Base' Class and 'Nazi' Class:
  • If set to 1, the actor's health bar is always drawn, regardless of it has the BOSS flag or if it's in view of the player
  • The underlying variable for the Base.AlwaysDrawHealthBar property
  • If set to 1, forces the enemy to always drop their weapon when killed
  • Has the side effect of *not* dropping any other defined DropItems
user_conversation (currently unused in BoA) 
  • Intended to mark actors that can be interacted with via dialogue
  • If set to 1, marks the actor with an interaction excalamation point marker that will follow them as they move, and will grey out once the player 'uses' the actor and enters a conversation with them.
  • Marker is removed when the actor is killed or this value is reset to 0
  • Intended to mark actors that can be harmed by a specific light level (e.g. zombies)
  • If set to 1, makes the actor burn at a specific light level which can be defined with the appropriate Base. properties (see below)
  'Nazi' Class Only:
  • The underlying variable for the Nazi.Sneakable property. If set to 1, this can be used to set actors as sneakable in-editor, without creating a custom actor class.
  • IF set to 1, actor will remain at its spawn location until the player is within 256 units
  • The actor will still aim and fire at the player, but won't walk toward him until the player is within the 256-unit range
  • Has no mapper use
  • Just a leftover variable name from the original DECORATE code

Flag effects

Certain editor flags have been given additional meaning when applied to a 'Nazi'-class actor.

'Nazi' Class Only:
  • Actors with the AMBUSH flag set will default to their 'aiming' frame - there's no behavioral change, just the actor's appearance
  • Actors with the BOSS flag set will show a health bar at the top of the screen when the player is aiming at them
Properties for new actor definitions 'Base' Class and 'Nazi' Class:
  • String property that is used to look up the icon image that is displayed with the enemy's health bar
  • Must be used in combination with the +BOSS flag (which enables the boss health bar to be drawn) or the Base.AlwaysDrawHealthBar property below.
  • Has no effect if the enemy is not flagged to have health bar drawn.
  • Boolean value that is used to tell the game if the enemy's health bar should always be drawn.
  • Does not require the +BOSS flag to be set, and can alternatively be controlled via ACS or in-editor by setting the user_DrawHealthBar variable
  • Sets the light level at which the enemy will turn around and run away (afraid of light)
  • Adds to the behavior above by causing any enemy that is under a sky texture that breaks their defined light threshold to die (via fire, if they have the state defined for it), as with the zombie deaths in C3M0_A.
  • Causes smoke to spawn all over the enemy when it's on the edge of bursting into flame.
  • Boolean value that sets whether the actor should be restricted to staying underwater or not. Used by sharks.
  • Integer value that sets the range from the spawn point that this actor will wander while it is idle (normally only on spawn).
  • Default is zero. Currently used by dogs and sharks.
  • Flags the actor to not be able to be healed by a medic.
'Nazi' Class Only:
  • Boolean that controls if the enemy is a sneakable enemy or not.
  • Can also be set in-editor on a per-actor basis by setting the user_sneakable variable.
  • Can be set in-game (e.g., after a cutscene using normal actors) by setting the actor's state to "MakeSneakable" via ACS.
  • Integer value that controls how close to the actor the player must be before visibility amount begins to increase dramatically (essentially, when the meter begins to ramp up as you get within touching distance)
  • Default value is 64
  • Integer value that controls how many tics a disguised player must remain in sight of this enemy before the player's disguise fails.
  • Default value is 0, meaning "can't see through disguises"
  • Used by SneakableEyesIdle actor (as seen on sneakable Gestapo)
  • Integer value that controls the FOV of the enemy when trying to see through player disguises.
  • Used by SneakableEyesIdle actor (as seen on sneakable Gestapo)
  • Value 1 (defined as HLR_ALLIES) is normal medic behavior.
  • Value 2 (HLR_ZOMBIES) changes the behavior to only search for dead enemies that have a zombie counterpart, and to replace the dead actor with the zombie variant on resurrection.
  • Defines the zombie actor that should be resurrected from this actor's corpse by "Totengraber" et al
  • If not provided (or set to ""), resurrection will not occur (this doesn't affect normal medic healing).

Actor States

'Nazi' Class Only:
Sneakable State Changes

These are intended to be used as workarounds to set up certain actor effects from ACS. e.g., 'SetActorState(0, "MakeSneakable");' will turn the current actor into a sneakable actor. This is used in the beginnning of C2M1 after the (non-sneakable) 'firing squad' that you see through the vent is done executing their prisoners to make them sneakable

  • Actor will be made into a sneakable actor
  • Actor will be alerted as if it were sneakable and had seen a player
  • Note that this will turn non-sneakables into sneakable actors! They will go idle, etc. just like any other sneakable after this is used.
Walking Speed Modification

These are only really useful if you are defining a new class - instead of copy and pasting all of the 'See' state, you can simply use "Goto See.Faster", etc.

State Walking Frame Duration Footstep sounds? Frames
See.Normal 8 tics Normal footsteps ABCD
See.Fast 6 tics Normal footsteps ABCD
See.Faster 4 tics Normal footsteps ABCD
See.MutantFaster 4 tics Normal footsteps ABCD (Sounds play on opposite frames from See.Faster)
See.MutantFasterAlt 4 tics Normal footsteps BCDE
See.Boss 8 tics Heavy footsteps ABCD
See.BossFast 6 tics Heavy footsteps ABCD
See.BossMech 8 tics Mech footsteps ABCD
See.Static 1 tic - intended for non-moving actors N/A A
Other miscellaneous states
Alarm Activation

A 'Nazi'-class actor that activates an alarm has special handling. When they activate an alarm, they are set to the 'Alarm' state.

Actor Spawners

These actors spawn enemies when activated, and maintain a set number of those enemies alive (1 by default). Actors will not be spawned if a player can see the spawn point or if a player is within a defined minimum spawn distance from the spawner (default 512 units).

By default, the spawner will spawn a single guard. Once that guard is killed, the spawner will spawn another guard, and so on. This can replace situations where an ACS script might mindlessly spam a huge flood enemies, regardless of how many are being killed or not, by metering how many enemies are active at once.

Spawned actors can be given a TID and can be set to navigate to a specific PatrolPoint TID after spawn as well.

11519 - ActorSpawner

Custom UDMF Attributes
Attribute Usage
arg0str Sets the class of actor to be spawned (default "Guard"). Note that you must select the 'String' value to enter a string in the arg0 field in GZDB, otherwise, you will be forced to enter an integer which will be interpreted internally as a spawn ID - so you'll end up with imps, or cyberdemons, or whatever, spawning...
user_tid Sets the TID that the spawned enemies are given. By default they have no TID.
user_goal Sets the goal/patrolpoint TID that the spawned enemies will walk to once they return to being idle. By default, they go back to their spawn point and stand still.
user_maxactors Sets how many enemies from this spawner to maintain alive at once (default 1)
user_minspawndistance Distance from player inside of which the spawner will stop spawning (default 512)


Alarm Configuration

There are three main actors that should be configured together to make realistic alarm scenarios.

Alarms and Alarm Spawners must be given the same TID as an Alarm Panel that will control them, otherwise they will not function unless activated via ACS. You can have multiple Alarm Panels with the same TID (e.g., so that the player can turn of alarms from a side office after the alarms are turned on by a guard in a main area).

11516 - Alarm

These are simple actors that, upon activation, alert all actors within a 512-unit radius. If activated from an alarm panel, they set the alerted actors' target to the alarm panel activator's target.

11517 - AlarmSpawner

These are specialized ActorSpawners that spawn up to three SneakableSSMP40Guard actors when they are activated. A maximum of three guards will be present at any time; if three guards were spawned and one guard was killed before the alarm was shut off, the next time the alarm goes off, only one additional guard will spawn. A major difference from the ActorSpawner is that this spawner will only spawn the specified number of actors per activation; it will not maintain a continuous stream of new actors.

Spawning only occurs when no player can see the spawn point.

Custom UDMF Attributes
Attribute Usage
user_tid Sets the TID that the spawned enemies are given. By default they have no TID.
user_goal Sets the goal/patrolpoint TID that the spawned enemies will walk to once they return to being idle. By default, they go back to their spawn point and stand still.

11518 - AlarmPanel

These are usable flatsprite actors that control Alarms and Alarm Spawners that have the same TID as the panel. The 'Nazi'-class descendant actor who is closest to the alarm panel (within 1024 units) will be automatically selected as the activator, and, once alerted, will automatically walk to the alarm panel and activate it.

Any actors with the same TID as the Alarm Panel will be toggled to their 'Active' or 'Inactive' state, as appropriate, so any Alarm of Alarm Spawner actors (as well as any other switchable decorations) that have the same TID as the panel can be controlled by the panel.

To silence alarms, the player must manually deactivate the alarm, or the Alarm Panel can be deactivated via ACS to set inactive all controlled actors.

Players can also turn deactivated alarms on... This would normally be dumb, but might be useful for flushing guards into a courtyard away from a key, or something similar.

Active AlarmPanel actors have a red glow on them.

Custom Crosshairs & Hold-to-activate Lines

The player's crosshair can be set via ACS or by setting the user_crosshair UDMF property on a linedef that the player is directly looking at.

Setting via ACS

The player's current crosshair can also be changed via ACS by setting the player's 'crosshair' property to a valid crosshair number, as discussed above. This change takes precedence over any line-set crosshair. This can only be reverted by setting the 'crosshair' variable to zero.

  • This command will set the crosshair to the XHAIR90 graphic:
    SetUserVariable(0, "crosshair", 90);
  • This command will restore the crosshair to the player's set crosshair:
    SetUserVariable(0, "crosshair", 0);

Setting when looking at a line

Any blocking line (in essence, any line that could be hit by a hitscan) can be set up to show the player a custom crosshair/icon by setting the 'user_crosshair' UDMF property on the line. The value of this property must correspond to an existing crosshair graphic - e.g., a value of 97 will set the crosshair to XHAIR97/XHAIRB97 (see the ZDoom wiki for details on crosshair graphics). The crosshair will be restored to normal once the player is no longer looking at the line.

This effect can be used on an activation line to give a hint as to a required inventory item, key, etc. (as with the generator repair points in C3M0_A).

Custom UDMF Attributes
  • Sets the crosshair of the player when the player's crosshair is over a portion of the line.

"Hold-to-activate" lines

Within Blade of Agony, player control handling has been altered so that holding down the 'use' button while facing a 'repeatable' activation line will cause that line's special to be run once per tick for as long as the 'use' button is held (and not just once per 'use' press, as is normal). In most cases, this change doesn't alter gameplay at all, however, scripts can be written to take advantage of this implementation.

The line to be activated must be set up to be activated "When player presses use" and as a "Repeatable Action", and must be assigned a unique id/tag.
If the portion of the line that you want to be activated is the midtexture rather than an upper or lower section, you must set the line to "Block Everything" or "Block Hitscans".

The line's special must be set to 80 - Script Execute, and pointed to a custom script that takes, at a minimum, the line's id as a parameter.

  • A generic "hold-to-activate" script will look something like this:
    Script "ActivateGenerator" (int lineid)
       if (ACS_NamedExecuteWithResult("Activate", lineid, 5)) // The 'Activate' script takes line id and activation time in seconds as parameters.
          /* Activation complete.  Do post-activation stuff here. */
       else { PlaySound(0, "effects/repair", CHAN_AUTO, 0.7); } // Play repair sounds

Player Followers

An actor that will stand dormant until it sees a player, then will follow that player. The actor can be set to carry a specific weapon.

If a playerfollower has no weapon, and falls significantly far behind the player, when he re-appears, he will have gained a pistol.

Editor number Type
12710 PrisonerAgent - Agent Ryan as a prisoner (No weapon)
12740 AgentArmed - Agent Ryan after returning to duty (Luger)
12741 AgentArmedMP40 - Agent Ryan after returning to duty (MP40 - but with no new sprites)
12742 DouglasArmed - Douglas (Pistol)
12743 SoldierArmed - Generic Soldier (Pistol)
12744 SoldierArmedRifle - Generic Soldier (Rifle)
12745 AscherArmed - Lt Ascher (Rifle)
No editor number Dog Follower - A German Shepherd (Melee, with handling to patrol the general area instead of standing still)

Custom Properties

Weapon that the PlayerFollower will spawn with, set based on FollowerWeapons enum:
  • If true, actor will immediately forget its target if the player moves out of range.
  • This has the effect of making the actor follow the player more closely
  • Behavior and following is more predictable, but more realistic for an escaping prisoner (vice a soldier in combat)
  • Chance that the actor will stop while chasing to attack enemies
  • because of how often this check is performed, values will need to be *very* low (e.g., 2-4) to see any change in actor behavior.
  • FOV used for look/search/sight calls
  • Chance of using grenades. By default, the actor has an infinite supply of grenades
  • Alternatively, if you give the actor a specific number of grenades via a script, then the PlayerFollower will throw up to that many grenades, then no more
Useful Variables

These are intended to be set via ACS using 'SetUserVariable(tid, "variable", value);'

  • Normally, if a PlayerFollower falls 100 pathmarkers behind the player, the actor will be warped ahead to the 50th pathmarker (if the player can't see the marker)
  • Setting this boolean to 1 disables that behavior. This is useful if you want to force a PlayerFollower along a certain route in the map, and don't want him skipping ahead
  • Be cautious! If the PlayerFollower gets stuck somewhere in the level geometry while this is set, then the PlayerFollower will never be able to become un-stuck
  • Setting this boolean to 1 causes the PlayerFollower to stand in place and not follow the player anymore
  • This differs from being dormant/Deactivated in that the PlayerFollower will still look for players, look for enemies, and open fire on enemies
Editing Tricks
Block the PlayerFollower
Normally the PlayerFollowers are not blocked by Monster-Blocking lines. If you want to limit where a PlayerFollower can go, just remove the NOBLOCKMONST flag in ACS:
SetActorFlag(tid, "NOBLOCKMONST", 0);
Then place monster blocking lines in the map, and the PlayerFollower won't be able to cross them.
Change PlayerFollower Weapon
  • You can change the weapon that a PlayerFollower is carrying by giving them a new weapon via ACS. Note that the weapon must be one of those that is coded into the actors...
  • Valid weapons are: Luger9mm, MP40, Sten, KnifeSilent (and GrenadePickup, as discussed in the PlayerFollower.GrenadeChance property section above)

Screen Shaders

There are various post-processing shaders for the player screen that can be used at any time as effects to support certain situations. Just give or take the corresponding tokens to the player inventory to activate or deactivate time ingame.

Inventory Token Effect
BlurShaderControl Distords the sight after an explosion. The amount of the item that you give sets how long the effect lasts - if you give 35, the effect will last 35 tics, 70 -> ~2 seconds, 350 -> ~10 seconds, etc.  The effect will stack if you give more when there's already a blur in action. There's also a ~0.5 second fade in to the blur effect, then a slow fade back to normal over time once the blur is in place
OldVideoShaderControl Adds an old video effect to the screen. To enable a shader, give 2 of the ShaderControl subclass item to the player. To disable a shader, take 1 of the shader control item away so that the player only has 1 of said item.
ShakeShaderControl Adds an shake effect to the screen, works well for situations when being on a truck or a minecart. To enable a shader, give 2 of the ShaderControl subclass item to the player. To disable a shader, take 1 of the shader control item away so that the player only has 1 of said item.


Static Skyboxes

A derivative of the skybox viewpoint actor that moves in relation to the player's movement, giving the illusion that the skybox is a part of normal level geometry.

The map author can specify the amount that the skybox's movement is scaled relative to the player's motion, allowing for a very small skybox to appear much larger and closer in relation to the player.

By default, the "anchor", or the neutral origin point of the skybox view, will be the player's spawn location. Alternatively, the viewpoint can also be "anchored" to a map actor by specifying the TID of the actor to use as the anchor.

19990 - SkyViewpointStatic - The viewpoint actor for use in static skyboxes

Editor Arguments
Argument Usage
Arg[1] - Skybox Scene Scale The scale of the skybox's scene (default is 100). The larger this number is, the farther away the skybox contents will appear to be.
Arg[2] - Anchor Object TID TID of an actor to anchor the skybox on. Default value (0) means to anchor on player start spot.

19991 - SkyViewpointAnchor - A generic mapspot that can be assigned a TID and used as an anchor for static skybox viewpoints