The following articles describe the new functionalities that have been implemented into Blade of Agony. It's mostly for us and other developers as an easy to find and use documentation.
'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:
user_drawhealthbar |
---|
|
user_forceweapondrop |
|
user_conversation (currently unused in BoA) |
|
user_lightburns |
|
user_oncompass |
|
'Nazi' Class Only:
user_sneakable |
---|
|
user_static |
|
user_incombat |
|
Flag effects
Certain editor flags have been given additional meaning when applied to a 'Nazi'-class actor.
'Nazi' Class Only:
AMBUSH |
---|
|
BOSS |
|
Properties for new actor definitions 'Base' Class and 'Nazi' Class:
Base.BossIcon |
---|
|
Base.AlwaysDrawHealthBar |
|
Base.LightThreshold |
|
Base.LightKills |
|
Base.Swimmer |
|
Base.LoiterDistance |
|
Base.NoMedicHeal |
|
'Nazi' Class Only:
Nazi.Sneakable |
---|
|
Nazi.SneakableCloseSightRadius |
|
Nazi.PerceptionTime |
|
Nazi.PerceptionFOV |
|
Nazi.PerceptionDistance |
|
Nazi.Healer |
|
Nazi.ZombieVariant |
|
Actor States
'Nazi' Class Only:
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
MakeSneakable |
---|
|
MakeAlerted |
|
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
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) |
user_oncompass | When set to 1, spawned enemies will be added to the player's compass as grey dot |
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
11517 - AlarmSpawner
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
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.
Color Grading
Color Grading in Scripts
For transitioning to a color grading directly in a script, the following two scripts can be used:
ScriptCall("ColorGradeThinker", "TransitionTo", 0, 1, 140);
ScriptCall("ColorGradeThinker", "TransitionTo", 0, 2, 700);
The first one makes a seamless transition to the color grade with the index number 1 in 140 tics, the second one a very slow transition to index number 15 (max) in 700 tics (which is about 10 seconds)
ScriptCall("ColorGradeThinker", "Set", 0, 1);
Instead of transitioning to a color grading in a certain amount of time, you can also directly set it in a script. The above line sets the color grading instantly to the look-up table index 1.
Color Grading on Lines
ColorGradeSet immediately sets the supplied LUT index on the player who called the script.
ACS_NamedAlwaysExecute("ColorGradeSet", 0, 9); // Instantly sets to index 9
ColorGradeTo transitions to the supplied LUT index over the course of the specified number of tics. If a transition is already taking place, the LUT is queued to transition to after the current transition is done.
ACS_NamedAlwaysExecute("ColorGradeTo", 0, 4, 70); // Index 4, in 70 tics (what is standard if set to 0)
ColorGradeBetween is meant to be used as a linedef action. It will transition to a LUT depending on which side the line is triggered from. This is useful to mark a LUT "boundary" between two areas without having to use two linedefs with a ColorGradeTo call.
ACS_NamedAlwaysExecute("ColorGradeBetween", 0, 0, 4, 70); // Repeatable and player walkover
Color Grading Types
The textures/pplut.png look-up table has a wide variety of different color gradings for different situations.
Grading Index | Type |
---|---|
0 | Standard |
1 | Old photography (brown with low contrast, red to yellow stay, other colors desaturated) |
2 | Ending Sequence (light, blue to cyan, green to lime, low contrast) |
3 | C1M4 (blue teint, high contrast, dark look) |
4 | C2M2 (blue saturated, green to olive and weak, red to purple) |
5 | C3M1 (green tone, higher contrast) |
6 | C3M0_A (colder white, higher contrast, darker middle tones) |
More Grading Types will be added soon.
Compass Markers
These actor types will show up on the player's compass automatically when they are placed in the map. A good reference map for how these should be implemented is C3M2.
As a general rule, Primary Objective Markers (red) should be used to mark mission-critical areas that must be visited, and Secondary Markers (orange) should be used to indicate necessary specific actions/conversations/pickups.
Additionally, any other actors that are tagged with a specific TID can be made to show up as a grey dot on the compass via ACS by calling the "BoA_CompassQueue" script.
ACS_NamedExecuteAlways("BoA_CompassQueue", 0, thingTID);
Or, you can specify a specific image ("ICON", here) to be used as the icon.
ACS_NamedExecuteAlways("BoA_CompassAddIcon", 0, "ICON", thingTID);
Note that calling this script will add all actors with the matching TID to the compass.
Primary Objective Markers
These actors are used to indicate the general area of a primary objective or significant waypoint in the map. They should be used sparingly, so that seeing a red exclamation pointon the compass doesn't lose importance; only major mission-related locations should have a red marker.
These actors can be spawned as DORMANT, then activated via "Thing_Activate" in ACS, or they can be spawned normally and hidden or removed later using "Thing_Deactivate" or "Thing_Remove".
Take special care to properly activated/deactivated/removed markers via ACS as the mission progresses in order to keep the path of progression clearly indicated on the compass... In other words, as the path to a specific objective becomes available to the player, the marker for that objective should become active, then, once the objective is reached, the marker should be deactivated or removed.
These don't have to correspond perfectly to the listed objectives - For example, most maps essentially have a final objective of "Find Douglas/Ryan/Asher in order to return to HQ" upon completion of all of the primary objectives; even though "Finish the map" is not a listed objective, there should probably still be a red marker placed once that becomes the player's next goal. As another example, if a single objective requires multiple similar actions across the map to complete (like placing Comp B charges), each of those locations should be marked with a red marker.
Editor number | Type |
---|---|
21238 | ObjectiveIcon - Red exclamation mark that shows up on both the compass and the automap; it is invisible during gameplay. |
21239 | ExclamationCompass - Red exclamation mark that only shows up on the compass; it is invisible during gameplay. |
Secondary Objective Markers
These actors are typically used to mark NPCs that can be talked to, switches that should be activated, etc. These markers will not be added to the player's compass until the player is within 2048 units and has a line of sight to the marker.
Editor number | Type |
---|---|
21236 | Exclamation - Static static orange exclamation mark. These should be spawned/removed via ACS as the mission progresses in order to avoid cluttering the compass with no-longer-needed markers. |
21237 | ExclamationTouchable - Orange exclamation mark that changes to grey when a player approaches. |
Mission/Quest Item Markers
All items which inherit from the 'CompassItem' class, as well as any disguise/uniform pickups, will automatically be added to the player's compass. These actors will use their inventory icon as their compass icon; if one is not set, they will use their spawn state sprite as their icon.
Akten AktenEisenmann AktenV2 AktenDream AktenDreamClue ArtifactAstrostrein ArtifactAstrostreinIM ArtifactEgyptian ArtifactEgyptian_H1 ArtifactEgyptian_H2 SpearOfDestiny Cartridge51 Cartridge52 Cartridge53 RepairKit Crank RadioPickup Kennkarte GrapplingHook ChutePickup ScientistUniform SSBJUniform CCBJUniform ZombieArmClue ZombieHeadClue MineralClue
Base- and Nazi-class Enemies
By setting the 'user_oncompass' UDMF attribute of an enemy actor to 1, that actor will be added to the player's compass automatically. These actors will use a grey dot as their compass icon. The icon for actors that are also tagged with the 'user_drawhealthbar' UDMF property will be tinted with color to indicate the health level of that actor.
ActorSpawner-Spawned Enemies
By setting the 'user_oncompass' UDMF attribute of an ActorSpawner actor to 1, all enemies spawned by that actor will be added to the player's compass automatically. These actors will use a grey dot as their compass icon. See the initial machine-gun turret fight in C3M2 for a working example.
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 a thing class or a text string - e.g., a "RepairKit" string will display the corresponding actor graphic. 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).
- Sets the crosshair of the player when the player's crosshair is over a portion of the line (can be thing class or text)
"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
PlayerFollower.Weapon |
---|
Weapon that the PlayerFollower will spawn with, set based on FollowerWeapons enum:
PWEAP_None PWEAP_Melee PWEAP_Luger PWEAP_MP40 PWEAP_Rifle PWEAP_Grenade |
PlayerFollower.CloseFollow |
|
PlayerFollower.ChaseAttackChance |
|
PlayerFollower.FOV |
|
PlayerFollower.GrenadeChance |
|
Useful Variables
These are intended to be set via ACS using 'SetUserVariable(tid, "variable", value);'
nocatchup |
---|
|
nonmoving |
|
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 |
|
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. |