BITFALL/Assets/Artists/Scripts/Item/WorldItemContainer.cs

129 lines
3.5 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BITKit;
using Quadtree;
using Quadtree.Items;
using Steamworks.Ugc;
using UnityEngine;
namespace BITFALL.Items
{
public class WorldItemContainer : MonoBehaviour,IBasicItemContainer,IDescription, IItem<WorldItemContainer, Node<WorldItemContainer>>
{
private static readonly QuadtreeRoot<WorldItemContainer,Node<WorldItemContainer>> _quadtreeRoot=new(Vector3.zero,Vector3.one*1024);
public static WorldItemContainer[] Query(Vector3 position, Vector3 size)
{
return _quadtreeRoot.Find(new Bounds(position,size)).ToArray();
}
/// <summary>
/// 容器名称
/// </summary>
[SerializeField] private string containerName;
/// <summary>
/// 是否允许拾取
/// </summary>
[SerializeField] public bool AllowLoot;
/// <summary>
/// 是否允许存储
/// </summary>
[SerializeField] public bool AllowStorage;
public string Name => containerName;
private readonly Dictionary<int,IBasicItem> _items = new();
public int Id => GetInstanceID();
private void Start()
{
_quadtreeRoot.Insert(this);
destroyCancellationToken.Register(OnDisposed);
releaseHandle.AddListener(x=>OnRelease?.Invoke(!x));
}
private void OnDisposed()
{
_quadtreeRoot.Remove(this);
}
public bool TryGetItem(Func<IBasicItem, bool> func, out IBasicItem item)
{
if (_items.Values.TryGetAny(func.Invoke,out item))
{
return true;
}
item=null;
return false;
}
public IBasicItem[] GetItems()=>_items.Values.ToArray();
public bool Add(IBasicItem item)
{
if (AllowStorage is false) return false;
if (AddFactory.CastAsFunc().Any(x=>x.Invoke(item) is false)) return false;
if (_items.ContainsKey(item.Id)) return false;
AddInternal(item);
return true;
}
public void AddInternal(IBasicItem item)
{
_items.Add(item.Id,item);
OnAdd?.Invoke(item);
OnSet?.Invoke(item);
}
public bool Remove(IBasicItem item)
{
return Remove(item.Id);
}
public bool Remove(int id)
{
if (AllowLoot is false) return false;
if (_items.TryGetValue(id, out var item) is false) return false;
if (RemoveFactory.CastAsFunc().Any(x=>x.Invoke(item) is false)) return false;
if (!_items.Remove(id)) return false;
OnRemove?.Invoke(item);
return true;
}
public bool Remove(Func<IBasicItem, bool> removeFactory)
{
return _items.Values.TryGetAny(removeFactory.Invoke,out var item) && Remove(item);
}
public bool Drop(int Id)
{
throw new NotImplementedException();
}
public bool DropOrSpawn(IBasicItem item)
{
throw new NotImplementedException();
}
public event Func<IBasicItem, bool> AddFactory;
public event Func<IBasicItem, bool> RemoveFactory;
public event Func<IBasicItem, bool> DropFactory;
public event Action<IBasicItem> OnAdd;
public event Action<IBasicItem> OnRemove;
public event Action<IBasicItem> OnSet;
public event Action<IBasicItem> OnDrop;
public event Action<IBasicItemContainer> OnRebuild;
public event Action<bool> OnRelease;
private readonly ValidHandle releaseHandle = new();
public void AddHandle(int id)
{
releaseHandle.AddElement(id);
}
public void RemoveHandle(int id)
{
releaseHandle.RemoveElement(id);
}
public Bounds GetBounds() => new Bounds(transform.position, Vector3.one);
public Node<WorldItemContainer> ParentNode { get; set; }
public void QuadTree_Root_Initialized(IQuadtreeRoot<WorldItemContainer, Node<WorldItemContainer>> root)
{
}
}
}