# `BPC_EquipmentSlotSystem` — Equipment & Gear Slots

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

---

## 1. Overview

`BPC_EquipmentSlotSystem` manages wearable gear slots on the player — head, torso, hands, legs, feet, backpack, eyewear, and accessory. It reads from the linked [`BPC_InventorySystem`](docs/blueprints/04-inventory/BPC_InventorySystem.md) and marks items as equipped/unequipped via the inventory's `S_InventoryEntry.bIsEquipped` flag.

Equipping moves stat modifiers (defense, move speed, carry capacity, sensory range) into a live `S_EquipmentModifiers` struct that other systems query. Unequipping removes them. Equipment also attaches skeletal meshes to character socket points for visual representation.

---

## 2. Mermaid — Equipment Flow

```mermaid
flowchart TD
    A[Player selects Equip Action] --> B{BPC_EquipmentSlotSystem.EquipItem}
    B --> C{Slot Occupied?}
    C -->|Yes| D[Unequip current item]
    C -->|No| E[Set Item.bIsEquipped = true]
    
    D --> F[Remove modifiers from active pool]
    E --> G[Add modifiers to active pool]
    F --> H[Detach skeletal mesh from socket]
    G --> I[Attach skeletal mesh to socket]
    
    H --> J[Broadcast OnEquipmentChanged]
    I --> J
    
    J --> K[Systems Query Modifiers]
    K --> L[BPC_MovementStateSystem]
    K --> M[BPC_InventorySystem Weight]
    K --> N[BPC_HealthSystem Defense]
    K --> O[InteractionDetector Range]
```

---

## 3. Enums

### `E_EquipmentSlot`

| Value | Description |
|-------|-------------|
| `Head` | Helmets, masks, headgear. |
| `Torso` | Chest armor, vests, jackets. |
| `Hands` | Gloves, wrist devices. |
| `Legs` | Pants, leg armor. |
| `Feet` | Boots, shoes. |
| `Backpack` | Back slot — increases carry capacity. |
| `Eyewear` | Night vision, goggles, glasses. |
| `Accessory_1` | Ring, necklace, badge (slot 1). |
| `Accessory_2` | Ring, necklace, badge (slot 2). |
| `Weapon_Primary` | Main weapon (slot shared with quick slots). |
| `Weapon_Secondary` | Sidearm / backup weapon. |
| `Tool` | Equipped tool (lockpick, scanner, flashlight). |

### `E_EquipResult`

| Value | Description |
|-------|-------------|
| `Success` | Item was equipped. |
| `SlotOccupied` | Slot is full; unequip first. |
| `NotEquippable` | Item's category does not match any slot. |
| `ItemNotFound` | Item is not in inventory. |
| `BlockedByState` | Cannot equip in current state (e.g., hiding). |
| `BlockedByCondition` | Player condition blocks equip (e.g., injured arm). |

### `E_EquipAnimationType`

| Value | Description |
|-------|-------------|
| `Instant` | No animation — immediate attach. |
| `Holster` | Holster/draw weapon animation. |
| `Equip` | Generic equip animation (armor, backpack). |
| `Unequip` | Generic unequip animation. |

---

## 4. Structs

### `S_EquipmentSlotDef`

| Field | Type | Description |
|-------|------|-------------|
| `Slot` | `E_EquipmentSlot` | Which slot this definition is for. |
| `SocketName` | `FName` | Skeletal mesh socket to attach equipment visuals to. |
| `AllowedCategories` | `TArray<E_ItemCategory>` | Item categories that can be equipped in this slot. |
| `bMustBeEmptyToEquip` | `bool` | If true, slot must be empty before equipping. |
| `bAutoEquipOnPickup` | `bool` | If true, items matching categories auto-equip. |

### `S_EquipmentModifiers`

| Field | Type | Description |
|-------|------|-------------|
| `DefenseBonus` | `float` | Flat damage reduction applied by HealthSystem (0.0 = none). |
| `MoveSpeedModifier` | `float` | Multiplier for character max walk speed (1.0 = normal). |
| `CarryCapacityBonus` | `float` | Additional kg the inventory can hold. |
| `StaminaDrainModifier` | `float` | Multiplier for stamina drain rate (1.0 = normal). |
| `SensoryRangeModifier` | `float` | Multiplier for detection range (1.0 = normal). |
| `StressResistanceModifier` | `float` | Multiplier for stress gain (1.0 = normal, 0.5 = half). |
| `HealthRegenPerSecond` | `float` | Passive health regen when equipped. |

### `S_EquipmentState`

| Field | Type | Description |
|-------|------|-------------|
| `EquippedItems` | `TMap<E_EquipmentSlot, FGuid>` | Map of slot → ItemID of equipped item. |
| `ActiveModifiers` | `S_EquipmentModifiers` | Current summed modifiers from all equipped items. |
| `VisualAttachments` | `TMap<E_EquipmentSlot, UChildActorComponent*>` | Map of slot → attached mesh component. |

---

## 5. Variables

### Configuration (Instance Editable)

| Variable | Type | Description |
|----------|------|-------------|
| `SlotDefinitions` | `TArray<S_EquipmentSlotDef>` | Definitions for each equipment slot. |
| `bAllowUnequipInCombat` | `bool` | If false, cannot unequip during combat. |
| `bAutoEquipStartingItems` | `bool` | If true, starting items with matching categories auto-equip. |
| `bReplicates` | `bool` | Whether equipment state is replicated. |

### State (Blueprint Read Only, Replicated)

| Variable | Type | Description |
|----------|------|-------------|
| `EquippedItems` | `TMap<E_EquipmentSlot, FGuid>` | Currently equipped items by slot. |
| `ActiveModifiers` | `S_EquipmentModifiers` | Summed modifier values from all equipped gear. |

### Internal (Not Replicated)

| Variable | Type | Description |
|----------|------|-------------|
| `OwningInventory` | `BPC_InventorySystem*` | Cached inventory reference. |
| `OwningCharacter` | `ACharacter*` | Cached character for skeletal mesh attachment. |
| `VisualAttachments` | `TMap<E_EquipmentSlot, AActor*>` | Spawned attachment actors/meshes. |

---

## 6. Functions & Events

### Public Functions

| Function | Description |
|----------|-------------|
| `EquipItem` | Equips an item from inventory to its matching slot. Returns `E_EquipResult`. Handles slot swap if occupied. |
| `UnequipItem` | Unequips item from a slot. Returns result. Item stays in inventory. |
| `UnequipAll` | Unequips all slots. Broadcasts final state. |
| `GetEquippedItemInSlot` | Returns `S_InventoryEntry` for the item in a given slot. |
| `GetSlotForItemCategory` | Returns the best `E_EquipmentSlot` for an item category. |
| `IsSlotOccupied` | Returns true if a slot has an equipped item. |
| `GetActiveModifiers` | Returns the current `S_EquipmentModifiers` struct. |
| `GetEquippedItems` | Returns `TMap<E_EquipmentSlot, FGuid>` of all equipped items. |
| `CanEquipItem` | Pre-checks if an item can be equipped (category, slot, state). Returns `E_EquipResult`. |
| `CanUnequipSlot` | Pre-checks if a slot can be unequipped (not locked by state). |

### Protected Functions

| Function | Description |
|----------|-------------|
| `BeginPlay` | Caches inventory and character references, auto-equips starting items. |
| `FindMatchingSlot` | Finds an `E_EquipmentSlot` whose allowed categories include the item's category. |
| `ApplyEquipmentVisual` | Attaches a skeletal or static mesh to the character's socket. |
| `RemoveEquipmentVisual` | Detaches and destroys the visual for a slot. |
| `RecalculateModifiers` | Iterates all equipped items, sums modifier values into `ActiveModifiers`. |
| `SetItemEquippedFlag` | Sets `bIsEquipped` on the inventory entry to true/false. |
| `ValidateEquipState` | Called periodically or on save: verifies equipped items still exist in inventory. |
| `OnRep_EquippedItems` | RepNotify: rebuilds visual attachments on remote clients. |

### Event Dispatchers

| Dispatcher | Payload | Description |
|------------|---------|-------------|
| `OnItemEquipped` | `E_EquipmentSlot Slot`, `S_InventoryEntry Item` | Fired after successful equip. |
| `OnItemUnequipped` | `E_EquipmentSlot Slot`, `S_InventoryEntry Item` | Fired after successful unequip. |
| `OnEquipmentChanged` | `S_EquipmentModifiers NewModifiers`, `S_EquipmentModifiers OldModifiers` | Fired when any modifier value changes. |
| `OnEquipFailed` | `E_EquipResult Reason`, `E_EquipmentSlot Slot` | Fired when equip is rejected. |

---

## 7. Blueprint Graph Flow

```
Event BeginPlay
    → GetOwner → FindComponentByClass BPC_InventorySystem → Cache
    → GetOwner → Cast to ACharacter → Cache
    → If bAutoEquipStartingItems:
        → Inventory has starting items → For each with matching slot → Call EquipItem

EquipItem (ItemID, Slot)
    → CanEquipItem → If fail → return NotEquippable
    → Get item from inventory by ItemID
    → FindMatchingSlot (item's category)
    → If slot is occupied → Call UnequipItem (current slot)
    → SetItemEquippedFlag (true)
    → Add to EquippedItems map
    → ApplyEquipmentVisual (slot, item)
    → RecalculateModifiers
    → Broadcast OnItemEquipped
    → Broadcast OnEquipmentChanged
    → Return Success

UnequipItem (Slot)
    → CanUnequipSlot → If fail → return BlockedByState
    → Get ItemID from EquippedItems (Slot)
    → Get item from inventory by ItemID
    → SetItemEquippedFlag (false)
    → Remove from EquippedItems map
    → RemoveEquipmentVisual (Slot)
    → RecalculateModifiers
    → Broadcast OnItemUnequipped
    → Broadcast OnEquipmentChanged
    → Return Success

ApplyEquipmentVisual (Slot, Item)
    → Get SocketName from SlotDefinitions for this slot
    → If item has skeletal mesh → SpawnAttached SkeletalMeshComponent to socket
    → If item has static mesh → SpawnAttached StaticMeshComponent to socket
    → Store reference in VisualAttachments

RemoveEquipmentVisual (Slot)
    → If VisualAttachments contains slot → Destroy attached component
    → Remove from VisualAttachments map

RecalculateModifiers
    → Zero out all modifier fields
    → For each equipped item:
        → Read modifiers from DA_ItemData.EquipmentModifiers
        → Sum each field into ActiveModifiers
    → Broadcast OnEquipmentChanged
```

---

## 8. Replication

| Variable | Replication | Callback |
|----------|-------------|----------|
| `EquippedItems` | `RepNotify` | `OnRep_EquippedItems` — rebuilds visuals on remote |
| `ActiveModifiers` | `Replicated` | — |

**Authority:** Server validates all equip/unequip operations. Client predicts input; server broadcasts authoritative state.

---

## 9. Dependencies & Communication

| System | Relationship |
|--------|--------------|
| `BPC_InventorySystem` | Source of item data; sets/reads `bIsEquipped` flag. |
| `BPC_ActiveItemSystem` | Automatically updates quick slots when equipment changes. |
| `BPC_HealthSystem` | Reads `ActiveModifiers.DefenseBonus` for damage calculations. |
| `BPC_StaminaSystem` | Reads `ActiveModifiers.StaminaDrainModifier`. |
| `BPC_MovementStateSystem` | Reads `ActiveModifiers.MoveSpeedModifier`. |
| `BPC_StressSystem` | Reads `ActiveModifiers.StressResistanceModifier`. |
| `BPC_CameraStateLayer` | May adjust camera based on head equipment (e.g., night vision overlay). |
| `BPC_InteractionDetector` | Reads `ActiveModifiers.SensoryRangeModifier` for detection range. |
| `BP_PlayerCharacter` (Skeletal Mesh) | Provides sockets for equipment visual attachment. |
| `Save/Load System` | Serializes `EquippedItems` for restore. |
| `UI (WBP_InventoryMenu)` | Subscribes to all dispatchers for visual updates. |

---

## 10. Success Criteria

1. Item equip swaps into slot; old item is unequipped automatically.
2. Unequipped item stays in inventory, not lost.
3. Modifiers are correctly summed from all equipped items.
4. Visual meshes attach to the correct character sockets.
5. Equipping a helmet with night vision applies the camera overlay.
6. Carrying a backpack increases max carry weight.
7. Equipping armor reduces incoming damage.
8. Multiplayer: visual equipment and modifiers sync to remote clients.
9. Save/load restores equipped state.
10. Auto-equip on pickup works for configured item categories.

---

## 11. Data Flow Summary

```
Player equips armor vest from inventory
    → BPC_EquipmentSlotSystem.EquipItem (item ID, Torso slot)
    → Validate (not occupied? category matches?)
    → Set inventory entry bIsEquipped = true
    → Add to EquippedItems map
    → Attach vest skeletal mesh to Torso socket
    → RecalculateModifiers → DefenseBonus, MoveSpeed, etc.
    → Broadcast OnItemEquipped, OnEquipmentChanged
    → BPC_HealthSystem reads new DefenseBonus
    → BPC_MovementStateSystem reads new MoveSpeed
    → UI updates equipment panel
```

## 12. Reuse Notes

- Renamed from `BPC_EquipmentSystem` to `BPC_EquipmentSlotSystem` per Master naming convention.
- Cross-references updated: `BPC_InventoryComponent` → `BPC_InventorySystem`, `BPC_InventoryQuickSlot` → `BPC_ActiveItemSystem`, `BPC_InventoryWeightSystem` → `BPC_ActiveItemSystem`.