165 lines
5.9 KiB
C#
165 lines
5.9 KiB
C#
|
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<int, UXContainer> containers = new();
|
||
|
|
||
|
private readonly Dictionary<string, UXContainer> 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<IEquipmentSlot>())
|
||
|
{
|
||
|
var element = document.rootVisualElement.Q(x.Name);
|
||
|
if(element is not null)
|
||
|
{
|
||
|
UXContainer uxContainer = new(element);
|
||
|
equipContainers.Add(x.Name, uxContainer);
|
||
|
element.RegisterCallback<MouseDownEvent>(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<IWeightedCallback>(this);
|
||
|
entity.RegisterCallback<IPlayerEquipCallback>(this);
|
||
|
inventory = entity.Get<IBasicItemContainer>();
|
||
|
equipContainer = entity.Get<IPlayerEquipContainer>();
|
||
|
|
||
|
inventory.OnAdd += OnAdd;
|
||
|
inventory.OnRemove += OnRemove;
|
||
|
inventory.OnSet += OnSet;
|
||
|
}
|
||
|
private void OnInventory(InputAction.CallbackContext context)
|
||
|
{
|
||
|
if (context.action.WasPressedThisFrame() && returnInterval)
|
||
|
UXFramework.Enter<HUD>();
|
||
|
}
|
||
|
private void OnReturn(InputAction.CallbackContext context)
|
||
|
{
|
||
|
if (context.started && returnInterval)
|
||
|
UXFramework.Enter<HUD>();
|
||
|
}
|
||
|
|
||
|
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<AssetableItem>(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<MouseDownEvent>(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<int>(out var count))
|
||
|
{
|
||
|
uxContainer.numberLabel.text = count.ToString();
|
||
|
}
|
||
|
}
|
||
|
private void UseItem(IBasicItem item)
|
||
|
{
|
||
|
IEntity.LocalPlayer.Get<IRequestor<IBasicItem>>().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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|