124 lines
3.7 KiB
C++
124 lines
3.7 KiB
C++
#pragma once
|
|
|
|
#include <map>
|
|
#include <memory>
|
|
#include <random>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <QPoint>
|
|
|
|
#include "BeltSystem.h"
|
|
#include "SchematicDropEvent.h"
|
|
#include "BuildingType.h"
|
|
#include "EntityId.h"
|
|
#include "FireEvent.h"
|
|
#include "GameConfig.h"
|
|
#include "Rotation.h"
|
|
#include "Tick.h"
|
|
|
|
class BuildingSystem;
|
|
class CombatSystem;
|
|
class ShipSystem;
|
|
class ScrapSystem;
|
|
class WaveSystem;
|
|
|
|
class Simulation
|
|
{
|
|
public:
|
|
explicit Simulation(GameConfig config, unsigned int seed = 0);
|
|
~Simulation();
|
|
|
|
const GameConfig& config() const;
|
|
|
|
// Reinitializes all simulation state as if constructed fresh.
|
|
void reset(unsigned int seed = 0);
|
|
|
|
// Reloads config then reinitializes all simulation state.
|
|
void reset(GameConfig newConfig, unsigned int seed = 0);
|
|
|
|
// Advances the simulation by one tick. Tick order per architecture.md §Tick Order.
|
|
void tick();
|
|
|
|
// Returns all fire events accumulated since the last drain, clearing the
|
|
// internal queue. Call once per rendered frame (REQ-SHP-FIRING-BEAM).
|
|
std::vector<FireEvent> drainFireEvents();
|
|
|
|
// Returns all schematic drop events since the last drain.
|
|
std::vector<SchematicDropEvent> drainSchematicDropEvents();
|
|
|
|
Tick currentTick() const;
|
|
int buildingBlocksStock() const;
|
|
bool isGameOver() const;
|
|
double threatLevel() const;
|
|
|
|
// Schematic state queries.
|
|
int schematicLevel(const std::string& shipId) const;
|
|
bool isSchematicUnlocked(const std::string& shipId) const;
|
|
|
|
// Checks affordability, deducts building blocks, and places the building.
|
|
// Returns the new entity id, or kInvalidEntityId if blocks are insufficient.
|
|
EntityId tryPlaceBuilding(BuildingType type, QPoint anchor, Rotation rotation);
|
|
|
|
// Demolishes the building with the given id and refunds building blocks.
|
|
void demolish(EntityId id);
|
|
|
|
BuildingSystem& buildings();
|
|
const BuildingSystem& buildings() const;
|
|
BeltSystem& belts();
|
|
const BeltSystem& belts() const;
|
|
ShipSystem& ships();
|
|
const ShipSystem& ships() const;
|
|
ScrapSystem& scraps();
|
|
const ScrapSystem& scraps() const;
|
|
|
|
private:
|
|
EntityId allocateId(); // Strictly increasing; never returns kInvalidEntityId.
|
|
|
|
// Populate HQ, player defence stations, and the first enemy station set.
|
|
void placeInitialStructures();
|
|
|
|
// Place two enemy defence stations for the given generation level.
|
|
// Stores their IDs in m_currentEnemyStationIds.
|
|
void placeEnemyStationSet(int generation);
|
|
|
|
// Tick step 9: remove dead ships and buildings, drop scrap, handle push.
|
|
void tickDeathsAndLoot();
|
|
|
|
// Award a random schematic drop (REQ-DEF-SCHEMATIC-DROP) and emit the event.
|
|
void awardSchematicDrop();
|
|
|
|
GameConfig m_config;
|
|
std::mt19937 m_rng;
|
|
|
|
Tick m_currentTick;
|
|
Tick m_nextDepartureTick;
|
|
EntityId m_nextId;
|
|
int m_buildingBlocksStock;
|
|
bool m_gameOver = false;
|
|
|
|
// Pre-placed structure IDs.
|
|
EntityId m_hqId;
|
|
EntityId m_playerStation1Id;
|
|
EntityId m_playerStation2Id;
|
|
EntityId m_currentEnemyStationIds[2];
|
|
|
|
// Schematic unlock state (REQ-DEF-SCHEMATIC-DROP).
|
|
struct SchematicState
|
|
{
|
|
bool unlocked;
|
|
int level;
|
|
};
|
|
std::map<std::string, SchematicState> m_schematicLevels;
|
|
|
|
BeltSystem m_beltSystem;
|
|
std::unique_ptr<BuildingSystem> m_buildingSystem;
|
|
std::unique_ptr<ShipSystem> m_shipSystem;
|
|
std::unique_ptr<ScrapSystem> m_scrapSystem;
|
|
std::unique_ptr<WaveSystem> m_waveSystem;
|
|
std::unique_ptr<CombatSystem> m_combatSystem;
|
|
|
|
std::vector<FireEvent> m_fireEvents;
|
|
std::vector<SchematicDropEvent> m_schematicDropEvents;
|
|
};
|