boss waves
This commit is contained in:
@@ -29,73 +29,33 @@ static GameConfig loadConfig()
|
||||
// Threat accumulation
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("WaveSystem: threat stays 0 for first 30 game-seconds", "[wave]")
|
||||
TEST_CASE("WaveSystem: threat accumulates at boss wave counter rate", "[wave]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
std::mt19937 rng(42);
|
||||
WaveSystem ws(cfg, rng);
|
||||
|
||||
// threat_rate_formula = "1*x - 30", which is <= 0 for x <= 30.
|
||||
const int ticks30s = static_cast<int>(secondsToTicks(30.0));
|
||||
for (int i = 0; i < ticks30s; ++i)
|
||||
// threat_rate_formula = "x", boss wave counter starts at 1 → rate = 1 threat/s.
|
||||
// After 1 second: threat ≈ 1.0.
|
||||
const int ticks1s = static_cast<int>(secondsToTicks(1.0));
|
||||
for (int i = 0; i < ticks1s; ++i)
|
||||
{
|
||||
ws.tickThreatAccumulation(static_cast<Tick>(i));
|
||||
ws.tickThreatAccumulation();
|
||||
}
|
||||
|
||||
REQUIRE(ws.threatLevel() == Approx(0.0));
|
||||
REQUIRE(ws.threatLevel() == Approx(1.0));
|
||||
}
|
||||
|
||||
TEST_CASE("WaveSystem: threat accumulates after 30 game-seconds", "[wave]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
std::mt19937 rng(42);
|
||||
WaveSystem ws(cfg, rng);
|
||||
|
||||
// Run 31 seconds worth of ticks.
|
||||
const int ticks31s = static_cast<int>(secondsToTicks(31.0));
|
||||
for (int i = 0; i < ticks31s; ++i)
|
||||
{
|
||||
ws.tickThreatAccumulation(static_cast<Tick>(i));
|
||||
}
|
||||
|
||||
REQUIRE(ws.threatLevel() > 0.0);
|
||||
}
|
||||
|
||||
TEST_CASE("WaveSystem: applyPush increases threat accumulation rate", "[wave]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
std::mt19937 rng(42);
|
||||
WaveSystem ws(cfg, rng);
|
||||
|
||||
// Accumulate for 1 tick past the 30s mark to get a baseline rate.
|
||||
const Tick baseTick = secondsToTicks(31.0);
|
||||
ws.tickThreatAccumulation(baseTick);
|
||||
const double levelBefore = ws.threatLevel();
|
||||
|
||||
// Apply push: multiplier should increase.
|
||||
ws.applyPush();
|
||||
|
||||
WaveSystem ws2(cfg, rng);
|
||||
ws2.tickThreatAccumulation(baseTick);
|
||||
|
||||
// After the push the same tick adds more threat.
|
||||
ws.tickThreatAccumulation(baseTick + 1);
|
||||
ws2.tickThreatAccumulation(baseTick + 1);
|
||||
|
||||
// ws has the push multiplier applied; ws2 does not.
|
||||
REQUIRE(ws.threatLevel() > ws2.threatLevel());
|
||||
}
|
||||
|
||||
TEST_CASE("WaveSystem: generation starts at 0 and increments on push", "[wave]")
|
||||
TEST_CASE("WaveSystem: generation starts at 0 and increments on station destruction", "[wave]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
std::mt19937 rng(42);
|
||||
WaveSystem ws(cfg, rng);
|
||||
|
||||
REQUIRE(ws.generation() == 0);
|
||||
ws.applyPush();
|
||||
ws.onEnemyStationsDestroyed();
|
||||
REQUIRE(ws.generation() == 1);
|
||||
ws.applyPush();
|
||||
ws.onEnemyStationsDestroyed();
|
||||
REQUIRE(ws.generation() == 2);
|
||||
}
|
||||
|
||||
@@ -217,18 +177,23 @@ TEST_CASE("WaveSystem: enemy ships spawn after the initial gap elapses", "[wave]
|
||||
|
||||
// The maximum gap is gapMaxSeconds = 45s → 1350 ticks.
|
||||
// Run 1500 ticks to guarantee at least one wave has triggered.
|
||||
// Check each tick: enemy ships may be killed quickly by player stations,
|
||||
// so we must detect them while they are alive, not only after the loop.
|
||||
const int limit = static_cast<int>(secondsToTicks(50.0));
|
||||
bool foundEnemyShip = false;
|
||||
for (int i = 0; i < limit; ++i)
|
||||
{
|
||||
sim.tick();
|
||||
}
|
||||
|
||||
bool foundEnemyShip = false;
|
||||
sim.admin().forEach<ShipIdentityComponent, FactionComponent>(
|
||||
[&](entt::entity /*e*/, const ShipIdentityComponent& /*si*/, const FactionComponent& f)
|
||||
if (!foundEnemyShip)
|
||||
{
|
||||
if (f.isEnemy) { foundEnemyShip = true; }
|
||||
});
|
||||
sim.admin().forEach<ShipIdentityComponent, FactionComponent>(
|
||||
[&](entt::entity /*e*/, const ShipIdentityComponent& /*si*/,
|
||||
const FactionComponent& f)
|
||||
{
|
||||
if (f.isEnemy) { foundEnemyShip = true; }
|
||||
});
|
||||
}
|
||||
}
|
||||
REQUIRE(foundEnemyShip);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user