From bf5ee8b3f168ff97bdc48f40563dcb9d98913b98 Mon Sep 17 00:00:00 2001 From: Malte Langkabel Date: Wed, 8 Jul 2026 21:32:44 +0200 Subject: [PATCH] Render HP bar below the HQ The HQ was drawn by drawBuildings(), which had no HP-bar code, so it never showed an HP bar despite REQ-UI-HP-BARS requiring one. Add HQ handling that reads HP from the HQ proxy entity and draws the bar below the footprint, matching the defence stations. Factor the shared bar-drawing logic into drawHpBar() and reuse it from drawStations(), drawShips(), and the new HQ path to avoid duplication. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01DyCu8vwChKMbLJQ3xosYEN --- src/ui/GameWorldView.cpp | 42 +++++++++++++++++++++++++++------------- src/ui/GameWorldView.h | 2 ++ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/ui/GameWorldView.cpp b/src/ui/GameWorldView.cpp index 1abd308..918918a 100644 --- a/src/ui/GameWorldView.cpp +++ b/src/ui/GameWorldView.cpp @@ -39,6 +39,7 @@ #include "FactionComponent.h" #include "GameOverEvent.h" #include "HealthComponent.h" +#include "HqProxyComponent.h" #include "PositionComponent.h" #include "RepairBehavior.h" #include "SalvageScrapBehavior.h" @@ -883,6 +884,21 @@ void GameWorldView::drawBuildings(QPainter& painter) painter.setBrush(Qt::NoBrush); painter.drawRect(bboxRect.adjusted(-1, -1, 1, 1)); } + + // HP bar below the HQ footprint; the HQ's HP lives on its proxy entity. + if (b.type == BuildingType::Hq) + { + m_sim->admin().forEach( + [&](entt::entity /*e*/, const HqProxyComponent& /*hq*/, + const FactionComponent& f, const HealthComponent& h) + { + if (h.maxHp > 0.0f) + { + drawHpBar(painter, bboxRect.left(), bboxRect.bottom() + 1.0, + bboxRect.width(), h.hp / h.maxHp, f.isEnemy); + } + }); + } } painter.setOpacity(0.5); @@ -1041,14 +1057,8 @@ void GameWorldView::drawStations(QPainter& painter) // HP bar below footprint. if (h.maxHp > 0.0f) { - const float fraction = std::max(0.0f, h.hp / h.maxHp); - const qreal barH = static_cast(tilePx()) * 0.12; - const qreal barY = bboxRect.bottom() + 1.0; - const qreal barW = bboxRect.width(); - painter.fillRect(QRectF(bboxRect.left(), barY, barW, barH), - QColor(60, 60, 60)); - painter.fillRect(QRectF(bboxRect.left(), barY, barW * static_cast(fraction), barH), - f.isEnemy ? QColor(200, 60, 60) : QColor(60, 200, 60)); + drawHpBar(painter, bboxRect.left(), bboxRect.bottom() + 1.0, + bboxRect.width(), h.hp / h.maxHp, f.isEnemy); } }); } @@ -1094,18 +1104,24 @@ void GameWorldView::drawShips(QPainter& painter) if (h.maxHp > 0.0f) { - const float fraction = std::max(0.0f, h.hp / h.maxHp); const qreal barW = static_cast(fwd) * 2.0; - const qreal barH = static_cast(tilePx()) * 0.12; const qreal barX = center.x() - static_cast(fwd); const qreal barY = center.y() + static_cast(fwd) + 1.0; - painter.fillRect(QRectF(barX, barY, barW, barH), QColor(60, 60, 60)); - painter.fillRect(QRectF(barX, barY, barW * static_cast(fraction), barH), - fac.isEnemy ? QColor(200, 60, 60) : QColor(60, 200, 60)); + drawHpBar(painter, barX, barY, barW, h.hp / h.maxHp, fac.isEnemy); } }); } +void GameWorldView::drawHpBar(QPainter& painter, qreal left, qreal top, qreal width, + float fraction, bool isEnemy) +{ + const qreal barH = static_cast(tilePx()) * 0.12; + const float clamped = std::max(0.0f, fraction); + painter.fillRect(QRectF(left, top, width, barH), QColor(60, 60, 60)); + painter.fillRect(QRectF(left, top, width * static_cast(clamped), barH), + isEnemy ? QColor(200, 60, 60) : QColor(60, 200, 60)); +} + void GameWorldView::drawDebugSensorRanges(QPainter& painter) { painter.setBrush(Qt::NoBrush); diff --git a/src/ui/GameWorldView.h b/src/ui/GameWorldView.h index 22cde0a..7874e3c 100644 --- a/src/ui/GameWorldView.h +++ b/src/ui/GameWorldView.h @@ -119,6 +119,8 @@ private: void drawBeltItems(QPainter& painter); void drawScrap(QPainter& painter); void drawShips(QPainter& painter); + void drawHpBar(QPainter& painter, qreal left, qreal top, qreal width, + float fraction, bool isEnemy); void drawDebugSensorRanges(QPainter& painter); void drawDebugTargetLines(QPainter& painter); void drawDebugOverlay(QPainter& painter);