using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UIElements; using VOID.Generic.Dict; using VOID.Generic.Objects.Item; using VOID.Generic.Objects.Unit; using VOID.Generic.Objects.Unit.Actions; using VOID.Generic.Objects.Unit.Events; using VOID.UserInterface.Game.Interfaces; using VOID.UserInterface.Game.Util; namespace VOID.UserInterface.Game { /// /// Manages all visuals in one instance of . /// public class OtherUnitBackpackUI : MonoBehaviour, IHasWindow { public static readonly List CurrentList = new(); // WindowUI public WindowUI windowUI { get; private set; } // ContainerObject, its content to which this UI is connected and also unit who opened it public UnitObject unit { get; private set; } private UnitObjectBackpack _unitBackpack; private UnitObject _openedBy; // Visual Elements private VisualElement _rootElement; private VisualElement _slotsElement; private SlotUI[] _slots; private void Awake() { CurrentList.Add(this); var uiDocument = gameObject.GetComponent(); var template = uiDocument.rootVisualElement; // Find all important elements _rootElement = template.Q("root-container"); _slotsElement = template.Q("slots"); windowUI = gameObject.GetComponent(); // Remove place holders _slotsElement.Clear(); windowUI.OnClose += Close; _rootElement.dataSource = this; _rootElement.pickingMode = PickingMode.Position; } /// /// Opens newly initialized . /// This should be called from . /// public void Open(UnitObject unit, UnitObject openedBy) { this.unit = unit; _unitBackpack = unit.unitBackpack; _openedBy = openedBy; _slots = new SlotUI[_unitBackpack.items.Length]; for (var i = 0; i < _unitBackpack.items.Length; i++) SetSlot(i, _unitBackpack.items[i]); unit.unitEvents.onClosedByOtherUnit.AddListener(OnClose); unit.unitEvents.onBackpackResize.AddListener(OnResize); unit.unitEvents.onBackpackSwap.AddListener(OnSwap); unit.unitEvents.onBackpackPick.AddListener(OnMoveIn); unit.unitEvents.onBackpackDrop.AddListener(OnMoveOut); windowUI.SetTitle(unit.basicData.finalName); // Make sure it is visible _rootElement.style.display = DisplayStyle.Flex; } /// /// Orders player's active to . /// This action will close which execute . /// public void Close() { new CloseOtherUnitAction(_openedBy, unit).DoIt(); } private void OnClose(CloseOtherUnitEvent closeOtherUnitEvent) { unit.unitEvents.onClosedByOtherUnit.RemoveListener(OnClose); unit.unitEvents.onBackpackResize.RemoveListener(OnResize); unit.unitEvents.onBackpackSwap.RemoveListener(OnSwap); unit.unitEvents.onBackpackPick.RemoveListener(OnMoveIn); unit.unitEvents.onBackpackDrop.RemoveListener(OnMoveOut); windowUI.OnClose -= Close; _rootElement.parent.parent.Remove(_rootElement.parent); CurrentList.Remove(this); Destroy(this); } private void OnResize(BackpackResizeEvent backpackResizeEvent) { // Before resizing - remove all unused slots if (backpackResizeEvent.beforeSlotCount > backpackResizeEvent.afterSlotCount) for (var i = backpackResizeEvent.afterSlotCount; i < backpackResizeEvent.beforeSlotCount; i++) RemoveSlot(i); Array.Resize(ref _slots, backpackResizeEvent.afterSlotCount); // After resizing - insert empty slots if (backpackResizeEvent.beforeSlotCount < backpackResizeEvent.afterSlotCount) for (var i = backpackResizeEvent.beforeSlotCount; i < backpackResizeEvent.afterSlotCount; i++) SetSlot(i, null); } private void OnSwap(BackpackSwapEvent backpackSwapEvent) { SetSlot(backpackSwapEvent.firstSlotIndex, backpackSwapEvent.firstItem); SetSlot(backpackSwapEvent.secondSlotIndex, backpackSwapEvent.secondItem); } private void OnMoveIn(BackpackPickEvent backpackPickEvent) { SetSlot(backpackPickEvent.slotIndex, backpackPickEvent.item); } private void OnMoveOut(BackpackDropEvent backpackDropEvent) { SetSlot(backpackDropEvent.slotIndex, null); } private void SetSlot(int slotIndex, ItemObject item) { // Create new VisualElement if not exists if (_slots[slotIndex] is null) { _slots[slotIndex] = new SlotUI(); _slots[slotIndex].InitNew(_slotsElement, SlotType.OtherUnitBackpackSlot, slotIndex, "Slot-" + slotIndex); } // Put item's icon or else remain default _slots[slotIndex].Set(item); } private void RemoveSlot(int slotIndex) { _slots[slotIndex].Destroy(); } } }