rename behavior components
This commit is contained in:
@@ -64,10 +64,10 @@ struct Fixture
|
||||
void runBehaviorTick()
|
||||
{
|
||||
ships.clearMovementIntents();
|
||||
ai.tickHomeReturn(admin);
|
||||
ai.tickThreatResponse(admin, buildings);
|
||||
ai.tickHomeReturnBehavior(admin);
|
||||
ai.tickThreatResponseBehavior(admin, buildings);
|
||||
ai.tickRepairBehavior(admin, buildings);
|
||||
ai.tickScrapCollector(admin, scraps, buildings);
|
||||
ai.tickSalvageBehavior(admin, scraps, buildings);
|
||||
movement.tick(admin);
|
||||
++tick;
|
||||
}
|
||||
@@ -139,40 +139,40 @@ TEST_CASE("BehaviorSystem: tickMovement stops exactly at target without overshoo
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// tickHomeReturn
|
||||
// tickHomeReturnBehavior
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("BehaviorSystem: tickHomeReturn does nothing when HP is above threshold",
|
||||
TEST_CASE("BehaviorSystem: tickHomeReturnBehavior does nothing when HP is above threshold",
|
||||
"[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
const entt::entity e = f.ships.spawn("interceptor", 1, QVector2D(0.0f, 0.0f));
|
||||
f.admin.addComponent<HomeReturn>(e, HomeReturn{0.3f, QVector2D(-10.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.ships.clearMovementIntents();
|
||||
f.ai.tickHomeReturn(f.admin);
|
||||
f.ai.tickHomeReturnBehavior(f.admin);
|
||||
|
||||
REQUIRE(intent(f.admin, e).priority == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("BehaviorSystem: tickHomeReturn writes priority-4 intent toward homePos when HP is low",
|
||||
TEST_CASE("BehaviorSystem: tickHomeReturnBehavior writes priority-4 intent toward homePos when HP is low",
|
||||
"[behavior]")
|
||||
{
|
||||
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<HomeReturn>(e, HomeReturn{0.5f, homePos});
|
||||
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.ships.clearMovementIntents();
|
||||
f.ai.tickHomeReturn(f.admin);
|
||||
f.ai.tickHomeReturnBehavior(f.admin);
|
||||
|
||||
REQUIRE(intent(f.admin, e).priority == 4);
|
||||
REQUIRE(intent(f.admin, e).target.x() == Approx(homePos.x()));
|
||||
}
|
||||
|
||||
TEST_CASE("BehaviorSystem: tickHomeReturn priority-4 beats tickThreatResponse priority-3",
|
||||
TEST_CASE("BehaviorSystem: tickHomeReturnBehavior priority-4 beats tickThreatResponseBehavior priority-3",
|
||||
"[behavior]")
|
||||
{
|
||||
Fixture f;
|
||||
@@ -180,19 +180,19 @@ TEST_CASE("BehaviorSystem: tickHomeReturn priority-4 beats tickThreatResponse pr
|
||||
f.ships.spawn("interceptor", 1, QVector2D(5.0f, 0.0f), /*isEnemy=*/true);
|
||||
|
||||
const QVector2D homePos(-50.0f, 0.0f);
|
||||
f.admin.addComponent<HomeReturn>(player, HomeReturn{0.5f, homePos});
|
||||
f.admin.addComponent<HomeReturnBehavior>(player, HomeReturnBehavior{0.5f, homePos});
|
||||
f.admin.get<Health>(player).hp = f.admin.get<Health>(player).maxHp * 0.1f;
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickHomeReturn(f.admin);
|
||||
f.ai.tickThreatResponse(f.admin, f.buildings);
|
||||
f.ai.tickHomeReturnBehavior(f.admin);
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE(intent(f.admin, player).priority == 4);
|
||||
REQUIRE(intent(f.admin, player).target.x() == Approx(homePos.x()));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// tickThreatResponse — player ships
|
||||
// tickThreatResponseBehavior — player ships
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("BehaviorSystem: player combat ship acquires nearest enemy ship in range",
|
||||
@@ -204,12 +204,12 @@ TEST_CASE("BehaviorSystem: player combat ship acquires nearest enemy ship in ran
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponse(f.admin, f.buildings);
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE(f.admin.hasAll<ThreatResponse>(player));
|
||||
const ThreatResponse& tr = f.admin.get<ThreatResponse>(player);
|
||||
REQUIRE(tr.currentTarget.has_value());
|
||||
REQUIRE(*tr.currentTarget == enemy);
|
||||
REQUIRE(f.admin.hasAll<ThreatResponseBehavior>(player));
|
||||
const ThreatResponseBehavior& threatResponseBehavior = f.admin.get<ThreatResponseBehavior>(player);
|
||||
REQUIRE(threatResponseBehavior.currentTarget.has_value());
|
||||
REQUIRE(*threatResponseBehavior.currentTarget == enemy);
|
||||
}
|
||||
|
||||
TEST_CASE("BehaviorSystem: player combat ship does not target friendly ships",
|
||||
@@ -220,10 +220,10 @@ TEST_CASE("BehaviorSystem: player combat ship does not target friendly ships",
|
||||
f.ships.spawn("interceptor", 1, QVector2D(5.0f, 0.0f)); // also player
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponse(f.admin, f.buildings);
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE(f.admin.hasAll<ThreatResponse>(e1));
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponse>(e1).currentTarget.has_value());
|
||||
REQUIRE(f.admin.hasAll<ThreatResponseBehavior>(e1));
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehavior>(e1).currentTarget.has_value());
|
||||
}
|
||||
|
||||
TEST_CASE("BehaviorSystem: player combat ship ignores enemy beyond engagement range",
|
||||
@@ -234,13 +234,13 @@ TEST_CASE("BehaviorSystem: player combat ship ignores enemy beyond engagement ra
|
||||
f.ships.spawn("interceptor", 1, QVector2D(500.0f, 0.0f), /*isEnemy=*/true);
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponse(f.admin, f.buildings);
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponse>(player).currentTarget.has_value());
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehavior>(player).currentTarget.has_value());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// tickThreatResponse — enemy ships
|
||||
// tickThreatResponseBehavior — enemy ships
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("BehaviorSystem: enemy ship acquires nearest player ship in range",
|
||||
@@ -252,12 +252,12 @@ TEST_CASE("BehaviorSystem: enemy ship acquires nearest player ship in range",
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponse(f.admin, f.buildings);
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE(f.admin.hasAll<ThreatResponse>(enemy));
|
||||
const ThreatResponse& tr = f.admin.get<ThreatResponse>(enemy);
|
||||
REQUIRE(tr.currentTarget.has_value());
|
||||
REQUIRE(*tr.currentTarget == player);
|
||||
REQUIRE(f.admin.hasAll<ThreatResponseBehavior>(enemy));
|
||||
const ThreatResponseBehavior& threatResponseBehavior = f.admin.get<ThreatResponseBehavior>(enemy);
|
||||
REQUIRE(threatResponseBehavior.currentTarget.has_value());
|
||||
REQUIRE(*threatResponseBehavior.currentTarget == player);
|
||||
}
|
||||
|
||||
TEST_CASE("BehaviorSystem: enemy ship with no target writes leftward movement intent",
|
||||
@@ -268,7 +268,7 @@ TEST_CASE("BehaviorSystem: enemy ship with no target writes leftward movement in
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponse(f.admin, f.buildings);
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE(intent(f.admin, enemy).priority == 3);
|
||||
REQUIRE(intent(f.admin, enemy).target.x() < 0.0f);
|
||||
@@ -330,7 +330,7 @@ TEST_CASE("BehaviorSystem: repair ship does not heal above maxHp", "[behavior]")
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// tickScrapCollector
|
||||
// tickSalvageBehavior
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("BehaviorSystem: salvage ship writes intent toward nearest scrap", "[behavior]")
|
||||
@@ -342,7 +342,7 @@ TEST_CASE("BehaviorSystem: salvage ship writes intent toward nearest scrap", "[b
|
||||
f.scraps.spawn(scrapPos, 1, 100000);
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickScrapCollector(f.admin, f.scraps, f.buildings);
|
||||
f.ai.tickSalvageBehavior(f.admin, f.scraps, f.buildings);
|
||||
|
||||
REQUIRE(intent(f.admin, ship).priority == 1);
|
||||
REQUIRE(intent(f.admin, ship).target.x() == Approx(scrapPos.x()));
|
||||
@@ -355,7 +355,7 @@ TEST_CASE("BehaviorSystem: salvage ship collects scrap on arrival", "[behavior]"
|
||||
const entt::entity scrapEntity = f.scraps.spawn(QVector2D(0.0f, 0.0f), 1, 100000);
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickScrapCollector(f.admin, f.scraps, f.buildings);
|
||||
f.ai.tickSalvageBehavior(f.admin, f.scraps, f.buildings);
|
||||
|
||||
REQUIRE(f.admin.get<SalvageCargo>(ship).current == 1);
|
||||
REQUIRE_FALSE(f.admin.isValid(scrapEntity));
|
||||
@@ -383,7 +383,7 @@ TEST_CASE("BehaviorSystem: full-cargo salvage ship moves toward SalvageBay", "[b
|
||||
cargo.current = cargo.capacity; // full cargo
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickScrapCollector(f.admin, f.scraps, f.buildings);
|
||||
f.ai.tickSalvageBehavior(f.admin, f.scraps, f.buildings);
|
||||
|
||||
const MovementIntent& i = intent(f.admin, ship);
|
||||
REQUIRE(i.priority == 1);
|
||||
@@ -402,7 +402,7 @@ TEST_CASE("SensorRange: sensorRange is populated from config formula at spawn",
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Sensor range — tickThreatResponse
|
||||
// Sensor range — tickThreatResponseBehavior
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("SensorRange: player combat ship acquires enemy just inside sensor range", "[sensor]")
|
||||
@@ -413,9 +413,9 @@ TEST_CASE("SensorRange: player combat ship acquires enemy just inside sensor ran
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponse(f.admin, f.buildings);
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE(f.admin.get<ThreatResponse>(player).currentTarget == enemy);
|
||||
REQUIRE(f.admin.get<ThreatResponseBehavior>(player).currentTarget == enemy);
|
||||
}
|
||||
|
||||
TEST_CASE("SensorRange: player combat ship ignores enemy just outside sensor range", "[sensor]")
|
||||
@@ -425,9 +425,9 @@ TEST_CASE("SensorRange: player combat ship ignores enemy just outside sensor ran
|
||||
f.ships.spawn("interceptor", 1, QVector2D(210.0f, 0.0f), /*isEnemy=*/true);
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponse(f.admin, f.buildings);
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponse>(player).currentTarget.has_value());
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehavior>(player).currentTarget.has_value());
|
||||
}
|
||||
|
||||
TEST_CASE("SensorRange: enemy ship ignores player just outside sensor range", "[sensor]")
|
||||
@@ -438,9 +438,9 @@ TEST_CASE("SensorRange: enemy ship ignores player just outside sensor range", "[
|
||||
/*isEnemy=*/true);
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickThreatResponse(f.admin, f.buildings);
|
||||
f.ai.tickThreatResponseBehavior(f.admin, f.buildings);
|
||||
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponse>(enemy).currentTarget.has_value());
|
||||
REQUIRE_FALSE(f.admin.get<ThreatResponseBehavior>(enemy).currentTarget.has_value());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -486,7 +486,7 @@ TEST_CASE("SensorRange: repair ship does not acquire damaged ally beyond sensor
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Sensor range — tickScrapCollector
|
||||
// Sensor range — tickSalvageBehavior
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("SensorRange: salvage ship ignores scrap beyond sensor range", "[sensor]")
|
||||
@@ -496,8 +496,8 @@ TEST_CASE("SensorRange: salvage ship ignores scrap beyond sensor range", "[senso
|
||||
f.scraps.spawn(QVector2D(300.0f, 0.0f), 1, 100000);
|
||||
|
||||
f.ships.clearMovementIntents();
|
||||
f.ai.tickScrapCollector(f.admin, f.scraps, f.buildings);
|
||||
f.ai.tickSalvageBehavior(f.admin, f.scraps, f.buildings);
|
||||
|
||||
REQUIRE_FALSE(f.admin.get<ScrapCollector>(ship).scrapTarget.has_value());
|
||||
REQUIRE_FALSE(f.admin.get<SalvageBehavior>(ship).scrapTarget.has_value());
|
||||
REQUIRE(intent(f.admin, ship).target.x() > pos(f.admin, ship).value.x());
|
||||
}
|
||||
|
||||
@@ -68,9 +68,9 @@ struct CombatFixture
|
||||
admin.get<Weapon>(enemy).currentTarget = playerTarget;
|
||||
admin.get<Weapon>(enemy).cooldownTicks = 0.0f;
|
||||
}
|
||||
if (admin.hasAll<ThreatResponse>(enemy))
|
||||
if (admin.hasAll<ThreatResponseBehavior>(enemy))
|
||||
{
|
||||
admin.get<ThreatResponse>(enemy).currentTarget = playerTarget;
|
||||
admin.get<ThreatResponseBehavior>(enemy).currentTarget = playerTarget;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -33,11 +33,11 @@ TEST_CASE("ShipSystem: interceptor spawn has weapon and threatResponse, no cargo
|
||||
|
||||
REQUIRE(admin.isValid(e));
|
||||
REQUIRE(admin.hasAll<Weapon>(e));
|
||||
REQUIRE(admin.hasAll<ThreatResponse>(e));
|
||||
REQUIRE(admin.hasAll<ThreatResponseBehavior>(e));
|
||||
REQUIRE_FALSE(admin.hasAll<SalvageCargo>(e));
|
||||
REQUIRE_FALSE(admin.hasAll<RepairTool>(e));
|
||||
REQUIRE_FALSE(admin.hasAll<RepairBehavior>(e));
|
||||
REQUIRE_FALSE(admin.hasAll<ScrapCollector>(e));
|
||||
REQUIRE_FALSE(admin.hasAll<SalvageBehavior>(e));
|
||||
}
|
||||
|
||||
TEST_CASE("ShipSystem: interceptor level 1 stats match config formulas", "[ship]")
|
||||
@@ -100,7 +100,7 @@ TEST_CASE("ShipSystem: salvage_ship spawn has cargo and scrapCollector, no weapo
|
||||
const entt::entity e = ss.spawn("salvage_ship", 1, QVector2D(0.0f, 0.0f));
|
||||
|
||||
REQUIRE(admin.hasAll<SalvageCargo>(e));
|
||||
REQUIRE(admin.hasAll<ScrapCollector>(e));
|
||||
REQUIRE(admin.hasAll<SalvageBehavior>(e));
|
||||
REQUIRE_FALSE(admin.hasAll<Weapon>(e));
|
||||
REQUIRE_FALSE(admin.hasAll<RepairTool>(e));
|
||||
}
|
||||
@@ -116,8 +116,8 @@ TEST_CASE("ShipSystem: salvage_ship cargo capacity matches config", "[ship]")
|
||||
// cargo_capacity = 10
|
||||
REQUIRE(admin.get<SalvageCargo>(e).capacity == 10);
|
||||
REQUIRE(admin.get<SalvageCargo>(e).current == 0);
|
||||
REQUIRE(admin.get<ScrapCollector>(e).deliveryBay == kInvalidBuildingId);
|
||||
REQUIRE_FALSE(admin.get<ScrapCollector>(e).scrapTarget.has_value());
|
||||
REQUIRE(admin.get<SalvageBehavior>(e).deliveryBay == kInvalidBuildingId);
|
||||
REQUIRE_FALSE(admin.get<SalvageBehavior>(e).scrapTarget.has_value());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user