BITFALL/Assets/Artists/Scripts/LootSystem/LootService.cs

123 lines
3.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using BITFALL.GameMode;
using BITKit;
using BITKit.Probability;
using Cysharp.Threading.Tasks;
using Quadtree;
using Quadtree.Items;
using UnityEngine;
using YooAsset;
using Random = UnityEngine.Random;
namespace BITFALL.LootSystem
{
public class LootService : MonoBehaviour,ILootSystem
{
private class LootQuad:IItem<LootQuad,Node<LootQuad>>
{
public int Id { get; set; }
public Bounds GetBounds() => Bounds;
public Bounds Bounds { get; set; }
public Node<LootQuad> ParentNode { get; set; }
public void QuadTree_Root_Initialized(IQuadtreeRoot<LootQuad, Node<LootQuad>> root)
{
}
}
private readonly QuadtreeRoot<LootQuad, Node<LootQuad>> _quadtreeRoot = new(default,Vector3.one*2048);
[SerializeReference, SubclassSelector] private ITicker ticker;
[SerializeField, ReadOnly] private int tickCount;
[SerializeField, ReadOnly] private int count;
private readonly Dictionary<int,LootQuad> _lootQuads = new();
private bool _isBusy;
private readonly List<ScriptableLootTable> _lootTables = new();
private async void Start()
{
NodeQuery.AddRegisterListener(typeof(InfoLootSpawn), OnLootSpawnRegister);
foreach (var x in NodeQuery.Query<InfoLootSpawn>())
{
OnLootSpawnRegister(x);
}
foreach (var x in YooAssets.GetAssetInfos(nameof(ScriptableLootTable)))
{
var assetHandle = YooAssets.LoadAssetAsync<ScriptableLootTable>(x.Address);
await assetHandle;
if (destroyCancellationToken.IsCancellationRequested) return;
_lootTables.Add(assetHandle.AssetObject.As<ScriptableLootTable>());
}
destroyCancellationToken.Register(Dispose);
ticker.Add(OnTick);
}
private async void OnTick(float obj)
{
if (_isBusy) return;
_isBusy = true;
tickCount++;
var cameraPosition = Camera.main.transform.position;
await UniTask.SwitchToThreadPool();
var quads = _quadtreeRoot.Find(new Bounds(cameraPosition,Vector3.one*32));
await UniTask.SwitchToMainThread();
if (destroyCancellationToken.IsCancellationRequested) return;
foreach (var quad in quads)
{
foreach (var item in GetValues())
{
var so = item.GetAssetable();
var instance = Instantiate(so.GetPrefab(),quad.Bounds.center,Quaternion.identity);
}
}
foreach (var x in quads)
{
_quadtreeRoot.Remove(x);
}
_isBusy = false;
}
private void OnLootSpawnRegister(object obj)
{
var info = (InfoLootSpawn) obj;
var quad = new LootQuad()
{
Id = count++,
Bounds = new Bounds(info.Position,info.Size)
};
_quadtreeRoot.Insert(quad);
_lootQuads.Add(quad.Id,quad);
}
private void Dispose()
{
ticker.Remove(OnTick);
}
public object GetValueObject(params IProbabilityProperty[] properties)
{
throw new System.NotImplementedException();
}
public object[] GetValuesObject(params IProbabilityProperty[] properties)
{
throw new System.NotImplementedException();
}
public IBasicItem GetValue(params IProbabilityProperty[] properties)
{
throw new System.NotImplementedException();
}
public IBasicItem[] GetValues(params IProbabilityProperty[] properties)
{
var list = new List<IBasicItem>();
foreach (var table in _lootTables.Random().Tables)
{
if (table.Probability > Random.Range(0, 100))
{
list.Add(table.Item);
}
}
return list.ToArray();
}
}
}