Equipment
UPulseEquipmentComponent (module PulseInventory, no GAS) gives a character equipment slots: armor, two hands and a hotbar. Equipping takes an item stack out of an inventory, with its instance traits (durability, rolled stats), and puts it into a slot; unequipping puts it back.
Setup
- Add Pulse Equipment to an actor the player owns (pawn, controller or player state), next to the inventory.
- Check the Slots. The default has
Pulse.Equipment.Slot.Head,.Chest,.Legs,.Feet,.Hands,.MainHand,.OffHandandPulse.Equipment.Hotbar.1to.8. Add own slots belowPulse.Equipment.SlotorPulse.Equipment.Hotbar;ItemQuerylimits a slot by the tags of the item definitions. - Give equippable items the trait Equippable (
FPulseItemTrait_Equippable):Slots: the slots the item fits. A parent tag covers all slots below it (Pulse.Equipment.Hotbar= every hotbar slot); empty = every slot whose query accepts it.AttachMeshorAttachActorClasswithAttachSocket/AttachOffset: the look while equipped, on the component taggedEquipmentMesh, else the first skeletal mesh, else the root. Shown on every machine, not replicated (an attached actor exists on the server too, e.g. for weapon sockets).bShowOnlyWhenActive: in a hotbar slot only shown while it is the active slot.
Using it
| Function | Where | Does |
|---|---|---|
EquipFromInventory(Inventory, ItemId, Slot) | authority | Equips a stack; an item already in the slot goes back into the inventory (the new item’s cells count as free). All or nothing: without room for the whole old stack nothing changes (NoSpace). Empty slot = first fitting free slot. |
EquipItem(Definition, Count, Traits, Slot, ReturnInventory) | authority | New item into a slot (starting gear, rewards). An item already in the slot goes completely into ReturnInventory, or nothing changes (NoSpace; Occupied without ReturnInventory). |
Unequip(Slot, Inventory) | authority | Back into the inventory, all or nothing: a stack that only partly fits stays equipped completely (NoSpace). |
ConsumeEquippedItem(Slot, Count) | authority | Uses up items of a stack (ammunition, bombs in the hotbar). |
SetEquippedItemTrait(Slot, Trait) | authority | Changes an instance trait of an equipped item (durability). |
SelectHotbarSlot(Slot) | authority | The active hotbar slot (also empty: empty hands). |
RequestEquip, RequestUnequip, RequestSelectHotbarSlot, RequestCycleHotbar | any machine | Client requests go to the server (RPC on the component). The server checks CanRequesterModify of the inventory. |
bAutoSelectHotbar selects the first hotbar item when nothing is active.
Rules as data (C++)
Every change of the equipment is a plan (Equipment/PulseEquipmentState.h, namespace Pulse::Inventory::Equipment): FPulseEquipmentState is the equipment as one value, FPulseEquipmentView what the rules read (GetView). PlanEquip, PlanEquipNew, PlanUnequip and PlanConsume make an FPulseEquipmentPlan with the equipment steps and the inventory side (the stack that leaves or enters the inventory, planned on the inventory as it will be). UPulseInventoryComponent::ApplyTogether validates the inventory plan and the equipment plan, applies both and only then fires the events (inventory first, then equipment), so inventory listeners already see the new item equipped. The equipment events of the operation are held until its inventory events have fired: equipment changes that inventory listeners make (an unequip, a consumed stack) fire after them, also when the operation itself runs inside an inventory listener. Equipment::ValidatePlan and Equipment::ApplyPlan return an EPulseEquipmentResult; Equipment::ToEquipmentResult / ToInventoryResult are the one mapping between the two result types (Success and NoAuthority stay, everything else is InvalidItem).
Events
OnEquipped, OnUnequipped, OnEquippedItemChanged (count or traits) and OnActiveSlotChanged, native and dynamic, on every machine. Message bus: Pulse.Message.Inventory.Equipment.Equipped, .Unequipped, .ActiveSlotChanged (payload FPulseEquipmentMessage; the context names the owner as Target, as Player when it is a player’s actor, the item definition as Source with its tags, and the stack count as Amount). Other modules build on these events: stats while equipped (PulseInventoryEffects) and weapons (PulseCombatInventory).
Saving
ExportSaveData / ImportSaveData and SaveToBytes / LoadFromBytes (versioned) save the equipped items with their persisted instance traits and the active slot. Items are saved by their id with the path as fallback (see Inventory system; data version 2). An import is one step with its events afterwards; a second item saved for the same slot is skipped with a message. A saved active slot that exists but is no hotbar slot is not selected and reported (the items still load). With PulseSave use UPulseSaveEquipmentComponent from PulseCoreSaveBridge.
Cheats
| Command | Does |
|---|---|
PulseInventoryGrant [size] | Gives the pawn an inventory and equipment (test pawns) |
PulseInventoryEquip [item\|any] [slot] | Equips an item of the inventory (slot by tag or last part: Head, 2) |
PulseInventoryUnequip <slot> | Puts the item back |
PulseInventoryHotbar <1-8\|next\|prev> | Selects a hotbar slot |
PulseInventoryEquipment | Prints the equipment |