Highlight tunnel connections in green when selected
This commit is contained in:
@@ -889,20 +889,11 @@ BuildingType GameWorldView::effectiveBuilderType() const
|
||||
return inTunnelMode() ? m_tunnelGhostType : *m_builderType;
|
||||
}
|
||||
|
||||
void GameWorldView::updateTunnelGhost()
|
||||
std::map<std::pair<int, int>, TunnelTileInfo> GameWorldView::collectTunnelTiles() const
|
||||
{
|
||||
m_tunnelGhostType = BuildingType::TunnelEntry;
|
||||
m_tunnelPartnerTile.reset();
|
||||
|
||||
// The connection preview and entry/exit switch only apply at a valid placement
|
||||
// (REQ-BLD-TUNNEL-MODE); at an invalid position the ghost stays a plain entry.
|
||||
if (!m_ghostValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Index every tunnel entry/exit — built or still a construction site — by its
|
||||
// single-cell tile, so a just-placed entry (not yet constructed) is matchable.
|
||||
// single-cell tile, so a just-placed tunnel (not yet constructed) is matchable
|
||||
// (REQ-BLD-TUNNEL-MODE, REQ-BLD-TUNNEL-SELECT-HIGHLIGHT).
|
||||
std::map<std::pair<int, int>, TunnelTileInfo> tunnels;
|
||||
for (const Building& b : m_sim->getBuildings().getAllBuildings())
|
||||
{
|
||||
@@ -918,7 +909,22 @@ void GameWorldView::updateTunnelGhost()
|
||||
tunnels[{s.anchor.x(), s.anchor.y()}] = TunnelTileInfo{s.type, s.rotation};
|
||||
}
|
||||
}
|
||||
return tunnels;
|
||||
}
|
||||
|
||||
void GameWorldView::updateTunnelGhost()
|
||||
{
|
||||
m_tunnelGhostType = BuildingType::TunnelEntry;
|
||||
m_tunnelPartnerTile.reset();
|
||||
|
||||
// The connection preview and entry/exit switch only apply at a valid placement
|
||||
// (REQ-BLD-TUNNEL-MODE); at an invalid position the ghost stays a plain entry.
|
||||
if (!m_ghostValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const std::map<std::pair<int, int>, TunnelTileInfo> tunnels = collectTunnelTiles();
|
||||
const TunnelLookup lookup = [&tunnels](QPoint tile) -> std::optional<TunnelTileInfo>
|
||||
{
|
||||
const std::map<std::pair<int, int>, TunnelTileInfo>::const_iterator it =
|
||||
@@ -1819,8 +1825,71 @@ void GameWorldView::drawBeams(QPainter& painter)
|
||||
painter.setRenderHints(savedHints);
|
||||
}
|
||||
|
||||
void GameWorldView::drawSelectedTunnelConnections(QPainter& painter)
|
||||
{
|
||||
if (m_selectedBuildingIds.empty()) { return; }
|
||||
|
||||
const std::map<std::pair<int, int>, TunnelTileInfo> tunnels = collectTunnelTiles();
|
||||
if (tunnels.empty()) { return; }
|
||||
|
||||
const TunnelLookup lookup = [&tunnels](QPoint tile) -> std::optional<TunnelTileInfo>
|
||||
{
|
||||
const std::map<std::pair<int, int>, TunnelTileInfo>::const_iterator it =
|
||||
tunnels.find({tile.x(), tile.y()});
|
||||
if (it == tunnels.end()) { return std::nullopt; }
|
||||
return it->second;
|
||||
};
|
||||
|
||||
// Collect the tiles to highlight in a set so a connection selected from both ends
|
||||
// (or overlapping runs) is filled exactly once — filling a semi-transparent green
|
||||
// twice would darken it (REQ-BLD-TUNNEL-SELECT-HIGHLIGHT).
|
||||
std::set<std::pair<int, int>> highlightTiles;
|
||||
for (const BuildingId id : m_selectedBuildingIds)
|
||||
{
|
||||
std::optional<QPoint> anchor;
|
||||
std::optional<BuildingType> type;
|
||||
Rotation rotation = Rotation::East;
|
||||
if (const Building* b = m_sim->getBuildings().findBuilding(id))
|
||||
{
|
||||
anchor = b->anchor; type = b->type; rotation = b->rotation;
|
||||
}
|
||||
else if (const ConstructionSite* s = m_sim->getBuildings().findSite(id))
|
||||
{
|
||||
anchor = s->anchor; type = s->type; rotation = s->rotation;
|
||||
}
|
||||
if (!type.has_value()
|
||||
|| (*type != BuildingType::TunnelEntry && *type != BuildingType::TunnelExit))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::optional<QPoint> partner = findTunnelPartner(
|
||||
lookup, *anchor, *type, rotation, m_config->world.tunnelMaxDistance_tiles);
|
||||
if (!partner.has_value()) { continue; }
|
||||
|
||||
// Add every tile from the selected end to its partner inclusive (colinear run).
|
||||
const QPoint delta = *partner - *anchor;
|
||||
const QPoint stepDir((delta.x() > 0) - (delta.x() < 0),
|
||||
(delta.y() > 0) - (delta.y() < 0));
|
||||
for (QPoint t = *anchor; ; t += stepDir)
|
||||
{
|
||||
highlightTiles.insert({t.x(), t.y()});
|
||||
if (t == *partner) { break; }
|
||||
}
|
||||
}
|
||||
|
||||
const QColor green = m_visuals->overlays.tunnelPreview;
|
||||
for (const std::pair<int, int>& tile : highlightTiles)
|
||||
{
|
||||
painter.fillRect(tileRect(QPoint(tile.first, tile.second)), green);
|
||||
}
|
||||
}
|
||||
|
||||
void GameWorldView::drawOverlays(QPainter& painter)
|
||||
{
|
||||
// Green connection highlight for any selected tunnel end (REQ-BLD-TUNNEL-SELECT-HIGHLIGHT).
|
||||
drawSelectedTunnelConnections(painter);
|
||||
|
||||
// Builder-mode ghost
|
||||
if (m_builderType.has_value())
|
||||
{
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <random>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <QElapsedTimer>
|
||||
@@ -42,6 +44,7 @@
|
||||
#include "Rotation.h"
|
||||
#include "Tick.h"
|
||||
#include "TickDriver.h"
|
||||
#include "TunnelCompletion.h"
|
||||
#include "VisualsConfig.h"
|
||||
|
||||
struct Command;
|
||||
@@ -214,6 +217,12 @@ private:
|
||||
// Recomputes m_tunnelGhostType and m_tunnelPartnerTile from the current ghost
|
||||
// tile, rotation, and sub-tile cursor position. Only meaningful in tunnel mode.
|
||||
void updateTunnelGhost();
|
||||
// Indexes every tunnel entry/exit — built or still a construction site — by its
|
||||
// single-cell tile. Shared by the placement preview and the selection highlight.
|
||||
std::map<std::pair<int, int>, TunnelTileInfo> collectTunnelTiles() const;
|
||||
// Draws the green connection highlight for every selected tunnel end that has a
|
||||
// matching end (REQ-BLD-TUNNEL-SELECT-HIGHLIGHT).
|
||||
void drawSelectedTunnelConnections(QPainter& painter);
|
||||
|
||||
// Belt drag placement (REQ-BLD-BELT-DRAG).
|
||||
// Per-path-tile decision, shared by ghost drawing and release-time placement.
|
||||
|
||||
Reference in New Issue
Block a user