implement waves

This commit is contained in:
2026-04-20 14:10:01 +02:00
parent 65de4ddc5c
commit 498b97db20
17 changed files with 1798 additions and 18 deletions

67
src/lib/sim/WaveSystem.h Normal file
View File

@@ -0,0 +1,67 @@
#pragma once
#include <random>
#include <string>
#include <vector>
#include <QVector2D>
#include "GameConfig.h"
#include "Tick.h"
class ShipSystem;
// Manages wave scheduling (tick-order step 1) and threat-level accumulation
// (tick-order step 2). REQ-WAV-*.
class WaveSystem
{
public:
WaveSystem(const GameConfig& config, std::mt19937& rng);
// Tick step 1: start a new wave when the current gap has expired; spawn
// any ships in the pending list whose scheduled tick has arrived.
void tickWaveScheduler(Tick currentTick, ShipSystem& ships,
int worldHeightTiles);
// Tick step 2: accumulate threat from the rate formula, scaled by the
// current push multiplier (REQ-WAV-THREAT-RATE, REQ-PSH-ACCUMULATION).
void tickThreatAccumulation(Tick currentTick);
// Called by Simulation (tick step 9) when the current enemy-station set
// is fully destroyed: multiplies the push scaling and increments generation.
void applyPush();
double threatLevel() const;
// Current enemy-station generation level (0 for initial set,
// incremented by 1 after each push — REQ-PSH-STATION-STATS).
int generation() const;
private:
struct SpawnEntry
{
std::string blueprintId;
int level;
Tick spawnAt;
QVector2D position;
};
// Compose the next wave from the current threat budget, returning timed
// spawn entries spread across spawnDurationSeconds. Leaves any unspent
// budget in m_threatLevel (carry-over, REQ-WAV-TRIGGER).
std::vector<SpawnEntry> composeWave(Tick currentTick, int worldHeightTiles);
// Draw a random gap duration in ticks from [gapMin, gapMax].
Tick drawGapTicks();
const GameConfig& m_config;
std::mt19937& m_rng;
double m_threatLevel = 0.0;
double m_pushScalingMultiplier = 1.0;
int m_generation = 0;
bool m_waveActive = false;
Tick m_nextEventTick = 0; // absolute tick when the current gap expires
std::vector<SpawnEntry> m_pendingSpawns;
};