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 _onSpawn; public float SpawnRateScale => _spawnRateScale; public float ElapsedTime => _elapsedTime; public int WaveCount => _enemyTypes?.Length ?? 0; public void Init(DRLevel level, Action 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; } } }