wave behavior and fixed explosion
This commit is contained in:
100
managers/Wave/WaveManager.cs
Normal file
100
managers/Wave/WaveManager.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
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 (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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user