86 lines
2.9 KiB
C++
86 lines
2.9 KiB
C++
#pragma once
|
|
|
|
#include <random>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <QVector2D>
|
|
|
|
#include "GameConfig.h"
|
|
#include "ShipLayout.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: advance the boss countdown and normal wave gap; trigger
|
|
// normal or boss waves when their timers expire; spawn any ships in the
|
|
// pending queues whose scheduled tick has arrived.
|
|
void tickWaveScheduler(Tick currentTick, ShipSystem& ships,
|
|
int worldHeightTiles);
|
|
|
|
// Tick step 2: accumulate threat from the rate formula evaluated at the
|
|
// current boss wave counter (REQ-WAV-THREAT-RATE).
|
|
void tickThreatAccumulation();
|
|
|
|
// Called by Simulation (tick step 9) when the current enemy-station set
|
|
// is fully destroyed: advances the boss countdown and increments generation
|
|
// (REQ-WAV-BOSS-ADVANCE, REQ-PSH-STATION-STATS).
|
|
void onEnemyStationsDestroyed();
|
|
|
|
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 schematicId;
|
|
int level;
|
|
Tick spawnAt;
|
|
QVector2D position;
|
|
ShipLayoutConfig layout;
|
|
};
|
|
|
|
// Select ships from the given threat budget until no eligible ship fits.
|
|
// Reduces budget in-place to the remaining (carry-over) amount.
|
|
std::vector<SpawnEntry> selectWaveShips(double& budget, Tick currentTick,
|
|
int worldHeightTiles);
|
|
|
|
void triggerNormalWave(Tick currentTick, int worldHeightTiles);
|
|
void triggerBossWave(Tick currentTick, int worldHeightTiles);
|
|
|
|
// Returns true while normal-wave spawning should be suppressed (REQ-WAV-QUIET).
|
|
bool isInQuietWindow() const;
|
|
|
|
// 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;
|
|
int m_generation = 0;
|
|
|
|
// Boss wave cycle (REQ-WAV-BOSS-COUNTER, REQ-WAV-BOSS-COUNTDOWN).
|
|
int m_bossWaveCounter = 1;
|
|
Tick m_bossCountdownTicks; // counts down each tick; reset after boss fires
|
|
Tick m_postBossQuietRemainingTicks = 0;
|
|
|
|
// Normal wave gap — frozen during quiet windows (REQ-WAV-GAP).
|
|
bool m_normalWaveActive = false;
|
|
Tick m_normalGapRemainingTicks; // replaces old m_nextEventTick
|
|
|
|
// Spawn queues — kept separate so normal-wave completion is trackable.
|
|
std::vector<SpawnEntry> m_normalPendingSpawns;
|
|
std::vector<SpawnEntry> m_bossPendingSpawns;
|
|
};
|