# BPC_ReloadSystem — Actor Component

**File:** [`Content/Framework/Weapons/BPC_ReloadSystem`](Content/Framework/Weapons/BPC_ReloadSystem.uasset)
**Parent Class:** `UActorComponent`
**Dependencies:** [`DA_WeaponData`](49_BP_WeaponBase.md), [`BPC_FirearmSystem`](BPC_FirearmSystem.md), [`BPC_AmmoResourceSystem`](../04-inventory/BPC_KeyItemSystem.md)

**Purpose:** Manages reload animations, timing, and ammo transfer from pool to weapon magazine. Supports tactical reload, partial reload, and reload interruption.

---

## Variables

| Name | Type | Description |
|------|------|-------------|
| `bIsReloading` | Bool | Reload in progress |
| `ReloadMontage` | AnimMontage | Per-weapon reload animation |
| `AmmoTypeTag` | GameplayTag | Which ammo pool to draw from |
| `bPartialReload` | Bool | Whether partial reload is supported |
| `RoundsToAdd` | Integer | How many rounds to transfer on reload complete |

## Functions / Events

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `RequestReload` | — | — | Player presses reload; checks if reload needed |
| `BeginReload` | — | — | Plays reload montage, locks fire input |
| `CompleteReload` | — | — | Transfers ammo from pool to magazine |
| `InterruptReload` | — | — | Cancels reload, retains partial rounds if configured |
| `CanReload` | — | Bool | Checks magazine not full AND ammo pool has rounds |

## Event Dispatchers

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnReloadStarted` | — | Reload begins |
| `OnReloadCompleted` | RoundsAdded: Integer | Reload finishes successfully |
| `OnReloadInterrupted` | RoundsAdded: Integer | Reload cancelled mid-way |
| `OnReloadFailed` | — | Cannot reload (full mag or no ammo) |

## Blueprint Flow

```
[Player presses Reload] -> CanReload?
  -> Yes: BeginReload -> Play ReloadMontage -> bIsReloading = true -> Lock fire input
  -> Animation Notify "TransferRounds" -> CompleteReload -> Consume ammo from pool
  -> Unlock fire input -> Broadcast OnReloadCompleted
  -> No: Broadcast OnReloadFailed
```

## Communications With

| Target System | Method | Why |
|---------------|--------|-----|
| `BPC_FirearmSystem` | Direct LockFire / UnlockFire | Prevent firing during reload |
| `BPC_AmmoResourceSystem` | Direct ConsumeAmmo | Draw rounds from ammo pool |
| `ABP_PlayerBody` | Animation Notify events | Reload animation timing |

## Reuse Notes

- ReloadMontage from DA_WeaponData per weapon; swap for each weapon type
- Partial reload enabled per weapon (e.g. shotguns use individual shell reloads)
- AmmoTypeTag links to correct ammo pool in BPC_AmmoResourceSystem

---

## Manual Implementation Guide

### Class Setup
1. Create Blueprint Class: Parent = `ActorComponent`, Name = `BPC_ReloadSystem`
2. Attach to `BP_WeaponBase` or `BPC_FirearmSystem`
3. Weapon must have a `ReloadMontage` with Animation Notifies

### Variable Init (BeginPlay)
```
Event BeginPlay
  ├─ Set bIsReloading = false
  ├─ Set bPartialReload = false
  ├─ Get Owner → Read DA_WeaponData → Load ReloadMontage, AmmoTypeTag, MagazineSize
  └─ Cache: BPC_AmmoComponent, BP_WeaponBase (for state check)
```

### Function Implementations

#### `RequestReload()` → `void`

```
[Function: RequestReload]
  Step 1: Get BP_WeaponBase → Check WeaponState == Ready → If not, return (can't reload while firing)
  Step 2: Call CanReload() → Branch:
    False → Fire OnReloadFailed → Return
    True → Call BeginReload()
```

#### `CanReload()` → `Boolean`

```
[Function: CanReload] (Pure)
  Step 1: Get BPC_AmmoComponent → Call GetAmmoInMagazine()
    If magazine >= MagazineSize → Return false (already full)
  Step 2: Get BPC_AmmoComponent → Call GetReserveAmmo(AmmoTypeTag)
    If reserve <= 0 → Return false (no ammo to load)
  Step 3: Return true
```

#### `BeginReload()` → `void`

```
[Function: BeginReload]
  Step 1: Set bIsReloading = true
  Step 2: Notify BP_WeaponBase → SetWeaponState(Reloading)
  Step 3: Play Montage (ReloadMontage)
  Step 4: Fire OnReloadStarted

  Step 5: Animation Notify "TransferRounds" setup:
    In the animation montage, add Notify at the frame where the magazine is inserted.
    On trigger → Call CompleteReload()

  Step 6: Animation Notify "ReloadEnd" setup:
    Add Notify at montage end → Call FinishReload()
```

#### `CompleteReload()` → `void` *(Called by Notify "TransferRounds")*

```
[Function: CompleteReload]
  Step 1: Get BPC_AmmoComponent:
    MagazineCurrent = GetAmmoInMagazine()
    ReserveCurrent = GetReserveAmmo(AmmoTypeTag)
  Step 2: RoundsToAdd = Min(MagazineSize - MagazineCurrent, ReserveCurrent)
  Step 3: BPC_AmmoComponent.RemoveReserveAmmo(AmmoTypeTag, RoundsToAdd)
  Step 4: BPC_AmmoComponent.AddMagazineAmmo(RoundsToAdd)
```

#### `FinishReload()` → `void` *(Called by Notify "ReloadEnd")*

```
  Step 1: Set bIsReloading = false
  Step 2: Notify BP_WeaponBase → SetWeaponState(Ready)
  Step 3: Fire OnReloadCompleted(RoundsToAdd)
```

#### `InterruptReload()` → `void`

```
[Function: InterruptReload]
  Step 1: Branch on bIsReloading → If false, return
  Step 2: If bPartialReload AND CompleteReload already called:
    Keep transferred rounds (partial reload success)
  Step 3: Else: no rounds transferred
  Step 4: Stop Montage (ReloadMontage)
  Step 5: Set bIsReloading = false
  Step 6: Notify BP_WeaponBase → SetWeaponState(Ready)
  Step 7: Fire OnReloadInterrupted(RoundsTransferred)
```

### Build Checklist
- [ ] Create BPC_ReloadSystem, add to BP_RangedWeapon
- [ ] Create ReloadMontage per weapon with Notifies: TransferRounds, ReloadEnd
- [ ] Implement CanReload checking magazine fullness and reserve ammo
- [ ] Implement BeginReload with montage playback and state lock
- [ ] Wire CompleteReload to ammo transfer
- [ ] Wire FinishReload to state restoration
- [ ] Implement InterruptReload for mid-reload weapon swap
- [ ] Test: empty magazine → reload → rounds transfer → magazine full