# 54 — BPC_CombatFeedbackComponent

## Blueprint Spec — UE 5.5–5.7

---

### Parent Class
`ActorComponent`

### Dependencies
- [`BP_WeaponBase`](49_BP_WeaponBase.md) — Owner weapon
- [`BPC_DamageHandlerComponent`](53_BPC_DamageHandlerComponent.md) — Damage result data
- [`DA_WeaponData`](../12-content/60_DA_WeaponDataAsset.md) — FX/sound references
- [`DA_ImpactFXConfig`](../12-content/62_DA_ImpactFXConfigDataAsset.md) — Surface impact map
- [`AudioManager`](../09-atmosphere/69_BPC_AudioManager.md) — Spatial audio requests
- [`VFXManager`](../09-atmosphere/70_BPC_VFXManager.md) — Particle system pooling

### Purpose
Centralized visual and audio feedback for combat actions. Decouples weapon and damage logic from presentation. Manages muzzle flash, tracer trajectories, impact decals and particles, bullet holes, hit confirmation UI numbers, weapon sounds (fire, reload, empty click, melee whoosh), and screen effects (camera shake, hit directional indicator). Implemented as a reusable component attached to weapon actors.

### Variables

| Name | Type | Description |
|------|------|-------------|
| `WeaponMesh` | USkeletalMeshComponent | Reference to owner weapon mesh |
| `MuzzleFlashPS` | UParticleSystem | Muzzle flash effect |
| `TracerPS` | UParticleSystem | Tracer trail effect |
| `TracerSpawnChance` | Float | 0.0–1.0 probability per shot |
| `MuzzleSocketName` | FName | Spawn point name |
| `ImpactDecalMap` | TMap<PhysicalMaterial, UMaterialInterface> | Surface material → decal |
| `ImpactParticleMap` | TMap<PhysicalMaterial, UParticleSystem> | Surface → hit particle |
| `ImpactDecalLifeSpan` | Float | Seconds before decal fades |
| `ImpactDecalSize` | FVector | Decal projection scale |
| `FireSound` | USoundBase | Fire sound cue |
| `FireSoundTail` | USoundBase | Tail loop (full auto) |
| `ReloadSound` | USoundBase | Reload start |
| `ReloadFinishSound` | USoundBase | Reload complete |
| `EmptyClickSound` | USoundBase | Empty magazine fire attempt |
| `MeleeWhooshSound` | USoundBase | Melee swing whoosh |
| `MeleeHitSound` | USoundBase | Melee impact |
| `BlockSound` | USoundBase | Block/parry impact |
| `CameraShakeClass` | TSubclassOf<UCameraShakeBase> | Per-weapon shake profile |
| `ScreenHitIndicatorClass` | TSubclassOf<UUserWidget> | Hit direction HUD overlay |
| `HitNumberWidgetClass` | TSubclassOf<UUserWidget> | Floating damage number |
| `BulletHolePool` | Array<ABulletHoleActor> | Reusable pooled actors |
| `MaxBulletHoles` | Int | Pool limit (e.g. 50) |

### Structs

| Struct | Fields | Description |
|--------|--------|-------------|
| `FImpactContext` | HitLocation: FVector, HitNormal: FVector, HitMaterial: UPhysicalMaterial, bIsCrit: Bool, Damage: Float, bIsKill: Bool | Full hit data for FX |

### Functions

| Name | Inputs | Outputs | Description |
|------|--------|---------|-------------|
| `PlayMuzzleFlash` | — | — | Spawn muzzle particle at socket |
| `SpawnTracer` | EndPoint: FVector | — | Line trail particle from muzzle to impact |
| `SpawnImpactFX` | Impact: FImpactContext | — | Decal + particle at hit location |
| `SpawnBulletHole` | Location: FVector, Rotation: FRotator | AActor | Pooled bullet hole actor |
| `PlayFireSound` | — | — | Fire sound with optional tail |
| `StopFireSound` | — | — | End tail loop |
| `PlayReloadSound` | — | — | Reload start |
| `PlayReloadFinishSound` | — | — | Reload complete |
| `PlayEmptyClickSound` | — | — | Dry fire |
| `PlayMeleeWhoosh` | — | — | Melee attack sound |
| `PlayMeleeHitSound` | Impact: FImpactContext | — | Melee impact sound |
| `PlayBlockSound` | — | — | Block/parry impact |
| `PlayCameraShake` | — | — | Fire camera shake |
| `ShowHitNumber` | Damage: Float, Location: FVector, IsCrit: Bool | — | Floating damage widget |
| `ShowHitIndicator` | DamageDirection: FVector | — | Screen edge indicator |
| `GetImpactContextFromHit` | HitResult: FHitResult | FImpactContext | Extract material, location etc. |
| `PlayHitConfirmationSound` | bIsKill: Bool | — | Hit marker or kill sound |
| `InitializePool` | — | — | Spawn bullet hole pool |

### Blueprint Flow

```
[OnFire → called by WeaponBase]
  └─► PlayMuzzleFlash
  └─► SpawnTracer(EndPoint)
  └─► PlayFireSound (if full auto: start tail loop)
  └─► PlayCameraShake

[OnHit → called by DamageHandler dispatcher]
  └─► FX Pipeline:
         ImpactCtx = GetImpactContextFromHit(Hit)
         If ImpactCtx.bIsCrit: PlayCritImpactFX
         Else: SpawnImpactFX(ImpactCtx)
         SpawnBulletHole(ImpactCtx.HitLocation, RotationFromNormal)
         PlayMeleeHitSound or generic hit sound
         ShowHitNumber(ImpactCtx.Damage, ImpactCtx.HitLocation, ImpactCtx.bIsCrit)
         ShowHitIndicator(GetDirectionFromInstigator)
         If ImpactCtx.bIsKill: PlayKillConfirmation

[OnAmmoEmpty → called by AmmoComponent dispatcher]
  └─► PlayEmptyClickSound

[OnReloadStarted/Completed → called by AmmoComponent dispatcher]
  └─► PlayReloadSound / PlayReloadFinishSound
```

### Pooled Bullet Hole System

```
[InitializePool]
  └─► For i = 1 .. MaxBulletHoles:
         Spawn ABulletHoleActor deactivated
         Add to BulletHolePool

[SpawnBulletHole]
  └─► Find first inactive actor in pool
  └─► If none → recycle oldest active
  └─► Set transform, set decal material based on surface
  └─► Activate, start life timer
```

### Impact Decal Material Mapping

| Physical Material | Decal Material | Particle System |
|-------------------|---------------|-----------------|
| Concrete | T_ConcreteDecal | P_ConcreteHit |
| Metal | T_MetalDecal | P_MetalSparks |
| Wood | T_WoodDecal | P_WoodSplinters |
| Flesh | T_FleshDecal | P_BloodSplash |
| Glass | T_GlassDecal | P_GlassShards |
| Water | T_WaterRipple | P_WaterSplash |
| Default | T_BulletHole | P_GenericHit |

### Communications With

| Target | Method | Why |
|--------|--------|-----|
| [`BP_WeaponBase`](49_BP_WeaponBase.md) | Owner | Fire/reload/empty event hooks |
| [`BPC_AmmoComponent`](52_BPC_AmmoComponent.md) | Dispatcher listener | Empty click, reload sounds |
| [`BPC_DamageHandlerComponent`](53_BPC_DamageHandlerComponent.md) | Dispatcher listener | Hit FX on damage dealt |
| [`BPC_PlayerCameraManager`](../02-player/14_BPC_PlayerCameraManager.md) | Get from Owner | Camera shake |
| [`AudioManager`](../09-atmosphere/69_BPC_AudioManager.md) | Get Game Instance | Spatial audio for distant sounds |
| [`VFXManager`](../09-atmosphere/70_BPC_VFXManager.md) | Get Game Instance | Particle pooling |
| HUD Widget | Direct or Dispatcher | Hit marker and damage numbers |
| Bullet Hole Pool | Direct | Spawn / recycle |

### Reuse Notes
- Pure presentation component: swap entire feedback profile by replacing DA_WeaponData FX references
- Impact material map driven by physical materials, no hardcoded surface checks
- Pooled bullet holes prevent spawn/despawn overhead
- Camera shake per weapon allows distinct feel (pistol vs shotgun)
- All sounds use distance-based attenuation curves from the audio manager