namespace Ashwild.Inventory { /// /// A single inventory cell: the item it holds, how many, and — for items that track uses /// (tool durability, multi-bite food) — the remaining uses of this specific instance. Items /// with uses never stack, so a slot's uses always describe one concrete instance. /// [System.Serializable] public class InventorySlot { private ItemData itemData; private int quantity; private int currentUses; public ItemData ItemData => itemData; public int Quantity => quantity; public int CurrentUses => currentUses; public bool IsEmpty => itemData == null; /// /// Whether this slot holds a uses-tracked item whose uses have run out — kept in the /// inventory (shown red and unusable) when the item is not destroyed on depletion. /// public bool IsDepleted => itemData != null && itemData.HasUses && currentUses <= 0; /// /// Places an item in the slot, resetting its uses to full for uses-tracked items. /// public void Set(ItemData data, int qty) { itemData = data; quantity = qty; currentUses = (data != null && data.HasUses) ? data.MaxUses : 0; } /// /// Places an item with an explicit remaining-uses value, used when restoring a partially /// used instance (e.g. picking a dropped tool back up). A negative value means "full". /// public void Set(ItemData data, int qty, int uses) { itemData = data; quantity = qty; if (data != null && data.HasUses) currentUses = uses < 0 ? data.MaxUses : uses; else currentUses = 0; } public void Clear() { itemData = null; quantity = 0; currentUses = 0; } public void RemoveQuantity(int amount) { quantity -= amount; if (quantity <= 0) Clear(); } /// /// Spends uses on this instance (a tool hit, a food bite), clamped at 0. Has no effect on /// items that do not track uses. /// public void ConsumeUse(int amount = 1) { if (itemData == null || !itemData.HasUses) return; currentUses -= amount; if (currentUses < 0) currentUses = 0; } /// /// Uses-tracked items are non-stackable, so they never merge into an existing slot — /// every instance keeps its own uses bar. /// public bool CanAccept(ItemData data) { if (IsEmpty) return true; if (data != null && data.HasUses) return false; return itemData == data && itemData.IsStackable && quantity < itemData.MaxStackSize; } } }