using System.Collections.Generic; using UnityEngine; using Object = UnityEngine.Object; namespace SpellBoundAR.Items.Inventories.UI { public class InventoryDisplay : MonoBehaviour { [SerializeField] private Object inventoryObject; [SerializeField] protected InventoryEntryDisplay entryPrefab; [SerializeField] protected Transform entriesParent; [SerializeField] private int minimumEntries = 9; [SerializeField] private bool ensureCountIsMultiple = false; [SerializeField] private int multiples = 1; [Header("Cache")] private IInventory _inventory; public IInventory Inventory { get { if (_inventory != null) return _inventory; OnValidate(); return _inventory; } set { if (_inventory == value) return; if (_inventory != null) _inventory.OnEntriesChanged -= Refresh; _inventory = value; inventoryObject = value as Object; if (_inventory != null && isActiveAndEnabled) _inventory.OnEntriesChanged += Refresh; Refresh(); } } private void ValidateInventoryObject() { if (inventoryObject is GameObject target) inventoryObject = target.GetComponent() as Object; if (inventoryObject is not IInventory) inventoryObject = null; _inventory = inventoryObject as IInventory; } private void OnValidate() { ValidateInventoryObject(); if (minimumEntries < 0) minimumEntries = 0; if (multiples < 1) multiples = 1; } private void OnEnable() { if (Inventory != null) Inventory.OnEntriesChanged += Refresh; Refresh(); } private void OnDisable() { if (Inventory != null) Inventory.OnEntriesChanged -= Refresh; } public void Refresh() { DestroyAllEntries(); int entries = SpawnEntries(); FillRemainingSlots(entries); } private void DestroyAllEntries() { if (!entriesParent) return; foreach (Transform entry in entriesParent) { if (!entry || !entry.gameObject) continue; Destroy(entry.gameObject); } } protected virtual bool SpawnEntry(IInventoryEntry entry) { if (!entryPrefab) return false; InventoryEntryDisplay instantiated = Instantiate(entryPrefab, entriesParent); if (!instantiated) return false; instantiated.Entry = entry; return true; } protected virtual int SpawnEntries() { int count = 0; if (Inventory == null) return count; List entries = Inventory.GetAllEntries(); foreach (IInventoryEntry entry in entries) { if (entry?.ItemTypeData == null || !entry.ItemTypeData.ShowInInventory) continue; if (SpawnEntry(entry)) count++; } return count; } private void FillRemainingSlots(int amountPresent) { while (amountPresent < minimumEntries || ensureCountIsMultiple && amountPresent % multiples != 0) { SpawnEntry(null); amountPresent++; } } } }