show team EHP in balancing target

This commit is contained in:
2026-07-04 07:11:22 +02:00
parent 4d5b218fec
commit d9e7dd0fe8
8 changed files with 100 additions and 2 deletions

View File

@@ -2,6 +2,8 @@
#include <algorithm>
#include <cassert>
#include <cmath>
#include <string>
#include <QVector2D>
@@ -86,12 +88,49 @@ ArenaSimulation::ArenaSimulation(const GameConfig& gameConfig,
placeStructures();
spawnShips();
computeTeamMaxEhp();
m_shipSystem->triggerRallyDeparture();
updateStatus();
}
std::string ArenaStatus::TeamStatus::ehpPercentText() const
{
if (maxEhp <= 0.0)
{
return "n/a";
}
const int percent = static_cast<int>(std::lround(100.0 * currentEhp / maxEhp));
return std::to_string(percent) + "%";
}
void ArenaSimulation::computeTeamMaxEhp()
{
m_teamMaxEhp[0] = 0.0;
m_teamMaxEhp[1] = 0.0;
// Ships contribute their full max HP.
m_admin.forEach<ShipIdentityComponent, FactionComponent, HealthComponent>(
[this](entt::entity /*e*/, const ShipIdentityComponent& /*si*/,
const FactionComponent& f, const HealthComponent& h)
{
m_teamMaxEhp[f.isEnemy ? 1 : 0] += static_cast<double>(h.maxHp);
});
// Defence stations contribute their full max HP; the HQ is excluded.
m_admin.forEach<StationBodyComponent, FactionComponent, HealthComponent>(
[this](entt::entity e, const StationBodyComponent& /*sb*/,
const FactionComponent& f, const HealthComponent& h)
{
if (m_admin.hasAll<HqProxyComponent>(e))
{
return;
}
m_teamMaxEhp[f.isEnemy ? 1 : 0] += static_cast<double>(h.maxHp);
});
}
ArenaSimulation::~ArenaSimulation() = default;
BuildingId ArenaSimulation::allocateBuildingId()
@@ -477,11 +516,39 @@ void ArenaSimulation::updateStatus()
newStatus.finished = m_finished;
newStatus.winnerTeam = m_winnerTeam;
// Live remaining HP of each team's ships and defence stations (HQ excluded);
// the EHP-percentage numerator (denominator is the fixed m_teamMaxEhp).
double currentEhp[2] = {0.0, 0.0};
m_admin.forEach<ShipIdentityComponent, FactionComponent, HealthComponent>(
[&currentEhp](entt::entity /*e*/, const ShipIdentityComponent& /*si*/,
const FactionComponent& f, const HealthComponent& h)
{
if (h.hp > 0.0f)
{
currentEhp[f.isEnemy ? 1 : 0] += static_cast<double>(h.hp);
}
});
m_admin.forEach<StationBodyComponent, FactionComponent, HealthComponent>(
[this, &currentEhp](entt::entity e, const StationBodyComponent& /*sb*/,
const FactionComponent& f, const HealthComponent& h)
{
if (m_admin.hasAll<HqProxyComponent>(e))
{
return;
}
if (h.hp > 0.0f)
{
currentEhp[f.isEnemy ? 1 : 0] += static_cast<double>(h.hp);
}
});
for (int ti = 0; ti < 2; ++ti)
{
ArenaStatus::TeamStatus& teamStatus = newStatus.teams[ti];
teamStatus.name = m_arenaConfig.teams[ti].name;
teamStatus.threatLevel = m_teamThreat[ti];
teamStatus.currentEhp = currentEhp[ti];
teamStatus.maxEhp = m_teamMaxEhp[ti];
// HQ entry (always first).
{