Files
dota_factory/src/lib/sim/WaveSystem.h
2026-06-03 22:14:31 +02:00

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;
};