using System; using System.Collections.Generic; using RebootKit.Engine.Foundation; namespace RebootReality.jelycho.Items { public class Inventory { static readonly Logger s_Logger = new Logger(nameof(Inventory)); class ItemState { public List Actors = new List(); } readonly ItemState[] m_Items; public event Action OnItemPickedUp = delegate { }; public event Action OnItemDropped = delegate { }; public event Action OnSlotUpdated = delegate { }; public int SlotsCount { get { return m_Items.Length; } } public Inventory(int slotsCount) { m_Items = new ItemState[slotsCount]; for (int i = 0; i < slotsCount; i++) { m_Items[i] = new ItemState(); } } public bool TryPickup(ItemActor actor) { if (Contains(actor)) { s_Logger.Error($"Item {actor.name} is already in the inventory."); return false; } (int slotIndex, ItemState freeItemState) = FindFreeItemState(); if (freeItemState == null) { s_Logger.Error("Inventory is full, cannot pick up item."); return false; } freeItemState.Actors.Add(actor); OnItemPickedUp?.Invoke(actor); OnSlotUpdated?.Invoke(slotIndex); return true; } public bool TryDrop(ItemActor actor) { for (int i = 0; i < m_Items.Length; i++) { if (m_Items[i].Actors.Remove(actor)) { OnItemDropped?.Invoke(actor); OnSlotUpdated?.Invoke(i); return true; } } s_Logger.Error($"Item {actor.name} is not in the inventory."); return false; } public ItemActor TryDropOne(int slotIndex) { if (slotIndex < 0 || slotIndex >= m_Items.Length) { s_Logger.Error($"Slot index {slotIndex} is out of range."); return null; } if (m_Items[slotIndex].Actors.Count == 0) { s_Logger.Error($"No items in slot {slotIndex} to drop."); return null; } ItemActor actor = m_Items[slotIndex].Actors[0]; m_Items[slotIndex].Actors.RemoveAt(0); OnItemDropped?.Invoke(actor); OnSlotUpdated?.Invoke(slotIndex); return actor; } public int GetQuantity(int slotIndex) { if (slotIndex < 0 || slotIndex >= m_Items.Length) { throw new ArgumentOutOfRangeException(nameof(slotIndex), "Slot index is out of range."); } return m_Items[slotIndex].Actors.Count; } public ItemActor GetFirstItem(int slotIndex) { if (slotIndex < 0 || slotIndex >= m_Items.Length) { throw new ArgumentOutOfRangeException(nameof(slotIndex), "Slot index is out of range."); } if (m_Items[slotIndex].Actors.Count > 0) { return m_Items[slotIndex].Actors[0]; } return null; } public bool Contains(ItemActor actor) { for (int i = 0; i < m_Items.Length; i++) { if (m_Items[i].Actors.Contains(actor)) { return true; } } return false; } (int, ItemState) FindFreeItemState() { for (int i = 0; i < m_Items.Length; i++) { if (m_Items[i].Actors.Count == 0) { return (i, m_Items[i]); } } return (-1, null); } } }