183 lines
6.5 KiB
C#
183 lines
6.5 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 Awake()
|
|
{
|
|
base.Awake();
|
|
inputActionGroup.RegisterCallback(returnAction, OnReturn);
|
|
inputActionGroup.RegisterCallback(inventoryAction, OnInventory);
|
|
|
|
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 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;
|
|
|
|
_unityEntity = unityEntity;
|
|
|
|
|
|
}
|
|
private void OnInventory(InputAction.CallbackContext context)
|
|
{
|
|
if(context is {interaction:PressInteraction,performed:true})
|
|
UXService.Entry<UXHud>();
|
|
}
|
|
private static void OnReturn(InputAction.CallbackContext context)
|
|
{
|
|
if (context.JustPressed())
|
|
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;
|
|
}
|
|
}
|
|
} |