Remove schematic upgrades and module and ship levels
This commit is contained in:
@@ -238,7 +238,7 @@ TEST_CASE("BehaviorSystem: clearMovementIntents resets all ships to inactive",
|
||||
"[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity e = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
|
||||
f.admin.get<MovementIntentComponent>(e) = MovementIntentComponent{true, QVector2D(10.0f, 0.0f)};
|
||||
f.ships.clearMovementIntents();
|
||||
@@ -254,7 +254,7 @@ TEST_CASE("BehaviorSystem: tickMovement advances ship by maxSpeed_tpt toward tar
|
||||
"[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity e = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
|
||||
const float speed = f.admin.get<DynamicBodyComponent>(e).maxSpeed_tpt;
|
||||
f.admin.get<MovementIntentComponent>(e) = MovementIntentComponent{true, QVector2D(100.0f, 0.0f)};
|
||||
@@ -269,7 +269,7 @@ TEST_CASE("BehaviorSystem: tickMovement stops exactly at target without overshoo
|
||||
"[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity e = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
|
||||
const float speed = f.admin.get<DynamicBodyComponent>(e).maxSpeed_tpt;
|
||||
const QVector2D target(speed * 0.5f, 0.0f);
|
||||
@@ -288,7 +288,7 @@ TEST_CASE("BehaviorSystem: tickMovement stops exactly at target without overshoo
|
||||
TEST_CASE("BehaviorSystem: healthy player ship does not retreat", "[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity e = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
f.admin.get<HealthComponent>(e).hp = f.admin.get<HealthComponent>(e).maxHp; // full HP
|
||||
|
||||
f.decide();
|
||||
@@ -301,7 +301,7 @@ TEST_CASE("BehaviorSystem: low-HP player ship retreats toward the rally point",
|
||||
Fixture f;
|
||||
const QVector2D rallyPoint(-50.0f, 0.0f);
|
||||
f.ships.setRallyPoint(rallyPoint);
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity e = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
f.admin.get<HealthComponent>(e).hp = f.admin.get<HealthComponent>(e).maxHp * 0.2f; // below threshold
|
||||
|
||||
f.decide();
|
||||
@@ -316,8 +316,8 @@ TEST_CASE("BehaviorSystem: low-HP retreat outranks attacking a nearby enemy", "[
|
||||
Fixture f;
|
||||
const QVector2D rallyPoint(-50.0f, 0.0f);
|
||||
f.ships.setRallyPoint(rallyPoint);
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
f.ships.spawn("interceptor", 1, QVector2D(5.0f, 0.0f), /*isEnemy=*/true);
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
f.ships.spawn("interceptor", QVector2D(5.0f, 0.0f), /*isEnemy=*/true);
|
||||
f.admin.get<HealthComponent>(player).hp = f.admin.get<HealthComponent>(player).maxHp * 0.1f;
|
||||
|
||||
f.decide();
|
||||
@@ -329,7 +329,7 @@ TEST_CASE("BehaviorSystem: low-HP retreat outranks attacking a nearby enemy", "[
|
||||
TEST_CASE("BehaviorSystem: enemy ships never retreat even at low HP", "[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
f.admin.get<HealthComponent>(enemy).hp = f.admin.get<HealthComponent>(enemy).maxHp * 0.05f;
|
||||
|
||||
@@ -347,8 +347,8 @@ TEST_CASE("BehaviorSystem: player combat ship acquires nearest enemy ship in ran
|
||||
"[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", 1, QVector2D(10.0f, 0.0f),
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", QVector2D(10.0f, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
@@ -364,8 +364,8 @@ TEST_CASE("BehaviorSystem: player combat ship does not target friendly ships",
|
||||
"[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity e1 = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
f.ships.spawn("interceptor", 1, QVector2D(5.0f, 0.0f)); // also player
|
||||
const entt::entity e1 = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
f.ships.spawn("interceptor", QVector2D(5.0f, 0.0f)); // also player
|
||||
|
||||
f.decide();
|
||||
|
||||
@@ -378,8 +378,8 @@ TEST_CASE("BehaviorSystem: player combat ship ignores enemy beyond engagement ra
|
||||
"[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
f.ships.spawn("interceptor", 1, QVector2D(500.0f, 0.0f), /*isEnemy=*/true);
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
f.ships.spawn("interceptor", QVector2D(500.0f, 0.0f), /*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
|
||||
@@ -398,10 +398,10 @@ TEST_CASE("BehaviorSystem: overclaim penalty steers a ship off a claimed target"
|
||||
SECTION("no claim: the nearer enemy is chosen")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity nearEnemy = f.ships.spawn("interceptor", 1, QVector2D(8.0f, 0.0f),
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
const entt::entity nearEnemy = f.ships.spawn("interceptor", QVector2D(8.0f, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
f.ships.spawn("interceptor", 1, QVector2D(0.0f, 12.0f), /*isEnemy=*/true);
|
||||
f.ships.spawn("interceptor", QVector2D(0.0f, 12.0f), /*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
|
||||
@@ -412,15 +412,15 @@ TEST_CASE("BehaviorSystem: overclaim penalty steers a ship off a claimed target"
|
||||
{
|
||||
const float d = 10.0f;
|
||||
Fixture f;
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemyA = f.ships.spawn("interceptor", 1, QVector2D(d, 0.0f),
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemyA = f.ships.spawn("interceptor", QVector2D(d, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
const entt::entity enemyB = f.ships.spawn("interceptor", 1, QVector2D(0.0f, d),
|
||||
const entt::entity enemyB = f.ships.spawn("interceptor", QVector2D(0.0f, d),
|
||||
/*isEnemy=*/true);
|
||||
|
||||
// A second player ship already commits to enemyA, registering a claim, so
|
||||
// the penalised score of enemyA falls below the unclaimed equidistant enemyB.
|
||||
const entt::entity claimant = f.ships.spawn("interceptor", 1, QVector2D(d, 1.0f));
|
||||
const entt::entity claimant = f.ships.spawn("interceptor", QVector2D(d, 1.0f));
|
||||
f.admin.get<AttackBehavior>(claimant).currentTarget = enemyA;
|
||||
|
||||
f.decide();
|
||||
@@ -437,10 +437,10 @@ TEST_CASE("BehaviorSystem: hysteresis keeps a ship on its own claimed target",
|
||||
{
|
||||
const float d = 10.0f;
|
||||
Fixture f;
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemyA = f.ships.spawn("interceptor", 1, QVector2D(d, 0.0f),
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemyA = f.ships.spawn("interceptor", QVector2D(d, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
f.ships.spawn("interceptor", 1, QVector2D(0.0f, d), /*isEnemy=*/true);
|
||||
f.ships.spawn("interceptor", QVector2D(0.0f, d), /*isEnemy=*/true);
|
||||
|
||||
// The ship already holds enemyA; enemyB is equidistant. Without self-exclusion
|
||||
// the ship's own claim would penalise enemyA and flip the choice.
|
||||
@@ -459,10 +459,10 @@ TEST_CASE("BehaviorSystem: a ship switches off a heavily overclaimed target",
|
||||
{
|
||||
const float d = 10.0f;
|
||||
Fixture f;
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemyA = f.ships.spawn("interceptor", 1, QVector2D(d, 0.0f),
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemyA = f.ships.spawn("interceptor", QVector2D(d, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
const entt::entity enemyB = f.ships.spawn("interceptor", 1, QVector2D(0.0f, d),
|
||||
const entt::entity enemyB = f.ships.spawn("interceptor", QVector2D(0.0f, d),
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.admin.get<AttackBehavior>(player).currentTarget = enemyA;
|
||||
@@ -471,7 +471,7 @@ TEST_CASE("BehaviorSystem: a ship switches off a heavily overclaimed target",
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
const entt::entity other =
|
||||
f.ships.spawn("interceptor", 1, QVector2D(d, static_cast<float>(2 + i)));
|
||||
f.ships.spawn("interceptor", QVector2D(d, static_cast<float>(2 + i)));
|
||||
f.admin.get<AttackBehavior>(other).currentTarget = enemyA;
|
||||
}
|
||||
|
||||
@@ -488,8 +488,8 @@ TEST_CASE("BehaviorSystem: enemy ship acquires nearest player ship in range",
|
||||
"[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", 1, QVector2D(10.0f, 0.0f),
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", QVector2D(10.0f, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
@@ -505,7 +505,7 @@ TEST_CASE("BehaviorSystem: enemy ship with no target advances leftward",
|
||||
"[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", 1, QVector2D(100.0f, 0.0f),
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", QVector2D(100.0f, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
@@ -526,7 +526,7 @@ TEST_CASE("BehaviorSystem: advancing ship targets center between enemy defence s
|
||||
f.admin.spawnStation(QPoint(1000, 10), QSize(1, 1), body, 100.0f, 100.0f, /*isEnemy=*/true);
|
||||
f.admin.spawnStation(QPoint(1000, 30), QSize(1, 1), body, 100.0f, 100.0f, /*isEnemy=*/true);
|
||||
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f),
|
||||
/*isEnemy=*/false);
|
||||
// Player ships rally until departure; drop Rally so Advance is the fallback.
|
||||
f.ships.triggerRallyDeparture();
|
||||
@@ -549,7 +549,7 @@ TEST_CASE("BehaviorSystem: advancing ship falls back to enemy HQ, then off-world
|
||||
const QVector2D hqPos(5.0f, 7.0f);
|
||||
const entt::entity hq = f.admin.spawnHqProxy(hqPos, 100.0f, 100.0f);
|
||||
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", 1, QVector2D(1000.0f, 0.0f),
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", QVector2D(1000.0f, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
@@ -576,9 +576,9 @@ TEST_CASE("BehaviorSystem: repair ship orbits damaged friendly ship",
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", 1, QVector2D(5.0f, 0.0f));
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", QVector2D(5.0f, 0.0f));
|
||||
|
||||
f.admin.get<HealthComponent>(friendly).hp = f.admin.get<HealthComponent>(friendly).maxHp * 0.5f;
|
||||
|
||||
@@ -605,10 +605,10 @@ TEST_CASE("BehaviorSystem: idle repair ship stands by with the fleet instead of
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
// A healthy ally (nothing to repair) and a far enemy station (no threat in range).
|
||||
const entt::entity ally = f.ships.spawn("interceptor", 1, QVector2D(50.0f, 0.0f));
|
||||
const entt::entity ally = f.ships.spawn("interceptor", QVector2D(50.0f, 0.0f));
|
||||
const std::vector<QPoint> body{QPoint(0, 0)};
|
||||
f.admin.spawnStation(QPoint(1000, 0), QSize(1, 1), body, 100.0f, 100.0f, /*isEnemy=*/true);
|
||||
|
||||
@@ -628,8 +628,8 @@ TEST_CASE("BehaviorSystem: repair ship heals damaged ally within repair range",
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f), false, repairLayout);
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", 1, QVector2D(1.0f, 0.0f));
|
||||
f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f), false, repairLayout);
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", QVector2D(1.0f, 0.0f));
|
||||
|
||||
const float initialHp = f.admin.get<HealthComponent>(friendly).maxHp * 0.5f;
|
||||
f.admin.get<HealthComponent>(friendly).hp = initialHp;
|
||||
@@ -644,8 +644,8 @@ TEST_CASE("BehaviorSystem: repair ship does not heal above maxHp", "[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f), false, repairLayout);
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", 1, QVector2D(1.0f, 0.0f));
|
||||
f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f), false, repairLayout);
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", QVector2D(1.0f, 0.0f));
|
||||
|
||||
f.admin.get<HealthComponent>(friendly).hp = f.admin.get<HealthComponent>(friendly).maxHp - 0.001f;
|
||||
|
||||
@@ -666,9 +666,9 @@ TEST_CASE("RepairSystem: tool heals the in-range damaged target chosen by the ex
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", 1, QVector2D(10.0f, 0.0f));
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", QVector2D(10.0f, 0.0f));
|
||||
|
||||
const float initHp = f.admin.get<HealthComponent>(friendly).maxHp * 0.5f;
|
||||
f.admin.get<HealthComponent>(friendly).hp = initHp;
|
||||
@@ -688,12 +688,12 @@ TEST_CASE("RepairSystem: tool falls back to in-range target when its target is o
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
// out of repair range (80) but in sensor range (200)
|
||||
const entt::entity outOfRange = f.ships.spawn("interceptor", 1, QVector2D(90.0f, 0.0f));
|
||||
const entt::entity outOfRange = f.ships.spawn("interceptor", QVector2D(90.0f, 0.0f));
|
||||
// within repair range
|
||||
const entt::entity fallback = f.ships.spawn("interceptor", 1, QVector2D(20.0f, 0.0f));
|
||||
const entt::entity fallback = f.ships.spawn("interceptor", QVector2D(20.0f, 0.0f));
|
||||
|
||||
const float outInitHp = f.admin.get<HealthComponent>(outOfRange).maxHp * 0.5f;
|
||||
const float fallbackInitHp = f.admin.get<HealthComponent>(fallback).maxHp * 0.5f;
|
||||
@@ -717,10 +717,10 @@ TEST_CASE("RepairSystem: tool falls back when its target is fully healed",
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
const entt::entity healed = f.ships.spawn("interceptor", 1, QVector2D(10.0f, 0.0f));
|
||||
const entt::entity fallback = f.ships.spawn("interceptor", 1, QVector2D(15.0f, 0.0f));
|
||||
const entt::entity healed = f.ships.spawn("interceptor", QVector2D(10.0f, 0.0f));
|
||||
const entt::entity fallback = f.ships.spawn("interceptor", QVector2D(15.0f, 0.0f));
|
||||
|
||||
f.admin.get<HealthComponent>(healed).hp = f.admin.get<HealthComponent>(healed).maxHp;
|
||||
const float fallbackInitHp = f.admin.get<HealthComponent>(fallback).maxHp * 0.5f;
|
||||
@@ -740,10 +740,10 @@ TEST_CASE("RepairSystem: tool falls back when its target is destroyed",
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
const entt::entity gone = f.ships.spawn("interceptor", 1, QVector2D(10.0f, 0.0f));
|
||||
const entt::entity fallback = f.ships.spawn("interceptor", 1, QVector2D(15.0f, 0.0f));
|
||||
const entt::entity gone = f.ships.spawn("interceptor", QVector2D(10.0f, 0.0f));
|
||||
const entt::entity fallback = f.ships.spawn("interceptor", QVector2D(15.0f, 0.0f));
|
||||
|
||||
const float fallbackInitHp = f.admin.get<HealthComponent>(fallback).maxHp * 0.5f;
|
||||
f.admin.get<HealthComponent>(fallback).hp = fallbackInitHp;
|
||||
@@ -763,10 +763,10 @@ TEST_CASE("RepairSystem: tool target is cleared when no repairable target is in
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
// damaged but beyond repair range (80)
|
||||
const entt::entity outOfRange = f.ships.spawn("interceptor", 1, QVector2D(150.0f, 0.0f));
|
||||
const entt::entity outOfRange = f.ships.spawn("interceptor", QVector2D(150.0f, 0.0f));
|
||||
|
||||
const float initHp = f.admin.get<HealthComponent>(outOfRange).maxHp * 0.5f;
|
||||
f.admin.get<HealthComponent>(outOfRange).hp = initHp;
|
||||
@@ -785,9 +785,9 @@ TEST_CASE("RepairSystem: two repair modules both heal the chosen target additive
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeTwoModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
const entt::entity targetA = f.ships.spawn("interceptor", 1, QVector2D(10.0f, 0.0f));
|
||||
const entt::entity targetA = f.ships.spawn("interceptor", QVector2D(10.0f, 0.0f));
|
||||
|
||||
const float initHp = f.admin.get<HealthComponent>(targetA).maxHp * 0.5f;
|
||||
f.admin.get<HealthComponent>(targetA).hp = initHp;
|
||||
@@ -813,10 +813,10 @@ TEST_CASE("RepairSystem: two modules both fall back and heal the same target",
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeTwoModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
const entt::entity healed = f.ships.spawn("interceptor", 1, QVector2D(10.0f, 0.0f));
|
||||
const entt::entity targetB = f.ships.spawn("interceptor", 1, QVector2D(20.0f, 0.0f));
|
||||
const entt::entity healed = f.ships.spawn("interceptor", QVector2D(10.0f, 0.0f));
|
||||
const entt::entity targetB = f.ships.spawn("interceptor", QVector2D(20.0f, 0.0f));
|
||||
|
||||
f.admin.get<HealthComponent>(healed).hp = f.admin.get<HealthComponent>(healed).maxHp;
|
||||
const float initHp = f.admin.get<HealthComponent>(targetB).maxHp * 0.5f;
|
||||
@@ -847,7 +847,7 @@ TEST_CASE("RepairSystem: does not crash when a tool's owner is not a repair ship
|
||||
Fixture f;
|
||||
|
||||
// Bare child entity: RepairToolComponent + ModuleOwnerComponent, owner is a combat ship.
|
||||
const entt::entity ownerShip = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity ownerShip = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
const entt::entity moduleEntity = f.admin.createModuleEntity();
|
||||
RepairToolComponent rt;
|
||||
rt.repairAmountHp = 1.0f;
|
||||
@@ -868,7 +868,7 @@ TEST_CASE("RepairSystem: repair tool does not repair an HQ", "[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
|
||||
// A damaged, same-faction HQ in repair range — spawned as a station and tagged
|
||||
@@ -890,7 +890,7 @@ TEST_CASE("RepairSystem: repair tool still repairs a damaged defence station", "
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
|
||||
// A damaged, same-faction defence station (no HQ tag) in repair range.
|
||||
@@ -914,7 +914,7 @@ TEST_CASE("BehaviorSystem: salvage ship orbits nearest scrap", "[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig salvageLayout = makeSingleModuleLayout("salvager");
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", QVector2D(0.0f, 0.0f),
|
||||
false, salvageLayout);
|
||||
|
||||
const QVector2D scrapPos(100.0f, 0.0f);
|
||||
@@ -937,7 +937,7 @@ TEST_CASE("BehaviorSystem: salvage ship collects scrap on arrival", "[behavior]"
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig salvageLayout = makeSingleModuleLayout("salvager");
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", QVector2D(0.0f, 0.0f),
|
||||
false, salvageLayout);
|
||||
const entt::entity scrapEntity = f.scraps.spawn(QVector2D(0.0f, 0.0f), 1, 100000);
|
||||
|
||||
@@ -967,7 +967,7 @@ TEST_CASE("BehaviorSystem: full-cargo salvage ship moves toward SalvageBay", "[b
|
||||
REQUIRE(f.buildings.findBuilding(bayId) != nullptr);
|
||||
|
||||
const ShipLayoutConfig salvageLayout = makeSingleModuleLayout("salvager");
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(5.0f, 0.0f),
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", QVector2D(5.0f, 0.0f),
|
||||
false, salvageLayout);
|
||||
{
|
||||
REQUIRE(f.admin.isValid(firstSalvageChild(f.admin, ship)));
|
||||
@@ -1001,7 +1001,7 @@ TEST_CASE("SalvagerSystem: module does not collect scrap beyond its collection r
|
||||
// collection_range_m_formula = "50"; scrap at distance 55 must not be collected.
|
||||
Fixture f;
|
||||
const ShipLayoutConfig salvageLayout = makeSingleModuleLayout("salvager");
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", QVector2D(0.0f, 0.0f),
|
||||
false, salvageLayout);
|
||||
f.scraps.spawn(QVector2D(55.0f, 0.0f), 1, 100000);
|
||||
|
||||
@@ -1016,7 +1016,7 @@ TEST_CASE("SalvagerSystem: module collects scrap within its collection range",
|
||||
// collection_range_m_formula = "50"; scrap at distance 45 must be collected.
|
||||
Fixture f;
|
||||
const ShipLayoutConfig salvageLayout = makeSingleModuleLayout("salvager");
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", QVector2D(0.0f, 0.0f),
|
||||
false, salvageLayout);
|
||||
f.scraps.spawn(QVector2D(45.0f, 0.0f), 1, 100000);
|
||||
|
||||
@@ -1033,7 +1033,7 @@ TEST_CASE("SalvagerSystem: collection sets cooldown on module", "[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig salvageLayout = makeSingleModuleLayout("salvager");
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", QVector2D(0.0f, 0.0f),
|
||||
false, salvageLayout);
|
||||
f.scraps.spawn(QVector2D(0.0f, 0.0f), 1, 100000);
|
||||
|
||||
@@ -1051,7 +1051,7 @@ TEST_CASE("SalvagerSystem: module on cooldown does not collect scrap", "[behavio
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig salvageLayout = makeSingleModuleLayout("salvager");
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", QVector2D(0.0f, 0.0f),
|
||||
false, salvageLayout);
|
||||
f.scraps.spawn(QVector2D(0.0f, 0.0f), 1, 100000);
|
||||
|
||||
@@ -1066,7 +1066,7 @@ TEST_CASE("SalvagerSystem: module collects again after cooldown expires", "[beha
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig salvageLayout = makeSingleModuleLayout("salvager");
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", QVector2D(0.0f, 0.0f),
|
||||
false, salvageLayout);
|
||||
const entt::entity sc = firstSalvageChild(f.admin, ship);
|
||||
|
||||
@@ -1093,7 +1093,7 @@ TEST_CASE("SalvagerSystem: two salvage modules collect independently in same tic
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig salvageLayout = makeTwoModuleLayout("salvager");
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", QVector2D(0.0f, 0.0f),
|
||||
false, salvageLayout);
|
||||
|
||||
f.scraps.spawn(QVector2D(0.0f, 0.0f), 1, 100000);
|
||||
@@ -1110,7 +1110,7 @@ TEST_CASE("SalvagerSystem: second salvage module does not collect when first is
|
||||
// One module on cooldown, one ready: only the ready module collects.
|
||||
Fixture f;
|
||||
const ShipLayoutConfig salvageLayout = makeTwoModuleLayout("salvager");
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", QVector2D(0.0f, 0.0f),
|
||||
false, salvageLayout);
|
||||
|
||||
// Put the first salvage child on cooldown.
|
||||
@@ -1141,7 +1141,7 @@ TEST_CASE("SalvagerSystem: second salvage module does not collect when first is
|
||||
TEST_CASE("SensorRange: sensorRange is populated from config formula at spawn", "[sensor]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity e = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
REQUIRE(f.admin.get<SensorRangeComponent>(e).value_tiles == Approx(200.0f));
|
||||
}
|
||||
|
||||
@@ -1152,8 +1152,8 @@ TEST_CASE("SensorRange: sensorRange is populated from config formula at spawn",
|
||||
TEST_CASE("SensorRange: player combat ship acquires enemy just inside sensor range", "[sensor]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", 1, QVector2D(190.0f, 0.0f),
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", QVector2D(190.0f, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
@@ -1164,8 +1164,8 @@ TEST_CASE("SensorRange: player combat ship acquires enemy just inside sensor ran
|
||||
TEST_CASE("SensorRange: player combat ship ignores enemy just outside sensor range", "[sensor]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
f.ships.spawn("interceptor", 1, QVector2D(210.0f, 0.0f), /*isEnemy=*/true);
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
f.ships.spawn("interceptor", QVector2D(210.0f, 0.0f), /*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
|
||||
@@ -1175,8 +1175,8 @@ TEST_CASE("SensorRange: player combat ship ignores enemy just outside sensor ran
|
||||
TEST_CASE("SensorRange: enemy ship ignores player just outside sensor range", "[sensor]")
|
||||
{
|
||||
Fixture f;
|
||||
f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", 1, QVector2D(210.0f, 0.0f),
|
||||
f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", QVector2D(210.0f, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
@@ -1194,9 +1194,9 @@ TEST_CASE("SensorRange: repair ship retreats from enemy within sensor range", "[
|
||||
const QVector2D rallyPoint(-100.0f, 0.0f);
|
||||
f.ships.setRallyPoint(rallyPoint);
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
f.ships.spawn("interceptor", 1, QVector2D(200.0f, 0.0f), /*isEnemy=*/true);
|
||||
f.ships.spawn("interceptor", QVector2D(200.0f, 0.0f), /*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
|
||||
@@ -1208,9 +1208,9 @@ TEST_CASE("SensorRange: repair ship does not retreat from enemy beyond sensor ra
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
f.ships.spawn("interceptor", 1, QVector2D(300.0f, 0.0f), /*isEnemy=*/true);
|
||||
f.ships.spawn("interceptor", QVector2D(300.0f, 0.0f), /*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
|
||||
@@ -1225,9 +1225,9 @@ TEST_CASE("SensorRange: repair ship does not acquire damaged ally beyond sensor
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig repairLayout = makeSingleModuleLayout("repair_tool");
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", QVector2D(0.0f, 0.0f),
|
||||
false, repairLayout);
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", 1, QVector2D(300.0f, 0.0f));
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", QVector2D(300.0f, 0.0f));
|
||||
f.admin.get<HealthComponent>(friendly).hp = f.admin.get<HealthComponent>(friendly).maxHp * 0.5f;
|
||||
|
||||
f.decide();
|
||||
@@ -1243,7 +1243,7 @@ TEST_CASE("SensorRange: salvage ship ignores scrap beyond sensor range", "[senso
|
||||
{
|
||||
Fixture f;
|
||||
const ShipLayoutConfig salvageLayout = makeSingleModuleLayout("salvager");
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(0.0f, 0.0f),
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", QVector2D(0.0f, 0.0f),
|
||||
false, salvageLayout);
|
||||
f.scraps.spawn(QVector2D(300.0f, 0.0f), 1, 100000);
|
||||
|
||||
@@ -1261,8 +1261,8 @@ TEST_CASE("Orbit: combat ship's intent carries the target center and orbit radiu
|
||||
"[orbit]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", 1, QVector2D(10.0f, 0.0f),
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", QVector2D(10.0f, 0.0f),
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.decide();
|
||||
@@ -1282,7 +1282,7 @@ TEST_CASE("Orbit: rally ship orbits the rally point at the configured rally radi
|
||||
Fixture f;
|
||||
const QVector2D rallyPoint(-50.0f, 0.0f);
|
||||
f.ships.setRallyPoint(rallyPoint);
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
|
||||
f.decide();
|
||||
|
||||
@@ -1298,8 +1298,8 @@ TEST_CASE("Orbit: combat ship settles near the orbit radius and circles a statio
|
||||
{
|
||||
Fixture f;
|
||||
const QVector2D enemyPos(80.0f, 0.0f);
|
||||
const entt::entity player = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", 1, enemyPos, /*isEnemy=*/true);
|
||||
const entt::entity player = f.ships.spawn("interceptor", QVector2D(0.0f, 0.0f));
|
||||
const entt::entity enemy = f.ships.spawn("interceptor", enemyPos, /*isEnemy=*/true);
|
||||
|
||||
const float orbitRadius = f.admin.get<AttackBehavior>(player).orbitRadius_tiles;
|
||||
REQUIRE(orbitRadius > 0.0f);
|
||||
|
||||
Reference in New Issue
Block a user