draw ghost in semi-transparent building color

This commit is contained in:
2026-06-23 21:17:16 +02:00
parent 577927ef70
commit f818c90af0
3 changed files with 71 additions and 38 deletions

View File

@@ -1086,25 +1086,8 @@ void GameWorldView::drawOverlays(QPainter& painter)
// Builder-mode ghost
if (m_builderType.has_value())
{
const BuildingDef* def = findBuildingDef(*m_builderType);
if (def)
{
const ParsedSurfaceMask parsed =
parseSurfaceMask(def->surfaceMask, m_ghostRotation);
const QColor& ghostColor = m_ghostValid
? m_visuals->overlays.ghostValid
: m_visuals->overlays.ghostInvalid;
for (const QPoint& cell : parsed.bodyCells)
{
painter.fillRect(tileRect(m_ghostTile + cell), ghostColor);
}
for (const Port& port : parsed.outputPorts)
{
const QPoint absBody = m_ghostTile
+ portBodyTile(port.tile, port.direction);
drawPortGlyph(painter, absBody, port.direction, Qt::white);
}
}
drawBuildingGhost(painter, *m_builderType, m_ghostTile,
m_ghostRotation, m_ghostValid);
}
// Blueprint placement ghost
@@ -1114,22 +1097,7 @@ void GameWorldView::drawOverlays(QPainter& painter)
{
const QPoint anchor = m_blueprintGhostTile + bb.offset;
const bool valid = isValidPlacement(bb.type, anchor, bb.rotation);
const QColor& ghostColor = valid
? m_visuals->overlays.ghostValid
: m_visuals->overlays.ghostInvalid;
const BuildingDef* def = findBuildingDef(bb.type);
if (!def) { continue; }
const ParsedSurfaceMask parsed = parseSurfaceMask(def->surfaceMask, bb.rotation);
for (const QPoint& cell : parsed.bodyCells)
{
painter.fillRect(tileRect(anchor + cell), ghostColor);
}
for (const Port& port : parsed.outputPorts)
{
drawPortGlyph(painter,
anchor + portBodyTile(port.tile, port.direction),
port.direction, Qt::white);
}
drawBuildingGhost(painter, bb.type, anchor, bb.rotation, valid);
}
}
@@ -1160,6 +1128,68 @@ void GameWorldView::drawOverlays(QPainter& painter)
}
}
void GameWorldView::drawBuildingGhost(QPainter& painter, BuildingType type,
QPoint anchorTile, Rotation rotation,
bool valid)
{
const BuildingDef* def = findBuildingDef(type);
if (!def) { return; }
const std::map<BuildingType, BuildingVisuals>::const_iterator it =
m_visuals->buildings.find(type);
if (it == m_visuals->buildings.end()) { return; }
const BuildingVisuals& bv = it->second;
// Valid ghosts show the building type's own colors; invalid ghosts override
// with the distinct invalid color (REQ-BLD-GHOST, REQ-BLD-PLACE-VALID). The
// invalid color's RGB is taken at full opacity so it does not double-dim
// against the setOpacity below (the configured color carries its own alpha).
const QColor invalidColor(m_visuals->overlays.ghostInvalid.red(),
m_visuals->overlays.ghostInvalid.green(),
m_visuals->overlays.ghostInvalid.blue());
const QColor fillColor = valid ? bv.fill : invalidColor;
const QColor lineColor = valid ? bv.outline : invalidColor;
const ParsedSurfaceMask parsed = parseSurfaceMask(def->surfaceMask, rotation);
if (parsed.bodyCells.empty()) { return; }
painter.setOpacity(0.5);
QPoint minCell = parsed.bodyCells.front();
QPoint maxCell = parsed.bodyCells.front();
for (const QPoint& cell : parsed.bodyCells)
{
painter.fillRect(tileRect(anchorTile + cell), fillColor);
minCell.setX(std::min(minCell.x(), cell.x()));
minCell.setY(std::min(minCell.y(), cell.y()));
maxCell.setX(std::max(maxCell.x(), cell.x()));
maxCell.setY(std::max(maxCell.y(), cell.y()));
}
const QPointF tl = tileToWidget(anchorTile + minCell);
const QRectF bboxRect(tl.x(), tl.y(),
(maxCell.x() - minCell.x() + 1) * static_cast<qreal>(tilePx()),
(maxCell.y() - minCell.y() + 1) * static_cast<qreal>(tilePx()));
painter.setPen(QPen(lineColor, 1));
painter.setBrush(Qt::NoBrush);
painter.drawRect(bboxRect);
if (!bv.glyph.isEmpty())
{
painter.setPen(lineColor);
painter.drawText(bboxRect, Qt::AlignCenter, bv.glyph);
}
for (const Port& port : parsed.outputPorts)
{
drawPortGlyph(painter, anchorTile + portBodyTile(port.tile, port.direction),
port.direction, lineColor);
}
painter.setOpacity(1.0);
}
void GameWorldView::drawScreenSpace(QPainter& /*painter*/)
{
}

View File

@@ -126,6 +126,9 @@ private:
void drawPortGlyph(QPainter& painter, QPoint bodyTile,
Rotation direction, const QColor& color);
void drawBuildingGhost(QPainter& painter, BuildingType type,
QPoint anchorTile, Rotation rotation, bool valid);
void placeBlueprintAtTile(QPoint center);
std::optional<QVector2D> entityPosition(entt::entity entity) const;