111 lines
3.2 KiB
C#
111 lines
3.2 KiB
C#
using System.Collections.Generic;
|
|
using GeometryTD.Entity;
|
|
using GeometryTD.Map;
|
|
using UnityEngine;
|
|
|
|
namespace GeometryTD.CustomComponent
|
|
{
|
|
internal sealed class SpawnerResolver
|
|
{
|
|
private readonly List<Spawner> _spawners = new();
|
|
private readonly Dictionary<int, Spawner> _spawnerByOrder = new();
|
|
private readonly List<Vector3> _pathBuffer = new();
|
|
|
|
private int _nextSpawnerIndex;
|
|
private int _currentMapEntityId;
|
|
|
|
public void Reset()
|
|
{
|
|
_spawners.Clear();
|
|
_spawnerByOrder.Clear();
|
|
_pathBuffer.Clear();
|
|
_nextSpawnerIndex = 0;
|
|
_currentMapEntityId = 0;
|
|
}
|
|
|
|
public void RefreshCache(CombatScheduler combatScheduler, bool force)
|
|
{
|
|
MapEntity currentMap = combatScheduler != null ? combatScheduler.CurrentMap : null;
|
|
if (currentMap == null)
|
|
{
|
|
Reset();
|
|
return;
|
|
}
|
|
|
|
if (!force && _currentMapEntityId == currentMap.Id && _spawners.Count > 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_spawners.Clear();
|
|
_spawnerByOrder.Clear();
|
|
_nextSpawnerIndex = 0;
|
|
_currentMapEntityId = currentMap.Id;
|
|
|
|
Spawner[] mapSpawners = currentMap.Spawners;
|
|
for (int i = 0; i < mapSpawners.Length; i++)
|
|
{
|
|
Spawner spawner = mapSpawners[i];
|
|
if (spawner == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!currentMap.TryGetDefaultPathCells(spawner, out _))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
_spawners.Add(spawner);
|
|
if (spawner.SpawnOrder > 0 && !_spawnerByOrder.ContainsKey(spawner.SpawnOrder))
|
|
{
|
|
_spawnerByOrder[spawner.SpawnOrder] = spawner;
|
|
}
|
|
}
|
|
|
|
_spawners.Sort((left, right) => left.SpawnOrder.CompareTo(right.SpawnOrder));
|
|
}
|
|
|
|
public bool TryResolveSpawnPath(CombatScheduler combatScheduler, int spawnPointId, out IReadOnlyList<Vector3> pathPoints)
|
|
{
|
|
pathPoints = null;
|
|
MapEntity currentMap = combatScheduler != null ? combatScheduler.CurrentMap : null;
|
|
if (currentMap == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Spawner spawner = ResolveSpawner(spawnPointId);
|
|
if (spawner == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!currentMap.TryFindPathWorldPoints(spawner, null, _pathBuffer) || _pathBuffer.Count <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
pathPoints = _pathBuffer;
|
|
return true;
|
|
}
|
|
|
|
private Spawner ResolveSpawner(int spawnPointId)
|
|
{
|
|
if (spawnPointId > 0 && _spawnerByOrder.TryGetValue(spawnPointId, out Spawner mappedSpawner))
|
|
{
|
|
return mappedSpawner;
|
|
}
|
|
|
|
if (_spawners.Count <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Spawner fallbackSpawner = _spawners[_nextSpawnerIndex % _spawners.Count];
|
|
_nextSpawnerIndex++;
|
|
return fallbackSpawner;
|
|
}
|
|
}
|
|
}
|