using System; using System.Collections.Generic; using System.Text; using UnityEngine; public class Inventory : MonoBehaviour { public List slots = new List(); public int maxSlots = 32; public List testResources = new List(); public event Action OnInventoryChanged; public InventorySlot GetSlot(int index) { if (index < 0 || index >= slots.Count) { return null; } InventorySlot slot = slots[index]; return slot == null || slot.IsEmpty() ? null : slot; } public bool HasItem(ItemData item, int amount) { if (item == null || amount <= 0) { return false; } return GetItemAmount(item) >= amount; } public int GetItemAmount(ItemData item) { if (item == null) { return 0; } int total = 0; for (int i = 0; i < slots.Count; i++) { InventorySlot slot = slots[i]; if (slot != null && slot.item == item && slot.amount > 0) { total += slot.amount; } } return total; } public bool AddItem(ItemData item, int amount) { if (!CanAddItem(item, amount)) { return false; } AddItemInternal(item, amount); RaiseChanged(); return true; } public bool RemoveItem(ItemData item, int amount) { if (item == null || amount <= 0 || !HasItem(item, amount)) { return false; } int remaining = amount; for (int i = slots.Count - 1; i >= 0 && remaining > 0; i--) { InventorySlot slot = slots[i]; if (slot == null || slot.item != item || slot.amount <= 0) { continue; } int removed = Mathf.Min(slot.amount, remaining); slot.amount -= removed; remaining -= removed; if (slot.IsEmpty()) { slots.RemoveAt(i); } } RaiseChanged(); return true; } public bool RemoveFromSlot(int slotIndex, int amount) { InventorySlot slot = GetSlot(slotIndex); if (slot == null || amount <= 0 || slot.amount < amount) { return false; } slot.amount -= amount; if (slot.IsEmpty()) { slots.RemoveAt(slotIndex); } RaiseChanged(); return true; } public void Clear() { slots.Clear(); RaiseChanged(); } public void AddTestResources() { slots.Clear(); for (int i = 0; i < testResources.Count; i++) { InventorySlot resource = testResources[i]; if (resource != null && resource.item != null && resource.amount > 0) { AddItemInternal(resource.item, resource.amount); } } RaiseChanged(); } public string GetInventoryDebugText() { if (slots.Count == 0) { return "Инвентарь пуст"; } StringBuilder builder = new StringBuilder(); for (int i = 0; i < slots.Count; i++) { InventorySlot slot = slots[i]; if (slot == null || slot.IsEmpty()) { continue; } builder.AppendLine(slot.GetDisplayText()); } return builder.ToString(); } // Used by CraftingSystem to prevent losing ingredients when the result has no room. public bool CanAddItem(ItemData item, int amount) { if (item == null || amount <= 0) { return false; } int remaining = amount; int maxStack = Mathf.Max(1, item.maxStack); for (int i = 0; i < slots.Count; i++) { InventorySlot slot = slots[i]; if (slot != null && slot.item == item && slot.amount > 0 && slot.amount < maxStack) { remaining -= maxStack - slot.amount; if (remaining <= 0) { return true; } } } int freeSlots = Mathf.Max(0, maxSlots - slots.Count); int requiredSlots = Mathf.CeilToInt(remaining / (float)maxStack); return requiredSlots <= freeSlots; } private void AddItemInternal(ItemData item, int amount) { int remaining = amount; int maxStack = Mathf.Max(1, item.maxStack); for (int i = 0; i < slots.Count && remaining > 0; i++) { InventorySlot slot = slots[i]; if (slot == null || slot.item != item || slot.amount >= maxStack) { continue; } int added = Mathf.Min(maxStack - slot.amount, remaining); slot.amount += added; remaining -= added; } while (remaining > 0 && slots.Count < maxSlots) { int added = Mathf.Min(maxStack, remaining); slots.Add(new InventorySlot(item, added)); remaining -= added; } } private void RaiseChanged() { OnInventoryChanged?.Invoke(); } }