using System; using System.Collections.Generic; using UnityEngine; /// /// Inventory holds and managed a list of slots which can contain an item. /// public class Inventory : MonoBehaviour { // Actions -> Used for Callback in other scripts public static Action OnPlayerInventoryChanged; public static Action OnPlayerItemAdded; public static Action OnPlayerItemRemoved; // Serialized [Header("Inventory")] [Tooltip("The number of slots a player has in the inventory.")] [SerializeField] int numberOfSlots = 20; [Tooltip("Maximal count of items in ONE slot. How big is one stack.")] [SerializeField] int maxSpaceOfSlots = 10; [Tooltip("Is this inventory owned by the player")] [SerializeField] bool isPlayerInventory = true; [Tooltip("List of the slots ('The inventory').")] [SerializeField] List inventory = new List(); public List GetInventory() => inventory; /// /// Add slots to the inventory. You can extend the inventory space. /// /// The count of slots which should be added to the inventory public void AddSlots(int _numberOfSlots) { for (int i = 0; i < _numberOfSlots; i++) { inventory.Add(new Slot()); } if(isPlayerInventory) OnPlayerInventoryChanged?.Invoke(); } /// /// GetEmptySlot gives you the first empty slot in the inventory. /// /// An empty slot of the inventory Slot GetEmptySlot() { foreach (Slot slot in inventory) { if (slot.GetItem() == null) return slot; } return null; } /// /// GetSlotByItem lets you find a slot by the item it's containing. /// /// /// Slot with the specified item. Slot GetSlotByItem(Item item) { foreach (Slot slot in inventory) { if (slot.GetItem() != null) { if (slot.GetItem().id == item.id) return slot; } } return null; } /// /// GetRest calculates the rest count of an item and a slot. /// Example: Slot has a capacity of 20. Count of item is 22. Returns 2. /// /// The rest count of an item and a slot. int GetRest(int count, Slot slot) { if (CountFitsInSlot(count, slot)) { return 0; } else { return (count - (maxSpaceOfSlots - slot.GetCount())); } } /// /// CountFitsInSlot calculates if the item count fits in the slot capacity /// /// /// /// True: Count fits. False: Count does not fit. bool CountFitsInSlot(int count, Slot slot) { int leftSize = maxSpaceOfSlots - slot.GetCount(); if (leftSize > count) { return true; } else { return false; } } /// /// IndexIsInRange looks if an index of the inventory list is in range. /// /// /// True: Is in range. False: Is not in range. bool IndexIsInRange(int index) { // Returns true if a given index is in the bounds of the inventory. // Example (maxSize = 10) index = -10 : false , index = 100: false, index = 7 : true if (index < inventory.Count && index >= 0) { return true; } else { return false; } } /// /// Remove removes an item/s of the inventory list. It can be based in a specific index. /// /// which item should be removed /// Count of the item you want to remove /// (optional) Index of the inventory list /// The rest of the count, which could not be removed. public int Remove(Item itemType, int count, int invIndex = -1) { Slot slot = null; Item item = Instantiate(itemType); if (item == null) return -1; // Get Slot if (invIndex > -1) { if (IndexIsInRange(invIndex)) slot = inventory[invIndex]; } else { slot = GetSlotByItem(item); } if (slot == null) return -1; // remove if (slot.GetItem() != null && slot.GetItem().id == item.id) // Wenn im Slot schon das gleiche item ist { int rest = 0; if (slot.GetCount() >= count) { slot.RemoveCount(count); } else { rest = count - slot.GetCount(); slot.Clear(); } if (isPlayerInventory) { OnPlayerInventoryChanged?.Invoke(); OnPlayerItemRemoved?.Invoke(); } return rest; } else return -1; } /// /// Add adds an item/s of the inventory list. It can be based in a specific index. /// /// which item should be added /// Count of the item you want to add /// (optional) Index of the inventory list /// The rest of the count, which could not be added. public int Add(Item itemType, int count, int invIndex = -1) { int rest = 0; Slot slot = null; Item item = Instantiate(itemType); if (item == null) return -1; // Get Slot if (invIndex > -1) { if(IndexIsInRange(invIndex)) slot = inventory[invIndex]; } else { slot = GetSlotByItem(item); if (slot == null) slot = GetEmptySlot(); } if (slot == null) return -1; // add if (slot.GetItem() != null && slot.GetItem().id == item.id) // Wenn im Slot schon das selbe item ist { if (CountFitsInSlot(count, slot)) { slot.AddCount(count); } else { rest = GetRest(count, slot); slot.Set(item, maxSpaceOfSlots); } } else if (slot.GetItem() == null) { if (CountFitsInSlot(count, slot)) { slot.Set(item, count); } else { rest = GetRest(count, slot); slot.Set(item, maxSpaceOfSlots); } } else return -1; if (isPlayerInventory) { OnPlayerInventoryChanged?.Invoke(); OnPlayerItemAdded?.Invoke(); } return rest; } void Start() { // Initialize Inventory Slots AddSlots(numberOfSlots); } }