switch to ECS architecture
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
#include "BuildingSystem.h"
|
||||
#include "BuildingType.h"
|
||||
#include "ConfigLoader.h"
|
||||
#include "EcsComponents.h"
|
||||
#include "EntityAdmin.h"
|
||||
#include "Rotation.h"
|
||||
#include "Ship.h"
|
||||
#include "ShipSystem.h"
|
||||
@@ -100,16 +102,23 @@ TEST_CASE("WaveSystem: Simulation pre-places HQ + 2 player + 2 enemy stations",
|
||||
{
|
||||
const Simulation sim(loadConfig(), 42);
|
||||
|
||||
int hqCount = 0;
|
||||
int playerCount = 0;
|
||||
int enemyCount = 0;
|
||||
// HQ is still a Building (for belt integration).
|
||||
int hqCount = 0;
|
||||
for (const Building& b : sim.buildings().allBuildings())
|
||||
{
|
||||
if (b.type == BuildingType::Hq) { ++hqCount; }
|
||||
else if (b.type == BuildingType::PlayerDefenceStation) { ++playerCount; }
|
||||
else if (b.type == BuildingType::EnemyDefenceStation) { ++enemyCount; }
|
||||
if (b.type == BuildingType::Hq) { ++hqCount; }
|
||||
}
|
||||
|
||||
// Stations are ECS entities.
|
||||
int playerCount = 0;
|
||||
int enemyCount = 0;
|
||||
sim.admin().forEach<StationBody, Faction>(
|
||||
[&](entt::entity /*e*/, const StationBody& /*sb*/, const Faction& f)
|
||||
{
|
||||
if (f.isEnemy) { ++enemyCount; }
|
||||
else { ++playerCount; }
|
||||
});
|
||||
|
||||
REQUIRE(hqCount == 1);
|
||||
REQUIRE(playerCount == 2);
|
||||
REQUIRE(enemyCount == 2);
|
||||
@@ -159,16 +168,18 @@ TEST_CASE("WaveSystem: player stations have weapon set", "[wave]")
|
||||
const Simulation sim(loadConfig(), 42);
|
||||
|
||||
int armedPlayerStations = 0;
|
||||
for (const Building& b : sim.buildings().allBuildings())
|
||||
{
|
||||
if (b.type == BuildingType::PlayerDefenceStation && b.weapon)
|
||||
sim.admin().forEach<StationBody, Faction, StationWeapon>(
|
||||
[&](entt::entity /*e*/, const StationBody& /*sb*/, const Faction& f,
|
||||
const StationWeapon& w)
|
||||
{
|
||||
++armedPlayerStations;
|
||||
REQUIRE(b.weapon->damage > 0.0f);
|
||||
REQUIRE(b.weapon->range > 0.0f);
|
||||
REQUIRE(b.weapon->fireRateHz > 0.0f);
|
||||
}
|
||||
}
|
||||
if (!f.isEnemy)
|
||||
{
|
||||
++armedPlayerStations;
|
||||
REQUIRE(w.damage > 0.0f);
|
||||
REQUIRE(w.range > 0.0f);
|
||||
REQUIRE(w.fireRateHz > 0.0f);
|
||||
}
|
||||
});
|
||||
REQUIRE(armedPlayerStations == 2);
|
||||
}
|
||||
|
||||
@@ -177,16 +188,18 @@ TEST_CASE("WaveSystem: enemy stations have weapon set", "[wave]")
|
||||
const Simulation sim(loadConfig(), 42);
|
||||
|
||||
int armedEnemyStations = 0;
|
||||
for (const Building& b : sim.buildings().allBuildings())
|
||||
{
|
||||
if (b.type == BuildingType::EnemyDefenceStation && b.weapon)
|
||||
sim.admin().forEach<StationBody, Faction, StationWeapon>(
|
||||
[&](entt::entity /*e*/, const StationBody& /*sb*/, const Faction& f,
|
||||
const StationWeapon& w)
|
||||
{
|
||||
++armedEnemyStations;
|
||||
REQUIRE(b.weapon->damage > 0.0f);
|
||||
REQUIRE(b.weapon->range > 0.0f);
|
||||
REQUIRE(b.weapon->fireRateHz > 0.0f);
|
||||
}
|
||||
}
|
||||
if (f.isEnemy)
|
||||
{
|
||||
++armedEnemyStations;
|
||||
REQUIRE(w.damage > 0.0f);
|
||||
REQUIRE(w.range > 0.0f);
|
||||
REQUIRE(w.fireRateHz > 0.0f);
|
||||
}
|
||||
});
|
||||
REQUIRE(armedEnemyStations == 2);
|
||||
}
|
||||
|
||||
@@ -207,14 +220,11 @@ TEST_CASE("WaveSystem: enemy ships spawn after the initial gap elapses", "[wave]
|
||||
}
|
||||
|
||||
bool foundEnemyShip = false;
|
||||
for (const Ship& s : sim.ships().allShips())
|
||||
{
|
||||
if (s.isEnemy)
|
||||
sim.admin().forEach<ShipIdentity, Faction>(
|
||||
[&](entt::entity /*e*/, const ShipIdentity& /*si*/, const Faction& f)
|
||||
{
|
||||
foundEnemyShip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f.isEnemy) { foundEnemyShip = true; }
|
||||
});
|
||||
REQUIRE(foundEnemyShip);
|
||||
}
|
||||
|
||||
@@ -229,13 +239,14 @@ TEST_CASE("WaveSystem: only eligible ships (cost > 0) appear in waves", "[wave]"
|
||||
sim.tick();
|
||||
}
|
||||
|
||||
for (const Ship& s : sim.ships().allShips())
|
||||
{
|
||||
if (!s.isEnemy) { continue; }
|
||||
// salvage_ship and repair_ship have cost_formula = "0" and must not spawn.
|
||||
REQUIRE(s.schematicId != "salvage_ship");
|
||||
REQUIRE(s.schematicId != "repair_ship");
|
||||
}
|
||||
sim.admin().forEach<ShipIdentity, Faction>(
|
||||
[&](entt::entity /*e*/, const ShipIdentity& si, const Faction& f)
|
||||
{
|
||||
if (!f.isEnemy) { return; }
|
||||
// salvage_ship and repair_ship have cost_formula = "0" and must not spawn.
|
||||
REQUIRE(si.schematicId != "salvage_ship");
|
||||
REQUIRE(si.schematicId != "repair_ship");
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -247,22 +258,21 @@ TEST_CASE("WaveSystem: destroying both enemy stations triggers a push", "[wave]"
|
||||
Simulation sim(loadConfig(), 42);
|
||||
|
||||
// Damage both enemy stations to 0.
|
||||
sim.buildings().forEachBuilding([](Building& b)
|
||||
{
|
||||
if (b.type == BuildingType::EnemyDefenceStation)
|
||||
sim.admin().forEach<StationBody, Faction, Health>(
|
||||
[](entt::entity /*e*/, const StationBody& /*sb*/, const Faction& f, Health& h)
|
||||
{
|
||||
b.hp = -1.0f;
|
||||
}
|
||||
});
|
||||
if (f.isEnemy) { h.hp = -1.0f; }
|
||||
});
|
||||
|
||||
sim.tick();
|
||||
|
||||
// After push: should have 2 new enemy stations.
|
||||
int enemyCount = 0;
|
||||
for (const Building& b : sim.buildings().allBuildings())
|
||||
{
|
||||
if (b.type == BuildingType::EnemyDefenceStation) { ++enemyCount; }
|
||||
}
|
||||
sim.admin().forEach<StationBody, Faction>(
|
||||
[&](entt::entity /*e*/, const StationBody& /*sb*/, const Faction& f)
|
||||
{
|
||||
if (f.isEnemy) { ++enemyCount; }
|
||||
});
|
||||
REQUIRE(enemyCount == 2);
|
||||
}
|
||||
|
||||
@@ -270,13 +280,11 @@ TEST_CASE("WaveSystem: push emits exactly one SchematicDropEvent", "[wave]")
|
||||
{
|
||||
Simulation sim(loadConfig(), 42);
|
||||
|
||||
sim.buildings().forEachBuilding([](Building& b)
|
||||
{
|
||||
if (b.type == BuildingType::EnemyDefenceStation)
|
||||
sim.admin().forEach<StationBody, Faction, Health>(
|
||||
[](entt::entity /*e*/, const StationBody& /*sb*/, const Faction& f, Health& h)
|
||||
{
|
||||
b.hp = -1.0f;
|
||||
}
|
||||
});
|
||||
if (f.isEnemy) { h.hp = -1.0f; }
|
||||
});
|
||||
|
||||
sim.tick();
|
||||
|
||||
@@ -288,13 +296,11 @@ TEST_CASE("WaveSystem: push schematic drop awards a known ship id", "[wave]")
|
||||
{
|
||||
Simulation sim(loadConfig(), 42);
|
||||
|
||||
sim.buildings().forEachBuilding([](Building& b)
|
||||
{
|
||||
if (b.type == BuildingType::EnemyDefenceStation)
|
||||
sim.admin().forEach<StationBody, Faction, Health>(
|
||||
[](entt::entity /*e*/, const StationBody& /*sb*/, const Faction& f, Health& h)
|
||||
{
|
||||
b.hp = -1.0f;
|
||||
}
|
||||
});
|
||||
if (f.isEnemy) { h.hp = -1.0f; }
|
||||
});
|
||||
|
||||
sim.tick();
|
||||
const std::vector<SchematicDropEvent> events = sim.drainSchematicDropEvents();
|
||||
@@ -319,28 +325,31 @@ TEST_CASE("WaveSystem: push places new enemy stations further right", "[wave]")
|
||||
|
||||
// Record the X position of the initial enemy stations.
|
||||
int initialX = std::numeric_limits<int>::min();
|
||||
for (const Building& b : sim.buildings().allBuildings())
|
||||
{
|
||||
if (b.type == BuildingType::EnemyDefenceStation)
|
||||
sim.admin().forEach<StationBody, Faction>(
|
||||
[&](entt::entity /*e*/, const StationBody& sb, const Faction& f)
|
||||
{
|
||||
if (b.anchor.x() > initialX) { initialX = b.anchor.x(); }
|
||||
}
|
||||
}
|
||||
if (f.isEnemy && sb.anchor.x() > initialX)
|
||||
{
|
||||
initialX = sb.anchor.x();
|
||||
}
|
||||
});
|
||||
|
||||
sim.buildings().forEachBuilding([](Building& b)
|
||||
{
|
||||
if (b.type == BuildingType::EnemyDefenceStation) { b.hp = -1.0f; }
|
||||
});
|
||||
sim.admin().forEach<StationBody, Faction, Health>(
|
||||
[](entt::entity /*e*/, const StationBody& /*sb*/, const Faction& f, Health& h)
|
||||
{
|
||||
if (f.isEnemy) { h.hp = -1.0f; }
|
||||
});
|
||||
sim.tick();
|
||||
|
||||
int newX = std::numeric_limits<int>::min();
|
||||
for (const Building& b : sim.buildings().allBuildings())
|
||||
{
|
||||
if (b.type == BuildingType::EnemyDefenceStation)
|
||||
sim.admin().forEach<StationBody, Faction>(
|
||||
[&](entt::entity /*e*/, const StationBody& sb, const Faction& f)
|
||||
{
|
||||
if (b.anchor.x() > newX) { newX = b.anchor.x(); }
|
||||
}
|
||||
}
|
||||
if (f.isEnemy && sb.anchor.x() > newX)
|
||||
{
|
||||
newX = sb.anchor.x();
|
||||
}
|
||||
});
|
||||
|
||||
REQUIRE(newX > initialX);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user