using System; using SepCore.Definition; using SepCore.Timer; using UnityGameFramework.Runtime; using UnityEngine; namespace SepCore.EnemyManager { public class EnemySpawnScheduler { private static float MinSpawnRateScale => GameEntry.Luban.Global.MinSpawnRateScale / 1000f; 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; public void Init(LevelConfig level, Action onSpawn) { GameEntry.Timer.CancelByOwner(this); _onSpawn = onSpawn; int count = level.EnemySpawnConfigs.Count; _baseIntervals = new float[count]; _enemyTypes = new EnemyType[count]; _spawnCounts = new int[count]; _elapsedTime = 0f; for (int i = 0; i < count; i++) { var spawnConfig = level.EnemySpawnConfigs[i]; _baseIntervals[i] = spawnConfig.Interval / 1000f; _enemyTypes[i] = spawnConfig.EnemyType; _spawnCounts[i] = spawnConfig.EnemyCount; } _waveHandles = new TimerHandle[count]; for (int i = 0; i < count; 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) { if (_waveHandles == null) { Log.Error("Can not set spawn rate scale before scheduler init."); return; } _spawnRateScale = Mathf.Max(MinSpawnRateScale, scale); 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(_enemyTypes[waveIndex], _spawnCounts[waveIndex]); } private static float GetScaledInterval(float baseInterval, float scale) { float safeScale = Mathf.Max(MinSpawnRateScale, scale); return baseInterval / safeScale; } } }