123 lines
3.3 KiB
C#
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();
|
|
}
|
|
}
|
|
|
|
}
|