using System.Collections.Generic; using UnityEngine; using UnityEngine.UIElements; using UnityEngine.InputSystem; using BITKit; using BITKit.UX; using BITKit.Entities; using UnityEngine.AddressableAssets; namespace BITFALL.UX { public class Inventory : UXPanel,IWeightedCallback,IPlayerEquipCallback { [Header(Constant.Header.Input)] public InputActionReference inventoryAction; public InputActionReference returnAction; public InputActionGroup inputActionGroup = new(); [Header(Constant.Header.Components)] public UXBar weightBar; [Header(Constant.Header.Prefabs)] public VisualTreeAsset containerTemplate; public VisualTreeAsset cellTemplate; public VisualTreeAsset itemTemplate; [Header(Constant.Header.Components)] public UXImage containerRoot; public UXImage serializableRoot; public UXFactory factory; [Header(Constant.Header.InternalVariables)] private readonly Dictionary containers = new(); private readonly Dictionary equipContainers = new(); private readonly IntervalUpdate returnInterval = new(0.1f); private IBasicItemContainer inventory; private IPlayerEquipContainer equipContainer; public override async void OnStart() { base.OnStart(); inputActionGroup.RegisterCallback(returnAction, OnReturn); inputActionGroup.RegisterCallback(inventoryAction, OnInventory); foreach (var x in await ReflectionHelper.GetTypes()) { var element = document.rootVisualElement.Q(x.Name); if(element is not null) { UXContainer uxContainer = new(element); equipContainers.Add(x.Name, uxContainer); element.RegisterCallback(mouseEvent => { if (mouseEvent.button is 0) { } else if (mouseEvent.button is 1) { equipContainer.TryDeEquip(System.Activator.CreateInstance(x) as IEquipmentSlot); } }); } } } public override void Set(bool active) { base.Set(active); inputActionGroup.allowInput.SetElements(this, active); returnInterval.Reset(); } void OnEnable() { IEntity.OnSpawnLocalPlayer += OnSpawnLocalPlayer; } void OnDisable() { IEntity.OnSpawnLocalPlayer -= OnSpawnLocalPlayer; } void OnSpawnLocalPlayer(IEntity entity) { entity.RegisterCallback(this); entity.RegisterCallback(this); inventory = entity.Get(); equipContainer = entity.Get(); inventory.OnAdd += OnAdd; inventory.OnRemove += OnRemove; inventory.OnSet += OnSet; } private void OnInventory(InputAction.CallbackContext context) { if (context.action.WasPressedThisFrame() && returnInterval) UXFramework.Enter(); } private void OnReturn(InputAction.CallbackContext context) { if (context.started && returnInterval) UXFramework.Enter(); } public void OnWeighted(float current, float max) { weightBar.SetDirect( current is 0 ? 0 :(current / max).Fix(),$"{current}/{max}"); } private void OnAdd(IBasicItem item) { var asset = Addressables.LoadAssetAsync(item.AdressablePath).WaitForCompletion(); var uxContainer = factory.Create(); uxContainer.icon.style.backgroundImage = asset.SquareIcon; uxContainer.contextlabel.text = asset.Name; uxContainer.button.clicked += () => { UseItem(item); }; uxContainer.visualElement.RegisterCallback(x => { if (x.button is 1) { ContextMenuBuilder .Create() .BuildAction("使用", () => UseItem(item)) .BuildAction("丢下", () => DropItem(item)) .Build(); } }); containers.Add(item.Id, uxContainer); } private void OnRemove(IBasicItem item) { if (!containers.TryGetValue(item.Id, out var uxContainer)) return; factory.Remove(uxContainer); containers.Remove(item.Id); } void OnSet(IBasicItem item) { if (!containers.TryGetValue(item.Id, out var uxContainer)) return; if(item.TryGetProperty(out var count)) { uxContainer.numberLabel.text = count.ToString(); } } private void UseItem(IBasicItem item) { IEntity.LocalPlayer.Get>().Excute(item); } private void DropItem(IBasicItem item) { inventory.Drop(item.Id); } void IPlayerEquipCallback.OnEquip(IEquipmentSlot slot, IBasicItem item) { var asset = item.GetAssetable(); if (equipContainers.TryGetValue(slot.GetType().Name, out var container)) { container.icon.style.backgroundImage = asset.SquareIcon; } } void IPlayerEquipCallback.DeEquip(IEquipmentSlot slot, IBasicItem item) { if(equipContainers.TryGetValue(slot.GetType().Name,out var container)) { container.icon.style.backgroundImage = null; } } } }