# 04 — Inventory, Items & Collectibles Systems (Systems 24-34) **Category Purpose:** These 11 systems form the complete inventory management layer — core item storage grid, world containers, item pickups, consumable usage, equipment slots, item combination/crafting, key item tracking, document archiving, quick slots, journal tracking, and collectible progression. The `BPC_InventorySystem` is the single source of truth for all item data; every other inventory subsystem reads from and writes through it. **C++ Status:** System 31 (`BPC_InventorySystem`) is a full C++ implementation (`Source/PG_Framework/Public/Inventory/BPC_InventorySystem.h`) with native-speed TArray operations, auto-stacking, and weight tracking. System 07 (`DA_ItemData`) is also full C++. System 120 (`DA_EquipmentConfig`) is a C++ stub. All other inventory systems are BP-only. --- ## System Index | # | System | Asset Type | Role | |---|--------|-----------|------| | 24 | `BPC_ContainerInventory` | Component | World container inventory (chests, drawers, safes) | | 25 | `BP_ItemPickup` | Actor | Physical item pickup in world with bob/rotate effects | | 26 | `BPC_ActiveItemSystem` | Component | Quick-slot item management; contextual item use | | 27 | `BPC_CollectibleTracker` | Component | Collectible tracking, found count, set bonuses | | 28 | `BPC_ConsumableSystem` | Component | Consumable use (health packs, syringes, buffs) | | 29 | `BPC_DocumentArchiveSystem` | Component | Document/journal archive; read, categorize, flag | | 30 | `BPC_EquipmentSlotSystem` | Component | Equipment slots (weapon, armor, tool); equip/unequip | | 31 | `BPC_InventorySystem` | Component | **Core inventory grid** — add/remove/sort/stack/weight | | 32 | `BPC_ItemCombineSystem` | Component | Item combination crafting; recipe validation | | 33 | `BPC_JournalSystem` | Component | Quest/objective journal; active, completed, failed | | 34 | `BPC_KeyItemSystem` | Component | Key item tracking; use-on-target, consumed-on-use | --- ## Category Data Flow ``` ┌──────────────────────────────────────────────────────────────────────┐ │ INVENTORY ECOSYSTEM │ │ │ │ BPC_InventorySystem (CENTRAL AUTHORITY) │ │ │ Array of S_InventorySlot → each holds S_InventoryEntry │ │ │ Operations: AddItem, RemoveItem, UseItem, DropItem, │ │ │ TransferItem, MoveItem, SplitStack, SortInventory │ │ │ │ │ ├─► OnInventoryChanged → ALL other inventory systems react │ │ │ │ │ ├─► BPC_ActiveItemSystem (quick slots) │ │ │ └─► Routes equip/use to EquipmentSlotSystem or Consumable │ │ │ │ │ ├─► BPC_EquipmentSlotSystem (equip/unequip) │ │ │ └─► Validates slot type, notifies BP_WeaponBase │ │ │ │ │ ├─► BPC_ConsumableSystem (use health/stamina/stress items) │ │ │ └─► Calls BPC_HealthSystem.ApplyHealing() etc. │ │ │ │ │ ├─► BPC_ItemCombineSystem (crafting) │ │ │ └─► Reads DA_ItemData.CombinesWith/CombineResult │ │ │ │ │ ├─► BPC_KeyItemSystem (key item use-on-target) │ │ │ └─► Checks I_Lockable on target, consumes key if matching │ │ │ │ │ ├─► BPC_DocumentArchiveSystem (reading documents) │ │ ├─► BPC_JournalSystem (quest tracking) │ │ ├─► BPC_CollectibleTracker (completion tracking) │ │ │ │ │ External interactions: │ │ BP_ItemPickup ←── player picks up → BPC_InventorySystem.AddItem │ │ BPC_ContainerInventory ←── looting → transfer between inventories │ │ BPC_InventorySystem.DropItem → spawns BP_ItemPickup in world │ └──────────────────────────────────────────────────────────────────────┘ ``` --- ## 31 — BPC_InventorySystem: Core Inventory Grid **What It Does:** The central inventory authority on the player. Stores all items as an array of `S_InventorySlot` structs, each potentially containing an `S_InventoryEntry` with a reference to `DA_ItemData` plus runtime state (stack count, durability, custom metadata). All other inventory subsystems read from this component as their single source of truth. **How It Works Internally:** **Core Data Structures:** - `S_InventorySlot`: SlotIndex, Entry (S_InventoryEntry), bIsLocked, bIsQuickSlot, CategoryRestriction - `S_InventoryEntry`: ItemData (DA_ItemData*), ItemID (FGuid unique), StackCount, MaxStackSize, Durability, CustomTags, CustomData, SlotIndex, bIsEquipped - Slots array is the authoritative item list **Operation Validation (every add/remove is validated):** - `ValidateAddItem`: checks free slots, weight capacity (`TotalWeight + new weight <= MaxWeightCapacity`), category restrictions - `ValidateRemoveItem`: checks item exists, sufficient quantity - Returns `E_InventoryOperationResult`: Success, InventoryFull, ItemNotFound, StackLimitReached, InsufficientQuantity, ItemNotUsable, CategoryRestricted, WeightCapacityExceeded **Add Item Flow:** 1. `FindExistingStack()` — same ItemData, below MaxStackSize → increment stack 2. If overflow: `FindFreeSlot()` for remainder 3. If no existing stack: `FindFreeSlot()`, create new `S_InventoryEntry` 4. `RecalculateWeight()`, fire `OnItemAdded` + `OnInventoryChanged` **Remove Item Flow:** 1. Decrement stack count by Quantity 2. If stack <= 0: `ClearSlot()` 3. `RecalculateWeight()`, fire `OnItemRemoved` + `OnInventoryChanged` **Use Item Flow:** 1. Check cooldown (per-item cooldown map) 2. Check `bIsUsable` from DA_ItemData 3. Fire `OnItemUsed` → consumer systems react (health pack → heal, etc.) 4. If consumable: reduce stack, clear slot if 0 **Drop Item Flow:** 1. Remove item from inventory 2. Spawn `BP_ItemPickup` at world location with correct ItemData and StackCount 3. Fire `OnItemDropped` **Transfer Item Flow (between inventories):** 1. Validate source has item, target has space 2. Remove from source, add to target 3. Fire `OnItemTransferred` **Sort Modes:** ByName, ByCategory, ByRarity, ByWeight, ByQuantity, ByRecent **Weight System:** - `RecalculateWeight()` iterates all slots, sums `ItemData.Weight * StackCount` - `bIsOverEncumbered = TotalWeight > MaxWeightCapacity` - `OnOverEncumberedStateChanged` fires on threshold crossing **Replication:** Slots array replicated with `RepNotify` → `OnRep_Slots` refreshes UI and recalculates weight **Implementation Patterns:** - Stack split: creates new slot from partial stack - Stack combine: merges two same-item slots into one (capped at MaxStackSize) - `HasItemQuantity(Tag)` returns total count matching a tag across all slots - `FindAllItemsByCategory/Tag` for filtered queries - Cooldowns managed locally (not replicated), validated server-side **Integration Points:** - **Broadcasts:** `OnInventoryChanged`, `OnItemAdded/Removed/Used/Dropped/Transferred`, `OnOverEncumberedStateChanged`, `OnInventoryFull` - **Read by:** Every other inventory subsystem, `WBP_InventoryMenu`, `BPC_InteractionDetector` (pickup routing), Save System --- ## 24 — BPC_ContainerInventory: World Container Storage **What It Does:** Provides inventory storage for world actors (crates, cabinets, corpses, safes). Uses the same `S_InventorySlot` structs as `BPC_InventorySystem` but operates standalone — interacted with via `BPC_InteractionDetector`, transfers items to/from the player's inventory. **Fill Methods:** - `Fixed`: designer-defined contents via Data Asset - `LootTable`: randomly generated from weighted loot table - `Empty`: starts empty, filled by designer or player - `PlayerStored`: safe storage that persists **Key Features:** - Lock states: Unlocked, Locked, Jammed, KeyRequired, PuzzleRequired - Loot rarity tiers: Trash, Common, Uncommon, Rare, Legendary - `GenerateLoot()`: rolls weighted random selection, respects rarity filters - Respawn timer: refills after `RespawnTimeHours` - Decay timer: clears items after `DecayTimeHours` - Implements `I_Interactable` and `I_Persistable` **Interaction Flow:** 1. Player interacts → `OpenContainer()`, validates distance/lock/alive 2. UI opens showing container slots 3. Player clicks: `RemoveItemFromContainer()` transfers to player inventory 4. Player places: `AddItemToContainer()` transfers from player inventory 5. `CloseContainer()` → if empty, mark `bIsLooted`, start respawn/decay timers --- ## 25 — BP_ItemPickup: World Item Pickup Actor **What It Does:** A world-placed or runtime-spawned actor representing an item to pick up. Implements `I_Interactable` and optionally `I_Persistable`. Handles visual effects (bobbing, rotating), pickup animation, inventory transfer, and respawn. **Visual States:** Idle (floating/rotating) → Highlighted (within range, glowing outline) → BeingPickedUp (pickup animation) → Respawning (hidden during cooldown) **Spawn Reasons:** PlacedInLevel, DroppedFromInventory, LootDrop, QuestReward **Pickup Flow:** 1. Player overlaps interaction sphere → highlight, show prompt widget 2. Player leaves → unhighlight, hide prompt 3. Player interacts → validate availability + inventory space 4. Call `BPC_InventorySystem.AddItem(ItemData, Quantity)` 5. Play pickup sound + particle 6. If succeeded: broadcast `OnPickupCollected` 7. If infinite: don't destroy; if respawns: start timer; else: destroy **Drop from Inventory:** - Called by `BPC_InventorySystem.DropItem` - Sets transform, optionally applies physics velocity - Configures respawn behavior --- ## 28 — BPC_ConsumableSystem: Consumable Usage **What It Does:** Handles consumable item usage — health packs, stamina boosters, temporary buffs. Reads from `BPC_InventorySystem` when `OnItemUsed` fires for consumable items, applies effects through relevant player systems. **Key Features:** - Global cooldown between consumable uses - `ActiveBuffs` array tracks temporary buffs with durations - `TickBuffs()` decrements durations, removes expired, fires `OnBuffExpired` - Buff types affect: Health, Stamina, Speed, Stress, Damage - All effects data-driven via `DA_ItemData.ConsumableData` **Integration:** Calls `BPC_HealthSystem.ApplyHealing()`, `BPC_StaminaSystem.RestoreStamina()`, `BPC_StressSystem.RemoveStress()` based on item data. --- ## 30 — BPC_EquipmentSlotSystem: Equipment Slots **What It Does:** Manages equipment slots (primary weapon, secondary weapon, flashlight, shield, armor, tool). Validates equip/unequip operations against slot type restrictions and coordinates with `BP_WeaponBase` for visual attachment. **Key Features:** - Slot types mapped to body sockets (equip socket, holster socket) - Validation: slot type must match item's EquipmentData.SlotType - Unequip returns item to inventory; equip removes from inventory slot - `bIsEquipped` flag on inventory entry tracked - Notifies animation system for equip/holster montages --- ## 32 — BPC_ItemCombineSystem: Item Crafting **What It Does:** Handles item combination/crafting. Two items can be combined if one's `CombinesWith` array contains the other's ItemTag, producing the item specified in `CombineResult`. **Flow:** 1. Player selects two items in inventory UI 2. System checks: does ItemA.CombinesWith contain ItemB.ItemTag? (or vice versa) 3. If valid: remove both source items, add CombineResult item 4. Fire `OnItemsCombined` dispatcher --- ## 26, 27, 29, 33, 34 — Supporting Subsystems - **26 BPC_ActiveItemSystem:** Quick-slot hotbar mapping. Manages which items are on quick slots (1-4), routes quick-use to correct system (equip weapon, use consumable). - **27 BPC_CollectibleTracker:** Tracks found collectibles, fires dispatchers on set completion, unlocks rewards at milestones. - **29 BPC_DocumentArchiveSystem:** Stores read documents, categorizes them, allows flagging as important, supports re-reading. - **33 BPC_JournalSystem:** Quest/objective journal separate from inventory. Tracks active, completed, and failed objectives independently. - **34 BPC_KeyItemSystem:** Key items that can be used on locked targets. Checks `I_Lockable` on target, consumes key if matching `RequiredKeyTag`. --- ## Common Implementation Patterns in This Category 1. **Central Authority Pattern:** `BPC_InventorySystem` is the single source of truth. All additions, removals, and modifications go through it. Subsystems read and react to its dispatchers. 2. **Data-Driven Items:** All item properties live in `DA_ItemData` Data Assets. Changing an item's behavior never requires Blueprint edits. 3. **Stack Management:** Duplicate items automatically stack to `MaxStackSize`; overflow creates new slots. 4. **Validation Before Action:** Every operation validates capacity, weight, stack limits, and category restrictions before executing. 5. **Dispatcher Cascade:** `OnInventoryChanged` fires on any modification → UI updates, weight recalculates, metrics log, save system marks dirty. 6. **Weight as Soft Limit:** Over-encumbered is a state flag, not a hard block — systems can choose to penalize movement or block sprinting. --- ## Multiplayer Networking ### Category Authority Map | System | Authority | Anti-Cheat | |--------|-----------|------------| | `BPC_InventorySystem` | Server-authoritative add/remove/use/drop | Server validates slot space, weight, stack limits | | `BPC_ContainerInventory` | Server-authoritative open/loot/transfer | Server validates distance, lock, slot availability | | `BP_ItemPickup` | Server-authoritative pickup | Server validates inventory space before removing pickup | | `BPC_EquipmentSlotSystem` | Server-authoritative equip/unequip | Server validates slot type compatibility | | `BPC_ConsumableSystem` | Server-authoritative use | Server validates item exists, cooldown, applies effect | | `BPC_ItemCombineSystem` | Server-authoritative combine | Server validates recipe from DA_ItemData | ### Server RPCs - `Server_AddItem`, `Server_RemoveItem`, `Server_UseItem`, `Server_DropItem`, `Server_TransferItem` - `Server_EquipItem`, `Server_UnequipItem` - `Server_LootContainer`, `Server_PickupItem` ### Inventory Replication Strategy - **Slots array** replicated with `OnRep_Slots` → recalculates weight, fires `OnInventoryChanged` - **Client predicts UI** (item moves visually on drag-drop); server validates and corrects via OnRep - **Server validates all transactions** against slot space, weight capacity, stack limits, and category restrictions - **Cooldowns** managed locally (not replicated) but validated on server for authoritative actions --- *Developer Reference v1.0 — 04 Inventory Systems. Companion to docs/blueprints/04-inventory/ specs.*