InventorySlot.cs
using Sandbox;
using System;
public class InventorySlot
{
/// <summary>The item in this slot, or null if empty.</summary>
public InventoryItem Item { get; private set; }
/// <summary>How many of the item are in this slot.</summary>
public int Quantity { get; private set; }
/// <summary>Current durability. -1 means durability is not tracked for this slot.</summary>
public float Durability { get; set; } = -1f;
/// <summary>True if the slot has no item or zero quantity.</summary>
public bool IsEmpty => Item == null || Quantity <= 0;
/// <summary>
/// Add items to this slot. Returns leftover amount that didn't fit.
/// If the slot is empty it initialises with the given item.
/// </summary>
public int Add( InventoryItem item, int amount = 1 )
{
if ( IsEmpty )
{
Item = item;
Quantity = 0;
Durability = item.MaxDurability > 0 ? item.MaxDurability : -1f;
}
if ( Item != item ) return amount;
int canFit = Item.MaxStack - Quantity;
int toAdd = Math.Min( canFit, amount );
Quantity += toAdd;
return amount - toAdd;
}
/// <summary>Remove the given amount from this slot. Clears the slot if quantity reaches zero.</summary>
public void Remove( int amount = 1 )
{
Quantity = Math.Max( 0, Quantity - amount );
if ( Quantity == 0 )
{
Item = null;
Durability = -1f;
}
}
/// <summary>Clears the slot, removing the item and resetting durability.</summary>
public void Clear()
{
Item = null;
Quantity = 0;
Durability = -1f;
}
/// <summary>
/// Set the slot to a specific item and quantity.
/// Durability defaults to the item's MaxDurability when not provided.
/// </summary>
public void Set( InventoryItem item, int quantity, float durability = -1f )
{
Item = item;
Quantity = quantity;
Durability = durability >= 0 ? durability
: item?.MaxDurability > 0 ? item.MaxDurability
: -1f;
}
/// <summary>
/// Serialize to a string for network sync.
/// Format: "resourcepath:quantity[:durability]" or "" if empty.
/// </summary>
public string Serialize()
{
if ( IsEmpty ) return "";
if ( Durability >= 0 )
return $"{Item.ResourcePath}:{Quantity}:{Durability:F0}";
return $"{Item.ResourcePath}:{Quantity}";
}
/// <summary>Restore slot state from a serialized string.</summary>
public void Deserialize( string data )
{
if ( string.IsNullOrEmpty( data ) )
{
Clear();
return;
}
var parts = data.Split( ':' );
if ( parts.Length < 2 ) { Clear(); return; }
var item = ResourceLibrary.Get<InventoryItem>( parts[0] );
if ( item == null ) { Clear(); return; }
if ( !int.TryParse( parts[1], out int qty ) ) { Clear(); return; }
float dur = -1f;
if ( parts.Length >= 3 )
float.TryParse( parts[2], out dur );
Set( item, qty, dur );
}
}