using System.Collections.Generic; using System.Linq; using Chickensoft.AutoInject; using Chickensoft.Collections; using Chickensoft.Introspection; using Godot; using Movementtests.tools; namespace Movementtests.managers; [GlobalClass, Meta(typeof(IAutoNode))] public partial class WaveManager : Node { public override void _Notification(int what) => this.Notify(what); public WaveContent WaveContent { get; set; } public int CurrentWaveIndex { get; set; } public int CurrentWaveCount => WaveContent.Waves.Length; public Godot.Collections.Dictionary CurrentWave => WaveContent.Waves[CurrentWaveIndex].EnemiesToSpawn; public Dictionary CurrentSpawnedEnemies { get; set; } = []; public Set SpawnersInUse { get; set; } = []; public List Spawners { get; set; } = []; public void RegisterSpawner(Spawner spawner) => Spawners.Add(spawner); public void InitializeFromResource(WaveContent waveContent) => WaveContent = waveContent; public void StartWaves() { CurrentWaveIndex = 0; StartNextWave(); } public void StartNextWave() { if (CurrentWave.Count == 0) { GD.PrintErr("Wave has no enemies"); return; } if (Spawners.Count == 0) { GD.PrintErr("No spawners registered"); return; } SpawnEnemiesAsAvailable(); } public void SpawnEnemiesAsAvailable() { var randomizedSpawners = Spawners.ToArray(); randomizedSpawners.Shuffle(); foreach (var spawner in randomizedSpawners) { if (SpawnersInUse.Contains(spawner)) continue; foreach (var (enemyDescription, numberRemaining) in CurrentWave) { if (numberRemaining <= 0) continue; if (!spawner.SupportedEnemyTypes.Contains(enemyDescription.Type)) continue; var spawnedEnemy = spawner.SpawnEnemy(enemyDescription); if (spawnedEnemy == null) continue; CurrentSpawnedEnemies[spawnedEnemy.GetInstanceId()] = spawnedEnemy; SpawnersInUse.Add(spawner); spawnedEnemy.OnKilled += instanceId=> SpawnedEnemyDied(instanceId, spawner); CurrentWave[enemyDescription]--; break; } } // foreach (var (enemyDescription, numberRemaining) in CurrentWave) // { // if (numberRemaining <= 0) continue; // foreach (var spawner in randomizedSpawners) // { // if (!spawner.SupportedEnemyTypes.Contains(enemyDescription.Type)) continue; // if (SpawnersInUse.Contains(spawner)) continue; // // var spawnedEnemy = spawner.SpawnEnemy(enemyDescription); // if (spawnedEnemy == null) continue; // // CurrentSpawnedEnemies[spawnedEnemy.GetInstanceId()] = spawnedEnemy; // SpawnersInUse.Add(spawner); // // spawnedEnemy.OnKilled += instanceId=> SpawnedEnemyDied(instanceId, spawner); // // CurrentWave[enemyDescription]--; // break; // } // } var remainingEnemiesToSpawn = CurrentWave.Values.Sum(); if (remainingEnemiesToSpawn <= 0) return; // Wave is fully spawned GetTree().CreateTimer(1.0f).Timeout += SpawnEnemiesAsAvailable; // Call back the same function later to try and spawn the rest } public void SpawnedEnemyDied(ulong instanceId, Spawner spawner) { CurrentSpawnedEnemies.Remove(instanceId); SpawnersInUse.Remove(spawner); if (CurrentSpawnedEnemies.Count == 0) FinishWave(); } public void FinishWave() { if (CurrentWaveIndex >= CurrentWaveCount) return; // All waves finished CurrentWaveIndex++; GetTree().CreateTimer(1.0f).Timeout += StartNextWave; // Start next wave in 1s } }