85 lines
2.6 KiB
C#
85 lines
2.6 KiB
C#
using System;
|
|
using SepCore.DataTable;
|
|
using SepCore.Definition;
|
|
using SepCore.Timer;
|
|
using UnityEngine;
|
|
|
|
namespace SepCore.EnemyManager
|
|
{
|
|
public class EnemySpawnScheduler
|
|
{
|
|
private const float MinSpawnRateScale = 0.1f;
|
|
|
|
private float _elapsedTime;
|
|
private float[] _baseIntervals;
|
|
private EnemyType[] _enemyTypes;
|
|
private int[] _spawnCounts;
|
|
private TimerHandle[] _waveHandles;
|
|
private float _spawnRateScale = 1f;
|
|
private Action<EnemyType, int> _onSpawn;
|
|
|
|
public float SpawnRateScale => _spawnRateScale;
|
|
public float ElapsedTime => _elapsedTime;
|
|
public int WaveCount => _enemyTypes?.Length ?? 0;
|
|
|
|
public void Init(DRLevel level, Action<EnemyType, int> onSpawn)
|
|
{
|
|
GameEntry.Timer.CancelByOwner(this);
|
|
|
|
_onSpawn = onSpawn;
|
|
_baseIntervals = (float[])level.Intervals.Clone();
|
|
_enemyTypes = level.EntityTypes;
|
|
_spawnCounts = level.EntityCounts;
|
|
_elapsedTime = 0f;
|
|
|
|
_waveHandles = new TimerHandle[_baseIntervals.Length];
|
|
for (int i = 0; i < _baseIntervals.Length; i++)
|
|
{
|
|
int waveIndex = i;
|
|
float interval = GetScaledInterval(_baseIntervals[i], _spawnRateScale);
|
|
_waveHandles[i] = GameEntry.Timer.ScheduleRepeat(interval, () => OnWaveTick(waveIndex), -1, this);
|
|
}
|
|
}
|
|
|
|
public void Tick(float deltaTime)
|
|
{
|
|
_elapsedTime += deltaTime;
|
|
}
|
|
|
|
public void SetSpawnRateScale(float scale)
|
|
{
|
|
_spawnRateScale = Mathf.Max(MinSpawnRateScale, scale);
|
|
if (_waveHandles == null) return;
|
|
|
|
for (int i = 0; i < _waveHandles.Length; i++)
|
|
{
|
|
float newInterval = GetScaledInterval(_baseIntervals[i], _spawnRateScale);
|
|
GameEntry.Timer.SetInterval(_waveHandles[i], newInterval, adjustRemainingTime: true);
|
|
}
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
GameEntry.Timer.CancelByOwner(this);
|
|
_elapsedTime = 0;
|
|
_baseIntervals = null;
|
|
_enemyTypes = null;
|
|
_spawnCounts = null;
|
|
_waveHandles = null;
|
|
_spawnRateScale = 1f;
|
|
_onSpawn = null;
|
|
}
|
|
|
|
private void OnWaveTick(int waveIndex)
|
|
{
|
|
_onSpawn?.Invoke(_enemyTypes[waveIndex], _spawnCounts[waveIndex]);
|
|
}
|
|
|
|
private static float GetScaledInterval(float baseInterval, float scale)
|
|
{
|
|
float safeScale = Mathf.Max(MinSpawnRateScale, scale);
|
|
return baseInterval / safeScale;
|
|
}
|
|
}
|
|
}
|