BITFALL/Assets/Artists/Scripts/UX/UXInventory.cs

207 lines
7.1 KiB
C#

using System.Collections.Generic;
using BITFALL.Entities.Equipment;
using BITFALL.Entities.Inventory;
using BITFALL.Player.Inventory;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Interactions;
using BITKit;
using BITKit.UX;
using BITKit.Entities;
using BITKit.Entities.Player;
namespace BITFALL.UX
{
public class UXInventory : UIToolKitPanel
{
[Header(Constant.Header.Input)]
public InputActionReference inventoryAction;
public InputActionReference returnAction;
[Header(Constant.Header.Components)]
public UXBar weightBar;
[Header(Constant.Header.Providers)]
[SerializeReference, SubclassSelector] private IPlayerService playerService;
[Header(Constant.Header.Components)]
public UXBuilder builder;
[Header(Constant.Header.InternalVariables)]
private readonly Dictionary<int, UXContainer> itemContainers = new();
private readonly Dictionary<string, UXContainer> equipContainers = new();
[Inject]
private IEntityInventory inventory;
[Inject]
private IEntityEquipmentContainer equipContainer;
private IUnityEntity _unityEntity;
protected override async void Start()
{
base.Start();
foreach (var x in await ReflectionHelper.GetTypes<IEquipmentSlot>())
{
var element = document.rootVisualElement.Q(x.Name);
if (element is null) continue;
UXContainer uxContainer = new(element);
equipContainers.Add(x.Name, uxContainer);
element.RegisterCallback<MouseDownEvent>(mouseEvent =>
{
if(_unityEntity is null) return;
switch (mouseEvent.button)
{
case 0:
break;
case 1:
equipContainer.TryDeEquip(System.Activator.CreateInstance(x) as IEquipmentSlot);
break;
}
});
}
}
protected override void OnPanelEntry()
{
base.OnPanelEntry();
inputActionGroup.RegisterCallback(returnAction, OnReturn);
inputActionGroup.RegisterCallback(inventoryAction, OnReturn);
}
protected override void OnPanelExit()
{
base.OnPanelExit();
inputActionGroup.UnRegisterCallback(returnAction, OnReturn);
inputActionGroup.UnRegisterCallback(inventoryAction, OnReturn);
}
protected override void OnEnable()
{
base.OnEnable();
playerService.OnPlayerInitialized += OnPlayerInitializedLocalPlayer;
playerService.OnPlayerDisposed += OnPlayerDisposed;
}
private void OnPlayerDisposed(Entity obj)
{
inventory = null;
equipContainer = null;
}
protected override void OnDisable()
{
base.OnDisable();
playerService.OnPlayerDisposed -= OnPlayerDisposed;
playerService.OnPlayerInitialized -= OnPlayerInitializedLocalPlayer;
}
private void OnPlayerInitializedLocalPlayer(IUnityEntity unityEntity)
{
unityEntity.Inject(this);
itemContainers.Clear();
builder.Clear();
var weighted = unityEntity.Get<IPlayerInventoryWeightable>();
weighted.OnWeighted += OnWeighted;
equipContainer.OnEquip += OnEquip;
equipContainer.OnDeEquip += DeEquip;
inventory.OnAdd += OnAdd;
inventory.OnRemove += OnRemove;
inventory.OnUsedItem += OnRemove;
inventory.OnSet += OnSet;
inventory.OnRebuild += OnRebuild;
_unityEntity = unityEntity;
}
private void OnRebuild(IBasicItemContainer obj)
{
foreach (var x in itemContainers.Values)
{
x.visualElement.RemoveFromHierarchy();
}
foreach (var VARIABLE in obj.GetItems())
{
OnAdd(VARIABLE);
}
}
private static void OnReturn(InputAction.CallbackContext context)
{
if (context is {interaction:PressInteraction,performed:true})
UXService.Entry<UXHud>();
}
public void OnWeighted(double current, double max)
{
var value = current is 0 ? 0 : (current / max);
weightBar.SetDirect((float) value,$"{current}/{max}");
}
private void OnAdd(IBasicItem item)
{
// var asset = Addressables.LoadAssetAsync<AssetableItem>(item.AddressablePath).WaitForCompletion();
// var uxContainer = builder.BuildAsContainer();
// uxContainer.icon.style.backgroundImage = asset.SquareIcon;
// uxContainer.contextLabel.text = asset.Name;
var uxContainer = UXUtils.CreateItemContainer(builder.BuildAsContainer(), item);
uxContainer.button.clicked += () =>
{
UseItem(item);
};
uxContainer.visualElement.Q<Button>().RegisterCallback<MouseDownEvent>(x =>
{
if (x.button is 1)
{
ContextMenuBuilder
.Create()
.BuildAction("使用", () => UseItem(item))
.BuildAction("丢下", () => DropItem(item))
.BuildAction("检视", () => UXInventoryInspector.Entry(item))
.Build();
}
});
itemContainers.Add(item.Id, uxContainer);
}
private void OnRemove(IBasicItem item)
{
if (!itemContainers.TryGetValue(item.Id, out var uxContainer)) return;
uxContainer.visualElement.RemoveFromHierarchy();
itemContainers.Remove(item.Id);
}
private void OnSet(IBasicItem item)
{
if (!itemContainers.TryGetValue(item.Id, out var uxContainer)) return;
UXUtils.CreateItemContainer(uxContainer, item);
}
private void UseItem(IBasicItem item)
{
inventory.TryUseItem(item);
}
private void DropItem(IBasicItem item)
{
inventory.Drop(item.Id);
}
private void OnEquip(IEquipmentSlot slot, IBasicItem item)
{
var asset = item.GetAssetable();
if (!equipContainers.TryGetValue(slot.GetType().Name, out var container)) return;
container.icon.style.backgroundImage = asset.SquareIcon;
//BIT4Log.Log<UXInventory>($"已装备:{item.Name}@{slot.GetType().Name}");
}
private void DeEquip(IEquipmentSlot slot, IBasicItem item)
{
if (!equipContainers.TryGetValue(slot.GetType().Name, out var container)) return;
container.icon.style.backgroundImage = null;
}
}
}