# 52 — BPC_AmmoComponent ## Blueprint Spec — UE 5.5–5.7 --- ### Parent Class `ActorComponent` ### Dependencies - [`BP_WeaponBase`](49_BP_WeaponBase.md) — Owner weapon - [`BPC_InventoryComponent`](../04-inventory/25_BPC_InventoryComponent.md) — Consumable ammo items - [`DA_WeaponData`](../12-content/60_DA_WeaponDataAsset.md) — Magazine size, ammo type - [`DA_AmmoType`](../12-content/61_DA_AmmoTypeDataAsset.md) — Ammo definition ### Purpose Manages ammunition state for a weapon: current magazine count, total reserve, reload logic, ammo type validation, and UI updates. Attached to each weapon actor as a child component. ### Variables | Name | Type | Description | |------|------|-------------| | `WeaponDataRef` | DA_WeaponData | Weapon data asset (set at construction) | | `CurrentMagazineAmmo` | Int | Bullets currently in magazine | | `ReserveAmmo` | Int | Total carried ammo of matching type | | `MaxMagazineSize` | Int | From weapon data | | `AmmoTypeTag` | FGameplayTag | e.g. Tag.Ammo.9mm | | `bInfiniteAmmo` | Bool | Debug / cheat toggle | | `ReloadType` | EReloadType | Full, Partial, SingleBullet | | `ReloadTimeMultiplier` | Float | Per-weapon reload speed scaling | | `AmmoHistory` | Array | Save/load stack | ### Structs | Struct | Fields | Description | |--------|--------|-------------| | `FAmmoEntry` | AmmoTypeTag: FGameplayTag, MagazineCount: Int, ReserveCount: Int | State for save/load | ### Enums | Enum | Values | Description | |------|--------|-------------| | `EReloadType` | FullMagazine, PartialFill, SingleBulletLoad | How reload animation works | ### Functions | Name | Inputs | Outputs | Description | |------|--------|---------|-------------| | `InitializeAmmo` | WeaponData: DA_WeaponData | — | Set magazine size, count from reserve | | `CanFire` | — | Bool | MagazineAmmo > 0 | | `ConsumeAmmo` | Count: Int (default 1) | Int (remaining) | Remove from magazine | | `StartReload` | — | Bool | Check reserve; if > 0 begin reload | | `FinishReload` | — | — | Refill magazine from reserve; update UI | | `GetCurrentMagazineAmmo` | — | Int | UI binding | | `GetReserveAmmo` | — | Int | UI binding | | `AddAmmo` | Count: Int, AmmoTag: FGameplayTag | — | From pickup / reward | | `RemoveAmmoFromReserve` | Count: Int | — | Manufacturing / crafting | | `GetAmmoPercent` | — | Float | 0.0–1.0 for progress bar | | `IsAmmoEmpty` | — | Bool | Magazine + Reserve == 0 | | `OnAmmoChanged` | — | — | Trigger dispatcher | ### Event Dispatchers | Name | Parameters | Fired When | |------|-----------|-----------| | `OnAmmoUpdated` | CurrentMagazine: Int, Reserve: Int | Any ammo change | | `OnReloadStarted` | ReloadTime: Float | Reload begin | | `OnReloadCompleted` | — | Reload end | | `OnOutOfAmmo` | — | Magazine + Reserve == 0 | | `OnAmmoPickup` | AmmoTypeTag: FGameplayTag, Count: Int | Ammo added | ### Blueprint Flow ``` [InitializeAmmo] └─► MaxMagazineSize = WeaponData.MagazineSize └─► AmmoTypeTag = WeaponData.AmmoType └─► If start with full: CurrentMagazineAmmo = MaxMagazineSize └─► Else CurrentMagazineAmmo = 0 [ConsumeAmmo(Count)] └─► If bInfiniteAmmo → return └─► CurrentMagazineAmmo = FMath::Max(0, CurrentMagazineAmmo - Count) └─► OnAmmoChanged [StartReload] └─► If ReserveAmmo <= 0 → broadcast OnOutOfAmmo → return false └─► If ReloadType == FullMagazine: AmountNeeded = MaxMagazineSize - CurrentMagazineAmmo Taken = FMath::Min(AmountNeeded, ReserveAmmo) └─► If ReloadType == PartialFill: Taken = FMath::Min(ReloadAmount, ReserveAmmo) // per stage └─► If ReloadType == SingleBulletLoad: Taken = 1 └─► ReserveAmmo -= Taken └─► Wait for ReloadTime (configured in WeaponData) └─► CurrentMagazineAmmo += Taken └─► OnAmmoChanged └─► Return true [FinishReload — called by animation notify or timer] └─► Fill magazine based on remaining reserve └─► Broadcast OnReloadCompleted [AddAmmo(Count, AmmoTag)] └─► If AmmoTag matches AmmoTypeTag: ReserveAmmo += Count Broadcast OnAmmoPickup(AmmoTag, Count) OnAmmoChanged ``` ### Communications With | Target | Method | Why | |--------|--------|-----| | [`BP_WeaponBase`](49_BP_WeaponBase.md) | Owner | Ammo check before fire, reload notification | | [`BPC_InventoryComponent`](../04-inventory/25_BPC_InventoryComponent.md) | Get from Player | Add/remove ammo items from inventory | | HUD Widget | Dispatcher (via Owner) | Ammo counter and low ammo warning | | Save/Load System | GetSaveData / LoadFromData | Persist ammo state | | Owner Animation BP | Direct | Reload animation play | | [`BPC_CombatFeedbackComponent`](54_BPC_CombatFeedbackComponent.md) | Get Component | Click on empty fire attempt | ### Reuse Notes - Designed for magazine-fed and chamber-fed weapons - SingleBulletLoad used for shotguns / break-action weapons - Reload can be interrupted by StartFire if loaded magazine > 0 - Ammo pickup broadcasts to allow UI, audio, VFX reactions