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

163 lines
5.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
using UnityEngine.AddressableAssets;
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-20 19:31:12 +08:00
public abstract class EntityInventory : EntityComponent, 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-08-12 01:43:24 +08:00
public int Id => (int)entity.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-20 19:31:12 +08:00
public event Action<IBasicItem> OnUsed;
2023-06-08 14:09:50 +08:00
public event Action<IBasicItem> OnRemove;
public event Action<IBasicItem> OnSet;
public event Action<IBasicItem> OnDrop;
public event Action<IBasicItemContainer> OnRebuild;
2023-10-20 19:31:12 +08:00
public bool UseItem(IBasicItem item)
{
if (dictionary.ContainsKey(item.Id) is false)
{
return false;
}
dictionary.Remove(item.Id);
OnUsed?.Invoke(item);
return true;
}
[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-09-01 14:33:54 +08:00
private 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)
{
return dictionary.Values.TryGetAny(func, out item);
}
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-10-20 19:31:12 +08:00
protected void Drop(IBasicItem item)
2023-09-01 14:33:54 +08:00
{
OnDrop?.Invoke(item);
var prefab = Addressables.LoadAssetAsync<AssetableItem>(item.AddressablePath).WaitForCompletion();
2023-08-27 02:58:19 +08:00
var _transform = transform;
var position = _transform.position;
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-06-08 14:09:50 +08:00
}
}
}