Actor states

From ZDoom Wiki
Jump to: navigation, search

An actor's states can be defined within its DECORATE definition. State sequences describe all the behavior of the actor as well as its animation.

Usage

A state definition is started with the states keyword and enclosed by braces '{', '}'.

It consists of the following:

State labels

A state label is an identifier followed by a colon (:). State labels are used to give names to state. A number of predefined labels exist (such as Spawn: or Death:), corresponding to states needed by the engine.

A single state can have several labels, each on a different line. However, most states do not have a label, instead they merely follow other states in sequences.

State definitions

The main elements of any given state are the following:

  1. Its sprite name
  2. Its frame letter
  3. Its duration in tics
  4. Its associated action function
  5. Its successor (the next state in sequence)

It also might have additional properties which are expressed through special keywords detailed below.

These consist of a sprite name, a frame letter, the duration in tics and optionally additional keywords and an action function name (code pointer). For example:

STUF C 5 Bright A_Look

Here, STUF is the sprite name, C is the frame letter, 5 the duration, and A_Look the action function.

The successor is defined implicitly as the next defined state, unless a goto, loop, wait, or stop keyword is used to explicitly change it. For instance:

STUF C 5 Bright A_Look
STUF D 5 Bright

Here, the successor for the first state is the second state. The second state's successor is not defined in this example.

If several states share the same sprite name, duration, keywords, and action functions, and they follow in sequence, the states can be "collapsed" together by stringing the frame letters in a word.

STUF ABCD 5 Bright A_Look

Here, four different states are defined on a single line. Each of A, B, C, and D are different states. And likewise:

STUF VVVVVV 5 Bright A_Look

The six V states are all entirely identical (except for their successor), but they are nonetheless separate states.

When the duration runs out, the actor moves to the next state in the sequence and runs the new state's action function immediately. Note that setting -1 as a duration means infinite duration. The actor, once it enters this state, will never leave it on its own; though it can still be moved to a different state by external actions (e.g., suffering damage might put it in the Pain state).

Random durations are possible with the random(min, max) function. Alternatively, you can use A_SetTics; this allows to use full-fledged DECORATE expressions to set any kind of dynamic duration; but prevents the state from having another action function. (New from 2.7.1)

The next state is automatically implied to be the following letter on a frame sequence, or if there aren't any more states on a line, the states defined in the next line. Alternatively, flow control keywords (loop, wait, goto, stop) listed after a state can change it. Jump functions such as A_Jump will ignore normal sequence logic and immediately move to their designated state, without waiting for the duration to run out first.

Variable duration

(New from 2.7.1)

A state can have a random duration. Instead of defining a frame like this:

POSS A 10 A_Look

You can define it as:

POSS A random(10,20) A_Look

and the state will last a random duration between 10 and 20 tics, inclusive. More control can be obtained by using the A_SetTics function and DECORATE expressions.

POSS A 0 A_Look
POSS A 10 A_SetTics((waterlevel + 10) - (accuracy / 10))

State keywords

The existing keywords can be used in a state between the duration and the action function call.

  • Bright
The sprite will be displayed as fullbright while the actor is in this state. Note that this is ignored in fog.
Mark the state as allowing A_VileChase to target the actor provided the other conditions are met. By default, only states with a -1 (infinite) duration are eligible.
  • Fast
The state has its duration halved in fast mode (if using a skill with the FastMonsters property, or the -fast command-line parameter) and for actors with the ALWAYSFAST flag. This has no effect on actors with the NEVERFAST flag.
Adds a dynamic light to the state. See below for further information.
Forces the action function associated to the state to be executed during the actor's first tic. This is only useful for the first state in an actor's spawn sequence.
  • Offset(x, y)
Gives the state a sprite offset, only used for HUD sprites (most relevant for weapons. Note that Offset(0, 0) is interpreted as "keep previous offset", not as "reset offset to 0, 0" for compatibility with Hexen, which is the game from which this feature originates.
The state has its duration doubled in slow mode (if using a skill with the SlowMonsters property).

Example

POSS AABBCCDD 4 A_Chase

This defines 8 states. Each one of them uses the sprite POSS, has a duration of 4 and uses the code pointer A_Chase which is the standard walk function for monsters. Of these 8 states the first 2 will use the sprite frame 'A', the next 2 the frame 'B' and so on. The length of the frame sequence can be up to 256 characters. Valid frames are 'A'-'Z', '[', '\' and ']'. Different sprites can be freely mixed in an actor definition; however, each separate line of a state definition is limited to one sprite only.

Notes

  • If the frames '[', '\' or ']' are used the frame sequence has to be enclosed in quotation marks ('"').
  • Sprite name and frame TNT1 A means no sprite, making the actor invisible for the duration of the state.
  • It is possible for a state to keep the actor's current sprite and/or frame, using special sprite names such as "----" or "####". See the sprite page for more information.

Dynamic light binding

Graficon.gif (GZDoom only: not supported by ZDoom)
It is possible to attach a dynamic light directly to an actor state in its DECORATE definition, rather than binding it to the actor in a GLDEFS lump. The dynamic light itself must still be defined in GLDEFS, however. Contrarily to lights attached to actors in GLDEFS, a binding made to a state directly in the state definition will be inherited by derived actors.

This is done by adding the Light keyword, followed by the name of the light within parentheses and quote marks, in this way:

BLAH A 1337 Bright Light("MyLight") A_DoSomething

ZDoom itself does not support dynamic lights and thus will ignore the Light keyword and its parameter, but the actor will otherwise work correctly.

Flow control

There are 5 different instructions that control the execution order of an actor's frames directly:

loop
Jumps to the most recently defined state label. This is used for a looping animation. Do not put a loop on a state with a duration of -1, this is unnecessary and can cause problems.
stop
Stops animating this actor. Normally this is used at the end of the death sequences. If the last state has a duration > -1 the actor will be removed. Note that if a state contains only the stop instruction, the actor will behave as if it doesn't have that state. This can be useful, for example, to remove a state that an actor has inherited from its parent.
wait
Loops the last defined state. This is useful if a code pointer is used that waits a given time or for a certain event. Currently useful code pointers include A_WeaponReady, A_Raise, A_FreezeDeathChunks, and similar code pointer functionality.
fail
Used with custom inventory items, means that the state sequence failed to succeed.
goto label [+offset]
Jumps to an arbitrary state in the current actor. With this, you can also jump to a base class state, i.e. one that was inherited by a parent. The statement goto See jumps to the walking animation that has been overriden in the current actor class, or if such does not exist, to the inherited class's state. goto is however static, i.e. will not do virtual jumps — for that, see A_Jump.
In addition, if an actor is using inheritance, you can use goto with the scope operator (::) to go to a parent class' state. The keyword "super" always refers to the immediate parent, but any parent class can be referred to by name as well, for example "goto Actor::GenericFreezeDeath" is a valid instruction.


Important note

This format has been designed for maximum flexibility. As a result no assumptions are made about what the designer wants. States are never implicitly created.

Also, if no flow control is used ZDoom will continue to the state provided directly after. Consecutive state labels can be used to assign the same frames to more than one state.

States

These are the predefined states each actor has access to:

Spawn
Defines the state that is displayed when an actor is spawned. For monsters this is normally also the idle loop.
Note: An actor that has just been spawned does not run the codepointer from its first “Spawn” frame. It will be called, however, if the actor loops or returns to its Spawn state later. An easy workaround to have actors call a codepointer immediately after spawning consists in having the very first frame have a duration of 0 tics, followed by another frame in which the codepointer instruction is given. Another solution is to use the NoDelay keyword. (New from 2.7.1)
Idle
Defines an alternate idle state for a monster to return to when it has run out of targets. If this state is not present, the monster will return to the Spawn state instead.
See
Defines the walking animation for a monster. Note that this state must be present for actors which are able to chase and attack other actors.
Melee
Defines the melee (near) attack.
Missile
Defines the missile (far) attack.
Pain
Defines the pain action. Multiple Pain states can be used depending on the type of damage inflicted. See custom damage types.
Death
Defines the normal death sequence. Multiple Death states can be used depending on the type of damage that kills the actor. See custom damage types. Also entered by projectiles when hitting a wall (or an actor as well if the Crash and/or XDeath states are not defined).

XDeath (alternatively, Death.Extreme (development version 7e6a5c1 only))

Defines the extreme (splatter) death sequence. Multiple XDeath states can be used depending on the type of damage that kills the actor (development version 7e6a5c1 only). Also entered by projectiles when hitting a bleeding actor (if no XDeath state is defined, they enter their Death state instead).
Burn
Defines the burn (Fire) death sequence.
Ice
Defines the freeze (Ice) death sequence.
Disintegrate
Defines the disintegration death sequence.
Raise
Defines the resurrection sequence.
note: This is when a monster is being resurrected (ie: by an Arch-Vile), not when its resurrecting another monster.
Heal
Define the healing sequence. This is entered when this monster is resurrecting another one. Note that by the time this monster enters this state, the resurrection process has already started. The process is usually started either by A_Chase, with the CHF_RESURRECT flag passed to it, or A_VileChase.
Crash
Defines the crash sequence. Multiple Crash states can be used depending on the type of damage that kills the actor. This is entered when the actor is a corpse and hits the floor. Also entered by projectiles when hitting a non-bleeding actor (if no Crash state is defined, they enter their Death state instead).

Crash.Extreme (development version 7e6a5c1 only)

Defines the extreme (splatter) crash sequence. Multiple Crash.Extreme states can be used depending on the type of damage that kills the actor (development version 7e6a5c1 only). This is entered when the actor is a corpse and hits the floor after being gibbed.
Crush
Defines the crush sequence. This is entered when the actor is crushed by ceiling/door/etc.
Wound
This state is entered when the actor's health is lower than its WoundHealth but greater than 0. Multiple Wound states can be used depending on what type of damage is inflicted upon the actor. See custom damage types.
Greetings
This is used by the Strife dialog system. It is entered when a conversation is about to start.
Yes
This is used by the Strife dialog system. It is entered when the actor reacts positively to the player's choice.
No
This is used by the Strife dialog system. It is entered when the actor reacts negatively to the player's choice.
Active
This is used by Hexen-style switchable decorations. It is entered when the actor is activated.
Inactive
This is used by Hexen-style switchable decorations. It is entered when the actor is deactivated.
Bounce
This is used by bouncers with the USEBOUNCESTATE flag. It is entered when the actor bounces. (New from 2.7.1) Multiple bounce states can be used depending on what the actor bounced off:
  • Bounce
  • Bounce.Floor
  • Bounce.Ceiling
  • Bounce.Wall
  • Bounce.Actor
  • Bounce.Actor.Creature
Partial matches work just like Pain states, so if an actor bounces off a floor and you don't have a Bounce.Floor state, but you do have a Bounce state, it will use the Bounce state. Conversely, if you only have a Bounce.Floor state but no Bounce state, then the actor will only enter the Bounce.Floor state when it bounces on a floor; bouncing off anything else will not cause it to change state. The Bounce.Actor.Creature state is used for bouncing over a shootable actor without the NOBLOOD flag.

Weapons and custom inventory items define a few more states to define their animations.

Note that you can also define your own states that can be referred to using A_Jump or other jump instructions.

Examples

This is an example of a state sequence. The rest of this actor has been removed for readability:

actor ZombieMan 3004
{
   ...
   states
   {
   Spawn:
       POSS AB 10 A_Look
       loop
   See:
       POSS AABBCCDD 4 A_Chase
       loop
   Missile:
       POSS E 10 A_FaceTarget
       POSS F 8 A_PosAttack
       POSS E 8
       goto See
   Pain:
       POSS G 3
       POSS G 3 A_Pain
       goto See
   Death:
       POSS H 5
       POSS I 5 A_Scream
       POSS J 5 A_Fall
       POSS K 5
       POSS L -1
       stop
   XDeath:
       POSS M 5
       POSS N 5 A_XScream
       POSS O 5 A_Fall
       POSS PQRST 5
       POSS U -1
       stop
   Raise:
       POSS KJIH 5
       goto See
   }
}

Note: The first frame of the “Spawn” state, “POSS A 10”, contains a codepointer, A_Look. This codepointer is not called the very first time the zombie is spawned in the map, so it has to wait 10 tics to get into its second frame, “POSS B 10”. From then on, it will call all its codepointers reliably. If it runs out of targets, and since it has no “Idle” state, it will return to its Spawn state where it will call A_Look immediately, even in the A frame.


This example demonstrates using the stop keyword to remove a state. This definition uses inheritance to define a tougher version of the imp that cannot be resurrected by the Arch-Vile:

actor SuperImp : DoomImp
{
     health 1500
     mass 200
     painchance 10

     States {
          Raise:
              stop
     }
}

See also

Using inheritance