diff --git a/src/ui/GameWorldView.cpp b/src/ui/GameWorldView.cpp index 2caff0d..7e4bb87 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" @@ -871,6 +872,21 @@ void GameWorldView::drawBuildings(QPainter& painter) drawPortGlyph(painter, portBodyTile(port.tile, port.direction), port.direction, bv.outline); } + + // 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); @@ -1051,14 +1067,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); } }); } @@ -1104,18 +1114,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 11edfc9..abf0bf8 100644 --- a/src/ui/GameWorldView.h +++ b/src/ui/GameWorldView.h @@ -120,6 +120,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);