first commit

This commit is contained in:
2026-06-04 23:22:13 +03:00
commit d329f501be
310 changed files with 36395 additions and 0 deletions
+213
View File
@@ -0,0 +1,213 @@
using System;
using System.Collections.Generic;
using OTGIntegrated.Core;
using OTGIntegrated.Items;
using UnityEngine;
namespace OTGIntegrated.Inventory
{
public sealed class Inventory : MonoBehaviour
{
[SerializeField] private int maxSlots = 20;
[SerializeField] private List<InventorySlot> slots = new List<InventorySlot>();
public int MaxSlots => maxSlots;
public event Action OnInventoryChanged;
public bool AddItem(ItemData item, int amount)
{
if (!CanAddItem(item, amount))
{
GameEvents.RaiseNotification("Недостаточно места в инвентаре");
return false;
}
AddItemInternal(item, amount);
RaiseChanged();
GameEvents.RaiseItemAdded(item, amount);
GameEvents.RaiseNotification($"+{amount} {item.displayName}");
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();
GameEvents.RaiseItemRemoved(item, amount);
return true;
}
public bool HasItem(ItemData item, int amount)
{
return item != null && amount > 0 && GetAmount(item) >= amount;
}
public int GetAmount(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 IReadOnlyList<InventorySlot> GetAllSlots()
{
return slots;
}
public void Clear()
{
slots.Clear();
RaiseChanged();
}
public bool CanAddItem(ItemData item, int amount)
{
if (item == null || amount <= 0)
{
return false;
}
int remaining = amount;
int stackSize = 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 < stackSize)
{
remaining -= stackSize - slot.amount;
if (remaining <= 0)
{
return true;
}
}
}
int freeSlots = Mathf.Max(0, maxSlots - slots.Count);
int requiredSlots = Mathf.CeilToInt(remaining / (float)stackSize);
return requiredSlots <= freeSlots;
}
public List<InventorySlotSaveData> SaveData()
{
List<InventorySlotSaveData> saveSlots = new List<InventorySlotSaveData>();
for (int i = 0; i < slots.Count; i++)
{
InventorySlot slot = slots[i];
if (slot == null || slot.IsEmpty())
{
continue;
}
saveSlots.Add(new InventorySlotSaveData
{
itemId = slot.item.itemId,
amount = slot.amount
});
}
return saveSlots;
}
public void LoadData(List<InventorySlotSaveData> saveSlots, IEnumerable<ItemData> itemCatalog)
{
slots.Clear();
Dictionary<string, ItemData> lookup = new Dictionary<string, ItemData>(StringComparer.Ordinal);
if (itemCatalog != null)
{
foreach (ItemData item in itemCatalog)
{
if (item != null && !string.IsNullOrWhiteSpace(item.itemId))
{
lookup[item.itemId] = item;
}
}
}
if (saveSlots != null)
{
for (int i = 0; i < saveSlots.Count; i++)
{
InventorySlotSaveData slot = saveSlots[i];
if (slot == null || string.IsNullOrWhiteSpace(slot.itemId) || slot.amount <= 0)
{
continue;
}
if (lookup.TryGetValue(slot.itemId, out ItemData item))
{
AddItemInternal(item, slot.amount);
}
}
}
RaiseChanged();
}
private void AddItemInternal(ItemData item, int amount)
{
int remaining = amount;
int stackSize = 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 >= stackSize)
{
continue;
}
int added = Mathf.Min(stackSize - slot.amount, remaining);
slot.amount += added;
remaining -= added;
}
while (remaining > 0 && slots.Count < maxSlots)
{
int added = Mathf.Min(stackSize, remaining);
slots.Add(new InventorySlot(item, added));
remaining -= added;
}
}
private void RaiseChanged()
{
OnInventoryChanged?.Invoke();
}
}
}