draw glyph for output port at the target tile during build mode
This commit is contained in:
@@ -445,6 +445,7 @@ The screen is divided into two columns: a main column (75% width) containing the
|
|||||||
Because the contest-zone boundaries shift as the scrollable area grows with each push (REQ-GW-PUSH-EXPAND, REQ-GW-SCROLL-LIMIT), the ramp bands are recomputed from the current contest-zone boundaries. This is a presentation-only concern and does not affect the simulation, consistent with REQ-UI-NO-ZOOM.
|
Because the contest-zone boundaries shift as the scrollable area grows with each push (REQ-GW-PUSH-EXPAND, REQ-GW-SCROLL-LIMIT), the ramp bands are recomputed from the current contest-zone boundaries. This is a presentation-only concern and does not affect the simulation, consistent with REQ-UI-NO-ZOOM.
|
||||||
- REQ-UI-CONSTRUCTION-PROGRESS: Construction sites display the building's glyph centered on the footprint (same as an operational building). Below the glyph — or centered on the footprint if the building has no glyph — a construction progress percentage is shown (integer, e.g. `42%`), increasing from 0% to 100% as construction completes.
|
- REQ-UI-CONSTRUCTION-PROGRESS: Construction sites display the building's glyph centered on the footprint (same as an operational building). Below the glyph — or centered on the footprint if the building has no glyph — a construction progress percentage is shown (integer, e.g. `42%`), increasing from 0% to 100% as construction completes.
|
||||||
- REQ-UI-PORT-GLYPH: Every output port of every building is indicated by a directional glyph drawn on the port's tile. The glyph is a `>` rotated to face the port's exit direction (`>` for East, `^` for North, `<` for West, `v` for South). It is drawn at the midpoint between the tile center and the tile edge that the port exits through (i.e. halfway from center toward the exit edge). The indicator is rendered for all building states: operational buildings, construction sites, and the builder-mode ghost. Buildings with multiple output ports (e.g. splitters) show one indicator per port.
|
- REQ-UI-PORT-GLYPH: Every output port of every building is indicated by a directional glyph drawn on the port's tile. The glyph is a `>` rotated to face the port's exit direction (`>` for East, `^` for North, `<` for West, `v` for South). It is drawn at the midpoint between the tile center and the tile edge that the port exits through (i.e. halfway from center toward the exit edge). The indicator is rendered for all building states: operational buildings, construction sites, and the builder-mode ghost. Buildings with multiple output ports (e.g. splitters) show one indicator per port.
|
||||||
|
- REQ-UI-PORT-TARGET-GLYPH: While in builder mode (REQ-BLD-BUILDER-MODE), the builder-mode ghost additionally shows, for each of the building's output ports, a directional glyph drawn centered in the port's **target cell** — the cell immediately outside the footprint that the port pushes into, i.e. the cell the surface-mask output-port indicator occupies (see Surface Mask Format). As in REQ-UI-PORT-GLYPH the glyph is a `>` rotated to face the port's exit direction (`>` East, `^` North, `<` West, `v` South), previewing where the port's output will go before placement. This is in addition to the on-tile port glyph of REQ-UI-PORT-GLYPH, and — unlike that indicator — is shown only for the builder-mode ghost, not for operational buildings, construction sites, or the blueprint-placement ghost (REQ-UI-BLUEPRINT-PLACE). A building with multiple output ports (e.g. a splitter) shows one target-cell glyph per port. The target-cell glyph is drawn larger than the on-tile port glyph so it stands out as the flow-direction preview. Exceptions: the Tunnel Entry shows no target-cell glyph, because it receives items (which may arrive from any of its non-mouth edges, REQ-BLD-TUNNEL-ENTRY) rather than emitting into a single adjacent cell; the Shipyard shows none either, because its output port is a ship-spawn point (REQ-SHP-SPAWN-PLAYER) rather than a belt-item output (REQ-MAT-OUTPUT-EMERGE).
|
||||||
- REQ-UI-HP-BARS: All entities with HP — the HQ, player and enemy defence stations, and player and enemy ships — render an HP bar below them. The bar is always visible regardless of current HP. The bar's filled portion represents the fraction of current HP to maximum HP.
|
- REQ-UI-HP-BARS: All entities with HP — the HQ, player and enemy defence stations, and player and enemy ships — render an HP bar below them. The bar is always visible regardless of current HP. The bar's filled portion represents the fraction of current HP to maximum HP.
|
||||||
- REQ-UI-NO-ZOOM: The view has a fixed zoom level; the player cannot zoom in or out.
|
- REQ-UI-NO-ZOOM: The view has a fixed zoom level; the player cannot zoom in or out.
|
||||||
- REQ-UI-HOTKEYS: Global keyboard shortcuts:
|
- REQ-UI-HOTKEYS: Global keyboard shortcuts:
|
||||||
|
|||||||
@@ -895,31 +895,39 @@ void GameWorldView::placeAtTile(QPoint tile)
|
|||||||
// Port glyph helper
|
// Port glyph helper
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
void GameWorldView::drawPortGlyph(QPainter& painter, QPoint bodyTile,
|
void GameWorldView::drawPortGlyph(QPainter& painter, QPoint tile,
|
||||||
Rotation direction, const QColor& color)
|
Rotation direction, const QColor& color,
|
||||||
|
bool centered)
|
||||||
{
|
{
|
||||||
const float px = getTilePx();
|
const float px = getTilePx();
|
||||||
const QRectF tr = tileRect(bodyTile);
|
const QRectF tr = tileRect(tile);
|
||||||
const QPointF center(tr.x() + static_cast<qreal>(px) * 0.5,
|
const QPointF center(tr.x() + static_cast<qreal>(px) * 0.5,
|
||||||
tr.y() + static_cast<qreal>(px) * 0.5);
|
tr.y() + static_cast<qreal>(px) * 0.5);
|
||||||
|
|
||||||
QPointF offset;
|
QPointF edgeOffset;
|
||||||
const char* ch;
|
const char* ch;
|
||||||
switch (direction)
|
switch (direction)
|
||||||
{
|
{
|
||||||
case Rotation::East: offset = QPointF(px * 0.25f, 0); ch = ">"; break;
|
case Rotation::East: edgeOffset = QPointF(px * 0.25f, 0); ch = ">"; break;
|
||||||
case Rotation::West: offset = QPointF(-px * 0.25f, 0); ch = "<"; break;
|
case Rotation::West: edgeOffset = QPointF(-px * 0.25f, 0); ch = "<"; break;
|
||||||
case Rotation::North: offset = QPointF(0, -px * 0.25f); ch = "^"; break;
|
case Rotation::North: edgeOffset = QPointF(0, -px * 0.25f); ch = "^"; break;
|
||||||
case Rotation::South: offset = QPointF(0, px * 0.25f); ch = "v"; break;
|
case Rotation::South: edgeOffset = QPointF(0, px * 0.25f); ch = "v"; break;
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qreal half = static_cast<qreal>(px) * 0.3;
|
// Centered glyphs sit in the middle of the tile (used for a port's target
|
||||||
|
// cell, REQ-UI-PORT-TARGET-GLYPH) and are drawn 150% larger to stand out;
|
||||||
|
// otherwise offset toward the exit edge of the port's body tile
|
||||||
|
// (REQ-UI-PORT-GLYPH).
|
||||||
|
const QPointF offset = centered ? QPointF(0.0, 0.0) : edgeOffset;
|
||||||
|
const qreal glyphScale = centered ? 1.5 : 1.0;
|
||||||
|
|
||||||
|
const qreal half = static_cast<qreal>(px) * 0.3 * glyphScale;
|
||||||
const QPointF pos = center + offset;
|
const QPointF pos = center + offset;
|
||||||
const QRectF textRect(pos.x() - half, pos.y() - half, half * 2.0, half * 2.0);
|
const QRectF textRect(pos.x() - half, pos.y() - half, half * 2.0, half * 2.0);
|
||||||
|
|
||||||
QFont f = painter.font();
|
QFont f = painter.font();
|
||||||
f.setPixelSize(std::max(6, static_cast<int>(px * 0.4f)));
|
f.setPixelSize(std::max(6, static_cast<int>(px * 0.4f * glyphScale)));
|
||||||
painter.setFont(f);
|
painter.setFont(f);
|
||||||
painter.setPen(color);
|
painter.setPen(color);
|
||||||
painter.drawText(textRect, Qt::AlignCenter, QString::fromLatin1(ch));
|
painter.drawText(textRect, Qt::AlignCenter, QString::fromLatin1(ch));
|
||||||
@@ -991,7 +999,7 @@ void GameWorldView::drawBuildings(QPainter& painter)
|
|||||||
for (const Port& port : b.outputPorts)
|
for (const Port& port : b.outputPorts)
|
||||||
{
|
{
|
||||||
drawPortGlyph(painter, portBodyTile(port.tile, port.direction),
|
drawPortGlyph(painter, portBodyTile(port.tile, port.direction),
|
||||||
port.direction, bv.outline);
|
port.direction, bv.outline, /*centered*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HP bar below the HQ footprint; the HQ's HP lives on its proxy entity.
|
// HP bar below the HQ footprint; the HQ's HP lives on its proxy entity.
|
||||||
@@ -1070,7 +1078,8 @@ void GameWorldView::drawBuildings(QPainter& painter)
|
|||||||
{
|
{
|
||||||
const QPoint absBody = s.anchor
|
const QPoint absBody = s.anchor
|
||||||
+ portBodyTile(port.tile, port.direction);
|
+ portBodyTile(port.tile, port.direction);
|
||||||
drawPortGlyph(painter, absBody, port.direction, bv.outline);
|
drawPortGlyph(painter, absBody, port.direction, bv.outline,
|
||||||
|
/*centered*/ false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1571,7 +1580,8 @@ void GameWorldView::drawOverlays(QPainter& painter)
|
|||||||
if (m_builderType.has_value())
|
if (m_builderType.has_value())
|
||||||
{
|
{
|
||||||
drawBuildingGhost(painter, *m_builderType, m_ghostTile,
|
drawBuildingGhost(painter, *m_builderType, m_ghostTile,
|
||||||
m_ghostRotation, m_ghostValid);
|
m_ghostRotation, m_ghostValid,
|
||||||
|
/*showPortTargetGlyphs*/ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blueprint placement ghost
|
// Blueprint placement ghost
|
||||||
@@ -1581,7 +1591,8 @@ void GameWorldView::drawOverlays(QPainter& painter)
|
|||||||
{
|
{
|
||||||
const QPoint anchor = m_blueprintGhostTile + bb.offset;
|
const QPoint anchor = m_blueprintGhostTile + bb.offset;
|
||||||
const bool valid = isValidPlacement(bb.type, anchor, bb.rotation);
|
const bool valid = isValidPlacement(bb.type, anchor, bb.rotation);
|
||||||
drawBuildingGhost(painter, bb.type, anchor, bb.rotation, valid);
|
drawBuildingGhost(painter, bb.type, anchor, bb.rotation, valid,
|
||||||
|
/*showPortTargetGlyphs*/ false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1634,7 +1645,7 @@ void GameWorldView::drawOverlays(QPainter& painter)
|
|||||||
|
|
||||||
void GameWorldView::drawBuildingGhost(QPainter& painter, BuildingType type,
|
void GameWorldView::drawBuildingGhost(QPainter& painter, BuildingType type,
|
||||||
QPoint anchorTile, Rotation rotation,
|
QPoint anchorTile, Rotation rotation,
|
||||||
bool valid)
|
bool valid, bool showPortTargetGlyphs)
|
||||||
{
|
{
|
||||||
const BuildingDef* def = findBuildingDef(type);
|
const BuildingDef* def = findBuildingDef(type);
|
||||||
if (!def) { return; }
|
if (!def) { return; }
|
||||||
@@ -1688,7 +1699,24 @@ void GameWorldView::drawBuildingGhost(QPainter& painter, BuildingType type,
|
|||||||
for (const Port& port : parsed.outputPorts)
|
for (const Port& port : parsed.outputPorts)
|
||||||
{
|
{
|
||||||
drawPortGlyph(painter, anchorTile + portBodyTile(port.tile, port.direction),
|
drawPortGlyph(painter, anchorTile + portBodyTile(port.tile, port.direction),
|
||||||
port.direction, lineColor);
|
port.direction, lineColor, /*centered*/ false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// REQ-UI-PORT-TARGET-GLYPH: while in builder mode, additionally mark each
|
||||||
|
// output port's target cell (the cell just outside the footprint the port
|
||||||
|
// pushes into) with a directional glyph, previewing where output will flow.
|
||||||
|
// The Tunnel Entry is excluded — it receives items from any of its non-mouth
|
||||||
|
// edges rather than emitting into a single adjacent cell. The Shipyard is
|
||||||
|
// excluded too — it spawns a ship rather than emitting a belt item.
|
||||||
|
if (showPortTargetGlyphs
|
||||||
|
&& type != BuildingType::TunnelEntry
|
||||||
|
&& type != BuildingType::Shipyard)
|
||||||
|
{
|
||||||
|
for (const Port& port : parsed.outputPorts)
|
||||||
|
{
|
||||||
|
drawPortGlyph(painter, anchorTile + port.tile, port.direction,
|
||||||
|
lineColor, /*centered*/ true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
painter.setOpacity(1.0);
|
painter.setOpacity(1.0);
|
||||||
|
|||||||
@@ -175,11 +175,13 @@ private:
|
|||||||
std::vector<BuildingId> buildingsInBox(QPoint cornerA, QPoint cornerB) const;
|
std::vector<BuildingId> buildingsInBox(QPoint cornerA, QPoint cornerB) const;
|
||||||
QVector2D widgetToWorld(QPoint widgetPt) const;
|
QVector2D widgetToWorld(QPoint widgetPt) const;
|
||||||
|
|
||||||
void drawPortGlyph(QPainter& painter, QPoint bodyTile,
|
void drawPortGlyph(QPainter& painter, QPoint tile,
|
||||||
Rotation direction, const QColor& color);
|
Rotation direction, const QColor& color,
|
||||||
|
bool centered);
|
||||||
|
|
||||||
void drawBuildingGhost(QPainter& painter, BuildingType type,
|
void drawBuildingGhost(QPainter& painter, BuildingType type,
|
||||||
QPoint anchorTile, Rotation rotation, bool valid);
|
QPoint anchorTile, Rotation rotation, bool valid,
|
||||||
|
bool showPortTargetGlyphs);
|
||||||
|
|
||||||
void placeBlueprintAtTile(QPoint center);
|
void placeBlueprintAtTile(QPoint center);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user