dedupe tunnel lookup and key tunnel tiles by QPoint
This commit is contained in:
@@ -960,29 +960,39 @@ BuildingType GameWorldView::effectiveBuilderType() const
|
|||||||
return inTunnelMode() ? m_tunnelGhostType : *m_builderType;
|
return inTunnelMode() ? m_tunnelGhostType : *m_builderType;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::pair<int, int>, TunnelTileInfo> GameWorldView::collectTunnelTiles() const
|
TunnelTileMap GameWorldView::collectTunnelTiles() const
|
||||||
{
|
{
|
||||||
// Index every tunnel entry/exit — built or still a construction site — by its
|
// Index every tunnel entry/exit — built or still a construction site — by its
|
||||||
// single-cell tile, so a just-placed tunnel (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).
|
// (REQ-BLD-TUNNEL-MODE, REQ-BLD-TUNNEL-SELECT-HIGHLIGHT).
|
||||||
std::map<std::pair<int, int>, TunnelTileInfo> tunnels;
|
TunnelTileMap tunnels;
|
||||||
for (const Building& b : m_sim->getBuildings().getAllBuildings())
|
for (const Building& b : m_sim->getBuildings().getAllBuildings())
|
||||||
{
|
{
|
||||||
if (b.type == BuildingType::TunnelEntry || b.type == BuildingType::TunnelExit)
|
if (b.type == BuildingType::TunnelEntry || b.type == BuildingType::TunnelExit)
|
||||||
{
|
{
|
||||||
tunnels[{b.anchor.x(), b.anchor.y()}] = TunnelTileInfo{b.type, b.rotation};
|
tunnels[b.anchor] = TunnelTileInfo{b.type, b.rotation};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const ConstructionSite& s : m_sim->getBuildings().getAllSites())
|
for (const ConstructionSite& s : m_sim->getBuildings().getAllSites())
|
||||||
{
|
{
|
||||||
if (s.type == BuildingType::TunnelEntry || s.type == BuildingType::TunnelExit)
|
if (s.type == BuildingType::TunnelEntry || s.type == BuildingType::TunnelExit)
|
||||||
{
|
{
|
||||||
tunnels[{s.anchor.x(), s.anchor.y()}] = TunnelTileInfo{s.type, s.rotation};
|
tunnels[s.anchor] = TunnelTileInfo{s.type, s.rotation};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tunnels;
|
return tunnels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TunnelLookup GameWorldView::makeTunnelLookup(const TunnelTileMap& tunnels)
|
||||||
|
{
|
||||||
|
return [&tunnels](QPoint tile) -> std::optional<TunnelTileInfo>
|
||||||
|
{
|
||||||
|
const TunnelTileMap::const_iterator it = tunnels.find(tile);
|
||||||
|
if (it == tunnels.end()) { return std::nullopt; }
|
||||||
|
return it->second;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void GameWorldView::updateTunnelGhost()
|
void GameWorldView::updateTunnelGhost()
|
||||||
{
|
{
|
||||||
m_tunnelGhostType = BuildingType::TunnelEntry;
|
m_tunnelGhostType = BuildingType::TunnelEntry;
|
||||||
@@ -995,14 +1005,8 @@ void GameWorldView::updateTunnelGhost()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<std::pair<int, int>, TunnelTileInfo> tunnels = collectTunnelTiles();
|
const TunnelTileMap tunnels = collectTunnelTiles();
|
||||||
const TunnelLookup lookup = [&tunnels](QPoint tile) -> std::optional<TunnelTileInfo>
|
const TunnelLookup lookup = makeTunnelLookup(tunnels);
|
||||||
{
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
const TunnelCompletion completion =
|
const TunnelCompletion completion =
|
||||||
resolveTunnelCompletion(lookup, m_ghostTile, m_ghostRotation,
|
resolveTunnelCompletion(lookup, m_ghostTile, m_ghostRotation,
|
||||||
@@ -1979,21 +1983,15 @@ void GameWorldView::drawSelectedTunnelConnections(QPainter& painter)
|
|||||||
{
|
{
|
||||||
if (m_selectedBuildingIds.empty()) { return; }
|
if (m_selectedBuildingIds.empty()) { return; }
|
||||||
|
|
||||||
const std::map<std::pair<int, int>, TunnelTileInfo> tunnels = collectTunnelTiles();
|
const TunnelTileMap tunnels = collectTunnelTiles();
|
||||||
if (tunnels.empty()) { return; }
|
if (tunnels.empty()) { return; }
|
||||||
|
|
||||||
const TunnelLookup lookup = [&tunnels](QPoint tile) -> std::optional<TunnelTileInfo>
|
const TunnelLookup lookup = makeTunnelLookup(tunnels);
|
||||||
{
|
|
||||||
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
|
// 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
|
// (or overlapping runs) is filled exactly once — filling a semi-transparent green
|
||||||
// twice would darken it (REQ-BLD-TUNNEL-SELECT-HIGHLIGHT).
|
// twice would darken it (REQ-BLD-TUNNEL-SELECT-HIGHLIGHT).
|
||||||
std::set<std::pair<int, int>> highlightTiles;
|
std::set<QPoint, QPointCompare> highlightTiles;
|
||||||
for (const BuildingId id : m_selectedBuildingIds)
|
for (const BuildingId id : m_selectedBuildingIds)
|
||||||
{
|
{
|
||||||
std::optional<QPoint> anchor;
|
std::optional<QPoint> anchor;
|
||||||
@@ -2023,15 +2021,15 @@ void GameWorldView::drawSelectedTunnelConnections(QPainter& painter)
|
|||||||
(delta.y() > 0) - (delta.y() < 0));
|
(delta.y() > 0) - (delta.y() < 0));
|
||||||
for (QPoint t = *anchor; ; t += stepDir)
|
for (QPoint t = *anchor; ; t += stepDir)
|
||||||
{
|
{
|
||||||
highlightTiles.insert({t.x(), t.y()});
|
highlightTiles.insert(t);
|
||||||
if (t == *partner) { break; }
|
if (t == *partner) { break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QColor green = m_visuals->overlays.tunnelPreview;
|
const QColor green = m_visuals->overlays.tunnelPreview;
|
||||||
for (const std::pair<int, int>& tile : highlightTiles)
|
for (const QPoint& tile : highlightTiles)
|
||||||
{
|
{
|
||||||
painter.fillRect(tileRect(QPoint(tile.first, tile.second)), green);
|
painter.fillRect(tileRect(tile), green);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ struct QPointCompare
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Tunnel entries/exits indexed by their single-cell tile (REQ-BLD-TUNNEL-MODE).
|
||||||
|
using TunnelTileMap = std::map<QPoint, TunnelTileInfo, QPointCompare>;
|
||||||
|
|
||||||
class GameWorldView : public QOpenGLWidget,
|
class GameWorldView : public QOpenGLWidget,
|
||||||
public CombinedEventHandler<BeamFiredEvent,
|
public CombinedEventHandler<BeamFiredEvent,
|
||||||
BuildingTypeSelectedEvent,
|
BuildingTypeSelectedEvent,
|
||||||
@@ -242,7 +245,10 @@ private:
|
|||||||
void updateTunnelGhost();
|
void updateTunnelGhost();
|
||||||
// Indexes every tunnel entry/exit — built or still a construction site — by its
|
// 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.
|
// single-cell tile. Shared by the placement preview and the selection highlight.
|
||||||
std::map<std::pair<int, int>, TunnelTileInfo> collectTunnelTiles() const;
|
TunnelTileMap collectTunnelTiles() const;
|
||||||
|
// Wraps a tunnel tile index in the lookup functor the TunnelCompletion helpers
|
||||||
|
// take. The returned functor references `tunnels`, which must outlive it.
|
||||||
|
static TunnelLookup makeTunnelLookup(const TunnelTileMap& tunnels);
|
||||||
// Draws the green connection highlight for every selected tunnel end that has a
|
// Draws the green connection highlight for every selected tunnel end that has a
|
||||||
// matching end (REQ-BLD-TUNNEL-SELECT-HIGHLIGHT).
|
// matching end (REQ-BLD-TUNNEL-SELECT-HIGHLIGHT).
|
||||||
void drawSelectedTunnelConnections(QPainter& painter);
|
void drawSelectedTunnelConnections(QPainter& painter);
|
||||||
|
|||||||
Reference in New Issue
Block a user