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

215 lines
7.0 KiB
C#
Raw Normal View History

2023-06-08 14:09:50 +08:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BITKit;
using BITKit.Entities;
using System;
using System.Linq;
2023-08-27 02:58:19 +08:00
using System.Threading;
using AYellowpaper.SerializedCollections;
2023-10-20 19:31:12 +08:00
using BITFALL.Entities.Inventory;
using BITKit.Entities.Slot;
2023-08-27 02:58:19 +08:00
using Cysharp.Threading.Tasks;
2023-06-08 14:09:50 +08:00
namespace BITFALL
{
2023-10-20 19:31:12 +08:00
[CustomType(typeof(IEntityInventory))]
2023-08-27 02:58:19 +08:00
[CustomType(typeof(IBasicItemContainer))]
2023-10-30 01:25:53 +08:00
public class EntityInventory : EntityBehavior, IEntityInventory
2023-06-08 14:09:50 +08:00
{
/// <summary>
/// 数据字典
/// </summary>
2023-10-20 19:31:12 +08:00
protected readonly Dictionary<int, IBasicItem> dictionary = new();
2023-06-08 14:09:50 +08:00
/// <summary>
/// 隐式接口实现
/// </summary>
2023-10-30 01:25:53 +08:00
public int Id => (int)UnityEntity.Id;
2023-10-20 19:31:12 +08:00
public bool DropOrSpawn(IBasicItem item)
{
Drop(item);
return true;
}
2023-06-08 14:09:50 +08:00
/// <summary>
/// 工厂方法
/// </summary>
public event Func<IBasicItem, bool> AddFactory;
public event Func<IBasicItem, bool> RemoveFactory;
public event Func<IBasicItem, bool> DropFactory;
2023-08-27 02:58:19 +08:00
// 回调
2023-06-08 14:09:50 +08:00
public event Action<IBasicItem> OnAdd;
2023-10-24 23:37:59 +08:00
public event Action<IBasicItem> OnUsedItem;
2023-06-08 14:09:50 +08:00
public event Action<IBasicItem> OnRemove;
2023-10-24 23:37:59 +08:00
public event Func<IBasicItem, bool> TryUseItemFactory;
2023-06-08 14:09:50 +08:00
public event Action<IBasicItem> OnSet;
public event Action<IBasicItem> OnDrop;
public event Action<IBasicItemContainer> OnRebuild;
2023-10-24 23:37:59 +08:00
public bool Clear(int id)
{
throw new NotImplementedException();
}
public bool TryUseItem(IBasicItem item)
2023-10-20 19:31:12 +08:00
{
if (dictionary.ContainsKey(item.Id) is false)
{
return false;
}
2024-02-21 01:40:53 +08:00
// if (item.GetAssetable().TryGetProperty<ICustomItemBehavior>(out var customItemBehavior))
// {
// // customItemBehavior.Inject(UnityEntity);
// // if (customItemBehavior.TryUse(item))
// // {
// // customItemBehavior.OnUse(item);
// // Remove(item);
// // return true;
// // }
// customItemBehavior.Inject(UnityEntity);
// if (customItemBehavior.TryUse(item))
// {
// customItemBehavior.OnUse(item);
// }
// if (customItemBehavior.IsAdditive is false) return true;
// }
var isUsed=false;
2023-11-30 00:23:23 +08:00
if (item.GetAssetable().TryGetProperty<ICustomItemBehavior>(out var customItemBehavior))
{
2024-02-21 01:40:53 +08:00
Entity.Inject(customItemBehavior);
isUsed = customItemBehavior.TryUse(item);
2023-11-30 00:23:23 +08:00
}
2024-02-21 01:40:53 +08:00
return isUsed ||TryUseItemFactory is not null && TryUseItemFactory.CastAsFunc().Any(x => x.Invoke(item));
2023-10-24 23:37:59 +08:00
}
public void UseItem(IBasicItem item)
{
2024-02-21 01:40:53 +08:00
if(item.GetAssetable().TryGetProperty<ICustomItemBehavior>(out var customItemBehavior))
{
customItemBehavior.OnUse(item);
}
2023-10-24 23:37:59 +08:00
dictionary.TryRemove(item.Id);
2024-02-21 01:40:53 +08:00
OnUsedItem?.Invoke(item);
2023-10-20 19:31:12 +08:00
}
2023-12-03 17:35:43 +08:00
public bool TrySetItem(IBasicItem item)
{
if (dictionary.TryGetValue(item.Id, out var currentItem) is false) return false;
dictionary[item.Id] = item;
OnSet?.Invoke(item);
return true;
}
2023-10-20 19:31:12 +08:00
[Inject]
protected IHealth _health;
[Inject]
protected IEntitySlot<Transform> _modelSlots;
2023-08-27 02:58:19 +08:00
public override void OnAwake()
{
2023-09-01 14:33:54 +08:00
_health.OnSetAlive += OnSetAlive;
2023-10-20 22:46:14 +08:00
}
2023-11-30 00:23:23 +08:00
protected virtual void OnSetAlive(bool alive)
2023-08-27 02:58:19 +08:00
{
2023-09-01 14:33:54 +08:00
if (alive) return;
foreach (var x in dictionary.Values.ToArray())
2023-08-27 02:58:19 +08:00
{
2023-09-01 14:33:54 +08:00
OnRemove?.Invoke(x);
Drop(x);
2023-08-27 02:58:19 +08:00
}
2023-09-01 14:33:54 +08:00
dictionary.Clear();
2023-08-27 02:58:19 +08:00
}
2023-06-08 14:09:50 +08:00
public virtual bool Add(IBasicItem item)
{
2023-09-01 14:33:54 +08:00
if (_health.IsAlive is false)
{
Drop(item);
return true;
}
if (AddFactory?.GetInvocationList().Cast<Func<IBasicItem, bool>>().Any(x => x.Invoke(item)) is false)
{
return false;
}
if (!dictionary.TryAdd(item.Id, item)) return false;
2023-06-08 14:09:50 +08:00
{
OnAdd?.Invoke(item);
return true;
}
}
2023-09-01 14:33:54 +08:00
2023-06-08 14:09:50 +08:00
public virtual IBasicItem[] GetItems() => dictionary.Values.ToArray();
public virtual bool Remove(IBasicItem item)
{
return Remove(item.Id);
}
2023-09-01 14:33:54 +08:00
2023-06-08 14:09:50 +08:00
public virtual bool Remove(int id)
{
2023-09-01 14:33:54 +08:00
if (!dictionary.TryGetValue(id, out var item)) return false;
if (RemoveFactory is not null)
if (RemoveFactory.GetInvocationList().Cast<Func<IBasicItem,bool>>().Any(x => x.Invoke(item) is false))
2023-06-08 14:09:50 +08:00
{
2023-09-01 14:33:54 +08:00
return false;
2023-06-08 14:09:50 +08:00
}
2023-09-01 14:33:54 +08:00
dictionary.Remove(id);
OnRemove?.Invoke(item);
return true;
2023-06-08 14:09:50 +08:00
}
public virtual bool Remove(Func<IBasicItem, bool> removeFactory)
{
bool isRemoved = false;
foreach (var x in dictionary.Values.ToArray())
{
if (removeFactory.Invoke(x))
{
Remove(x.Id);
isRemoved = true;
}
}
return isRemoved;
}
public bool TryGetItem(Func<IBasicItem, bool> func, out IBasicItem item)
{
2023-12-03 17:35:43 +08:00
return dictionary.Values.OrderBy(x=>x.TryGetProperty<ICount>(out var count)?count.Count:0).Reverse().TryGetAny(func, out item);
2023-06-08 14:09:50 +08:00
}
2023-08-27 02:58:19 +08:00
2023-09-01 14:33:54 +08:00
public bool Drop(int _Id)
2023-06-08 14:09:50 +08:00
{
2023-09-01 14:33:54 +08:00
if (!dictionary.TryGetValue(_Id, out var item)) return false;
2023-08-27 02:58:19 +08:00
if (!Remove(item)) return false;
2023-09-01 14:33:54 +08:00
if (DropFactory != null && DropFactory.GetInvocationList().Cast<Func<IBasicItem, bool>>()
.Any(x => x.Invoke(item) is false))
{
return false;
}
Drop(item);
return true;
}
2023-12-15 00:08:02 +08:00
protected virtual void Drop(IBasicItem item)
2023-09-01 14:33:54 +08:00
{
OnDrop?.Invoke(item);
2023-11-15 23:54:54 +08:00
var prefab = item.GetAssetable();
2023-12-03 17:35:43 +08:00
var position = Transform.position + Vector3.up;
var rotation = Transform.rotation;
2023-10-20 19:31:12 +08:00
if (_modelSlots.Slots.TryGetValue(prefab.AddressablePath, out var anchor))
2023-08-27 02:58:19 +08:00
{
2023-10-20 19:31:12 +08:00
position = anchor.position;
rotation = anchor.rotation;
2023-06-08 14:09:50 +08:00
}
2023-08-27 02:58:19 +08:00
var instance = Instantiate(prefab.GetPrefab(), position, rotation);
instance.CopyItemsFrom(item);
2023-12-15 00:08:02 +08:00
instance.WaitForInitializationComplete();
}
protected virtual void InvokeOnDrop(IBasicItem item)
{
OnDrop?.Invoke(item);
2023-06-08 14:09:50 +08:00
}
2024-02-21 01:40:53 +08:00
protected void RebuildInternal()
{
OnRebuild?.Invoke(this);
}
2023-06-08 14:09:50 +08:00
}
}