-feat: implement wave logic, automatic ai ship spawning, tweak stats

This commit is contained in:
rsxri 2025-04-22 05:43:03 +01:00
parent fbca225784
commit 30f9bfa5ff
9 changed files with 276 additions and 114 deletions

View file

@ -15,6 +15,7 @@ font_size = 40
collision_mask = 13 collision_mask = 13
motion_mode = 1 motion_mode = 1
script = ExtResource("1_kyds1") script = ExtResource("1_kyds1")
Faction = 2
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_6vq6f") shape = SubResource("CircleShape2D_6vq6f")

View file

@ -4,9 +4,9 @@
[ext_resource type="Script" path="res://script/game.cs" id="1_dukjm"] [ext_resource type="Script" path="res://script/game.cs" id="1_dukjm"]
[ext_resource type="PackedScene" uid="uid://b6myj160l6vf8" path="res://scenes/hud.tscn" id="2_xbhg5"] [ext_resource type="PackedScene" uid="uid://b6myj160l6vf8" path="res://scenes/hud.tscn" id="2_xbhg5"]
[ext_resource type="PackedScene" uid="uid://dnvcics1ni4pa" path="res://scenes/asteroid.tscn" id="3_b8wlr"] [ext_resource type="PackedScene" uid="uid://dnvcics1ni4pa" path="res://scenes/asteroid.tscn" id="3_b8wlr"]
[ext_resource type="PackedScene" uid="uid://3e6fmds2x8q5" path="res://scenes/ai_fighter.tscn" id="5_nkk10"]
[ext_resource type="Texture2D" uid="uid://bjxo7mbl7nert" path="res://assets/Starfield/starfield1.png" id="6_kn6se"] [ext_resource type="Texture2D" uid="uid://bjxo7mbl7nert" path="res://assets/Starfield/starfield1.png" id="6_kn6se"]
[ext_resource type="PackedScene" uid="uid://4fnk5c2nf6a1" path="res://scenes/border.tscn" id="7_p4rds"] [ext_resource type="PackedScene" uid="uid://4fnk5c2nf6a1" path="res://scenes/border.tscn" id="7_p4rds"]
[ext_resource type="Script" path="res://script/wavecontroller.cs" id="8_fhk4p"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_4rlyh"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_4rlyh"]
texture = ExtResource("6_kn6se") texture = ExtResource("6_kn6se")
@ -8081,48 +8081,7 @@ position = Vector2(769, 202)
[node name="Asteroid5" parent="Asteroids" instance=ExtResource("3_b8wlr")] [node name="Asteroid5" parent="Asteroids" instance=ExtResource("3_b8wlr")]
position = Vector2(387, 230) position = Vector2(387, 230)
[node name="Ships" type="Node" parent="."] [node name="BackgroundTileMap" type="TileMap" parent="."]
[node name="Friendly" type="Node" parent="Ships"]
[node name="Player" parent="Ships/Friendly" instance=ExtResource("1_1w06w")]
position = Vector2(959, 539)
scale = Vector2(0.6, 0.6)
Type = 1
[node name="AI_Fighter" parent="Ships/Friendly" instance=ExtResource("5_nkk10")]
position = Vector2(1229, 430)
scale = Vector2(0.6, 0.6)
Faction = 1
[node name="AI_Fighter2" parent="Ships/Friendly" instance=ExtResource("5_nkk10")]
position = Vector2(686, 333)
scale = Vector2(0.6, 0.6)
Faction = 1
[node name="Enemy" type="Node" parent="Ships"]
[node name="AI_Fighter" parent="Ships/Enemy" instance=ExtResource("5_nkk10")]
position = Vector2(952, 214)
scale = Vector2(0.6, 0.6)
Faction = 2
[node name="AI_Fighter2" parent="Ships/Enemy" instance=ExtResource("5_nkk10")]
position = Vector2(429, 467)
scale = Vector2(0.6, 0.6)
Faction = 2
[node name="AI_Fighter3" parent="Ships/Enemy" instance=ExtResource("5_nkk10")]
position = Vector2(674, 887)
scale = Vector2(0.6, 0.6)
Faction = 2
[node name="AI_Fighter4" parent="Ships/Enemy" instance=ExtResource("5_nkk10")]
position = Vector2(1303, 840)
scale = Vector2(0.6, 0.6)
Faction = 2
[node name="TileMap" type="TileMap" parent="."]
position = Vector2(900, 500) position = Vector2(900, 500)
tile_set = SubResource("TileSet_lmb5c") tile_set = SubResource("TileSet_lmb5c")
format = 2 format = 2
@ -8153,11 +8112,50 @@ rotation = -1.5708
scale = Vector2(37.35, 5) scale = Vector2(37.35, 5)
collision_layer = 8 collision_layer = 8
[node name="WaveController" type="Node2D" parent="."]
script = ExtResource("8_fhk4p")
[node name="Ships" type="Node" parent="WaveController"]
[node name="Friendly" type="Node" parent="WaveController/Ships"]
[node name="Player" parent="WaveController/Ships/Friendly" instance=ExtResource("1_1w06w")]
position = Vector2(959, 539)
scale = Vector2(0.6, 0.6)
Color = 1
Type = 1
[node name="Enemy" type="Node" parent="WaveController/Ships"]
[node name="Spawns" type="Node" parent="WaveController"]
[node name="Enemy" type="Node" parent="WaveController/Spawns"]
[node name="ESpawn1" type="Marker2D" parent="WaveController/Spawns/Enemy"]
position = Vector2(-276, -585)
[node name="ESpawn2" type="Marker2D" parent="WaveController/Spawns/Enemy"]
position = Vector2(948, 1809)
[node name="ESpawn3" type="Marker2D" parent="WaveController/Spawns/Enemy"]
position = Vector2(2216, -428)
[node name="Friendly" type="Node" parent="WaveController/Spawns"]
[node name="FSpawn1" type="Marker2D" parent="WaveController/Spawns/Friendly"]
position = Vector2(-371, 842)
[node name="FSpawn2" type="Marker2D" parent="WaveController/Spawns/Friendly"]
position = Vector2(1921, 1512)
[node name="FSpawn3" type="Marker2D" parent="WaveController/Spawns/Friendly"]
position = Vector2(1279, -637)
[connection signal="Exploded" from="Asteroids/Asteroid" to="." method="OnAsteroidExploded"] [connection signal="Exploded" from="Asteroids/Asteroid" to="." method="OnAsteroidExploded"]
[connection signal="Exploded" from="Asteroids/Asteroid2" to="." method="OnAsteroidExploded"] [connection signal="Exploded" from="Asteroids/Asteroid2" to="." method="OnAsteroidExploded"]
[connection signal="Exploded" from="Asteroids/Asteroid3" to="." method="OnAsteroidExploded"] [connection signal="Exploded" from="Asteroids/Asteroid3" to="." method="OnAsteroidExploded"]
[connection signal="Exploded" from="Asteroids/Asteroid4" to="." method="OnAsteroidExploded"] [connection signal="Exploded" from="Asteroids/Asteroid4" to="." method="OnAsteroidExploded"]
[connection signal="Exploded" from="Asteroids/Asteroid5" to="." method="OnAsteroidExploded"] [connection signal="Exploded" from="Asteroids/Asteroid5" to="." method="OnAsteroidExploded"]
[connection signal="HealthUpdate" from="Ships/Friendly/Player" to="." method="OnPlayerHealthUpdate"] [connection signal="HealthUpdate" from="WaveController/Ships/Friendly/Player" to="." method="OnPlayerHealthUpdate"]
[connection signal="LaserShot" from="Ships/Friendly/Player" to="." method="OnPlayerLaserShot"] [connection signal="LaserShot" from="WaveController/Ships/Friendly/Player" to="." method="OnPlayerLaserShot"]
[connection signal="PlayerDeath" from="Ships/Friendly/Player" to="." method="OnPlayerDeath"] [connection signal="PlayerDeath" from="WaveController/Ships/Friendly/Player" to="." method="OnPlayerDeath"]

View file

@ -10,29 +10,27 @@ offset_right = 40.0
offset_bottom = 40.0 offset_bottom = 40.0
script = ExtResource("1_aksh1") script = ExtResource("1_aksh1")
[node name="Score" type="Label" parent="."] [node name="Layout" type="VBoxContainer" parent="."]
layout_mode = 0 layout_mode = 0
offset_left = 15.0 offset_right = 40.0
offset_top = 15.0 offset_bottom = 40.0
offset_right = 363.0
offset_bottom = 90.0 [node name="Score" type="Label" parent="Layout"]
layout_mode = 2
text = "SCORE: 9999" text = "SCORE: 9999"
label_settings = ExtResource("2_ns78v") label_settings = ExtResource("2_ns78v")
[node name="Health" type="Label" parent="."] [node name="Health" type="Label" parent="Layout"]
layout_mode = 0 layout_mode = 2
offset_left = 17.0
offset_top = 95.0
offset_right = 384.0
offset_bottom = 167.0
text = "Health:" text = "Health:"
label_settings = ExtResource("2_ns78v") label_settings = ExtResource("2_ns78v")
[node name="FlightAssist" type="Label" parent="."] [node name="WaveCounter" type="Label" parent="Layout"]
layout_mode = 0 layout_mode = 2
offset_left = 19.0 text = "Wave: "
offset_top = 174.0 label_settings = ExtResource("2_ns78v")
offset_right = 226.0
offset_bottom = 237.0 [node name="FlightAssist" type="Label" parent="Layout"]
layout_mode = 2
text = "FA: ON" text = "FA: ON"
label_settings = ExtResource("2_ns78v") label_settings = ExtResource("2_ns78v")

View file

@ -4,6 +4,9 @@ using System;
public partial class ai_fighter : ship public partial class ai_fighter : ship
{ {
[Signal]
public delegate void OnDeathEventHandler(int factionInt);
[Export] [Export]
public float AggroRange = 500f; public float AggroRange = 500f;
[Export] [Export]
@ -11,6 +14,8 @@ public partial class ai_fighter : ship
[Export] [Export]
public float EngageDistance = 300f; public float EngageDistance = 300f;
public bool SignalsConnected { get; set; } = false;
private Label _healthLabel; private Label _healthLabel;
private Label _hpLabel; private Label _hpLabel;
@ -74,6 +79,13 @@ public partial class ai_fighter : ship
UpdateHealthLabel(Health); UpdateHealthLabel(Health);
} }
protected override void Explode()
{
int factionInt = (int)Faction;
EmitSignal(SignalName.OnDeath, factionInt);
QueueFree();
}
private void HandleFiring(double delta) private void HandleFiring(double delta)
{ {
//GD.Print(Name, ": checking fire"); //GD.Print(Name, ": checking fire");
@ -112,11 +124,11 @@ public partial class ai_fighter : ship
Node shipParent = null; Node shipParent = null;
if (Faction == ShipFaction.FRIENDLY) if (Faction == ShipFaction.FRIENDLY)
{ {
shipParent = GetTree().Root.GetNode("Game/Ships/Enemy"); shipParent = GetTree().Root.GetNode("Game/WaveController/Ships/Enemy");
} }
else if (Faction == ShipFaction.ENEMY || Faction == ShipFaction.ACE) else if (Faction == ShipFaction.ENEMY || Faction == ShipFaction.ACE)
{ {
shipParent = GetTree().Root.GetNode("Game/Ships/Friendly"); shipParent = GetTree().Root.GetNode("Game/WaveController/Ships/Friendly");
} }
if (shipParent == null) if (shipParent == null)
{ {

View file

@ -4,8 +4,9 @@ using System;
public partial class game : Node2D public partial class game : Node2D
{ {
private Node _lasers; private Node _lasers;
private CharacterBody2D _player; private player _player;
private Node _asteroids; private Node _asteroids;
private wavecontroller _waveController;
private Node _friendlies; private Node _friendlies;
@ -21,53 +22,79 @@ public partial class game : Node2D
private Label _flightAssistLabel; private Label _flightAssistLabel;
private Label _waveCounterLabel;
private hud _h; private hud _h;
private int _score;
private readonly PackedScene _asteroidScene = GD.Load<PackedScene>("res://scenes/asteroid.tscn"); private readonly PackedScene _asteroidScene = GD.Load<PackedScene>("res://scenes/asteroid.tscn");
private int _score;
public override void _Ready() public override void _Ready()
{ {
_waveController = GetNode<wavecontroller>("WaveController");
_hud = GetNode<Control>("UI/HUD"); _hud = GetNode<Control>("UI/HUD");
_scoreLabel = GetNode<Label>("UI/HUD/Score"); _scoreLabel = GetNode<Label>("UI/HUD/Layout/Score");
_flightAssistLabel = GetNode<Label>("UI/HUD/FlightAssist"); _flightAssistLabel = GetNode<Label>("UI/HUD/Layout/FlightAssist");
//HealthLabel = GetNode<Label>("UI/HUD/Health"); //HealthLabel = GetNode<Label>("UI/HUD/Health");
_asteroids = GetNode<Node>("Asteroids"); _asteroids = GetNode<Node>("Asteroids");
_lasers = GetNode<Node>("Lasers"); _lasers = GetNode<Node>("Lasers");
_ships = GetNode<Node>("Ships"); _ships = GetNode<Node>("WaveController/Ships");
_enemies = GetNode<Node>("Ships/Enemy"); _enemies = GetNode<Node>("WaveController/Ships/Enemy");
_friendlies = GetNode<Node>("Ships/Friendly"); _friendlies = GetNode<Node>("WaveController/Ships/Friendly");
_player = GetNode<CharacterBody2D>("Ships/Friendly/Player"); _player = GetNode<player>("WaveController/Ships/Friendly/Player");
NewWave();
//var p = new player();
//p.LaserShot += OnPlayerLaserShot;
}
private void SetupAISignals()
{
//AI fighter signals //AI fighter signals
foreach (Node node in _enemies.GetChildren()) foreach (Node node in _enemies.GetChildren())
{ {
if (node is ai_fighter ai) if (node is not ai_fighter ai) continue;
{ //GD.Print("Connected laser signal for: ", ai.Name);
GD.Print("Connected laser signal for: ", ai.Name); ai.LaserShot += OnAILaserShot;
ai.OnDeath += OnAIDeath;
ai.LaserShot += OnAILaserShot;
}
} }
foreach (Node node in _friendlies.GetChildren()) foreach (Node node in _friendlies.GetChildren())
{ {
if (node is player) continue; switch (node)
if (node is ai_fighter ai)
{ {
GD.Print("Connected laser signal for: ", ai.Name); case player:
continue;
case ai_fighter ai:
if (ai.SignalsConnected) break;
//GD.Print("Connected laser signal for: ", ai.Name);
ai.LaserShot += OnAILaserShot; ai.LaserShot += OnAILaserShot;
ai.OnDeath += OnAIDeath;
ai.SignalsConnected = true;
break;
} }
} }
}
//var p = new player(); private void NewWave()
//p.LaserShot += OnPlayerLaserShot; {
_waveController.CurrWave++;
_waveController.StartWave();
UpdateWaveCounterLabel();
SetupAISignals();
if (_waveController.CurrWave % 2 == 0)
{
_player.HealShip(100); // heal ship by 100 at the start of each round
UpdateHealthLabel(_player.Health);
}
} }
public override void _Process(double delta) public override void _Process(double delta)
@ -91,6 +118,14 @@ public partial class game : Node2D
SpawnAsteroid(new Vector2(rand.Next(10, 800), rand.Next(10, 800)), (int)asteroid.AsteroidSize.LARGE); SpawnAsteroid(new Vector2(rand.Next(10, 800), rand.Next(10, 800)), (int)asteroid.AsteroidSize.LARGE);
} }
} }
if (_enemies.GetChildCount() == 0)
{
NewWave();
}
//if enemies == 0 -> spawn new wave, connect signals for new ships
} }
private void SpawnAsteroid(Vector2 position, int size) private void SpawnAsteroid(Vector2 position, int size)
@ -115,7 +150,7 @@ public partial class game : Node2D
private void UpdateHealthLabel(int health) private void UpdateHealthLabel(int health)
{ {
_healthLabel ??= GetNode<Label>("UI/HUD/Health"); _healthLabel = GetNode<Label>("UI/HUD/Layout/Health");
_healthLabel.Text = "HEALTH: " + health.ToString(); _healthLabel.Text = "HEALTH: " + health.ToString();
} }
@ -126,6 +161,12 @@ public partial class game : Node2D
else if (_flightAssistLabel.Text == "FA: ON"){_flightAssistLabel.Text = "FA: OFF";} else if (_flightAssistLabel.Text == "FA: ON"){_flightAssistLabel.Text = "FA: OFF";}
} }
private void UpdateWaveCounterLabel()
{
_healthLabel = GetNode<Label>("UI/HUD/Layout/WaveCounter");
_healthLabel.Text = "WAVE: " + _waveController.CurrWave.ToString();
}
//Signals and Connections //Signals and Connections
private void OnAILaserShot(Area2D laser) private void OnAILaserShot(Area2D laser)
{ {
@ -150,6 +191,27 @@ public partial class game : Node2D
CallDeferred(nameof(SafeReloadScene)); //Reload scene to act as restart CallDeferred(nameof(SafeReloadScene)); //Reload scene to act as restart
} }
private void OnAIDeath(int factionInt)
{
ship.ShipFaction faction = (ship.ShipFaction)factionInt;
switch (faction)
{
case ship.ShipFaction.ENEMY:
_score += 500;
break;
case ship.ShipFaction.FRIENDLY:
_score -= 150;
if (_score < 0) _score = 0;
break;
case ship.ShipFaction.ACE:
_score += 1000;
break;
}
UpdateScoreLabel(_score);
}
private void SafeReloadScene() private void SafeReloadScene()
{ {
GD.Print("Reloading scene"); GD.Print("Reloading scene");

View file

@ -8,11 +8,11 @@ public partial class hud : Control
public override void _Ready() public override void _Ready()
{ {
_score = GetNode<Label>("Score"); _score = GetNode<Label>("Layout/Score");
_score.Text = "SCORE: 0"; _score.Text = "SCORE: 0";
// Keeping health being initialised in game.cs // Keeping health being initialised in game.cs
_flightAssist = GetNode<Label>("FlightAssist"); _flightAssist = GetNode<Label>("Layout/FlightAssist");
_flightAssist.Text = "FA: ON"; // Should be on by default _flightAssist.Text = "FA: ON"; // Should be on by default
} }
} }

View file

@ -67,6 +67,13 @@ public partial class player : ship // Inherits from base ship class
} }
} }
public void HealShip(int health)
{
Health += health;
if (Health > MaxHealth) Health = MaxHealth;
}
private void ToggleFlightAssist() private void ToggleFlightAssist()
{ {
if (FlightAssistValue == 0f){FlightAssistValue = 2.5f;} if (FlightAssistValue == 0f){FlightAssistValue = 2.5f;}
@ -91,8 +98,11 @@ public partial class player : ship // Inherits from base ship class
LaserSpawn = GetNode<Node2D>("LaserSpawn"); LaserSpawn = GetNode<Node2D>("LaserSpawn");
//Connect("body_entered" +=) //Connect("body_entered" +=)
StatModifier = 1.3f;
SetShipStats(); SetShipStats();
MaxHealth *= 4; // quadruple player health (balancing)
Health = MaxHealth; Health = MaxHealth;
Damage *= 2; // double player damage (balancing)
EmitSignal(SignalName.HealthUpdate, Health); EmitSignal(SignalName.HealthUpdate, Health);
} }

View file

@ -31,6 +31,8 @@ public partial class ship : CharacterBody2D
public ShipType Type; public ShipType Type;
[Export] [Export]
public ShipFaction Faction; public ShipFaction Faction;
[Export]
public float StatModifier = 1f;
protected Sprite2D Sprite = new Sprite2D(); protected Sprite2D Sprite = new Sprite2D();
@ -41,6 +43,7 @@ public partial class ship : CharacterBody2D
protected string SpritePath; protected string SpritePath;
protected int RotationDirection; protected int RotationDirection;
protected readonly PackedScene LaserScene = GD.Load<PackedScene>("res://scenes/laser.tscn"); protected readonly PackedScene LaserScene = GD.Load<PackedScene>("res://scenes/laser.tscn");
@ -55,7 +58,7 @@ public partial class ship : CharacterBody2D
EmitSignal(SignalName.LaserShot, laser); EmitSignal(SignalName.LaserShot, laser);
} }
protected virtual void SetupVisual() public void SetupVisual()
{ {
Sprite = GetNode<Sprite2D>("ShipSprite"); Sprite = GetNode<Sprite2D>("ShipSprite");
SpritePath = ""; // Have to initialise as "" because of switch statements SpritePath = ""; // Have to initialise as "" because of switch statements
@ -144,36 +147,36 @@ public partial class ship : CharacterBody2D
switch (Type) switch (Type)
{ {
case ShipType.FIGHTER: case ShipType.FIGHTER:
Health = 100; Health = (int)(100 * StatModifier);
MaxSpeed = 300; MaxSpeed = (int)(300 * StatModifier);
MainSpeed = 20; MainSpeed = (int)(20 * StatModifier);
StrafeSpeed = 10; StrafeSpeed = (int)(10 * StatModifier);
RotationSpeed = 2f; RotationSpeed = 2f * StatModifier;
MaxHealth = 100; MaxHealth = (int)(100 * StatModifier);
Damage = 40; Damage = (int)(30 * StatModifier);
FireCooldown = 0.6f; FireCooldown = 0.6f * StatModifier;
break; break;
case ShipType.INTERCEPTOR: case ShipType.INTERCEPTOR:
Health = 75; Health = (int)(75 * StatModifier);
MaxSpeed = 450; MaxSpeed = (int)(450 * StatModifier);
MainSpeed = 35; MainSpeed = (int)(35 * StatModifier);
StrafeSpeed = 15; StrafeSpeed = (int)(15 * StatModifier);
RotationSpeed = 4f; RotationSpeed = 4f * StatModifier;
MaxHealth = 75; MaxHealth = (int)(75 * StatModifier);
Damage = 20; Damage = (int)(10 * StatModifier);
FireCooldown = 0.3f; FireCooldown = 0.3f * StatModifier;
break; break;
case ShipType.GUARDIAN: case ShipType.GUARDIAN:
Health = 200; Health = (int)(200 * StatModifier);
MaxSpeed = 200; MaxSpeed = (int)(200 * StatModifier);
MainSpeed = 15; MainSpeed = (int)(15 * StatModifier);
StrafeSpeed = 7; StrafeSpeed = (int)(7 * StatModifier);
RotationSpeed = 1.5f; RotationSpeed = 1.5f * StatModifier;
MaxHealth = 200; MaxHealth = (int)(200 * StatModifier);
Damage = 60; Damage = (int)(50 * StatModifier);
FireCooldown = 1.1f; FireCooldown = 1.1f * StatModifier;
break; break;
} }
} }

View file

@ -0,0 +1,78 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
public partial class wavecontroller : Node2D
{
public int CurrWave = 0;
private Node _friendlyNode;
private Node _enemyNode;
private player _playerNode;
public float _aiStatModifier = 1f;
private List<Marker2D> _enemySpawns;
private List<Marker2D> _friendlySpawns;
private PackedScene _aiShipScene;
private string _aiShipPath = "res://scenes/ai_fighter.tscn";
public override void _Ready()
{
_friendlyNode = GetNode<Node>("Ships/Friendly");
_enemyNode = GetNode<Node>("Ships/Enemy");
_playerNode = GetNode<player>("Ships/Friendly/Player");
_enemySpawns = GetNode<Node>("Spawns/Enemy").GetChildren().OfType<Marker2D>().ToList();
_friendlySpawns = GetNode<Node>("Spawns/Friendly").GetChildren().OfType<Marker2D>().ToList();
_aiShipScene = GD.Load<PackedScene>(_aiShipPath);
}
public void StartWave()
{
if (_playerNode.Health > _playerNode.MaxHealth) _playerNode.Health = 100;
if (CurrWave % 5 != 0)
{
// normal wave
foreach (var spawn in _enemySpawns) // spawn enemies
{
//var enemy = new ai_fighter();
Random rand = new Random();
var enemy = _aiShipScene.Instantiate<ai_fighter>();
enemy.Faction = ship.ShipFaction.ENEMY;
enemy.Type = (ship.ShipType)rand.Next(0, 3);
enemy.GlobalPosition = spawn.GlobalPosition;
enemy.StatModifier = _aiStatModifier;
enemy.Scale = new Vector2(0.6f, 0.6f);
_enemyNode.AddChild(enemy);
}
}
if ((CurrWave - 1) % 5 == 0)
{
GD.Print("attempting to spawn friendlies");
foreach (var spawn in _friendlySpawns)
{
Random rand = new Random();
var friendly = _aiShipScene.Instantiate<ai_fighter>();
friendly.Faction = ship.ShipFaction.FRIENDLY;
friendly.Type = (ship.ShipType)rand.Next(0, 3);
friendly.GlobalPosition = spawn.GlobalPosition;
friendly.StatModifier = (_aiStatModifier) * 1.1f; // make friendlies slightly stronger
friendly.Scale = new Vector2(0.6f, 0.6f);
_friendlyNode.AddChild(friendly);
}
}
else if (CurrWave % 5 == 0) // ace/boss wave
{
return;
}
}
}