FSM: Difference between revisions

From Unofficial EFPSE wiki Extended
Jump to navigation Jump to search
No edit summary
No edit summary
Line 108: Line 108:


=== Examples ===
=== Examples ===
'''Basic FSM for a weapon:'''<blockquote><code>image Weapon 0 7</code>


<code>sound WeaponFire</code>
<p>Basic FSM for a weapon:</p>


<code>sound WeaponReload</code>
<div id="progs">
 
<div>image Enemy 0 12</div>
<code>state IDLE NONE 0</code>
<br>
 
<div>state IDLE NONE 0</div>
<code>frame 1 0.25 0 0 0 NONE</code>
<div>frame 0 0.125 0 0 0 NONE</div>
 
<div>frame 0 0.125 0 0 0 READY</div>
<code>frame 1 0.25 0 0 0 READY</code>
<br>
 
<div>state SEE CHASE 0</div>
<code>state ATTACK IDLE 0</code>
<div>frame 0 0.125 0 0 0 NONE</div>
 
<div>frame 0 0.125 0 0 0 READY</div>
<code>frame 2 1 0 0 0 NONE</code>
<br>
 
<div>state CHASE NONE 0</div>
<code>frame 3 1 0 0 0 SOUNDANDATTACK 0</code>
<div>frame 1 1 0 0 0 NONE</div>
 
<div>frame 2 1 0 0 0 NONE</div>
<code>frame 4 1 0 0 0 MUZZLEFLASH</code>
<div>frame 3 1 0 0 0 NONE</div>
 
<div>frame 4 1 0 0 0 READY</div>
<code>frame 5 1 0 0 0 READY</code>
<br>
 
<div>state ATTACK CHASE 0</div>
<code>frame 6 1 0 0 0 NONE</code>
<div>frame 5 0.25 0 0 0 NONE</div>
 
<div>frame 5 0.25 0 0 0 NONE</div>
<code>frame 7 1 0 0 0 NONE</code>
<div>frame 6 0.0625 0 0 0 NONE</div>
 
<div>frame 6 0.0625 0 0 0 ATTACK</div>
<code>frame 1 0.25 0 0 0 NONE</code>
<div>frame 5 0.25 0 0 0 NONE</div>
 
<div>frame 5 0.25 0 0 0 READY</div>
<code>frame 1 0.25 0 0 0 NONE</code>
<br>
 
<div>state HURT CHASE 0</div>
<code>state RELOAD IDLE 0</code>
<div>frame 7 0.125 0 0 0 NONE</div>
 
<div>frame 8 0.125 0 0 0 NONE</div>
<code>frame 1 0 0 0 0 NONE</code>
<br>
 
<div>state DEATH DEAD 0</div>
<code>frame 1 0.1 0 0 0 NONE</code>
<div>frame 9 0.166 0 0 0 NONE</div>
 
<div>frame 10 0.166 0 0 0 NONE</div>
<code>frame 1 0.1 0 200 0 NONE</code>
<div>frame 11 0.166 0 0 0 NONE</div>
 
<br>
<code>frame 1 0.1 0 200 0 RELOAD</code>
<div>state DEAD NONE 0</div>
 
<div>frame 12 0.125 0 0 0 NONE</div>
<code>frame 1 0.1 0 0 0 SOUND 1</code></blockquote>'''Basic FSM for alt attack:'''<blockquote><code>state ALTATTACK IDLE 0</code>
<div>frame 12 0.125 0 0 0 NONE</div>
 
</div>
<code>frame 1 0 0 0 NONE</code>
<div id="progs">
 
<div>image Enemy 0 12</div>
<code>frame 2 0 0 0 SOUNDATTACK 0     (plays the attack sound)</code>
<br>
 
<div>state IDLE NONE 0</div>
<code>frame 3 0 0 0 MUZZLEFLASH         (Sets the muzzel flash)</code>
<div>frame 0 0.125 0 0 0 NONE</div>
 
<div>frame 0 0.125 0 0 0 READY</div>
<code>frameset 4 28 0 0 0 NONE               (This plays frames 4 through to 28 so that you don't have to write out each line)</code>
<br>
 
<div>state SEE CHASE 0</div>
<code>frame 29 0 0 0 ATTACK                   (sets the attack)</code>
<div>frame 0 0.125 0 0 0 NONE</div>
 
<div>frame 0 0.125 0 0 0 READY</div>
<code>frame 30 0 0 0 READY</code> </blockquote>
<br>
<div>state CHASE NONE 0</div>
<div>frame 1 1 0 0 0 NONE</div>
<div>frame 2 1 0 0 0 NONE</div>
<div>frame 3 1 0 0 0 NONE</div>
<div>frame 4 1 0 0 0 READY</div>
<br>
<div>state ATTACK CHASE 0</div>
<div>frame 5 0.25 0 0 0 NONE</div>
<div>frame 5 0.25 0 0 0 NONE</div>
<div>frame 6 0.0625 0 0 0 NONE</div>
<div>frame 6 0.0625 0 0 0 ATTACK</div>
<div>frame 5 0.25 0 0 0 NONE</div>
<div>frame 5 0.25 0 0 0 READY</div>
<br>
<div>state HURT CHASE 0</div>
<div>frame 7 0.125 0 0 0 NONE</div>
<div>frame 8 0.125 0 0 0 NONE</div>
<br>
<div>state DEATH DEAD 0</div>
<div>frame 9 0.166 0 0 0 NONE</div>
<div>frame 10 0.166 0 0 0 NONE</div>
<div>frame 11 0.166 0 0 0 NONE</div>
<br>
<div>state DEAD NONE 0</div>
<div>frame 12 0.125 0 0 0 NONE</div>
<div>frame 12 0.125 0 0 0 NONE</div>
</div>
<div id="progs">
<div>image Weapon 0 7</div>
<div>sound WeaponFire</div>
<div>sound WeaponReload</div>
<br>
<div>state IDLE NONE 0</div>
<div>frame 1 0.25 0 0 0 NONE </div>
<div>frame 1 0.25 0 0 0 READY </div>
<br>
<div>state ATTACK IDLE 0</div>
<div>frame 2 1 0 0 0 NONE</div>
<div>frame 3 1 0 0 0 SOUNDANDATTACK 0</div>
<div>frame 4 1 0 0 0 MUZZLEFLASH</div>
<div>frame 5 1 0 0 0 READY</div>
<div>frame 6 1 0 0 0 NONE</div>
<div>frame 7 1 0 0 0 NONE</div>
<div>frame 1 0.25 0 0 0 NONE</div>
<div>frame 1 0.25 0 0 0 NONE</div>
<br>
<div>state RELOAD IDLE 0</div>
<div>frame 1 0 0 0 0 NONE</div>
<div>frame 1 0.1 0 0 0 NONE</div>
<div>frame 1 0.1 0 200 0 NONE</div>
<div>frame 1 0.1 0 200 0 RELOAD</div>
<div>frame 1 0.1 0 0 0 SOUND 1</div>
</div>


===== '''Basic FSM for enemies:''' =====
===== '''Basic FSM for enemies:''' =====
<br />s
<div id="progs">
<div>image Enemy 0 12</div>
<br>
<div>state IDLE NONE 0</div>
<div>frame 0 0.125 0 0 0 NONE</div>
<div>frame 0 0.125 0 0 0 READY</div>
<br>
<div>state SEE CHASE 0</div>
<div>frame 0 0.125 0 0 0 NONE</div>
<div>frame 0 0.125 0 0 0 READY</div>
<br>
<div>state CHASE NONE 0</div>
<div>frame 1 1 0 0 0 NONE</div>
<div>frame 2 1 0 0 0 NONE</div>
<div>frame 3 1 0 0 0 NONE</div>
<div>frame 4 1 0 0 0 READY</div>
<br>
<div>state ATTACK CHASE 0</div>
<div>frame 5 0.25 0 0 0 NONE</div>
<div>frame 5 0.25 0 0 0 NONE</div>
<div>frame 6 0.0625 0 0 0 NONE</div>
<div>frame 6 0.0625 0 0 0 ATTACK</div>
<div>frame 5 0.25 0 0 0 NONE</div>
<div>frame 5 0.25 0 0 0 READY</div>
<br>
<div>state HURT CHASE 0</div>
<div>frame 7 0.125 0 0 0 NONE</div>
<div>frame 8 0.125 0 0 0 NONE</div>
<br>
<div>state DEATH DEAD 0</div>
<div>frame 9 0.166 0 0 0 NONE</div>
<div>frame 10 0.166 0 0 0 NONE</div>
<div>frame 11 0.166 0 0 0 NONE</div>
<br>
<div>state DEAD NONE 0</div>
<div>frame 12 0.125 0 0 0 NONE</div>
<div>frame 12 0.125 0 0 0 NONE</div>
</div>


===== '''Intermediate FSM for enemies:''' =====
===== '''Intermediate FSM for enemies:''' =====
<blockquote><code>image BORIS 0 455</code>
<div id="progs">
 
<div>image BORIS 0 455</div>
<code>sound AK</code>
<br>
 
<div>sound AK</div>
 
<code>state IDLE NONE 0</code>
 
<code>frameset 2 254 0.025 0 0 0 NONE</code>
 
<code>frame 255 0.025 0 0 0 NONE</code>
 
<code>frame 256 0.025 0 0 0 READY</code>
 
 
<code>state SEE CHASE 0</code>
 
<code>frameset 262 281 0.025 0 0 0 NONE</code>
 
<code>frame 282 0.025 0 0 0 NONE</code>
 
<code>frame 283 0.025 0 0 0 READY</code>
 
 
<code>state CHASE SEE 0</code>
 
<code>frameset 262 281 0.025 0 0 0 NONE</code>
 
<code>frame 282 0.025 0 0 0 NONE</code>
 
<code>frame 283 0.025 0 0 0 READY</code>
 
 
<code>state ATTACK CHASE 0</code>
 
<code>frame 463 0.025 0 0 0 NONE</code>
 
<code>frame 464 0.025 0 0 0 SOUNDANDATTACK 0</code>
 
<code>frameset 465 496 0.025 0 0 0 NONE</code>
 
<code>frame 497 0.025 0 0 0 READY</code>
 
 
<code>state HURT FLEE 0</code>
 
<code>frameset 286 340 0.025 0 0 0 NONE</code>
 
<code>frame 341 0.025 0 0 0 NONE</code>
 
<code>frame 342 0.025 0 0 0 READY</code>
 
 
<code>state FLEE SEE 0</code>
 
<code>frameset 262 281 0.025 0 0 0 NONE</code>
 
<code>frame 282 0.025 0 0 0 NONE</code>
 
<code>frame 283 0.025 0 0 0 READY</code>
 
 
<code>state SEE FLEE 0</code>
 
<code>frameset 262 281 0.025 0 0 0 NONE</code>
 
<code>frame 282 0.025 0 0 0 NONE</code>
 
<code>frame 283 0.025 0 0 0 READY</code>
 
 
<code>state FLEE CHASE 0</code>
 
<code>frameset 262 281 0.025 0 0 0 NONE</code>
 
<code>frame 282 0.025 0 0 0 NONE</code>
 
<code>frame 283 0.025 0 0 0 READY</code>
 
 
<code>state DEATH DEAD 0</code>
 
<code>frameset 357 453 0.025 0 0 0 NONE</code>
 
<code>frame 454 0.025 0 0 0 NONE</code>
 
<code>frame 455 0.025 0 0 0 NONE</code>
 
 
<code>state DEAD NONE 0</code>
 
<code>frame 455 0.025 0 0 0 NONE</code></blockquote>


<br>
<div>state IDLE NONE 0</div>
<div>frameset 2 254 0.025 0 0 0 NONE</div>
<div>frame 255 0.025 0 0 0 NONE</div>
<div>frame 256 0.025 0 0 0 READY</div>
<br>
<div>state SEE CHASE 0</div>
<div>frameset 262 281 0.025 0 0 0 NONE</div>
<div>frame 282 0.025 0 0 0 NONE</div>
<div>frame 283 0.025 0 0 0 READY</div>
<br>
<div>state CHASE SEE 0</div>
<div>frameset 262 281 0.025 0 0 0 NONE</div>
<div>frame 282 0.025 0 0 0 NONE</div>
<div>frame 283 0.025 0 0 0 READY</div>
<br>
<div>state ATTACK CHASE 0</div>
<div>frame 463 0.025 0 0 0 NONE</div>
<div>frame 464 0.025 0 0 0 SOUNDANDATTACK 0</div>
<div>frameset 465 496 0.025 0 0 0 NONE</div>
<div>frame 497 0.025 0 0 0 READY</div>
<br>
<div>state HURT FLEE 0</div>
<div>frameset 286 340 0.025 0 0 0 NONE</div>
<div>frame 341 0.025 0 0 0 NONE</div>
<div>frame 342 0.025 0 0 0 READY</div>
<br>
<div>state FLEE SEE 0</div>
<div>frameset 262 281 0.025 0 0 0 NONE</div>
<div>frame 282 0.025 0 0 0 NONE</div>
<div>frame 283 0.025 0 0 0 READY</div>
<br>
<div>state SEE FLEE 0</div>
<div>frameset 262 281 0.025 0 0 0 NONE</div>
<div>frame 282 0.025 0 0 0 NONE</div>
<div>frame 283 0.025 0 0 0 READY</div>
<br>
<div>state FLEE CHASE 0</div>
<div>frameset 262 281 0.025 0 0 0 NONE</div>
<div>frame 282 0.025 0 0 0 NONE</div>
<div>frame 283 0.025 0 0 0 READY</div>
<br>
<div>state DEATH DEAD 0</div>
<div>frameset 357 453 0.025 0 0 0 NONE</div>
<div>frame 454 0.025 0 0 0 NONE</div>
<div>frame 455 0.025 0 0 0 NONE</div>
<br>
<div>state DEAD NONE 0</div>
<div>frame 455 0.025 0 0 0 NONE</div>
</div>
===== '''Basic FSM for decorations:''' =====
===== '''Basic FSM for decorations:''' =====
<blockquote><code>image Decoration 0 3</code>
<div id="progs">
 
<div>image Enemy 0 12</div>
<code>state IDLE NONE 0</code>
<br>
 
<div>state IDLE NONE 0</div>
<code>frame 0 0.25 0 0 0 NONE</code>
<div>frame 0 0.125 0 0 0 NONE</div>
 
<div>frame 0 0.125 0 0 0 READY</div>
<code>frame 0 0.25 0 0 0 READY</code>
<br>
 
<div>state SEE CHASE 0</div>
<code>state DEATH DEAD 0</code>
<div>frame 0 0.125 0 0 0 NONE</div>
 
<div>frame 0 0.125 0 0 0 READY</div>
<code>frame 1 0.166 0 0 0 NONE</code>
<br>
 
<div>state CHASE NONE 0</div>
<code>frame 2 0.166 0 0 0 NONE</code>
<div>frame 1 1 0 0 0 NONE</div>
 
<div>frame 2 1 0 0 0 NONE</div>
<code>frame 3 0.166 0 0 0 NONE</code>
<div>frame 3 1 0 0 0 NONE</div>
 
<div>frame 4 1 0 0 0 READY</div>
<code>state DEAD NONE 0</code>
<br>
 
<div>state ATTACK CHASE 0</div>
<code>frame 3 0.25 0 0 0 NONE</code>
<div>frame 5 0.25 0 0 0 NONE</div>
 
<div>frame 5 0.25 0 0 0 NONE</div>
<code>frame 3 0.25 0 0 0 NONE</code></blockquote>
<div>frame 6 0.0625 0 0 0 NONE</div>
 
<div>frame 6 0.0625 0 0 0 ATTACK</div>
===== '''Basic FSM for ALT fire:''' =====
<div>frame 5 0.25 0 0 0 NONE</div>
<blockquote><code>image ColtNavy 0 12</code>
<div>frame 5 0.25 0 0 0 READY</div>
 
<br>
<code>sound ColtNavyFire</code>
<div>state HURT CHASE 0</div>
 
<div>frame 7 0.125 0 0 0 NONE</div>
<code>sound ColtNavyReload</code>
<div>frame 8 0.125 0 0 0 NONE</div>
 
<br>
<code>state IDLE NONE 0</code>
<div>state DEATH DEAD 0</div>
 
<div>frame 9 0.166 0 0 0 NONE</div>
<code>frame 1 0.1 0 0 0 NONE</code>
<div>frame 10 0.166 0 0 0 NONE</div>
 
<div>frame 11 0.166 0 0 0 NONE</div>
<code>frame 1 0.1 0 0 0 READY</code>
<br>
 
<div>state DEAD NONE 0</div>
<code>state ATTACK IDLE 0</code>
<div>frame 12 0.125 0 0 0 NONE</div>
 
<div>frame 12 0.125 0 0 0 NONE</div>
<code>frame 2 0.10 0 0 0 NONE</code>
</div>
 
<code>frame 3 0.10 0 0 0 NONE</code>
 
<code>frame 4 0.10 0 0 0 SOUNDANDATTACK 0</code>
 
<code>frame 5 0.10 0 0 0 MUZZLEFLASH</code>
 
<code>frame 6 0.10 0 0 0 NONE</code>
 
<code>frame 7 0.10 0 0 0 READY</code>
 
<code>state ALTATTACK IDLE 0</code>
 
<code>frame 8 0.04 0 0 0 NONE</code>
 
<code>frame 8 0.04 0 0 0 JUMPIFNOAMMO IDLE</code>
 
<code>frame 8 0.04 0 0 0 READY</code>
 
<code>frame 9 0.04 0 0 0 SOUNDANDATTACK 0</code>
 
<code>frame 10 0.04 0 0 0 MUZZLEFLASH</code>
 
<code>frame 10 0.04 0 0 0 JUMPIFNOAMMO IDLE</code>
 
<code>frame 11 0.04 0 0 0 READY</code>
 
<code>frame 9 0.04 0 0 0 SOUNDANDATTACK 0</code>
 
<code>frame 10 0.04 0 0 0 MUZZLEFLASH</code>
 
<code>frame 10 0.04 0 0 0 JUMPIFNOAMMO IDLE</code>
 
<code>frame 11 0.04 0 0 0 READY</code>
 
<code>frame 11 0.04 0 0 0 SOUNDANDATTACK 0</code>
 
<code>frame 10 0.04 0 0 0 MUZZLEFLASH</code>
 
<code>frame 9 0.04 0 0 0 NONE</code>
 
<code>frame 8 0.04 0 0 0 READY</code>
 
<code>state RELOAD IDLE 0</code>
 
<code>frame 1 0 0 0 0 NONE</code>
 
<code>frame 1 0.1 0 0 0 SOUND 1</code>
 
<code>frame 1 0.1 0 200 0 NONE</code>
 
<code>frame 1 0.1 0 200 0 RELOAD</code></blockquote>

Revision as of 22:32, 24 February 2024

FSM or Finite State Machine allows you to extend sprites animation and entities behavior on general. It is a set of lines that describe what sprites enemy or decorations will have and what will they do. In short, you can change how many sprites an entity has and how fast frames will switch one another.

To add a state machine, you need to create a file with the .states extension and the name of the weapon, enemy, or decoration in the ProjectName/States folder. When adding a state machine, the attack and reload speed will no longer depend on the setting in the editor - everything will be controlled only by the duration of the frames specified in the file. In addition, all sprites and (for weapons) some of the sounds will need to be loaded manually using the image and sound commands.

Best practices

Never have a space or tab Infront of any string. (White space is also counted when the engine reads the FSM/Script or script and unexpected spaces will break the FSM/Script


image Decoration 0 3 - loads sprites and adds them to a list. They are numbered from 0. In this case this command will load every sprite from "Decoration0" to "Decoration3". Sprites must be placed in Data/Sprites/ with apropriate entity folder (Decorations or Enemies) or weapons(Weapons). e.g. "Data/Sprites/Decorations". Weapon sprites MUST have frame 0 which is used for sprites on the floor.

image Decoration - will load only one sprite (in this case named "Decoration") and add it to a list.

sound WeaponFire - will load a sound and add it to a list. They are numbered from 0. Sounds must be placed in Data/Sounds.

state IDLE NONE 0 - creates a new state, where IDLE is a name, NONE - name of the next state to jump to after this one is done (if it's NONE, current state will be looped), 0 (или 1) - sets if you want this state to interpolate model frames or not (if you use 3D models).

frame 0 0.25 0 0 0 NONE - adds a frame to the latest created state. Here 0 - number of a sprite that was loaded (see earlier), 0.25 - time this frame will be staying on screen, 0 0 0 - offset coordinates (only for weapons), NONE - action (see further down).

States shown in examples are MANDATORY to create. There might be many other states, however enemies will only move while in CHASE state. Enemy will spawn blood when in state HURT.

There's also an additional state for weapons called ALTATTACK and can be used to use your weapon with right mouse button.

Weapons can also have optional DRAW and HOLSTER states, which will be used when you switch to/from the weapon respectively. If specified, these will replace the weapon-switching animations.

All key words are CASE SENSITIVE! Also be wary of whitespaces, they are important for engine to correctly parse parameters. Only latin characters are allowed.

Actions:

Weapons Decorations and Enemies
Math

INCREMENT name [$value: 1] - increments the value of a variable, i.e. increases

DECREMENT name [$value: 1] - decrements the value of a variable, i.e. decreases

MULTIPLY name $value - multiplies the value of a variable

DIVIDE name $value - divides the value of a variable

MODULO name $value - performs modulo operation on the value of a variable

CLAMP name $min $max - confines the value of a variable between min and max

Jumps

JUMPIFEQUALS variable $value state - moves to another state if variable value equal to the one we want. You can also use global. and map. prefixes.

JUMPIFNEQUALS variable $value state - moves to another state if variable value is not equal to the one we want. You can also use global. and map. prefixes.

JUMPIFGEQUALS variable $value state - moves to another state if variable value equal or greater to the one we want. You can also use global. and map. prefixes.

JUMPIFLEQUALS variable $value state - moves to another state if variable value equal or less to the one we want. You can also use global. and map. prefixes.

JUMPIFGREATER variable $value state - moves to another state if variable value greater to the one we want. You can also use global. and map. prefixes.

JUMPIFLESS variable $value state - moves to another state if variable value less to the one we want. You can also use global. and map. prefixes.

JUMPIFHPLESS $value state - moves to another state if hp is lower than specified value (0 = no health, 1 = 100% health)

Other

NONE - empty. Does nothing.

READY - sets if entity is ready to attack. Mandatory after enemy or weapon attack.

SOUND $value - plays a sound, value - number of a loaded sound (see earlier).

SOUNDANDATTACK $value - does attack and plays sound in one action.

PLAYERSPEED $value - controls player's movement speed. 1 = normal, 0.5 = half, 2 = double, etc..

PARTICLES imageindex i,l,x,y,z dx,dy,dz - creates particles. imageindex - number of sprite loaded, i - number of particles, l - particle lifetime, x,y,z - coordinates. Coordinates are local to enemy or player, meaning that 0,0,1 will always be in front of enemy or player. x - side offset, y - vertical offset, z - forward offset. dx,dy,dz - particle velocity. Also local to entity.

CUSTOMPARTICLE $id $lifetime $x,$y,$z $dx,$dy,$dz $scale $gravity - creates one custom particle. id - which particle image to use (shared between all entities, loaded from "Particles\CustomX.png", X is the particleID), lifetime and xyz are the same as in PARTICLES. dx,dy,dz are always exact values, and will not be randomised. scale affects the particle size. gravity is the fall strength.

SETVAR name $value - sets variable to a certain value. You can use RANDOM(0,100) instead of value. The value will be randomized from 0 to 100. You can also use global. and map. prefixes to set global or map variables (see Scripting). value can be set to LASTDAMAGE, HP or MAXHP to retrieve the last amount of damage the entity received, its current hp, or its max hp.

MODELTEXTURE path [name] - if a 3d model is used, sets the texture. Path is a texture path relative to your project directory (Textures/wallTexture.png). If a variable name is specified after the path, any $ symbols in the path will be replaced with that variable's value. Textures are cached when they are first used, allowing you to preload them for performance if required.

Weapons and Enemies

ATTACK - weapon or enemy attack

Enemies and Decorations

EXPLOSION name radius - creates an explosion with a name and radius where name is name of explosion sprites. Sprites must be place in Data/Sprites/Effects.

SPAWN name x,y,z f,v - creates an entity with a name (enemies and decoration) or a keyword (Key1, Key2, Key3, Hp1, Hp2, Hp3, Hp4). x,y,z - just like with particles, f - front velocity when spawned, v - vertical velocity when spawning. (enemies and decorations only).

Enemies only

PROJECTILE [$angle: 0] [absolute? 0] [$height: 0] [$spread: 0] - shoots a projectile in the specified direction. angle is in degrees. If absolute is 0, angle will be relative to the player's direction (0 = directly at player, 180 = directly away from player). If absolute is 1, angle will be an exact direction in the world. 0=North, 90 = East, etc.. Height is a relative height offset to shoot the projectile (negative = lower, positive = higher). Spread adjusts how much random jitter to apply to the projectile's direction.

Weapons only

JUMPIFLESSAMMO state - moves to another value if ammo in magazine is lower than maximum.

JUMPIFNOAMMO state - moves to another state if magazine is empty.

GIVEAMMO [$value: 1] [fromTotal?: 0] - adds ammo to the weapon. If fromTotal is set to 1, ammo is taken from the total count, otherwise it's taken from the magazine.

TAKEAMMO [$value: 1] [fromTotal?: 0] - takes ammo from the weapon.

SETAMMO $value [fromTotal?: 0] - directly sets the weapon's ammo.

RELOAD - reloads magazine.

MUZZLEFLASH - shows muzzle flash.

WEAPONSTAT stat $value - sets one of the weapon's stats to specified value. Same available stats as the weapon command

ZOOM $value - sets the current camera zoom (-100 to 100). Negative values will zoom out. 0 = no zoom.

Examples

Basic FSM for a weapon:

image Enemy 0 12


state IDLE NONE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY


state SEE CHASE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY


state CHASE NONE 0
frame 1 1 0 0 0 NONE
frame 2 1 0 0 0 NONE
frame 3 1 0 0 0 NONE
frame 4 1 0 0 0 READY


state ATTACK CHASE 0
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 NONE
frame 6 0.0625 0 0 0 NONE
frame 6 0.0625 0 0 0 ATTACK
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 READY


state HURT CHASE 0
frame 7 0.125 0 0 0 NONE
frame 8 0.125 0 0 0 NONE


state DEATH DEAD 0
frame 9 0.166 0 0 0 NONE
frame 10 0.166 0 0 0 NONE
frame 11 0.166 0 0 0 NONE


state DEAD NONE 0
frame 12 0.125 0 0 0 NONE
frame 12 0.125 0 0 0 NONE
image Enemy 0 12


state IDLE NONE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY


state SEE CHASE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY


state CHASE NONE 0
frame 1 1 0 0 0 NONE
frame 2 1 0 0 0 NONE
frame 3 1 0 0 0 NONE
frame 4 1 0 0 0 READY


state ATTACK CHASE 0
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 NONE
frame 6 0.0625 0 0 0 NONE
frame 6 0.0625 0 0 0 ATTACK
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 READY


state HURT CHASE 0
frame 7 0.125 0 0 0 NONE
frame 8 0.125 0 0 0 NONE


state DEATH DEAD 0
frame 9 0.166 0 0 0 NONE
frame 10 0.166 0 0 0 NONE
frame 11 0.166 0 0 0 NONE


state DEAD NONE 0
frame 12 0.125 0 0 0 NONE
frame 12 0.125 0 0 0 NONE
image Weapon 0 7
sound WeaponFire
sound WeaponReload


state IDLE NONE 0
frame 1 0.25 0 0 0 NONE
frame 1 0.25 0 0 0 READY


state ATTACK IDLE 0
frame 2 1 0 0 0 NONE
frame 3 1 0 0 0 SOUNDANDATTACK 0
frame 4 1 0 0 0 MUZZLEFLASH
frame 5 1 0 0 0 READY
frame 6 1 0 0 0 NONE
frame 7 1 0 0 0 NONE
frame 1 0.25 0 0 0 NONE
frame 1 0.25 0 0 0 NONE


state RELOAD IDLE 0
frame 1 0 0 0 0 NONE
frame 1 0.1 0 0 0 NONE
frame 1 0.1 0 200 0 NONE
frame 1 0.1 0 200 0 RELOAD
frame 1 0.1 0 0 0 SOUND 1
Basic FSM for enemies:
image Enemy 0 12


state IDLE NONE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY


state SEE CHASE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY


state CHASE NONE 0
frame 1 1 0 0 0 NONE
frame 2 1 0 0 0 NONE
frame 3 1 0 0 0 NONE
frame 4 1 0 0 0 READY


state ATTACK CHASE 0
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 NONE
frame 6 0.0625 0 0 0 NONE
frame 6 0.0625 0 0 0 ATTACK
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 READY


state HURT CHASE 0
frame 7 0.125 0 0 0 NONE
frame 8 0.125 0 0 0 NONE


state DEATH DEAD 0
frame 9 0.166 0 0 0 NONE
frame 10 0.166 0 0 0 NONE
frame 11 0.166 0 0 0 NONE


state DEAD NONE 0
frame 12 0.125 0 0 0 NONE
frame 12 0.125 0 0 0 NONE
Intermediate FSM for enemies:
image BORIS 0 455


sound AK


state IDLE NONE 0
frameset 2 254 0.025 0 0 0 NONE
frame 255 0.025 0 0 0 NONE
frame 256 0.025 0 0 0 READY


state SEE CHASE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY


state CHASE SEE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY


state ATTACK CHASE 0
frame 463 0.025 0 0 0 NONE
frame 464 0.025 0 0 0 SOUNDANDATTACK 0
frameset 465 496 0.025 0 0 0 NONE
frame 497 0.025 0 0 0 READY


state HURT FLEE 0
frameset 286 340 0.025 0 0 0 NONE
frame 341 0.025 0 0 0 NONE
frame 342 0.025 0 0 0 READY


state FLEE SEE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY


state SEE FLEE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY


state FLEE CHASE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY


state DEATH DEAD 0
frameset 357 453 0.025 0 0 0 NONE
frame 454 0.025 0 0 0 NONE
frame 455 0.025 0 0 0 NONE


state DEAD NONE 0
frame 455 0.025 0 0 0 NONE
Basic FSM for decorations:
image Enemy 0 12


state IDLE NONE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY


state SEE CHASE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY


state CHASE NONE 0
frame 1 1 0 0 0 NONE
frame 2 1 0 0 0 NONE
frame 3 1 0 0 0 NONE
frame 4 1 0 0 0 READY


state ATTACK CHASE 0
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 NONE
frame 6 0.0625 0 0 0 NONE
frame 6 0.0625 0 0 0 ATTACK
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 READY


state HURT CHASE 0
frame 7 0.125 0 0 0 NONE
frame 8 0.125 0 0 0 NONE


state DEATH DEAD 0
frame 9 0.166 0 0 0 NONE
frame 10 0.166 0 0 0 NONE
frame 11 0.166 0 0 0 NONE


state DEAD NONE 0
frame 12 0.125 0 0 0 NONE
frame 12 0.125 0 0 0 NONE