121 lines
4.1 KiB
C#
121 lines
4.1 KiB
C#
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<EnemyDescription, int> CurrentWave =>
|
|
WaveContent.Waves[CurrentWaveIndex].EnemiesToSpawn;
|
|
|
|
public Dictionary<ulong, Enemy?> CurrentSpawnedEnemies { get; set; } = [];
|
|
public Set<Spawner> SpawnersInUse { get; set; } = [];
|
|
|
|
public List<Spawner> 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
|
|
}
|
|
} |