BITFALL/Assets/Artists/Scripts/Entities/Inventory/PlayerInventory.cs

296 lines
9.5 KiB
C#
Raw Normal View History

2023-10-20 19:31:12 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BITKit;
using System.Threading.Tasks;
using UnityEngine.UIElements;
using System.Text;
using BITKit.Entities;
using System.Linq;
2024-01-03 00:27:12 +08:00
using System.Security.Cryptography;
2023-10-20 19:31:12 +08:00
using BITFALL.Entities;
using BITFALL.Entities.Improvised;
2024-04-06 16:33:57 +08:00
using BITFALL.Hotkey;
2023-12-15 00:08:02 +08:00
using BITFALL.Items;
2023-10-20 19:31:12 +08:00
using BITFALL.Player.Inventory;
2024-02-21 01:40:53 +08:00
using BITKit.IO;
2023-10-20 19:31:12 +08:00
using BITKit.Selection;
2023-12-03 17:35:43 +08:00
using BITKit.UX;
2023-12-15 00:08:02 +08:00
using Unity.Mathematics;
2024-02-21 01:40:53 +08:00
using YooAsset;
2023-10-20 19:31:12 +08:00
namespace BITFALL
{
[CustomType(typeof(IPlayerInventory))]
public class PlayerInventory : EntityInventory,IPlayerInventory
{
2024-01-03 00:27:12 +08:00
[SerializeField] private int currentMoney;
2023-12-15 00:08:02 +08:00
[Header(nameof(PlayerInventory))]
[SerializeReference,SubclassSelector] private INetClient netClient;
[SerializeReference,SubclassSelector] private INetServer netServer;
private INetProvider _clientNetProvider=>netClient as INetProvider;
private INetProvider _serverNetProvider=>netServer as INetProvider;
2024-04-06 16:33:57 +08:00
[Inject] private ISelector _selector;
[Inject(true)] private ImprovisedServiceInterface _improvisedService;
[Inject(true)] private IKnockdown _knockdown;
[Inject(true)] private IUXPopup _popup;
[Inject(true)] private IApplicationFile applicationFile;
[Inject(true)] private IHotkeyCollection _hotkeyCollection;
private HotkeyProvider? _pickItemHotkey;
2023-10-20 19:31:12 +08:00
public override void OnStart()
{
base.OnStart();
_selector.OnActive += OnActive;
2024-04-06 16:33:57 +08:00
_selector.OnSelected += OnSelected;
_selector.OnInactive += OnInactive;
2023-10-20 19:31:12 +08:00
if (_improvisedService is not null)
{
_improvisedService.OnUnEquipImprovisedItem += OnUnEquipImprovisedItem;
}
2023-12-03 17:35:43 +08:00
OnAdd += OnAddItem;
OnRemove += OnRemoveItem;
OnUsedItem += OnUseItem;
2024-02-21 01:40:53 +08:00
applicationFile.AddListener(nameof(PlayerInventory),OnRelease);
applicationFile.DataHandle += OnData;
2024-03-31 23:34:22 +08:00
OnMoneyChanged?.Invoke(currentMoney);
2024-02-21 01:40:53 +08:00
}
2024-04-06 16:33:57 +08:00
private void OnInactive(ISelectable obj)
{
CancelCurrent();
}
private void OnSelected(ISelectable obj)
{
if (obj.Transform.TryGetComponent<IWorldItemObject>(out var worldItemObject) && worldItemObject.Item is not null)
{
if (_pickItemHotkey?.Data == worldItemObject)
{
return;
}
CancelCurrent();
_pickItemHotkey = new HotkeyProvider()
{
Data = worldItemObject,
Description = "捡起可互动的物品",
Enabled = true,
Name = $"捡起:{worldItemObject.Item.Name}",
OnPerform = Pick,
};
_hotkeyCollection.Register(_pickItemHotkey);
void Pick()
{
if (Add(worldItemObject.Item))
{
Destroy(obj.Transform.gameObject);
}
}
}
else
{
CancelCurrent();
}
}
private void CancelCurrent()
{
if (_pickItemHotkey is null) return;
_hotkeyCollection.UnRegister(_pickItemHotkey);
_pickItemHotkey = null;
}
2024-02-21 01:40:53 +08:00
public override void OnDestroyComponent()
{
base.OnDestroyComponent();
applicationFile.RemoveListener(nameof(PlayerInventory),OnRelease);
applicationFile.DataHandle -= OnData;
}
private (string, byte[]) OnData()
{
using var ms = new System.IO.MemoryStream();
using var writer = new System.IO.BinaryWriter(ms);
var reportBuilder = new StringBuilder();
var items = GetItems();
writer.Write(items.Length);
reportBuilder.AppendLine(items.Length.ToString());
foreach (var item in items)
{
writer.Write(item.Id);
writer.Write(item.AddressablePath);
reportBuilder.AppendLine(item.AddressablePath);
}
BIT4Log.Log<PlayerInventory>(reportBuilder.ToString());
return new(nameof(PlayerInventory),ms.ToArray());
}
private void OnRelease(byte[] obj)
{
using var ms = new System.IO.MemoryStream(obj);
using var reader = new System.IO.BinaryReader(ms);
dictionary.Clear();
var length = reader.ReadInt32();
for (var i = 0; i < length; i++)
{
var id = reader.ReadInt32();
var path = reader.ReadString();
2024-04-06 16:33:57 +08:00
var so = YooAssets.LoadAssetSync(path).AssetObject.As<ScriptableItem>();
2024-02-21 01:40:53 +08:00
var item = new ManagedItem();
item.CopyItemsFrom(so);
item.Id = id;
dictionary.Add(id,item);
}
RebuildInternal();
2023-12-03 17:35:43 +08:00
}
private void OnUseItem(IBasicItem obj)
{
_popup?.Popup($"使用了[{obj.Name}]");
}
private void OnRemoveItem(IBasicItem obj)
{
_popup?.Popup($"移除了[{obj.Name}]");
}
private void OnAddItem(IBasicItem obj)
{
_popup?.Popup($"捡起了[{obj.Name}]");
2023-10-20 19:31:12 +08:00
}
2023-11-30 00:23:23 +08:00
protected override void OnSetAlive(bool alive)
{
var keepInventory = Data.Get<bool>(BITConstant.Environment.sp_keepInventory);
if (keepInventory)
{
}
else
{
base.OnSetAlive(alive);
}
}
2023-10-20 19:31:12 +08:00
private void OnUnEquipImprovisedItem(IBasicItem obj)
{
Drop(obj);
}
2023-12-15 00:08:02 +08:00
public override bool Add(IBasicItem item)
{
var result = base.Add(item);
if (result && netClient.IsConnected)
{
_clientNetProvider.ServerCommand(new WorldItemDespawnCommand()
{
Id = item.Id,
});
}
return result;
}
protected override void Drop(IBasicItem item)
{
if(netClient.IsConnected)
{
InvokeOnDrop(item);
_clientNetProvider.ServerCommand(new WorldItemSpawnCommand()
{
Id = item.Id,
AddressableId = item.GetAssetable().AddressableId,
Position = Transform.position,
Rotation = Transform.rotation,
});
}
else
{
base.Drop(item);
}
}
2023-10-20 19:31:12 +08:00
private void OnActive(ISelectable obj)
{
2024-04-06 16:33:57 +08:00
CancelCurrent();
2024-03-31 23:34:22 +08:00
if (obj.Transform.TryGetComponent<WorldItem>(out var item))
2023-10-20 19:31:12 +08:00
{
2024-03-31 23:34:22 +08:00
var _item = item.Pick();
if(item.GetAssetable().IsImprovised)
2023-10-20 19:31:12 +08:00
{
2024-03-31 23:34:22 +08:00
if (_knockdown is not null && _knockdown.IsKnockdown)
{
return;
}
if (_improvisedService.TryEquipImprovisedItem(_item))
{
item.Picked();
}
2023-10-20 19:31:12 +08:00
}
2024-03-31 23:34:22 +08:00
else if (Add(_item))
2023-10-20 19:31:12 +08:00
{
item.Picked();
}
}
2024-04-06 16:33:57 +08:00
if (obj.Transform.TryGetComponent<WorldMoney>(out var money))
2023-10-24 23:37:59 +08:00
{
2024-04-06 16:33:57 +08:00
Destroy(obj.Transform.gameObject);
//currentMoney += money.Money;
Transfer(new MonetStrace()
{
Detail = money.Name,
Money = money.Money,
});
}
2023-10-20 19:31:12 +08:00
}
2024-01-03 00:27:12 +08:00
public int Money => currentMoney;
public void Transfer(IMoneyStrace strace)
{
currentMoney += strace.Money;
if (string.IsNullOrEmpty(strace.Detail) is false)
{
_popup?.Popup($"{strace.Detail}:{strace.Money}");
}
2024-03-31 23:34:22 +08:00
OnMoneyChanged?.Invoke(currentMoney);
OnTransfer?.Invoke(strace);
}
public event Action<int> OnMoneyChanged;
public event Action<IMoneyStrace> OnTransfer;
public void Drop(IMoneyStrace strace)
{
var min = Mathf.Min(currentMoney,Mathf.Abs(strace.Money));
if (min <= 0) return;
Transfer(new MonetStrace()
{
Money = -Mathf.Abs(min),
Detail = strace.Detail,
});
var drop = WorldMoneyService.Singleton.Spawn(min);
drop.transform.position = Transform.position;
2024-01-03 00:27:12 +08:00
}
2023-10-20 19:31:12 +08:00
}
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(PlayerInventory))]
2024-01-03 00:27:12 +08:00
public class EntityPlayerInventoryInspector : BITInspector<PlayerInventory>
2023-10-20 19:31:12 +08:00
{
public override VisualElement CreateInspectorGUI()
{
FillDefaultInspector();
CreateSubTitle(Constant.Header.Debug);
var serializeLabel = root.Create<Label>();
StringBuilder stringBuilder = new StringBuilder();
foreach (var x in agent.GetItems())
{
stringBuilder.AppendLine($"{x.Id}@{x.Name}");
}
serializeLabel.text=stringBuilder.ToString();
return root;
}
}
#endif
}