# BPC_HitReactionSystem — Hit Reaction System ## Blueprint Spec — UE 5.5–5.7 --- ### Parent Class `ActorComponent` ### Dependencies - **Requires:** [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md) — Receives damage events - **Requires:** [`BPC_CameraStateLayer`](../02-player/14_BPC_CameraStateLayer.md) — Camera trauma effects - **Requires:** [`S_DamageEvent`](../02-player/08_BPC_HealthSystem.md) — Damage event struct (E_DamageType, Amount, HitLocation, HitNormal) - **Requires:** [`E_DamageType`](../01-core/03_I_InterfaceLibrary.md) — Damage type enum for montage selection - **Required By:** [`BPC_AdaptiveEnvironmentDirector`](../10-adaptive/BPC_AdaptiveEnvironmentDirector.md) — Reads trauma intensity for atmosphere - **Engine/Plugin Requirements:** Animation Blueprint (ABP_PlayerBody), GASP animation hooks ### Purpose Drives physical hit reaction behaviour: flinch animations, ragdoll blends, and camera trauma. Processes incoming damage events and triggers appropriate reaction animations based on damage magnitude, direction, and type. --- ## 1. Enums *Uses `E_DamageType` from [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md) — Physical, Fire, Psychic, Environmental, InstantKill, Scripted.* --- ## 2. Structs *No new structs defined. Uses `S_DamageEvent` from [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md).* --- ## 3. Variables ### Configuration (Instance Editable, Expose On Spawn) | Variable | Type | Default | Category | Description | |----------|------|---------|----------|-------------| | `FlinchThreshold` | Float | 5.0 | HitReaction | Minimum damage to trigger flinch animation | | `RagdollThreshold` | Float | 50.0 | HitReaction | Damage amount that triggers ragdoll blend | | `TraumaDecayRate` | Float | 2.0 | HitReaction | Camera trauma points recovered per second | | `HitReactionMontages` | Map (E_DamageType → AnimMontage) | Empty | HitReaction | Per-damage-type hit reaction animations | ### Internal (Private / Protected, No Expose) | Variable | Type | Default | Category | Description | |----------|------|---------|----------|-------------| | `CurrentTrauma` | Float | 0.0 | Internal | Accumulated camera trauma level | | `bIsReacting` | Bool | False | Internal | Reaction animation currently playing | | `LastDamageDirection` | Vector | (0,0,0) | Internal | Direction of most recent damage for animation blend | | `NextReactionIndex` | Integer | 0 | Internal | Cycles through available montages per type for variety | --- ## 4. Functions ### Public Functions #### `ProcessHitReaction` → `void` - **Description:** Main entry point. Called when player receives damage. Determines reaction type based on damage amount vs thresholds. - **Parameters:** | Param | Type | Description | |-------|------|-------------| | `DamageEvent` | S_DamageEvent | Full damage context from HealthSystem | - **Blueprint Authority:** Any - **Flow:** Checks thresholds → selects montage → plays animation → applies trauma → broadcasts dispatchers #### `ApplyTrauma` → `void` - **Description:** Adds camera trauma based on damage amount. - **Parameters:** | Param | Type | Description | |-------|------|-------------| | `Amount` | Float | Trauma points to add | - **Blueprint Authority:** Any #### `GetCurrentTrauma` → `Float` - **Description:** Returns current accumulated trauma level (0–100). - **Parameters:** None - **Blueprint Authority:** Any #### `ResetTrauma` → `void` - **Description:** Clears all accumulated camera trauma to zero. - **Parameters:** None - **Blueprint Authority:** Any ### Protected / Private Functions #### `SelectHitReactionMontage` → `AnimMontage` - **Description:** Picks a hit reaction montage based on damage type and cycles through available options for variety. - **Parameters:** | Param | Type | Description | |-------|------|-------------| | `DamageType` | E_DamageType | Type of damage received | | `DamageAmount` | Float | Magnitude of damage | - **Flow:** Look up HitReactionMontages map by damage type → cycle through entries → return selected montage #### `TickTraumaDecay` → `void` - **Description:** Called on tick to decay camera trauma toward zero at TraumaDecayRate. - **Parameters:** | Param | Type | Description | |-------|------|-------------| | `DeltaTime` | Float | Frame delta time | - **Flow:** `CurrentTrauma = FMath::FInterpTo(CurrentTrauma, 0.0, DeltaTime, TraumaDecayRate)` --- ## 5. Event Dispatchers | Dispatcher | Parameters | Bind Access | Description | |------------|-----------|-------------|-------------| | `OnFlinchTriggered` | DamageType: E_DamageType, Amount: Float | Public | Flinch animation fired (damage below ragdoll threshold) | | `OnRagdollBlend` | Amount: Float, Direction: Vector | Public | Ragdoll blend triggered (damage exceeded ragdoll threshold) | | `OnTraumaChanged` | CurrentTrauma: Float | Public | Trauma level changed (for camera/screen effects) | | `OnHitReactionComplete` | DamageType: E_DamageType | Public | Reaction animation finished playing | --- ## 6. Overridden Events / Custom Events ### Event: `ReceiveDamage` - **Description:** Called by [`BPC_DamageReceptionSystem`](BPC_DamageReceptionSystem.md) when player takes damage. Routes to `ProcessHitReaction`. - **Flow:** 1. Extract damage amount and type from DamageEvent 2. If DamageAmount >= FlinchThreshold → ProcessHitReaction 3. If DamageAmount >= RagdollThreshold → trigger ragdoll blend instead 4. Calculate LastDamageDirection from HitLocation relative to player 5. ApplyTrauma proportional to damage amount --- ## 7. Blueprint Graph Logic Flow ```mermaid flowchart TD A[ReceiveDamage called] --> B{Damage >= RagdollThreshold?} B -->|Yes| C[Disable input temporarily] B -->|No| D{Damage >= FlinchThreshold?} C --> E[Play ragdoll physics blend] D -->|Yes| F[SelectHitReactionMontage by DamageType] D -->|No| G[Skip reaction, only apply trauma] F --> H[Play montage with directional blend] H --> I[Broadcast OnFlinchTriggered] I --> J[Wait for montage end] J --> K[Broadcast OnHitReactionComplete] E --> L[Set bIsReacting = true] L --> M[Wait for ragdoll timer] M --> N[Recover from ragdoll] N --> K G --> O[ApplyTrauma proportional to damage] K --> O O --> P[Broadcast OnTraumaChanged] P --> Q[Camera system reads trauma] ``` --- ## 8. Communication Matrix | Who Talks | How | What Is Sent | |-----------|-----|-------------| | [`BPC_DamageReceptionSystem`](BPC_DamageReceptionSystem.md) | Direct call | `S_DamageEvent` | | [`BPC_CameraStateLayer`](../02-player/14_BPC_CameraStateLayer.md) | Dispatcher (`OnTraumaChanged`) | `CurrentTrauma: Float` | | [`WBP_ScreenEffectController`](../06-ui/WBP_ScreenEffectController.md) | Dispatcher (`OnTraumaChanged`) | `CurrentTrauma: Float` | | [`ABP_PlayerBody`](../02-player/13_BPC_EmbodimentSystem.md) | Direct (anim var write) | `LastDamageDirection`, reaction montage reference | | [`BPC_AdaptiveEnvironmentDirector`](../10-adaptive/BPC_AdaptiveEnvironmentDirector.md) | Direct read | `CurrentTrauma` via getter | --- ## 9. Validation / Testing Checklist - [ ] FlinchThreshold: damage at 5.0+ triggers flinch animation - [ ] RagdollThreshold: damage at 50.0+ triggers ragdoll blend - [ ] TraumaDecayRate: trauma reduces to zero over time when no damage received - [ ] HitReactionMontages map: correct montage plays per E_DamageType - [ ] Edge case: zero damage events do not trigger any reaction - [ ] Edge case: rapid succession hits cycle through montage variations - [ ] Edge case: death event (HealthSystem OnDeath) skips flinch, goes directly to ragdoll --- ## 10. Reuse Notes - FlinchThreshold and RagdollThreshold can be tuned per project for desired combat feel - HitReactionMontages map uses E_DamageType as key — add new damage types without modifying core logic - Trauma system is separate from camera shake — trauma drives persistent wobble, shake is transient - For non-combat projects, set FlinchThreshold very high (e.g., 9999) to disable reactions entirely --- *Specification based on Master Section 5.7, line 1821.*