wave behavior and fixed explosion
This commit is contained in:
@@ -36,7 +36,8 @@ public partial class TokenManager : Node
|
||||
if (RequestQueue.First() != owner.GetInstanceId()) return null; // Next in line is not the requester
|
||||
|
||||
RequestQueue.RemoveAt(0);
|
||||
var token = new Token(owner.GetInstanceId(), () => UseToken(owner.GetInstanceId()));
|
||||
var ownerInstanceId = owner.GetInstanceId();
|
||||
var token = new Token(ownerInstanceId, () => UseToken(ownerInstanceId));
|
||||
Tokens.Add(token.InstanceId, token);
|
||||
return token;
|
||||
}
|
||||
|
||||
21
managers/Wave/EnemyDescription.cs
Normal file
21
managers/Wave/EnemyDescription.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Godot;
|
||||
|
||||
namespace Movementtests.managers;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class EnemyDescription(PackedScene scene, EnemyDescription.EnemyType type, RMovement? movementOverride) : Resource
|
||||
{
|
||||
public enum EnemyType
|
||||
{
|
||||
Normal,
|
||||
Projectile,
|
||||
}
|
||||
|
||||
[Export(PropertyHint.NodeType)] public required PackedScene Scene { get; set; } = scene;
|
||||
|
||||
[Export] public required EnemyType Type { get; set; } = type;
|
||||
|
||||
[Export] public RMovement? MovementOverride { get; set; } = movementOverride;
|
||||
|
||||
public EnemyDescription() : this(ResourceLoader.Load<PackedScene>("uid://dxt0e2ugmttqq"), EnemyType.Normal, null) {}
|
||||
}
|
||||
1
managers/Wave/EnemyDescription.cs.uid
Normal file
1
managers/Wave/EnemyDescription.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://rhdkfi7nuvu1
|
||||
13
managers/Wave/SingleWave.cs
Normal file
13
managers/Wave/SingleWave.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
|
||||
namespace Movementtests.managers;
|
||||
|
||||
|
||||
[GlobalClass]
|
||||
public partial class SingleWave(EnemyDescription[] enemies) : Resource
|
||||
{
|
||||
[Export] public Godot.Collections.Dictionary<EnemyDescription, int> EnemiesToSpawn { get; set; } = [];
|
||||
|
||||
public SingleWave() : this([]) {}
|
||||
}
|
||||
1
managers/Wave/SingleWave.cs.uid
Normal file
1
managers/Wave/SingleWave.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cr8wog705ane6
|
||||
11
managers/Wave/WaveContent.cs
Normal file
11
managers/Wave/WaveContent.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Godot;
|
||||
|
||||
namespace Movementtests.managers;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class WaveContent(SingleWave[] waves) : Resource
|
||||
{
|
||||
[Export] public SingleWave[] Waves { get; set; } = waves;
|
||||
|
||||
public WaveContent() : this([]) {}
|
||||
}
|
||||
1
managers/Wave/WaveContent.cs.uid
Normal file
1
managers/Wave/WaveContent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dijmv0wqc1xuv
|
||||
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
|
||||
}
|
||||
}
|
||||
1
managers/Wave/WaveManager.cs.uid
Normal file
1
managers/Wave/WaveManager.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cprjrwfk8d0vf
|
||||
9
managers/Wave/resources/flying_enemy_desc.tres
Normal file
9
managers/Wave/resources/flying_enemy_desc.tres
Normal file
@@ -0,0 +1,9 @@
|
||||
[gd_resource type="Resource" script_class="EnemyDescription" format=3 uid="uid://cfyafss8ncbhh"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://cmlud1hwkd6sv" path="res://scenes/enemies/flying_enemy/flying_enemy.tscn" id="1_yvgr4"]
|
||||
[ext_resource type="Script" uid="uid://rhdkfi7nuvu1" path="res://managers/Wave/EnemyDescription.cs" id="2_hsb6g"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_hsb6g")
|
||||
Scene = ExtResource("1_yvgr4")
|
||||
metadata/_custom_type_script = "uid://rhdkfi7nuvu1"
|
||||
9
managers/Wave/resources/grounded_enemy_desc.tres
Normal file
9
managers/Wave/resources/grounded_enemy_desc.tres
Normal file
@@ -0,0 +1,9 @@
|
||||
[gd_resource type="Resource" script_class="EnemyDescription" format=3 uid="uid://3clksludry8g"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://dxt0e2ugmttqq" path="res://scenes/enemies/grounded_enemy/grounded_enemy.tscn" id="1_wxdbf"]
|
||||
[ext_resource type="Script" uid="uid://rhdkfi7nuvu1" path="res://managers/Wave/EnemyDescription.cs" id="2_gk6ig"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_gk6ig")
|
||||
Scene = ExtResource("1_wxdbf")
|
||||
metadata/_custom_type_script = "uid://rhdkfi7nuvu1"
|
||||
17
managers/Wave/resources/one_of_each_wave.tres
Normal file
17
managers/Wave/resources/one_of_each_wave.tres
Normal file
@@ -0,0 +1,17 @@
|
||||
[gd_resource type="Resource" script_class="SingleWave" format=3 uid="uid://dm71u0ryn0w1o"]
|
||||
|
||||
[ext_resource type="Resource" uid="uid://cfyafss8ncbhh" path="res://managers/Wave/resources/flying_enemy_desc.tres" id="1_bcssi"]
|
||||
[ext_resource type="Script" uid="uid://rhdkfi7nuvu1" path="res://managers/Wave/EnemyDescription.cs" id="2_3r6ce"]
|
||||
[ext_resource type="Resource" uid="uid://3clksludry8g" path="res://managers/Wave/resources/grounded_enemy_desc.tres" id="2_mmsra"]
|
||||
[ext_resource type="Resource" uid="uid://lnturc3ibr5c" path="res://managers/Wave/resources/projectile_enemy_desc.tres" id="3_3r6ce"]
|
||||
[ext_resource type="Script" uid="uid://cr8wog705ane6" path="res://managers/Wave/SingleWave.cs" id="5_qckro"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("5_qckro")
|
||||
Enemies = Array[Object]([ExtResource("1_bcssi"), ExtResource("2_mmsra"), ExtResource("3_3r6ce")])
|
||||
EnemiesToSpawn = Dictionary[ExtResource("2_3r6ce"), int]({
|
||||
ExtResource("1_bcssi"): 1,
|
||||
ExtResource("2_mmsra"): 1,
|
||||
ExtResource("3_3r6ce"): 1
|
||||
})
|
||||
metadata/_custom_type_script = "uid://cr8wog705ane6"
|
||||
10
managers/Wave/resources/projectile_enemy_desc.tres
Normal file
10
managers/Wave/resources/projectile_enemy_desc.tres
Normal file
@@ -0,0 +1,10 @@
|
||||
[gd_resource type="Resource" script_class="EnemyDescription" format=3 uid="uid://lnturc3ibr5c"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://dx3y8sjftqk8f" path="res://scenes/enemies/projectile_enemy/projectile_enemy.tscn" id="1_2nepo"]
|
||||
[ext_resource type="Script" uid="uid://rhdkfi7nuvu1" path="res://managers/Wave/EnemyDescription.cs" id="2_bn1dh"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_bn1dh")
|
||||
Scene = ExtResource("1_2nepo")
|
||||
Type = 1
|
||||
metadata/_custom_type_script = "uid://rhdkfi7nuvu1"
|
||||
Reference in New Issue
Block a user