# BPC_ConsumableSystem — Consumable System

**Parent Class:** `ActorComponent`
**Category:** Inventory
**Target UE Version:** 5.5–5.7
**Build Phase:** 3 — Inventory

## 1. Overview

`BPC_ConsumableSystem` manages consumable item usage — health packs, stamina boosters, temporary buff items, and one-time-use consumables. Reads from [`BPC_InventorySystem`](BPC_InventorySystem.md) and applies effects through the relevant player systems.

## 2. Variables

| Variable | Type | Description |
|----------|------|-------------|
| `ConsumableCooldown` | `float` | Global cooldown between consumable uses |
| `ActiveBuffs` | `TArray<S_ActiveBuff>` | Currently active temporary buffs |
| `bCanUseConsumables` | `bool` | Master toggle (blocked during certain states) |

## 3. Structs

### `S_ActiveBuff`

| Field | Type | Description |
|-------|------|-------------|
| `BuffTag` | `FGameplayTag` | Buff identifier |
| `RemainingDuration` | `float` | Time remaining |
| `BuffData` | `DA_ItemData*` | Source item data |
| `AffectedStat` | `E_PlayerStat` | Health, Stamina, Speed, Stress, Damage |

## 4. Functions

| Function | Description |
|----------|-------------|
| `UseConsumable` | Uses a consumable item from inventory slot |
| `ApplyBuff` | Applies a temporary buff to the player |
| `RemoveBuff` | Removes a buff by tag |
| `GetActiveBuffs` | Returns all active buffs |
| `HasBuff` | Checks if a specific buff is active |
| `TickBuffs` | Decrements buff durations, removes expired |

## 5. Event Dispatchers

| Dispatcher | Payload | Description |
|------------|---------|-------------|
| `OnConsumableUsed` | `S_InventoryEntry Item` | Consumable item used |
| `OnBuffApplied` | `FGameplayTag BuffTag`, `float Duration` | Buff activated |
| `OnBuffExpired` | `FGameplayTag BuffTag` | Buff ended |

## 6. Dependencies

| System | Relationship |
|--------|--------------|
| `BPC_InventorySystem` | Reads and modifies consumable items |
| `BPC_HealthSystem` | Health restoration via consumables |
| `BPC_StaminaSystem` | Stamina restoration |
| `BPC_StressSystem` | Stress reduction items |
| `BPC_MovementStateSystem` | Speed buffs |

## 7. Reuse Notes
- All consumable effects are data-driven via DA_ItemData
- Buffs support stacking (multiple buffs active simultaneously)

---

## 8. Manual Implementation Guide

### 8.1 Class Setup
1. Create Blueprint Class: Parent = `ActorComponent`, Name = `BPC_ConsumableSystem`
2. Save to: `Content/Framework/Inventory/`
3. Add to your Player Character or Player Controller

### 8.2 Variable Initialization (BeginPlay)

```
Event BeginPlay
  ├─ Set ConsumableCooldown = 1.5 (or expose as config)
  ├─ Set bCanUseConsumables = true
  ├─ Set ActiveBuffs = empty array
  ├─ Get Owner → Find Component by Class (BPC_InventorySystem) → Store reference
  │    └─ If found: Bind to BPC_InventorySystem.OnItemUsed → OnInventoryItemUsedHandler
  └─ Start a looping timer (0.1s) for TickBuffs
```

### 8.3 Function Implementations

#### `UseConsumable(SlotIndex: Integer)` → `Boolean`

**Node-by-Node Logic:**
```
[Function: UseConsumable]
  Step 1: Branch on bCanUseConsumables → If false, return false
  Step 2: Get InventorySystem reference → Call GetItemAtSlot(SlotIndex) → returns S_InventoryEntry
  Step 3: Branch on IsValid(ItemData) → If not valid, return false
  Step 4: Check ItemData.ItemType == Consumable → If not, return false
  Step 5: Read ItemData.ConsumableData → get effect values:
    - HealthRestore, StaminaRestore, StressReduce, SpeedBuff, DamageBuff, BuffDuration
  Step 6: Apply effects (branch on each value > 0):
    - If HealthRestore > 0: Get BPC_HealthSystem → Call ApplyHealing(HealthRestore)
    - If StaminaRestore > 0: Get BPC_StaminaSystem → Call RestoreStamina(StaminaRestore)
    - If StressReduce > 0: Get BPC_StressSystem → Call RemoveStress(StressReduce)
    - If SpeedBuff > 0 AND BuffDuration > 0: Call ApplyBuff(SpeedBuffTag, BuffDuration)
    - If DamageBuff > 0 AND BuffDuration > 0: Call ApplyBuff(DamageBuffTag, BuffDuration)
  Step 7: If any buff applied: add to ActiveBuffs array with RemainingDuration = BuffDuration
  Step 8: Fire OnConsumableUsed (pass the InventoryEntry)
  Step 9: Start ConsumableCooldown timer → set bCanUseConsumables = false
    └─ On timer end → set bCanUseConsumables = true
  Step 10: Return true
```

**Nodes Used:** `Branch`, `GetItemAtSlot`, `IsValid`, `Switch on E_ItemType`, `ApplyHealing`, `RestoreStamina`, `RemoveStress`, `Call ApplyBuff`, `Set Timer by Event`

#### `ApplyBuff(BuffTag: GameplayTag, Duration: Float, Stat: E_PlayerStat, SourceItem: DA_ItemData)` → `void`

```
[Function: ApplyBuff]
  Step 1: Create S_ActiveBuff struct:
    - BuffTag = input tag
    - RemainingDuration = Duration
    - BuffData = SourceItem
    - AffectedStat = Stat
  Step 2: Check if buff with same BuffTag already in ActiveBuffs:
    - If yes: update RemainingDuration (refresh)
    - If no: Add to ActiveBuffs array
  Step 3: Apply stat modification:
    - Switch on AffectedStat:
      - Health: NOT here (buffs are temporary, not direct heal)
      - Stamina: Get BPC_StaminaSystem → Call BlockRegen(0) or similar (buff handles in tick)
      - Speed: Get BPC_MovementStateSystem → Call ApplyMovementPenalty(1.0 + buffAmount, Duration)
      - Stress: Get BPC_StressSystem → Call AddStressSource(...)
      - Damage: Store as damage multiplier (read during damage calc)
  Step 4: Fire OnBuffApplied(BuffTag, Duration)
```

#### `RemoveBuff(BuffTag: GameplayTag)` → `void`

```
[Function: RemoveBuff]
  Step 1: Find buff in ActiveBuffs by BuffTag → ForEachLoop with Break
  Step 2: If found:
    - Remove from array
    - Reverse any active stat modification
    - Fire OnBuffExpired(BuffTag)
```

#### `TickBuffs` → `void` *(Timer callback, runs every 0.1s)*

```
[Function: TickBuffs]
  Step 1: ForEach ActiveBuffs (iterate backwards if removing):
    - RemainingDuration -= 0.1
    - Branch on RemainingDuration <= 0:
      - True → Call RemoveBuff(BuffTag)
  Step 2: If ActiveBuffs is empty after cleanup: stop the timer (optional)
```

#### `GetActiveBuffs` → `Array<S_ActiveBuff>`
```
[Function: GetActiveBuffs] (Pure)
  └─ Return ActiveBuffs array
```

#### `HasBuff(BuffTag: GameplayTag)` → `Boolean`
```
[Function: HasBuff] (Pure)
  Step 1: ForEach ActiveBuffs:
    - If ActiveBuffs[i].BuffTag == BuffTag → Return true
  Step 2: Return false
```

### 8.4 Event Dispatcher Bindings

| Bind to Dispatcher | Custom Event | Logic |
|-------------------|-------------|-------|
| `BPC_InventorySystem.OnItemUsed` | `OnInventoryItemUsedHandler(Item, Instigator)` | Check ItemData.ItemType == Consumable → Call UseConsumable(SlotIndex) |

### 8.5 Networking

| Variable | Replication | Notes |
|----------|-------------|-------|
| `ActiveBuffs` | `Replicated Using OnRep_ActiveBuffs` | OnRep reapplies visual effects |
| `bCanUseConsumables` | `Replicated` | Server controls cooldown |

**Server RPC:** `Server_UseConsumable(SlotIndex)` — Client calls, server validates item exists/cooldown, applies effects.

### 8.6 Blueprint Build Checklist

- [ ] Create BPC_ConsumableSystem component
- [ ] Add ConsumableCooldown, ActiveBuffs, bCanUseConsumables variables
- [ ] Define S_ActiveBuff struct in the component
- [ ] Implement UseConsumable with effect routing to Health/Stamina/Stress/Movement
- [ ] Implement ApplyBuff / RemoveBuff with ActiveBuffs array management
- [ ] Create TickBuffs timer (0.1s loop) for buff duration countdown
- [ ] Bind to BPC_InventorySystem.OnItemUsed
- [ ] Add networking: Replicated ActiveBuffs, Server_UseConsumable RPC