# BPC_ActiveItemSystem — Active Item System **Parent Class:** `ActorComponent` **Category:** Inventory **Target UE Version:** 5.5–5.7 **Build Phase:** 3 — Inventory --- ## 1. Overview `BPC_ActiveItemSystem` manages the player's currently selected/active item and quick slot assignments. It reads from [`BPC_InventorySystem`](BPC_InventorySystem.md) and maps up to 8 quick slots to inventory items, handling hotkey input, item switching, and active item context (usable, throwable, consumable). --- ## 2. Enums ### `E_QuickSlot` | Value | Description | |-------|-------------| | `Slot_1` | Hotkey 1 | | `Slot_2` | Hotkey 2 | | `Slot_3` | Hotkey 3 | | `Slot_4` | Hotkey 4 | | `Slot_5` | Hotkey 5 | | `Slot_6` | Hotkey 6 | | `Slot_7` | Hotkey 7 | | `Slot_8` | Hotkey 8 | --- ## 3. Variables | Variable | Type | Description | |----------|------|-------------| | `QuickSlots` | `TMap` | Hotkey → Inventory Item ID mapping | | `ActiveSlot` | `E_QuickSlot` | Currently selected quick slot | | `ActiveItem` | `S_InventoryEntry` | Currently active item data | | `bHasActiveItem` | `bool` | An item is currently selected | | `bCanSwitchItems` | `bool` | Item switching allowed (not during anim) | | `SwitchCooldown` | `float` | Min time between item switches | --- ## 4. Functions | Function | Description | |----------|-------------| | `SetQuickSlot` | Assigns an inventory item to a quick slot | | `ClearQuickSlot` | Clears a quick slot assignment | | `SelectSlot` | Sets the active quick slot by key press | | `GetActiveItem` | Returns current `S_InventoryEntry` | | `UseActiveItem` | Uses/consumes the active item | | `CycleNextItem` | Selects the next populated quick slot | | `CyclePreviousItem` | Selects the previous populated quick slot | | `IsQuickSlotEmpty` | Returns true if quick slot has no item | | `GetQuickSlotItem` | Returns item in a specific quick slot | --- ## 5. Event Dispatchers | Dispatcher | Payload | Description | |------------|---------|-------------| | `OnActiveItemChanged` | `S_InventoryEntry NewItem`, `E_QuickSlot Slot` | Active item switched | | `OnQuickSlotAssigned` | `E_QuickSlot Slot`, `FGuid ItemID` | Item assigned to quick slot | | `OnQuickSlotCleared` | `E_QuickSlot Slot` | Quick slot cleared | | `OnActiveItemUsed` | `S_InventoryEntry Item` | Active item consumed | --- ## 6. Dependencies & Communication | System | Relationship | |--------|--------------| | `BPC_InventorySystem` | Reads inventory slots; source of truth for items | | `BPC_EquipmentSlotSystem` | Automatically updates quick slots on equipment change | | `WBP_HUDController` | Displays active item in HUD | | `BPC_HealthSystem` | Consumed health items trigger healing | --- ## 7. Reuse Notes - Quick slots are configurable per project (4-8 slots) - Active item system is the bridge between inventory data and gameplay input --- ## 8. Manual Implementation Guide ### 8.1 Class Setup 1. Create Blueprint Class: Parent = `ActorComponent`, Name = `BPC_ActiveItemSystem` 2. Add to Player Character 3. Quick slots map inventory ItemIDs (Guid) to hotkey numbers (1-8) ### 8.2 Variable Initialization (BeginPlay) ``` Event BeginPlay ├─ Set QuickSlots = empty Map ├─ Set ActiveSlot = Slot_1 ├─ Set ActiveItem = empty S_InventoryEntry ├─ Set bHasActiveItem = false ├─ Set bCanSwitchItems = true ├─ Set SwitchCooldown = 0.2 └─ Get Owner → Find Component by Class (BPC_InventorySystem) → Cache └─ Bind to OnInventoryChanged → RefreshActiveItem ``` ### 8.3 Function Implementations #### `SetQuickSlot(Slot: E_QuickSlot, ItemID: Guid)` → `void` ``` [Function: SetQuickSlot] Step 1: Add/Update QuickSlots map: QuickSlots.Add(Slot, ItemID) Step 2: If ActiveSlot == Slot → Refresh active item display Step 3: Fire OnQuickSlotAssigned(Slot, ItemID) ``` #### `ClearQuickSlot(Slot: E_QuickSlot)` → `void` ``` [Function: ClearQuickSlot] Step 1: QuickSlots.Remove(Slot) Step 2: If ActiveSlot == Slot: Set bHasActiveItem = false, ActiveItem = empty Fire OnActiveItemChanged(empty, Slot) Step 3: Fire OnQuickSlotCleared(Slot) ``` #### `SelectSlot(Slot: E_QuickSlot)` → `void` ``` [Function: SelectSlot] Step 1: Branch on bCanSwitchItems → If false, return (switching blocked during animation) Step 2: Get ItemID from QuickSlots[Slot] → if no entry, return Step 3: Get InventorySystem → Call GetItemById(ItemID) Step 4: If item found AND valid: Set ActiveSlot = Slot Set ActiveItem = found entry Set bHasActiveItem = true Fire OnActiveItemChanged(ActiveItem, Slot) Step 5: If item NOT found (was removed from inventory): Call ClearQuickSlot(Slot) — auto-clean stale slot ``` **Nodes:** `Map Find`, `GetItemById`, `Branch IsValid`, `Fire Event` #### `GetActiveItem()` → `S_InventoryEntry` *(Pure)* ``` [Function: GetActiveItem] Return ActiveItem ``` #### `UseActiveItem()` → `Boolean` ``` [Function: UseActiveItem] Step 1: Branch on bHasActiveItem → If false, return false Step 2: Get InventorySystem → Call UseItem(ActiveItem.SlotIndex) Step 3: Branch on result == Success: True → Fire OnActiveItemUsed(ActiveItem) → Return true False → Return false (item not usable, cooldown, etc.) ``` #### `CycleNextItem()` → `void` ``` [Function: CycleNextItem] Step 1: CurrentIndex = ActiveSlot (as int, 1-8) Step 2: Loop 8 times: NextIndex = (CurrentIndex + i) % 8 + 1 If NOT IsQuickSlotEmpty(NextIndex): Call SelectSlot(NextIndex) Return Step 3: No populated slots → do nothing ``` #### `CyclePreviousItem()` → `void` ``` [Function: CyclePreviousItem] Same as CycleNextItem but decrementing: NextIndex = (CurrentIndex - i + 7) % 8 + 1 ``` #### `IsQuickSlotEmpty(Slot: E_QuickSlot)` → `Boolean` ``` [Function: IsQuickSlotEmpty] If QuickSlots.Find(Slot) returns valid → Return false Return true ``` #### `RefreshActiveItem()` → `void` *(Called when inventory changes)* ``` [Function: RefreshActiveItem] Step 1: If NOT bHasActiveItem → Return Step 2: Get InventorySystem → GetItemAtSlot(ActiveItem.SlotIndex) Step 3: If item still exists AND same ItemID: Update ActiveItem (stack count may have changed) Fire OnActiveItemChanged(ActiveItem, ActiveSlot) Step 4: If item no longer exists: Set bHasActiveItem = false, ActiveItem = empty ClearQuickSlot(ActiveSlot) ``` ### 8.4 Event Dispatcher Bindings | Bind to Dispatcher | Custom Event | Logic | |-------------------|-------------|-------| | `BPC_InventorySystem.OnInventoryChanged` | `RefreshActiveItem` | Re-validate current active item exists | | `InputAction IA_Hotkey1` through `IA_Hotkey8` | `OnHotkeyPressed(Slot)` | Call SelectSlot corresponding slot | | `InputAction IA_NextItem` | `OnNextItem` | Call CycleNextItem | | `InputAction IA_PreviousItem` | `OnPreviousItem` | Call CyclePreviousItem | | `InputAction IA_UseItem` | `OnUseItem` | Call UseActiveItem | ### 8.5 Blueprint Build Checklist - [ ] Define E_QuickSlot enum (Slot_1 through Slot_8) - [ ] Create BPC_ActiveItemSystem, add to Player Character - [ ] Add variables: QuickSlots (Map), ActiveSlot, ActiveItem, bHasActiveItem, bCanSwitchItems, SwitchCooldown - [ ] Implement SetQuickSlot/ClearQuickSlot for assignment - [ ] Implement SelectSlot with validity check and stale cleanup - [ ] Implement UseActiveItem routing to InventorySystem.UseItem - [ ] Implement CycleNext/Previous with wrap-around - [ ] Create 8 Input Actions: IA_Hotkey1 through IA_Hotkey8 - [ ] Bind hotkey inputs + next/previous item cycling - [ ] Bind to OnInventoryChanged for auto-refresh - [ ] Test: assign item to slot 1 → press 1 to select → press Use to consume