142 lines
4.1 KiB
C++
142 lines
4.1 KiB
C++
#pragma once
|
|
|
|
#include <atomic>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <optional>
|
|
#include <random>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "BalancingConfig.h"
|
|
#include "BeltSystem.h"
|
|
#include "FactoryState.h"
|
|
#include "EntityAdmin.h"
|
|
#include "BuildingId.h"
|
|
|
|
#include "entt/entity/entity.hpp"
|
|
#include "BeamFiredEvent.h"
|
|
#include "GameConfig.h"
|
|
#include "Tick.h"
|
|
|
|
class AiSystem;
|
|
class BuildingSystem;
|
|
class CombatSystem;
|
|
class DynamicBodySystem;
|
|
class MovementIntentSystem;
|
|
class RepairSystem;
|
|
class SalvagerSystem;
|
|
class ShipSystem;
|
|
class DebrisSystem;
|
|
|
|
struct ArenaStatus
|
|
{
|
|
struct Entry
|
|
{
|
|
std::string displayName;
|
|
// Level suffix shown in the widget/inspect display. Set for the HQ and
|
|
// defence stations; empty for ships, which no longer have a level.
|
|
std::optional<int> level;
|
|
int total;
|
|
int surviving;
|
|
};
|
|
|
|
struct TeamStatus
|
|
{
|
|
std::string name;
|
|
double threatLevel = 0.0; // accumulated threat of the team's configured ships
|
|
// Remaining durability of the team's ships and defence stations (HQ
|
|
// excluded). currentEhp is summed live; maxEhp is the fixed full-HP
|
|
// baseline. See getEhpPercentText() for the displayed value.
|
|
double currentEhp = 0.0;
|
|
double maxEhp = 0.0;
|
|
std::vector<Entry> entries; // HQ first, then ships, then stations
|
|
|
|
// Remaining EHP as a whole-number percentage ("NN%"), or "n/a" when the
|
|
// team has no ships or stations (maxEhp == 0).
|
|
std::string getEhpPercentText() const;
|
|
};
|
|
|
|
TeamStatus teams[2];
|
|
bool finished = false;
|
|
std::optional<int> winnerTeam; // 0 or 1 when finished; nullopt while running
|
|
// Game time the fight has lasted (simulated ticks * fixed tick duration).
|
|
// Meaningful once finished; the battle duration shown for completed runs.
|
|
double durationSeconds = 0.0;
|
|
};
|
|
|
|
class ArenaSimulation
|
|
{
|
|
public:
|
|
ArenaSimulation(const GameConfig& gameConfig,
|
|
ArenaConfig arenaConfig,
|
|
unsigned int seed = 0);
|
|
~ArenaSimulation();
|
|
|
|
void run();
|
|
void requestStop();
|
|
|
|
void tickOnce();
|
|
std::vector<BeamFiredEvent> drainBeamFiredEvents();
|
|
|
|
ArenaStatus getStatus() const;
|
|
bool isFinished() const;
|
|
std::optional<int> getWinnerTeam() const;
|
|
Tick getCurrentTick() const;
|
|
|
|
const ArenaConfig& getArenaConfig() const;
|
|
const BuildingSystem& getBuildings() const;
|
|
const ShipSystem& getShips() const;
|
|
const DebrisSystem& getDebrisSystem() const;
|
|
EntityAdmin& getAdmin();
|
|
const EntityAdmin& getAdmin() const;
|
|
|
|
private:
|
|
BuildingId allocateBuildingId();
|
|
void placeStructures();
|
|
void spawnShips();
|
|
void computeTeamMaxEhp();
|
|
void tick();
|
|
void tickDeaths();
|
|
void updateStatus();
|
|
|
|
const GameConfig& m_gameConfig;
|
|
ArenaConfig m_arenaConfig;
|
|
std::mt19937 m_rng;
|
|
|
|
Tick m_currentTick;
|
|
BuildingId m_nextBuildingId;
|
|
|
|
EntityAdmin m_admin;
|
|
FactoryState m_factoryState;
|
|
BeltSystem m_beltSystem;
|
|
std::unique_ptr<BuildingSystem> m_buildingSystem;
|
|
std::unique_ptr<ShipSystem> m_shipSystem;
|
|
std::unique_ptr<AiSystem> m_aiSystem;
|
|
std::unique_ptr<MovementIntentSystem> m_movementIntentSystem;
|
|
std::unique_ptr<DynamicBodySystem> m_dynamicBodySystem;
|
|
std::unique_ptr<CombatSystem> m_combatSystem;
|
|
std::unique_ptr<DebrisSystem> m_debrisSystem;
|
|
std::unique_ptr<SalvagerSystem> m_salvagerSystem;
|
|
std::unique_ptr<RepairSystem> m_repairSystem;
|
|
|
|
entt::entity m_team1HqEntity;
|
|
entt::entity m_team2HqEntity;
|
|
|
|
bool m_finished;
|
|
std::optional<int> m_winnerTeam;
|
|
std::atomic<bool> m_stopRequested;
|
|
|
|
// Static accumulated threat per team, computed once from the configured roster.
|
|
double m_teamThreat[2] = {0.0, 0.0};
|
|
|
|
// Full-HP baseline per team (ships + defence stations, HQ excluded), computed
|
|
// once after spawning; the EHP-percentage denominator.
|
|
double m_teamMaxEhp[2] = {0.0, 0.0};
|
|
|
|
std::vector<BeamFiredEvent> m_beamFiredEvents;
|
|
|
|
mutable std::mutex m_statusMutex;
|
|
ArenaStatus m_status;
|
|
};
|