# NPC and Monster Animation Flows This document lists all the flows that play animations for NPCs and monsters in the codebase. ## Main Entry Points ### 1. **PlayModelAction()** - Primary Animation Method **Location:** `CECNPC.cs:1447` - Main entry point for playing NPC/Monster animations - Calls `m_pNPCModelPolicy.PlayModelAction(iAction, bRestart, null)` - Filters out animations if NPC is dead (except death animations) --- ## Animation Flows by Trigger ### 2. **Attack Animations** #### Flow: Attack Result Message → Play Attack Animation **Location:** `CECNPC.cs:258-307` (`OnMsgNPCAtkResult`) 1. Message `MSG_NM_NPCATKRESULT` received 2. Calls `PlayAttackEffect()` → `PlayAttackAction()` → `m_pNPCModelPolicy.PlayAttackAction()` 3. **CECNPCModelDefaultPolicy.cs:47** (`PlayAttackAction`) - For Monsters/Pets: Random between `ACT_ATTACK1` or `ACT_ATTACK2` - For NPCs: `ACT_NPC_ATTACK` 4. Calls `PlayModelAction()` with attack action #### Flow: Attack Host Result → Play Attack Animation **Location:** `CECNPC.cs:224-257` (`OnMsgAttackHostResult`) 1. Message received when NPC attacks host 2. Calls `PlayAttackEffect()` → `PlayAttackAction()` → Same flow as above #### Attack Animation Details **Location:** `CECNPCModelDefaultPolicy.cs:104-122` (for ACT_ATTACK1/ACT_ATTACK2) - Plays attack start animation (with suffix "起") - Queues attack fall animation (with suffix "落") - Queues guard animation after attack **Location:** `CECNPCModelDefaultPolicy.cs:149-166` (for ACT_NPC_ATTACK) - Plays NPC attack start animation - Queues NPC attack fall animation - Queues NPC stand animation after attack --- ### 3. **Movement Animations** #### Flow: Move Command → Play Move Animation **Location:** `CECNPC.cs:1126-1196` (`MoveTo`) 1. `cmd_object_move` command received 2. Calls `StartWork(WT_NORMAL, WORK_MOVE)` 3. Calls `PlayMoveAction(iMoveMode)` **Location:** `CECNPC.cs:1421-1440` (`PlayMoveAction`) - **Run Mode** (`GP_MOVE_RUN` or `GP_MOVE_RETURN`): - Monsters/Pets: `ACT_RUN` - NPCs: `ACT_NPC_RUN` - **Walk Mode** (other modes): - Monsters/Pets: `ACT_WALK` - NPCs: `ACT_NPC_WALK` #### Flow: Stop Move Command → Play Move Animation **Location:** `CECNPC.cs:1000-1113` (`StopMoveTo`) 1. `cmd_object_stop_move` command received 2. If not already moving, calls `StartWork(WT_NORMAL, WORK_MOVE)` 3. Calls `PlayMoveAction(iMoveMode)` if not passive move --- ### 4. **Stand/Idle Animations** #### Flow: Work Stand → Play Stand Animation **Location:** `CECNPC.cs:1328-1341` (`StartWork_Stand`) 1. `StartWork(WT_NORMAL, WORK_STAND)` called 2. If not in fight mode: - Monsters/Pets: `ACT_STAND` - NPCs: `ACT_NPC_STAND` #### Flow: Idle Timer → Play Idle Animation **Location:** `CECNPC.cs:525-542` (`TickWork_Stand`) 1. `TickWork_Stand()` called every frame when in WORK_STAND 2. Idle counter increments (period: 25000ms) 3. When counter completes: - Monsters/Pets: `ACT_IDLE` - NPCs: Random between `ACT_NPC_IDLE1` or `ACT_NPC_IDLE2` **Idle Animation Details:** **Location:** `CECNPCModelDefaultPolicy.cs:123-135` (ACT_IDLE) - Plays idle animation - Queues stand animation after 300ms **Location:** `CECNPCModelDefaultPolicy.cs:136-148` (ACT_NPC_IDLE1/ACT_NPC_IDLE2) - Plays NPC idle animation - Queues NPC stand animation after 300ms --- ### 5. **Death Animations** #### Flow: Killed → Play Death Animation **Location:** `CECNPC.cs:748-762` (`Killed`) 1. `Killed()` called 2. Sets `GP_STATE_CORPSE` flag 3. Calls `StartWork(WT_NORMAL, WORK_DEAD)` **Location:** `CECNPC.cs:1355-1361` (`StartWork_Dead`) - Monsters/Pets: `ACT_DIE` - NPCs: `ACT_NPC_DIE` --- ### 6. **Wounded/Hit Animations** #### Flow: Damaged → Play Wounded Animation **Location:** `CECNPC.cs:775-833` (`Damaged`) 1. `Damaged()` called when NPC takes damage 2. If damage is -1 or -2 (other player hit): - If not in fight mode: `ACT_WOUNDED` 3. If damage > 0: - If not in fight mode: `ACT_WOUNDED` **Wounded Animation Details:** **Location:** `CECNPCModelDefaultPolicy.cs:95-103` - Tries to play `ACT_WOUNDED` - If animation doesn't exist, tries `ACT_WOUNDED2` --- ### 7. **Disappear Animation** #### Flow: Disappear → Play Disappear Animation **Location:** `CECNPC.cs:763-769` (`Disappear`) 1. `Disappear()` called when NPC should fade out 2. Calls `PlayModelAction(ACT_NPC_DISAPPEAR)` --- ### 8. **Policy Action (Server-Controlled Actions)** #### Flow: Policy Action Message → Play Policy Action **Location:** `CECNPC.cs:197-203` (`OnMsgNPCStartPlayAction`) 1. Message `MSG_NM_NPCSTARTPLAYACTION` received 2. If already in policy action, stops it 3. Calls `StartWork(WT_INTERRUPT, WORK_POLICYACTION, 0, cmd)` **Location:** `CECNPC.cs:1376-1387` (`StartWork_PolicyAction`) - Currently commented out, but would handle server-controlled actions --- ### 9. **Born Animation** #### Flow: Born Animation **Location:** `CECNPCModelDefaultPolicy.cs:167-179` - Plays `ACT_COMMON_BORN` animation - Queues stand animation after 300ms --- ## Animation Implementation Details ### NPCVisual Class **Location:** `NPCVisual.cs` - **TryPlayAction()** (line 18): Actually plays the animation using Animancer - Uses `NamedAnimancerComponent.TryPlay(animationName)` - Supports attack event callbacks via `OnEnd` event ### CECNPCModelDefaultPolicy Class **Location:** `CECNPCModelDefaultPolicy.cs` - **PlayModelAction()** (line 86): Main animation policy implementation - Handles special cases for different action types - Queues follow-up animations using `CECModel.QueueAction()` - **GetActionName()** (line 20): Converts action index to animation name string ### Action Name Resolution **Location:** `CECNPC.cs:874-882` (`InitStaticRes`) - Loads action names from "actions_npc" file - **GetBaseActionName()** (line 990): Gets action name string from loaded table --- ## Work System Flow NPCs use a work system to manage different states: 1. **WORK_STAND**: Idle/Standing state - Entry: `StartWork_Stand()` → Plays stand animation - Update: `TickWork_Stand()` → Plays idle animation periodically 2. **WORK_MOVE**: Moving state - Entry: `StartWork_Move()` → Clears combat flags - Update: `TickWork_Move()` → Updates position - Animation: `PlayMoveAction()` → Plays run/walk animation 3. **WORK_FIGHT**: Fighting state - Entry: `StartWork_Fight()` → No animation (controlled by attack messages) - Update: `TickWork_Fight()` → Faces target, syncs position 4. **WORK_DEAD**: Dead state - Entry: `StartWork_Dead()` → Plays death animation - Update: `TickWork_Dead()` → Empty 5. **WORK_POLICYACTION**: Server-controlled action - Entry: `StartWork_PolicyAction()` → Handles server commands --- ## Key Animation Action Indices **Location:** `CECNPC.cs:1572-1603` (`NPCActionIndex` enum) ### Monster/Pet Actions: - `ACT_STAND` (0) - `ACT_IDLE` (1) - `ACT_WALK` (4) - `ACT_ATTACK1` (5) - `ACT_ATTACK2` (6) - `ACT_RUN` (7) - `ACT_DIE` (8) - `ACT_WOUNDED` (13) ### NPC Actions: - `ACT_NPC_STAND` (19) - `ACT_NPC_IDLE1` (17) - `ACT_NPC_IDLE2` (18) - `ACT_NPC_WALK` (20) - `ACT_NPC_RUN` (21) - `ACT_NPC_ATTACK` (22) - `ACT_NPC_DIE` (23) - `ACT_NPC_DISAPPEAR` (25) --- ## Summary of Animation Trigger Points 1. **Attack Messages** → Attack animations (ACT_ATTACK1/2, ACT_NPC_ATTACK) 2. **Move Commands** → Movement animations (ACT_RUN/WALK, ACT_NPC_RUN/WALK) 3. **Work Stand** → Stand animations (ACT_STAND, ACT_NPC_STAND) 4. **Idle Timer** → Idle animations (ACT_IDLE, ACT_NPC_IDLE1/2) 5. **Death** → Death animations (ACT_DIE, ACT_NPC_DIE) 6. **Damage** → Wounded animations (ACT_WOUNDED, ACT_WOUNDED2) 7. **Disappear** → Disappear animation (ACT_NPC_DISAPPEAR) 8. **Policy Action** → Server-controlled actions 9. **Born** → Born animation (ACT_COMMON_BORN)