Code/EquipmentSlots.cs
using Sandbox;
using System;
using System.Collections.Generic;
using System.Text;
/// <summary>
/// Manages named equipment slots (head, chest, weapon, etc.)
/// Each EquipSlot enum value that isn't None gets one slot.
/// </summary>
public class EquipmentSlots
{
private readonly Dictionary<EquipSlot, InventorySlot> _slots = new();
public EquipmentSlots()
{
// Create one slot for every equip slot type except None
foreach ( EquipSlot slotType in Enum.GetValues( typeof( EquipSlot ) ) )
{
if ( slotType == EquipSlot.None ) continue;
_slots[slotType] = new InventorySlot();
}
}
/// <summary>Returns the InventorySlot for the given equipment slot type, or null if not found.</summary>
public InventorySlot GetSlot( EquipSlot slotType )
=> _slots.TryGetValue( slotType, out var slot ) ? slot : null;
/// <summary>Returns true if the given equipment slot is empty or doesn't exist.</summary>
public bool IsSlotEmpty( EquipSlot slotType )
=> GetSlot( slotType )?.IsEmpty ?? true;
/// <summary>
/// Equip an item into its designated slot.
/// Returns the item that was previously in that slot (if any), or null.
/// </summary>
public InventoryItem Equip( InventoryItem item )
{
if ( item == null || item.EquipSlot == EquipSlot.None ) return null;
var slot = GetSlot( item.EquipSlot );
if ( slot == null ) return null;
// Grab whatever was there before
var previous = slot.IsEmpty ? null : slot.Item;
slot.Clear();
slot.Set( item, 1 );
return previous;
}
/// <summary>
/// Unequip whatever is in the given slot. Returns the item, or null if empty.
/// </summary>
public InventoryItem Unequip( EquipSlot slotType )
{
var slot = GetSlot( slotType );
if ( slot == null || slot.IsEmpty ) return null;
var item = slot.Item;
slot.Clear();
return item;
}
/// <summary>Iterates over all equipment slot key-value pairs.</summary>
public IEnumerable<KeyValuePair<EquipSlot, InventorySlot>> AllSlots()
=> _slots;
// ─── Network Serialization ───────────────────────────────────
/// <summary>
/// Format: "Head=item/path:1|Chest=item/path:1|..."
/// </summary>
public string Serialize()
{
var sb = new StringBuilder();
bool first = true;
foreach ( var kvp in _slots )
{
if ( !first ) sb.Append( '|' );
first = false;
sb.Append( kvp.Key.ToString() );
sb.Append( '=' );
sb.Append( kvp.Value.Serialize() );
}
return sb.ToString();
}
public void Deserialize( string data )
{
// Clear all first
foreach ( var slot in _slots.Values )
slot.Clear();
if ( string.IsNullOrEmpty( data ) ) return;
foreach ( var entry in data.Split( '|' ) )
{
var parts = entry.Split( '=' );
if ( parts.Length != 2 ) continue;
if ( Enum.TryParse<EquipSlot>( parts[0], out var slotType )
&& _slots.TryGetValue( slotType, out var slot ) )
{
slot.Deserialize( parts[1] );
}
}
}
}