Animation Events
Animation events are flags in the animation sequence representing interactions between the character and the world. Animation events tell the AI at what moment an attack is launched, or a character dies, when a scripted event (such as a scientist opening a door) has happened, and so on.
A sequence may have multiple animation events (for example a walk animation might have a footfall sound for each foot hitting the ground. Some scripted sequences can have quite a few events.
Events are enclosed in curly brackets. The simplest event calls look like {event <#> <frame>} where <#> is the number or the name which tells the system what kind of event has occurred and <frame> tells the system at which frame the event takes place.
Events can have an additional parameter. For example, events that call sound files have an additional parameter, which specifies which sound to play. Events which trigger map entities have an extra parameter for the name of the trigger (enclosed in quotes).
- Events with ID numbers below 1000 are specific to individual monsters, so the scientists' event 1 is different from the Vortigaunts' event 1. The meaning of monster specific events is indicated in the monster AI code.
- Events with numbers in the 1000 range are scripted sequence events.
- Events with numbers in the 2000's are for NPCs.
- Events with numbers in the 3000's are for weapons.
- Events in the 5000 range are client-side only, and are used primarily for muzzleflash or sound effects for weapon viewmodels.
.qc examples
Character movement
Events on movements use the attachments lfoot and rfoot on the players feet to create water effects as the player walks.
example from sourcesdk_content\cstrike\modelsrc\animation\cs_player_shared
:
$sequence Run_lower { a_RunNW a_RunN a_RunNE a_RunW a_RunZero a_RunE a_RunSW a_RunS a_RunSE blendwidth 3 blend move_y -1 1 blend move_x 1 -1 loop ACT_RUN 1 { event 7001 14 "lfoot" } { event 7001 5 "rfoot" } }
$sequence Crouch_walk_lower { a_Crouch_walkNW a_Crouch_walkN a_Crouch_walkNE a_Crouch_walkW a_Crouch_walkZero a_Crouch_walkE a_Crouch_walkSW a_Crouch_walkS a_Crouch_walkSE blendwidth 3 blend move_y -1 1 blend move_x 1 -1 loop ACT_RUN_CROUCH 1 { event 7002 17 "lfoot" } { event 7002 5 "rfoot" } }
Weapon
Reload
$sequence reload "Reload" fps 30 activity ACT_VM_RELOAD 1 node Ready { { event AE_CL_PLAYSOUND 28 "Weapon_357.OpenLoader" } { event AE_CL_PLAYSOUND 39 "Weapon_357.RemoveLoader" } { event 3015 55 } { event AE_CL_PLAYSOUND 67 "Weapon_357.ReplaceLoader" } { event AE_CL_PLAYSOUND 92 "Weapon_357.Spin" } }
Throw
$sequence throw "Throw" frames 9 20 ACT_VM_THROW 1 { event 3005 1 }
Muzzleflash
$sequence fire "Fire01" snap fps 30 activity ACT_VM_PRIMARYATTACK 1 { event AE_MUZZLEFLASH 0 "357 muzzle" } node Fire
Default muzzleflashes
AR2 SHOTGUN SMG1 SMG2 PISTOL COMBINE 357 RPG
Crossbow
$sequence reload "reload" fps 30 activity ACT_VM_RELOAD 1 node Ready { { event 3005 28 } // Initial placement of the bolt { event 3013 35 } // Start of charge-up { event 3016 55 } // Ready charged }
Eject a brass
$sequence pump "Pump" fps 30 activity ACT_SHOTGUN_PUMP 1 { event 6001 5 "2" } node 0
The number after the even code is the frame that this even will happen on. The last number is in this case the type of brass that will be ejected. 0 = pistol 1 = rifle 2 = shotgun
More types can be added in c_te_legacytempents.cpp around line 2013
Fire Input
Fires an input to the animating entity.
$sequence idle { { event 1100 200 "fireuser1" } // Fires input "FireUser1" to animating entity }
Event list
Server events
Defined in eventlist.h
.
- AE_INVALID = -1 // So we have something more succint to check for than '-1'
- AE_EMPTY
- AE_NPC_LEFTFOOT // NPC_EVENT_LEFTFOOT 2050
- AE_NPC_RIGHTFOOT // NPC_EVENT_RIGHTFOOT 2051
- AE_NPC_BODYDROP_LIGHT // NPC_EVENT_BODYDROP_LIGHT 2001
- AE_NPC_BODYDROP_HEAVY // NPC_EVENT_BODYDROP_HEAVY 2002
- AE_NPC_SWISHSOUND // NPC_EVENT_SWISHSOUND 2010
- AE_NPC_180TURN // NPC_EVENT_180TURN 2020
- AE_NPC_ITEM_PICKUP // NPC_EVENT_ITEM_PICKUP 2040
- AE_NPC_WEAPON_DROP // NPC_EVENT_WEAPON_DROP 2041
- AE_NPC_WEAPON_SET_SEQUENCE_NAME // NPC_EVENT_WEAPON_SET_SEQUENCE_NAME 2042
- AE_NPC_WEAPON_SET_SEQUENCE_NUMBER // NPC_EVENT_WEAPON_SET_SEQUENCE_NUMBER 2043
- AE_NPC_WEAPON_SET_ACTIVITY // NPC_EVENT_WEAPON_SET_ACTIVITY 2044
- AE_NPC_HOLSTER
- AE_NPC_DRAW
- AE_CL_PLAYSOUND// CL_EVENT_SOUND 5004 // Emit a sound
- AE_CL_STOPSOUND
- AE_SV_PLAYSOUND
- AE_START_SCRIPTED_EFFECT
- AE_STOP_SCRIPTED_EFFECT
- AE_CLIENT_EFFECT_ATTACH
- AE_MUZZLEFLASH // Muzzle flash from weapons held by the player
- AE_NPC_MUZZLEFLASH // Muzzle flash from weapons held by NPCs
- AE_THUMPER_THUMP //Thumper Thump!
- AE_AMMOCRATE_PICKUP_AMMO //Ammo crate pick up ammo!
- AE_NPC_RAGDOLL
Scripted sequence events
Defined in scriptevent.h
.
- SCRIPT_EVENT_DEAD 1000 // character is now dead
- SCRIPT_EVENT_NOINTERRUPT 1001 // does not allow interrupt
- SCRIPT_EVENT_CANINTERRUPT 1002 // will allow interrupt
- SCRIPT_EVENT_FIREEVENT 1003 // Fires OnScriptEventXX output in the script entity, where XX is the event number from the options data.
- SCRIPT_EVENT_SOUND 1004 // Play named wave file (on CHAN_BODY)
- SCRIPT_EVENT_SENTENCE 1005 // Play named sentence
- SCRIPT_EVENT_INAIR 1006 // Leave the character in air at the end of the sequence (don't find the floor)
- SCRIPT_EVENT_ENDANIMATION 1007 // Set the animation by name after the sequence completes
- SCRIPT_EVENT_SOUND_VOICE 1008 // Play named wave file (on CHAN_VOICE)
- SCRIPT_EVENT_SENTENCE_RND1 1009 // Play sentence group 25% of the time
- SCRIPT_EVENT_NOT_DEAD 1010 // Bring back to life (for life/death sequences)
- SCRIPT_EVENT_EMPHASIS 1011 // Emphasis point for gestures
- SCRIPT_EVENT_BODYGROUPON 1020 // Turn a bodygroup on
- SCRIPT_EVENT_BODYGROUPOFF 1021 // Turn a bodygroup off
- SCRIPT_EVENT_BODYGROUPTEMP 1022 // Turn a bodygroup on until this sequence ends
- SCRIPT_EVENT_FIRE_INPUT 1100 // Fires named input on the event handler
NPC events
Defined in npcevent.h
.
- NPC_EVENT_BODYDROP_LIGHT 2001
- NPC_EVENT_BODYDROP_HEAVY 2002
- NPC_EVENT_SWISHSOUND 2010
- NPC_EVENT_180TURN 2020
- NPC_EVENT_ITEM_PICKUP 2040
- NPC_EVENT_WEAPON_DROP 2041
- NPC_EVENT_WEAPON_SET_SEQUENCE_NAME 2042
- NPC_EVENT_WEAPON_SET_SEQUENCE_NUMBER 2043
- NPC_EVENT_WEAPON_SET_ACTIVITY 2044
- NPC_EVENT_LEFTFOOT 2050
- NPC_EVENT_RIGHTFOOT 2051
- NPC_EVENT_OPEN_DOOR 2060
Weapon events
Defined in npcevent.h
.
- EVENT_WEAPON_MELEE_HIT 3001
- EVENT_WEAPON_SMG1 3002
- EVENT_WEAPON_MELEE_SWISH 3003
- EVENT_WEAPON_SHOTGUN_FIRE 3004
- EVENT_WEAPON_THROW 3005
- EVENT_WEAPON_AR1 3006
- EVENT_WEAPON_AR2 3007
- EVENT_WEAPON_HMG1 3008
- EVENT_WEAPON_SMG2 3009
- EVENT_WEAPON_MISSILE_FIRE 3010
- EVENT_WEAPON_SNIPER_RIFLE_FIRE 3011
- EVENT_WEAPON_AR2_GRENADE 3012
- EVENT_WEAPON_THROW2 3013
- EVENT_WEAPON_PISTOL_FIRE 3014
- EVENT_WEAPON_RELOAD 3015
- EVENT_WEAPON_THROW3 3016
- EVENT_WEAPON_RELOAD_SOUND 3017 // Use this + EVENT_WEAPON_RELOAD_FILL_CLIP to prevent shooting during the reload animation
- EVENT_WEAPON_RELOAD_FILL_CLIP 3018
- EVENT_WEAPON_SMG1_BURST1 3101 // first round in a 3-round burst
- EVENT_WEAPON_SMG1_BURSTN 3102 // 2, 3 rounds
- EVENT_WEAPON_AR2_ALTFIRE 3103
- EVENT_WEAPON_SEQUENCE_FINISHED 3900
- EVENT_WEAPON_LAST 3999 //Must be the last weapon event
Client-side events
defined in cl_animeevent.h
Animation event codes
- AE_CL_CREATE_PARTICLE_BRASS // Eject a shell/casing. Requires you to define particle name and attachment point. Example:
AE_CL_CREATE_PARTICLE_BRASS 6 "weapon_shell_casing_9mm_L4D2_fp shell"
- CL_EVENT_MUZZLEFLASH0 5001 // Muzzleflash on attachment 0
- CL_EVENT_MUZZLEFLASH1 5011 // Muzzleflash on attachment 1
- CL_EVENT_MUZZLEFLASH2 5021 // Muzzleflash on attachment 2
- CL_EVENT_MUZZLEFLASH3 5031 // Muzzleflash on attachment 3
- CL_EVENT_SPARK0 5002 // Spark on attachment 0
- CL_EVENT_NPC_MUZZLEFLASH0 5003 // Muzzleflash on attachment 0 for third person views
- CL_EVENT_NPC_MUZZLEFLASH1 5013 // Muzzleflash on attachment 1 for third person views
- CL_EVENT_NPC_MUZZLEFLASH2 5023 // Muzzleflash on attachment 2 for third person views
- CL_EVENT_NPC_MUZZLEFLASH3 5033 // Muzzleflash on attachment 3 for third person views
- CL_EVENT_SOUND 5004 // Emit a sound, based on sound name in soundscript. // NOTE THIS MUST MATCH THE DEFINE AT CBaseEntity::PrecacheModel on the server!!!!!
- CL_EVENT_EJECTBRASS1 6001 // Eject a brass shell from attachment named "1"
- CL_EVENT_DISPATCHEFFECT0 9001 // Hook into a DispatchEffect on attachment 0
- CL_EVENT_DISPATCHEFFECT1 9011 // Hook into a DispatchEffect on attachment 1
- CL_EVENT_DISPATCHEFFECT2 9021 // Hook into a DispatchEffect on attachment 2
- CL_EVENT_DISPATCHEFFECT3 9031 // Hook into a DispatchEffect on attachment 3
- CL_EVENT_DISPATCHEFFECT4 9041 // Hook into a DispatchEffect on attachment 4
- CL_EVENT_DISPATCHEFFECT5 9051 // Hook into a DispatchEffect on attachment 5
- CL_EVENT_DISPATCHEFFECT6 9061 // Hook into a DispatchEffect on attachment 6
- CL_EVENT_DISPATCHEFFECT7 9071 // Hook into a DispatchEffect on attachment 7
- CL_EVENT_DISPATCHEFFECT8 9081 // Hook into a DispatchEffect on attachment 8
- CL_EVENT_DISPATCHEFFECT9 9091 // Hook into a DispatchEffect on attachment 9
- CL_EVENT_FOOTSTEP_LEFT 6004
- CL_EVENT_FOOTSTEP_RIGHT 6005
- CL_EVENT_MFOOTSTEP_LEFT 6006 // Footstep sounds based on material underfoot.
- CL_EVENT_MFOOTSTEP_RIGHT 6007
- CL_EVENT_MFOOTSTEP_LEFT_LOUD 6008 // Loud material impact sounds from feet attachments
- CL_EVENT_MFOOTSTEP_RIGHT_LOUD 6009
c_env_spritegroup
- CL_EVENT_SPRITEGROUP_CREATE 6002
- CL_EVENT_SPRITEGROUP_DESTROY 6003
Custom animation events
To declare custom animation event, you need to use DECLARE_ANIMEVENT macro within AI_BEGIN_CUSTOM_NPC section.
Then you can catch that custom event in HandleAnimEvent(animeevent_t *pEvent).
Other Events
These are events that have been found, but have not yet been added to their proper categories above, because they are yet unknown.
- AE_CL_BODYGROUP_SET_VALUE <FrameNumber> "<bodygroup name> <body>" //Chages model of a multi-model bodygroup
- AE_CL_ENABLE_BODYGROUP <FrameNumber> "<bodyGroupName>" //"Enables" bodygroup.
- AE_CL_DISABLE_BODYGROUP <FrameNumber> "<bodyGroupName>" //"disables" bodygroup.
- AE_CL_CREATE_PARTICLE_EFFECT <FrameNumber> "<particle effect name> <attachment type> <attachment name>"
- AE_CL_STOP_PARTICLE_EFFECT <FrameNumber> "<particle effect name> <boolean>"