move ecs related code to own folder
This commit is contained in:
@@ -12,14 +12,25 @@
|
||||
#include "ConfigLoader.h"
|
||||
#include "DynamicBodyComponent.h"
|
||||
#include "DynamicBodySystem.h"
|
||||
#include "EcsComponents.h"
|
||||
#include "EntityAdmin.h"
|
||||
#include "FactionComponent.h"
|
||||
#include "HealthComponent.h"
|
||||
#include "HomeReturnBehaviorComponent.h"
|
||||
#include "MovementIntentComponent.h"
|
||||
#include "MovementIntentSystem.h"
|
||||
#include "PositionComponent.h"
|
||||
#include "RallyBehaviorComponent.h"
|
||||
#include "RepairBehaviorComponent.h"
|
||||
#include "RepairToolComponent.h"
|
||||
#include "Rotation.h"
|
||||
#include "SalvageBehaviorComponent.h"
|
||||
#include "SalvageCargoComponent.h"
|
||||
#include "ScrapSystem.h"
|
||||
#include "Ship.h"
|
||||
#include "SensorRangeComponent.h"
|
||||
#include "ShipIdentityComponent.h"
|
||||
#include "ShipSystem.h"
|
||||
#include "Tick.h"
|
||||
#include "ThreatResponseBehaviorComponent.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Fixture
|
||||
@@ -78,19 +89,19 @@ struct Fixture
|
||||
};
|
||||
|
||||
// Helpers to read ECS data for a ship entity.
|
||||
static const MovementIntent& intent(EntityAdmin& a, entt::entity e)
|
||||
static const MovementIntentComponent& intent(EntityAdmin& a, entt::entity e)
|
||||
{
|
||||
return a.get<MovementIntent>(e);
|
||||
return a.get<MovementIntentComponent>(e);
|
||||
}
|
||||
|
||||
static const Health& health(EntityAdmin& a, entt::entity e)
|
||||
static const HealthComponent& health(EntityAdmin& a, entt::entity e)
|
||||
{
|
||||
return a.get<Health>(e);
|
||||
return a.get<HealthComponent>(e);
|
||||
}
|
||||
|
||||
static const Position& pos(EntityAdmin& a, entt::entity e)
|
||||
static const PositionComponent& pos(EntityAdmin& a, entt::entity e)
|
||||
{
|
||||
return a.get<Position>(e);
|
||||
return a.get<PositionComponent>(e);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -103,7 +114,7 @@ TEST_CASE("BehaviorSystem: clearMovementIntents resets all ships to priority 0",
|
||||
Fixture f;
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
|
||||
f.admin.get<MovementIntent>(e) = MovementIntent{3, QVector2D(10.0f, 0.0f)};
|
||||
f.admin.get<MovementIntentComponent>(e) = MovementIntentComponent{3, QVector2D(10.0f, 0.0f)};
|
||||
f.ships.clearMovementIntents();
|
||||
|
||||
REQUIRE(intent(f.admin, e).priority == 0);
|
||||
@@ -120,7 +131,7 @@ TEST_CASE("BehaviorSystem: tickMovement advances ship by maxSpeedPerTick toward
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
|
||||
const float speed = f.admin.get<DynamicBodyComponent>(e).maxSpeedPerTick;
|
||||
f.admin.get<MovementIntent>(e) = MovementIntent{1, QVector2D(100.0f, 0.0f)};
|
||||
f.admin.get<MovementIntentComponent>(e) = MovementIntentComponent{1, QVector2D(100.0f, 0.0f)};
|
||||
f.movementIntent.tick(f.admin);
|
||||
f.dynamicBody.tick(f.admin);
|
||||
|
||||
@@ -136,7 +147,7 @@ TEST_CASE("BehaviorSystem: tickMovement stops exactly at target without overshoo
|
||||
|
||||
const float speed = f.admin.get<DynamicBodyComponent>(e).maxSpeedPerTick;
|
||||
const QVector2D target(speed * 0.5f, 0.0f);
|
||||
f.admin.get<MovementIntent>(e) = MovementIntent{1, target};
|
||||
f.admin.get<MovementIntentComponent>(e) = MovementIntentComponent{1, target};
|
||||
f.movementIntent.tick(f.admin);
|
||||
f.dynamicBody.tick(f.admin);
|
||||
|
||||
@@ -153,8 +164,8 @@ TEST_CASE("BehaviorSystem: tickHomeReturnBehavior does nothing when HP is above
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
f.admin.addComponent<HomeReturnBehavior>(e, HomeReturnBehavior{0.3f, QVector2D(-10.0f, 0.0f)});
|
||||
f.admin.get<Health>(e).hp = f.admin.get<Health>(e).maxHp; // full HP
|
||||
f.admin.addComponent<HomeReturnBehaviorComponent>(e, HomeReturnBehaviorComponent{0.3f, QVector2D(-10.0f, 0.0f)});
|
||||
f.admin.get<HealthComponent>(e).hp = f.admin.get<HealthComponent>(e).maxHp; // full HP
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickHomeReturnBehavior(f.admin);
|
||||
@@ -168,8 +179,8 @@ TEST_CASE("BehaviorSystem: tickHomeReturnBehavior writes priority-4 intent towar
|
||||
Fixture f;
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
const QVector2D homePos(-10.0f, 0.0f);
|
||||
f.admin.addComponent<HomeReturnBehavior>(e, HomeReturnBehavior{0.5f, homePos});
|
||||
f.admin.get<Health>(e).hp = f.admin.get<Health>(e).maxHp * 0.2f; // below threshold
|
||||
f.admin.addComponent<HomeReturnBehaviorComponent>(e, HomeReturnBehaviorComponent{0.5f, homePos});
|
||||
f.admin.get<HealthComponent>(e).hp = f.admin.get<HealthComponent>(e).maxHp * 0.2f; // below threshold
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickHomeReturnBehavior(f.admin);
|
||||
@@ -186,8 +197,8 @@ TEST_CASE("BehaviorSystem: tickHomeReturnBehavior priority-4 beats tickThreatRes
|
||||
f.ships.spawn("interceptor", 1, QVector2D(5.0f, 0.0f), /*isEnemy=*/true);
|
||||
|
||||
const QVector2D homePos(-50.0f, 0.0f);
|
||||
f.admin.addComponent<HomeReturnBehavior>(player, HomeReturnBehavior{0.5f, homePos});
|
||||
f.admin.get<Health>(player).hp = f.admin.get<Health>(player).maxHp * 0.1f;
|
||||
f.admin.addComponent<HomeReturnBehaviorComponent>(player, HomeReturnBehaviorComponent{0.5f, homePos});
|
||||
f.admin.get<HealthComponent>(player).hp = f.admin.get<HealthComponent>(player).maxHp * 0.1f;
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickHomeReturnBehavior(f.admin);
|
||||
@@ -212,8 +223,8 @@ TEST_CASE("BehaviorSystem: player combat ship acquires nearest enemy ship in ran
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE(f.admin.hasAll<ThreatResponseBehavior>(player));
|
||||
const ThreatResponseBehavior& threatResponseBehavior = f.admin.get<ThreatResponseBehavior>(player);
|
||||
REQUIRE(f.admin.hasAll<ThreatResponseBehaviorComponent>(player));
|
||||
const ThreatResponseBehaviorComponent& threatResponseBehavior = f.admin.get<ThreatResponseBehaviorComponent>(player);
|
||||
REQUIRE(threatResponseBehavior.currentTarget.has_value());
|
||||
REQUIRE(*threatResponseBehavior.currentTarget == enemy);
|
||||
}
|
||||
@@ -228,8 +239,8 @@ TEST_CASE("BehaviorSystem: player combat ship does not target friendly ships",
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE(f.admin.hasAll<ThreatResponseBehavior>(e1));
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehavior>(e1).currentTarget.has_value());
|
||||
REQUIRE(f.admin.hasAll<ThreatResponseBehaviorComponent>(e1));
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehaviorComponent>(e1).currentTarget.has_value());
|
||||
}
|
||||
|
||||
TEST_CASE("BehaviorSystem: player combat ship ignores enemy beyond engagement range",
|
||||
@@ -242,7 +253,7 @@ TEST_CASE("BehaviorSystem: player combat ship ignores enemy beyond engagement ra
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehavior>(player).currentTarget.has_value());
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehaviorComponent>(player).currentTarget.has_value());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -260,8 +271,8 @@ TEST_CASE("BehaviorSystem: enemy ship acquires nearest player ship in range",
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE(f.admin.hasAll<ThreatResponseBehavior>(enemy));
|
||||
const ThreatResponseBehavior& threatResponseBehavior = f.admin.get<ThreatResponseBehavior>(enemy);
|
||||
REQUIRE(f.admin.hasAll<ThreatResponseBehaviorComponent>(enemy));
|
||||
const ThreatResponseBehaviorComponent& threatResponseBehavior = f.admin.get<ThreatResponseBehaviorComponent>(enemy);
|
||||
REQUIRE(threatResponseBehavior.currentTarget.has_value());
|
||||
REQUIRE(*threatResponseBehavior.currentTarget == player);
|
||||
}
|
||||
@@ -291,7 +302,7 @@ TEST_CASE("BehaviorSystem: repair ship writes intent toward damaged friendly shi
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", 1, QVector2D(5.0f, 0.0f));
|
||||
|
||||
f.admin.get<Health>(friendly).hp = f.admin.get<Health>(friendly).maxHp * 0.5f;
|
||||
f.admin.get<HealthComponent>(friendly).hp = f.admin.get<HealthComponent>(friendly).maxHp * 0.5f;
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickRepairBehavior(f.admin, f.buildings);
|
||||
@@ -307,8 +318,8 @@ TEST_CASE("BehaviorSystem: repair ship heals damaged ally within repair range",
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", 1, QVector2D(1.0f, 0.0f));
|
||||
|
||||
const float initialHp = f.admin.get<Health>(friendly).maxHp * 0.5f;
|
||||
f.admin.get<Health>(friendly).hp = initialHp;
|
||||
const float initialHp = f.admin.get<HealthComponent>(friendly).maxHp * 0.5f;
|
||||
f.admin.get<HealthComponent>(friendly).hp = initialHp;
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickRepairBehavior(f.admin, f.buildings);
|
||||
@@ -322,7 +333,7 @@ TEST_CASE("BehaviorSystem: repair ship does not heal above maxHp", "[behavior]")
|
||||
f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", 1, QVector2D(1.0f, 0.0f));
|
||||
|
||||
f.admin.get<Health>(friendly).hp = f.admin.get<Health>(friendly).maxHp - 0.001f;
|
||||
f.admin.get<HealthComponent>(friendly).hp = f.admin.get<HealthComponent>(friendly).maxHp - 0.001f;
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
@@ -330,7 +341,7 @@ TEST_CASE("BehaviorSystem: repair ship does not heal above maxHp", "[behavior]")
|
||||
f.ai.tickRepairBehavior(f.admin, f.buildings);
|
||||
}
|
||||
|
||||
const Health& h = health(f.admin, friendly);
|
||||
const HealthComponent& h = health(f.admin, friendly);
|
||||
REQUIRE(h.hp <= h.maxHp);
|
||||
REQUIRE(h.hp == Approx(h.maxHp));
|
||||
}
|
||||
@@ -363,7 +374,7 @@ TEST_CASE("BehaviorSystem: salvage ship collects scrap on arrival", "[behavior]"
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickSalvageBehavior(f.admin, f.scraps, f.buildings);
|
||||
|
||||
REQUIRE(f.admin.get<SalvageCargo>(ship).current == 1);
|
||||
REQUIRE(f.admin.get<SalvageCargoComponent>(ship).current == 1);
|
||||
REQUIRE_FALSE(f.admin.isValid(scrapEntity));
|
||||
}
|
||||
|
||||
@@ -385,13 +396,13 @@ TEST_CASE("BehaviorSystem: full-cargo salvage ship moves toward SalvageBay", "[b
|
||||
REQUIRE(f.buildings.findBuilding(bayId) != nullptr);
|
||||
|
||||
const entt::entity ship = f.ships.spawn("salvage_ship", 1, QVector2D(5.0f, 0.0f));
|
||||
SalvageCargo& cargo = f.admin.get<SalvageCargo>(ship);
|
||||
SalvageCargoComponent& cargo = f.admin.get<SalvageCargoComponent>(ship);
|
||||
cargo.current = cargo.capacity; // full cargo
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickSalvageBehavior(f.admin, f.scraps, f.buildings);
|
||||
|
||||
const MovementIntent& i = intent(f.admin, ship);
|
||||
const MovementIntentComponent& i = intent(f.admin, ship);
|
||||
REQUIRE(i.priority == 1);
|
||||
REQUIRE(i.target.x() < pos(f.admin, ship).value.x());
|
||||
}
|
||||
@@ -404,7 +415,7 @@ TEST_CASE("SensorRange: sensorRange is populated from config formula at spawn",
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
REQUIRE(f.admin.get<SensorRange>(e).value == Approx(200.0f));
|
||||
REQUIRE(f.admin.get<SensorRangeComponent>(e).value == Approx(200.0f));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -421,7 +432,7 @@ TEST_CASE("SensorRange: player combat ship acquires enemy just inside sensor ran
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE(f.admin.get<ThreatResponseBehavior>(player).currentTarget == enemy);
|
||||
REQUIRE(f.admin.get<ThreatResponseBehaviorComponent>(player).currentTarget == enemy);
|
||||
}
|
||||
|
||||
TEST_CASE("SensorRange: player combat ship ignores enemy just outside sensor range", "[sensor]")
|
||||
@@ -433,7 +444,7 @@ TEST_CASE("SensorRange: player combat ship ignores enemy just outside sensor ran
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehavior>(player).currentTarget.has_value());
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehaviorComponent>(player).currentTarget.has_value());
|
||||
}
|
||||
|
||||
TEST_CASE("SensorRange: enemy ship ignores player just outside sensor range", "[sensor]")
|
||||
@@ -446,7 +457,7 @@ TEST_CASE("SensorRange: enemy ship ignores player just outside sensor range", "[
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehavior>(enemy).currentTarget.has_value());
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehaviorComponent>(enemy).currentTarget.has_value());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -483,12 +494,12 @@ TEST_CASE("SensorRange: repair ship does not acquire damaged ally beyond sensor
|
||||
Fixture f;
|
||||
const entt::entity repairShip = f.ships.spawn("repair_ship", 1, QVector2D(0.0f, 0.0f));
|
||||
const entt::entity friendly = f.ships.spawn("interceptor", 1, QVector2D(300.0f, 0.0f));
|
||||
f.admin.get<Health>(friendly).hp = f.admin.get<Health>(friendly).maxHp * 0.5f;
|
||||
f.admin.get<HealthComponent>(friendly).hp = f.admin.get<HealthComponent>(friendly).maxHp * 0.5f;
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickRepairBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE_FALSE(f.admin.get<RepairBehavior>(repairShip).currentTarget.has_value());
|
||||
REQUIRE_FALSE(f.admin.get<RepairBehaviorComponent>(repairShip).currentTarget.has_value());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -504,6 +515,6 @@ TEST_CASE("SensorRange: salvage ship ignores scrap beyond sensor range", "[senso
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickSalvageBehavior(f.admin, f.scraps, f.buildings);
|
||||
|
||||
REQUIRE_FALSE(f.admin.get<SalvageBehavior>(ship).scrapTarget.has_value());
|
||||
REQUIRE_FALSE(f.admin.get<SalvageBehaviorComponent>(ship).scrapTarget.has_value());
|
||||
REQUIRE(intent(f.admin, ship).target.x() > pos(f.admin, ship).value.x());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user