120 lines
2.8 KiB
C#
120 lines
2.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
|
|
[Serializable]
|
|
public class InventorySlot
|
|
{
|
|
public ItemData item;
|
|
public int amount;
|
|
|
|
public InventorySlot(ItemData item, int amount)
|
|
{
|
|
this.item = item;
|
|
this.amount = Mathf.Max(0, amount);
|
|
}
|
|
}
|
|
|
|
public class Inventory : MonoBehaviour
|
|
{
|
|
[SerializeField] private List<InventorySlot> slots = new List<InventorySlot>();
|
|
|
|
public event Action OnInventoryChanged;
|
|
|
|
public IReadOnlyList<InventorySlot> Slots => slots;
|
|
|
|
public bool HasItem(ItemData item, int amount)
|
|
{
|
|
if (item == null)
|
|
return true;
|
|
|
|
return GetAmount(item) >= Mathf.Max(1, amount);
|
|
}
|
|
|
|
public int GetAmount(ItemData item)
|
|
{
|
|
if (item == null)
|
|
return 0;
|
|
|
|
InventorySlot slot = FindSlot(item);
|
|
return slot != null ? Mathf.Max(0, slot.amount) : 0;
|
|
}
|
|
|
|
public bool AddItem(ItemData item, int amount)
|
|
{
|
|
if (item == null || amount <= 0)
|
|
return false;
|
|
|
|
InventorySlot slot = FindSlot(item);
|
|
int maxStack = Mathf.Max(1, item.maxStack);
|
|
|
|
if (slot == null)
|
|
{
|
|
slots.Add(new InventorySlot(item, Mathf.Min(amount, maxStack)));
|
|
RaiseChanged();
|
|
return true;
|
|
}
|
|
|
|
int newAmount = Mathf.Clamp(slot.amount + amount, 0, maxStack);
|
|
if (newAmount == slot.amount)
|
|
return false;
|
|
|
|
slot.amount = newAmount;
|
|
RaiseChanged();
|
|
return true;
|
|
}
|
|
|
|
public bool RemoveItem(ItemData item, int amount)
|
|
{
|
|
if (item == null || amount <= 0)
|
|
return false;
|
|
|
|
InventorySlot slot = FindSlot(item);
|
|
if (slot == null || slot.amount < amount)
|
|
return false;
|
|
|
|
slot.amount -= amount;
|
|
if (slot.amount <= 0)
|
|
slots.Remove(slot);
|
|
|
|
RaiseChanged();
|
|
return true;
|
|
}
|
|
|
|
public string GetDebugText()
|
|
{
|
|
if (slots.Count == 0)
|
|
return "Инвентарь: пусто";
|
|
|
|
StringBuilder builder = new StringBuilder("Инвентарь: ");
|
|
bool first = true;
|
|
|
|
foreach (InventorySlot slot in slots)
|
|
{
|
|
if (slot == null || slot.item == null || slot.amount <= 0)
|
|
continue;
|
|
|
|
if (!first)
|
|
builder.Append(", ");
|
|
|
|
builder.Append(slot.item.itemName);
|
|
builder.Append(" x");
|
|
builder.Append(slot.amount);
|
|
first = false;
|
|
}
|
|
|
|
return first ? "Инвентарь: пусто" : builder.ToString();
|
|
}
|
|
|
|
private InventorySlot FindSlot(ItemData item)
|
|
{
|
|
return slots.Find(slot => slot != null && slot.item == item);
|
|
}
|
|
|
|
private void RaiseChanged()
|
|
{
|
|
OnInventoryChanged?.Invoke();
|
|
}
|
|
}
|