Files
Emberwild/Assets/GAME/Script/Inventory/InventorySlot.cs
T
2026-06-25 14:40:21 +02:00

99 lines
3.3 KiB
C#

namespace Ashwild.Inventory
{
/// <summary>
/// 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.
/// </summary>
[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;
/// <summary>
/// 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.
/// </summary>
public bool IsDepleted => itemData != null && itemData.HasUses && currentUses <= 0;
/// <summary>
/// Places an item in the slot, resetting its uses to full for uses-tracked items.
/// </summary>
public void Set(ItemData data, int qty)
{
itemData = data;
quantity = qty;
currentUses = (data != null && data.HasUses) ? data.MaxUses : 0;
}
/// <summary>
/// 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".
/// </summary>
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 int AddQuantity(int amount)
{
if (itemData == null || !itemData.IsStackable || itemData.HasUses)
return amount;
int space = itemData.MaxStackSize - quantity;
int toAdd = amount < space ? amount : space;
quantity += toAdd;
return amount - toAdd;
}
public void RemoveQuantity(int amount)
{
quantity -= amount;
if (quantity <= 0)
Clear();
}
/// <summary>
/// Spends uses on this instance (a tool hit, a food bite), clamped at 0. Has no effect on
/// items that do not track uses.
/// </summary>
public void ConsumeUse(int amount = 1)
{
if (itemData == null || !itemData.HasUses) return;
currentUses -= amount;
if (currentUses < 0) currentUses = 0;
}
/// <summary>
/// Uses-tracked items are non-stackable, so they never merge into an existing slot —
/// every instance keeps its own uses bar.
/// </summary>
public bool CanAccept(ItemData data)
{
if (IsEmpty) return true;
if (data != null && data.HasUses) return false;
return itemData == data && itemData.IsStackable && quantity < itemData.MaxStackSize;
}
}
}