show accumulated threat for teams in balancing target

This commit is contained in:
2026-06-17 21:17:45 +02:00
parent 1a682fdb79
commit 7f4ea93a70
7 changed files with 43 additions and 1 deletions

View File

@@ -26,6 +26,7 @@
#include "StationBodyComponent.h"
#include "StationsConfig.h"
#include "SurfaceMask.h"
#include "ThreatCostCalculator.h"
#include "WeaponComponent.h"
ArenaSimulation::ArenaSimulation(const GameConfig& gameConfig,
@@ -64,6 +65,24 @@ ArenaSimulation::ArenaSimulation(const GameConfig& gameConfig,
m_salvagerSystem = std::make_unique<SalvagerSystem>(m_admin);
m_repairSystem = std::make_unique<RepairSystem>(m_admin);
// Static accumulated threat per team: sum of count * per-ship threat cost
// (REQ-MOD-THREAT) over the configured ship roster. Ships only; HQ and
// defence stations are excluded. Level-independent, so computed once here.
for (int ti = 0; ti < 2; ++ti)
{
double teamThreat = 0.0;
for (const ArenaShipEntry& shipEntry : m_arenaConfig.teams[ti].ships)
{
const std::vector<PlacedModule>& modules = shipEntry.layout
? shipEntry.layout->placedModules
: std::vector<PlacedModule>{};
const double shipThreat = calculateShipThreatCost(
m_gameConfig.threatCosts, m_gameConfig, shipEntry.schematicId, modules);
teamThreat += shipThreat * shipEntry.count;
}
m_teamThreat[ti] = teamThreat;
}
placeStructures();
spawnShips();
@@ -460,6 +479,7 @@ void ArenaSimulation::updateStatus()
{
ArenaStatus::TeamStatus& teamStatus = newStatus.teams[ti];
teamStatus.name = m_arenaConfig.teams[ti].name;
teamStatus.threatLevel = m_teamThreat[ti];
// HQ entry (always first).
{

View File

@@ -40,6 +40,7 @@ struct ArenaStatus
struct TeamStatus
{
std::string name;
double threatLevel = 0.0; // accumulated threat of the team's configured ships
std::vector<Entry> entries; // HQ first, then ships, then stations
};
@@ -108,6 +109,9 @@ private:
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};
std::vector<WeaponFiredEvent> m_weaponFiredEvents;
mutable std::mutex m_statusMutex;

View File

@@ -61,6 +61,8 @@ void ArenaWidget::buildLayout(const std::string& arenaName)
headerFont.setBold(true);
m_team1Header->setFont(headerFont);
team1Layout->addWidget(m_team1Header);
m_team1Threat = new QLabel(this);
team1Layout->addWidget(m_team1Threat);
m_team1Content = new QLabel(this);
team1Layout->addWidget(m_team1Content);
team1Layout->addStretch();
@@ -71,6 +73,8 @@ void ArenaWidget::buildLayout(const std::string& arenaName)
m_team2Header = new QLabel(this);
m_team2Header->setFont(headerFont);
team2Layout->addWidget(m_team2Header);
m_team2Threat = new QLabel(this);
team2Layout->addWidget(m_team2Threat);
m_team2Content = new QLabel(this);
team2Layout->addWidget(m_team2Content);
team2Layout->addStretch();
@@ -101,6 +105,7 @@ void ArenaWidget::updateStatus(const ArenaStatus& status)
{
const ArenaStatus::TeamStatus& team = status.teams[ti];
QLabel* header = (ti == 0) ? m_team1Header : m_team2Header;
QLabel* threat = (ti == 0) ? m_team1Threat : m_team2Threat;
QLabel* content = (ti == 0) ? m_team1Content : m_team2Content;
if (status.finished && status.winnerTeam == ti)
@@ -112,6 +117,8 @@ void ArenaWidget::updateStatus(const ArenaStatus& status)
header->setText(QString::fromStdString(team.name));
}
threat->setText(tr("Threat: %1").arg(QString::number(team.threatLevel, 'f', 0)));
QString lines;
for (const ArenaStatus::Entry& entry : team.entries)
{

View File

@@ -27,6 +27,8 @@ private:
QLabel* m_titleLabel;
QLabel* m_team1Header;
QLabel* m_team2Header;
QLabel* m_team1Threat;
QLabel* m_team2Threat;
QLabel* m_team1Content;
QLabel* m_team2Content;
QPushButton* m_inspectButton;

View File

@@ -91,6 +91,8 @@ InspectWindow::InspectWindow(ArenaSimulation* sim, const GameConfig* config,
headerFont.setBold(true);
m_team1Header->setFont(headerFont);
team1Layout->addWidget(m_team1Header);
m_team1Threat = new QLabel(infoPanel);
team1Layout->addWidget(m_team1Threat);
m_team1Content = new QLabel(infoPanel);
team1Layout->addWidget(m_team1Content);
team1Layout->addStretch();
@@ -100,6 +102,8 @@ InspectWindow::InspectWindow(ArenaSimulation* sim, const GameConfig* config,
m_team2Header = new QLabel(infoPanel);
m_team2Header->setFont(headerFont);
team2Layout->addWidget(m_team2Header);
m_team2Threat = new QLabel(infoPanel);
team2Layout->addWidget(m_team2Threat);
m_team2Content = new QLabel(infoPanel);
team2Layout->addWidget(m_team2Content);
team2Layout->addStretch();
@@ -198,6 +202,7 @@ void InspectWindow::updateInfoPanel(const ArenaStatus& status)
{
const ArenaStatus::TeamStatus& team = status.teams[ti];
QLabel* header = (ti == 0) ? m_team1Header : m_team2Header;
QLabel* threat = (ti == 0) ? m_team1Threat : m_team2Threat;
QLabel* content = (ti == 0) ? m_team1Content : m_team2Content;
if (status.finished && status.winnerTeam == ti)
@@ -209,6 +214,8 @@ void InspectWindow::updateInfoPanel(const ArenaStatus& status)
header->setText(QString::fromStdString(team.name));
}
threat->setText(tr("Threat: %1").arg(QString::number(team.threatLevel, 'f', 0)));
QString lines;
for (const ArenaStatus::Entry& entry : team.entries)
{

View File

@@ -56,6 +56,8 @@ private:
std::vector<QPushButton*> m_speedButtons;
QLabel* m_team1Header;
QLabel* m_team2Header;
QLabel* m_team1Threat;
QLabel* m_team2Threat;
QLabel* m_team1Content;
QLabel* m_team2Content;
QTimer* m_pollTimer;