Files
BookRPG/Assets/Scripts/Inventory.cs

331 lines
9.1 KiB
C#

using UnityEngine;
using System.Collections.Generic;
[CreateAssetMenu(fileName = "NewItem", menuName = "Inventory/Item")]
public class Item : ScriptableObject
{
public string itemName;
public string itemDescription;
public int itemID;
public int maxStackSize = 1;
public bool isStackable;
public enum ItemType { Weapon, Armor, Consumable, QuestItem, Miscellaneous }
public ItemType itemType;
public Sprite itemIcon;
}
[System.Serializable]
public class InventorySlot
{
public Item item;
public int quantity;
public InventorySlot(Item newItem, int qty)
{
item = newItem;
quantity = qty;
}
}
public class Inventory : MonoBehaviour
{
[SerializeField] private GameObject inventoryUI;
[SerializeField] private int maxCapacity = 20;
[SerializeField] private List<Item> allItems = new List<Item>(); // All available items in game
private List<InventorySlot> inventorySlots = new List<InventorySlot>();
// Equipment slots
private Item equippedWeapon;
private Item equippedArmor;
private Item FindItemByName(string itemName)
{
return allItems.Find(i => i.itemName == itemName);
}
private Item FindItemByID(int itemID)
{
return allItems.Find(i => i.itemID == itemID);
}
public bool AddItem(string itemName, int quantity = 1)
{
Item item = FindItemByName(itemName);
if (item == null)
{
Debug.LogWarning($"Item '{itemName}' not found.");
return false;
}
return AddItemInternal(item, quantity);
}
public bool AddItem(int itemID, int quantity = 1)
{
Item item = FindItemByID(itemID);
if (item == null)
{
Debug.LogWarning($"Item with ID {itemID} not found.");
return false;
}
return AddItemInternal(item, quantity);
}
private bool AddItemInternal(Item item, int quantity = 1)
{
if (item == null)
{
Debug.LogWarning("Tried to add null item to inventory.");
return false;
}
// Try to add to existing stack if stackable
if (item.isStackable)
{
foreach (var slot in inventorySlots)
{
if (slot.item == item && slot.quantity < item.maxStackSize)
{
int spaceAvailable = item.maxStackSize - slot.quantity;
int amountToAdd = Mathf.Min(quantity, spaceAvailable);
slot.quantity += amountToAdd;
Debug.Log($"Added {amountToAdd} {item.itemName} to existing stack. Stack size: {slot.quantity}");
if (amountToAdd < quantity)
{
// Recursively add remaining items
return AddItemInternal(item, quantity - amountToAdd);
}
return true;
}
}
}
// Add new slot if space available
if (inventorySlots.Count < maxCapacity)
{
inventorySlots.Add(new InventorySlot(item, quantity));
Debug.Log($"Added {quantity} {item.itemName} to inventory. Slots used: {inventorySlots.Count}/{maxCapacity}");
return true;
}
Debug.Log("Inventory is full!");
return false;
}
public bool RemoveItem(string itemName, int quantity = 1)
{
Item item = FindItemByName(itemName);
if (item == null)
{
Debug.LogWarning($"Item '{itemName}' not found.");
return false;
}
return RemoveItemInternal(item, quantity);
}
public bool RemoveItem(int itemID, int quantity = 1)
{
Item item = FindItemByID(itemID);
if (item == null)
{
Debug.LogWarning($"Item with ID {itemID} not found.");
return false;
}
return RemoveItemInternal(item, quantity);
}
private bool RemoveItemInternal(Item item, int quantity = 1)
{
if (item == null)
{
Debug.LogWarning("Tried to remove null item from inventory.");
return false;
}
foreach (var slot in inventorySlots)
{
if (slot.item == item)
{
if (slot.quantity >= quantity)
{
slot.quantity -= quantity;
Debug.Log($"Removed {quantity} {item.itemName} from inventory.");
// Remove slot if empty
if (slot.quantity <= 0)
{
inventorySlots.Remove(slot);
}
return true;
}
else
{
Debug.LogWarning($"Not enough {item.itemName} in inventory. Have: {slot.quantity}, Need: {quantity}");
return false;
}
}
}
Debug.LogWarning($"{item.itemName} not found in inventory.");
return false;
}
public int GetItemQuantity(string itemName)
{
Item item = FindItemByName(itemName);
if (item == null) return 0;
return GetItemQuantityInternal(item);
}
public int GetItemQuantity(int itemID)
{
Item item = FindItemByID(itemID);
if (item == null) return 0;
return GetItemQuantityInternal(item);
}
private int GetItemQuantityInternal(Item item)
{
foreach (var slot in inventorySlots)
{
if (slot.item == item)
return slot.quantity;
}
return 0;
}
public List<InventorySlot> GetInventorySlots()
{
return new List<InventorySlot>(inventorySlots);
}
public int GetAvailableSlots()
{
return maxCapacity - inventorySlots.Count;
}
public void ClearInventory()
{
inventorySlots.Clear();
Debug.Log("Inventory cleared.");
}
public bool EquipItem(string itemName)
{
Item item = FindItemByName(itemName);
if (item == null)
{
Debug.LogWarning($"Item '{itemName}' not found.");
return false;
}
return EquipItemInternal(item);
}
public bool EquipItem(int itemID)
{
Item item = FindItemByID(itemID);
if (item == null)
{
Debug.LogWarning($"Item with ID {itemID} not found.");
return false;
}
return EquipItemInternal(item);
}
private bool EquipItemInternal(Item item)
{
if (item == null) return false;
if (item.itemType == Item.ItemType.Weapon)
{
if (equippedWeapon != null)
AddItemInternal(equippedWeapon);
equippedWeapon = item;
RemoveItemInternal(item, 1);
Debug.Log($"Equipped weapon: {item.itemName}");
return true;
}
else if (item.itemType == Item.ItemType.Armor)
{
if (equippedArmor != null)
AddItemInternal(equippedArmor);
equippedArmor = item;
RemoveItemInternal(item, 1);
Debug.Log($"Equipped armor: {item.itemName}");
return true;
}
return false;
}
public Item GetEquippedItem(Item.ItemType type)
{
return type == Item.ItemType.Weapon ? equippedWeapon :
type == Item.ItemType.Armor ? equippedArmor : null;
}
public bool UseItem(string itemName)
{
Item item = FindItemByName(itemName);
if (item == null)
{
Debug.LogWarning($"Item '{itemName}' not found.");
return false;
}
return UseItemInternal(item);
}
public bool UseItem(int itemID)
{
Item item = FindItemByID(itemID);
if (item == null)
{
Debug.LogWarning($"Item with ID {itemID} not found.");
return false;
}
return UseItemInternal(item);
}
private bool UseItemInternal(Item item)
{
if (item.itemType == Item.ItemType.Consumable)
{
Debug.Log($"Used {item.itemName}");
RemoveItemInternal(item, 1);
return true;
}
return false;
}
public bool DropItem(string itemName, int quantity = 1)
{
Item item = FindItemByName(itemName);
if (item == null)
{
Debug.LogWarning($"Item '{itemName}' not found.");
return false;
}
return DropItemInternal(item, quantity);
}
public bool DropItem(int itemID, int quantity = 1)
{
Item item = FindItemByID(itemID);
if (item == null)
{
Debug.LogWarning($"Item with ID {itemID} not found.");
return false;
}
return DropItemInternal(item, quantity);
}
private bool DropItemInternal(Item item, int quantity = 1)
{
if (RemoveItemInternal(item, quantity))
{
Debug.Log($"Dropped {quantity} {item.itemName}");
// TODO: Instantiate item drop in world
return true;
}
return false;
}
}