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

217 lines
7.6 KiB
C#
Raw Normal View History

2024-03-31 23:34:22 +08:00
using System;
2023-06-08 14:09:50 +08:00
using System.Collections.Generic;
2023-10-20 22:46:14 +08:00
using BITFALL.Entities.Equipment;
2023-10-24 23:37:59 +08:00
using BITFALL.Entities.Inventory;
2023-10-02 23:24:56 +08:00
using BITFALL.Player.Inventory;
2023-06-08 14:09:50 +08:00
using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.InputSystem;
2023-10-24 23:37:59 +08:00
using UnityEngine.InputSystem.Interactions;
2023-06-08 14:09:50 +08:00
using BITKit;
using BITKit.UX;
using BITKit.Entities;
2023-08-27 02:58:19 +08:00
using BITKit.Entities.Player;
2023-06-08 14:09:50 +08:00
namespace BITFALL.UX
{
2024-03-31 23:34:22 +08:00
[Serializable]
public struct PlayerUseCloseInventory:IProperty{}
2023-09-01 14:33:54 +08:00
public class UXInventory : UIToolKitPanel
2023-06-08 14:09:50 +08:00
{
[Header(Constant.Header.Input)]
public InputActionReference inventoryAction;
public InputActionReference returnAction;
2023-10-24 23:37:59 +08:00
2023-08-27 02:58:19 +08:00
2023-06-08 14:09:50 +08:00
[Header(Constant.Header.Components)]
public UXBar weightBar;
2023-08-27 02:58:19 +08:00
[Header(Constant.Header.Providers)]
[SerializeReference, SubclassSelector] private IPlayerService playerService;
2023-06-08 14:09:50 +08:00
[Header(Constant.Header.Components)]
2023-08-27 02:58:19 +08:00
public UXBuilder builder;
2023-06-08 14:09:50 +08:00
[Header(Constant.Header.InternalVariables)]
2023-08-27 02:58:19 +08:00
private readonly Dictionary<int, UXContainer> itemContainers = new();
2023-06-08 14:09:50 +08:00
private readonly Dictionary<string, UXContainer> equipContainers = new();
2024-03-31 23:34:22 +08:00
[Inject] private IEntityInventory inventory;
[Inject] private IEntityEquipmentContainer equipContainer;
[Inject] private IEntityEquipment _equipment;
2023-10-30 01:25:53 +08:00
private IUnityEntity _unityEntity;
2024-01-03 00:27:12 +08:00
protected override async void Start()
2023-06-08 14:09:50 +08:00
{
2024-01-03 00:27:12 +08:00
base.Start();
2023-06-08 14:09:50 +08:00
foreach (var x in await ReflectionHelper.GetTypes<IEquipmentSlot>())
{
var element = document.rootVisualElement.Q(x.Name);
2023-08-23 01:59:40 +08:00
if (element is null) continue;
UXContainer uxContainer = new(element);
equipContainers.Add(x.Name, uxContainer);
element.RegisterCallback<MouseDownEvent>(mouseEvent =>
2023-06-08 14:09:50 +08:00
{
2023-10-30 01:25:53 +08:00
if(_unityEntity is null) return;
2023-08-23 01:59:40 +08:00
switch (mouseEvent.button)
2023-06-08 14:09:50 +08:00
{
2023-08-23 01:59:40 +08:00
case 0:
break;
case 1:
2023-06-08 14:09:50 +08:00
equipContainer.TryDeEquip(System.Activator.CreateInstance(x) as IEquipmentSlot);
2023-08-23 01:59:40 +08:00
break;
}
});
2023-06-08 14:09:50 +08:00
}
}
2024-01-03 00:27:12 +08:00
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);
}
2023-08-23 01:59:40 +08:00
protected override void OnEnable()
2023-06-08 14:09:50 +08:00
{
2023-08-23 01:59:40 +08:00
base.OnEnable();
2023-08-27 02:58:19 +08:00
playerService.OnPlayerInitialized += OnPlayerInitializedLocalPlayer;
2023-10-20 22:46:14 +08:00
playerService.OnPlayerDisposed += OnPlayerDisposed;
2023-06-08 14:09:50 +08:00
}
2023-10-20 22:46:14 +08:00
private void OnPlayerDisposed(Entity obj)
{
inventory = null;
equipContainer = null;
}
2023-08-23 01:59:40 +08:00
protected override void OnDisable()
2023-06-08 14:09:50 +08:00
{
2023-08-23 01:59:40 +08:00
base.OnDisable();
2023-10-20 22:46:14 +08:00
playerService.OnPlayerDisposed -= OnPlayerDisposed;
2023-08-27 02:58:19 +08:00
playerService.OnPlayerInitialized -= OnPlayerInitializedLocalPlayer;
2023-06-08 14:09:50 +08:00
}
2023-10-30 01:25:53 +08:00
private void OnPlayerInitializedLocalPlayer(IUnityEntity unityEntity)
2023-06-08 14:09:50 +08:00
{
2023-10-30 01:25:53 +08:00
unityEntity.Inject(this);
2023-10-20 19:31:12 +08:00
itemContainers.Clear();
builder.Clear();
2023-10-30 01:25:53 +08:00
var weighted = unityEntity.Get<IPlayerInventoryWeightable>();
2023-10-20 22:46:14 +08:00
2023-09-01 14:33:54 +08:00
weighted.OnWeighted += OnWeighted;
equipContainer.OnEquip += OnEquip;
equipContainer.OnDeEquip += DeEquip;
2023-06-08 14:09:50 +08:00
inventory.OnAdd += OnAdd;
inventory.OnRemove += OnRemove;
2023-10-24 23:37:59 +08:00
inventory.OnUsedItem += OnRemove;
2024-03-31 23:34:22 +08:00
_equipment.OnEquip += x =>
{
if (x.GetAssetable().TryGetProperty<PlayerUseCloseInventory>(out _) is false) return;
UXService.Entry<UXHud>();
};
2023-06-08 14:09:50 +08:00
inventory.OnSet += OnSet;
2024-02-21 01:40:53 +08:00
inventory.OnRebuild += OnRebuild;
2023-08-23 01:59:40 +08:00
2023-10-30 01:25:53 +08:00
_unityEntity = unityEntity;
2023-10-20 19:31:12 +08:00
2024-03-31 23:34:22 +08:00
builder.Clear(true);
2023-06-08 14:09:50 +08:00
}
2024-02-21 01:40:53 +08:00
private void OnRebuild(IBasicItemContainer obj)
{
foreach (var x in itemContainers.Values)
{
x.visualElement.RemoveFromHierarchy();
}
foreach (var VARIABLE in obj.GetItems())
{
OnAdd(VARIABLE);
}
}
2023-08-27 02:58:19 +08:00
private static void OnReturn(InputAction.CallbackContext context)
2023-06-08 14:09:50 +08:00
{
2024-01-03 00:27:12 +08:00
if (context is {interaction:PressInteraction,performed:true})
2023-08-27 02:58:19 +08:00
UXService.Entry<UXHud>();
2023-06-08 14:09:50 +08:00
}
2023-09-01 14:33:54 +08:00
public void OnWeighted(double current, double max)
2023-06-08 14:09:50 +08:00
{
2023-09-01 14:33:54 +08:00
var value = current is 0 ? 0 : (current / max);
weightBar.SetDirect((float) value,$"{current}/{max}");
2023-06-08 14:09:50 +08:00
}
private void OnAdd(IBasicItem item)
{
2023-10-24 23:37:59 +08:00
// 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);
2023-06-08 14:09:50 +08:00
uxContainer.button.clicked += () =>
{
UseItem(item);
};
2023-08-27 02:58:19 +08:00
uxContainer.visualElement.Q<Button>().RegisterCallback<MouseDownEvent>(x =>
2023-06-08 14:09:50 +08:00
{
if (x.button is 1)
{
ContextMenuBuilder
.Create()
.BuildAction("使用", () => UseItem(item))
.BuildAction("丢下", () => DropItem(item))
2023-12-03 17:35:43 +08:00
.BuildAction("检视", () => UXInventoryInspector.Entry(item))
2023-06-08 14:09:50 +08:00
.Build();
}
});
2024-03-31 23:34:22 +08:00
uxContainer.visualElement.Q<Button>().tooltip = item.GetAssetable().Description;
2023-08-27 02:58:19 +08:00
itemContainers.Add(item.Id, uxContainer);
2024-03-31 23:34:22 +08:00
OnSet(item);
2023-06-08 14:09:50 +08:00
}
private void OnRemove(IBasicItem item)
{
2023-08-27 02:58:19 +08:00
if (!itemContainers.TryGetValue(item.Id, out var uxContainer)) return;
uxContainer.visualElement.RemoveFromHierarchy();
itemContainers.Remove(item.Id);
2023-06-08 14:09:50 +08:00
}
2023-08-23 01:59:40 +08:00
private void OnSet(IBasicItem item)
2023-06-08 14:09:50 +08:00
{
2023-08-27 02:58:19 +08:00
if (!itemContainers.TryGetValue(item.Id, out var uxContainer)) return;
2023-12-03 17:35:43 +08:00
UXUtils.CreateItemContainer(uxContainer, item);
2023-06-08 14:09:50 +08:00
}
2023-10-20 19:31:12 +08:00
2023-06-08 14:09:50 +08:00
private void UseItem(IBasicItem item)
{
2023-10-24 23:37:59 +08:00
inventory.TryUseItem(item);
2023-06-08 14:09:50 +08:00
}
2023-10-20 19:31:12 +08:00
2023-06-08 14:09:50 +08:00
private void DropItem(IBasicItem item)
{
inventory.Drop(item.Id);
}
2023-09-01 14:33:54 +08:00
private void OnEquip(IEquipmentSlot slot, IBasicItem item)
2023-06-08 14:09:50 +08:00
{
var asset = item.GetAssetable();
2023-09-01 14:33:54 +08:00
if (!equipContainers.TryGetValue(slot.GetType().Name, out var container)) return;
container.icon.style.backgroundImage = asset.SquareIcon;
2023-10-24 23:37:59 +08:00
//BIT4Log.Log<UXInventory>($"已装备:{item.Name}@{slot.GetType().Name}");
2023-06-08 14:09:50 +08:00
}
2023-09-01 14:33:54 +08:00
private void DeEquip(IEquipmentSlot slot, IBasicItem item)
2023-06-08 14:09:50 +08:00
{
2023-09-01 14:33:54 +08:00
if (!equipContainers.TryGetValue(slot.GetType().Name, out var container)) return;
container.icon.style.backgroundImage = null;
2023-06-08 14:09:50 +08:00
}
}
}