Unify tunnel build mode into a single Tunnel button
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "StateChecksum.h"
|
||||
#include "Tick.h"
|
||||
#include "TunnelCompletion.h"
|
||||
#include "tracing.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -177,55 +178,57 @@ void BeltSystem::reevaluateTunnelPairing()
|
||||
std::vector<TunnelLink> oldLinks;
|
||||
std::swap(oldLinks, m_tunnelLinks);
|
||||
|
||||
// Tunnel index over this system's own (completed) tunnel tiles, shared with the
|
||||
// scan primitive so the pairing rule lives in one place (REQ-BLD-TUNNEL-PAIR).
|
||||
const TunnelLookup lookup = [this](QPoint tile) -> std::optional<TunnelTileInfo>
|
||||
{
|
||||
const std::map<std::pair<int, int>, TunnelEntryTile>::const_iterator teIt =
|
||||
m_tunnelEntries.find(key(tile));
|
||||
if (teIt != m_tunnelEntries.end())
|
||||
{
|
||||
return TunnelTileInfo{BuildingType::TunnelEntry, teIt->second.direction};
|
||||
}
|
||||
const std::map<std::pair<int, int>, TunnelExitTile>::const_iterator txIt =
|
||||
m_tunnelExits.find(key(tile));
|
||||
if (txIt != m_tunnelExits.end())
|
||||
{
|
||||
return TunnelTileInfo{BuildingType::TunnelExit, txIt->second.direction};
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
for (const std::pair<const std::pair<int, int>, TunnelEntryTile>& entry : m_tunnelEntries)
|
||||
{
|
||||
const QPoint entryPos(entry.first.first, entry.first.second);
|
||||
const Rotation dir = entry.second.direction;
|
||||
const int maxDist = entry.second.maxDistance;
|
||||
|
||||
for (int d = 1; d <= maxDist; ++d)
|
||||
// The first same-direction tunnel ahead forms a pair only when it is an exit;
|
||||
// a same-direction entry blocks (firstTunnelFacing stops at it either way).
|
||||
const std::optional<QPoint> target =
|
||||
firstTunnelFacing(lookup, entryPos, dir, dir, maxDist);
|
||||
if (!target.has_value() || m_tunnelExits.find(key(*target)) == m_tunnelExits.end())
|
||||
{
|
||||
QPoint probe = entryPos;
|
||||
for (int step = 0; step < d; ++step)
|
||||
{
|
||||
probe = adjacentTile(probe, dir);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if a same-direction tunnel entry is here (blocks pairing)
|
||||
const std::map<std::pair<int, int>, TunnelEntryTile>::const_iterator teIt =
|
||||
m_tunnelEntries.find(key(probe));
|
||||
if (teIt != m_tunnelEntries.end() && teIt->second.direction == dir)
|
||||
TunnelLink link;
|
||||
link.entryTile = entryPos;
|
||||
link.exitTile = *target;
|
||||
// The exit is colinear with the entry along `dir`, so the tile-coordinate
|
||||
// distance is the Manhattan distance.
|
||||
link.length = static_cast<double>((*target - entryPos).manhattanLength());
|
||||
|
||||
for (const TunnelLink& old : oldLinks)
|
||||
{
|
||||
if (old.entryTile == entryPos && old.exitTile == *target)
|
||||
{
|
||||
link.items = old.items;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if a same-direction tunnel exit is here (forms pair)
|
||||
const std::map<std::pair<int, int>, TunnelExitTile>::const_iterator txIt =
|
||||
m_tunnelExits.find(key(probe));
|
||||
if (txIt != m_tunnelExits.end())
|
||||
{
|
||||
if (txIt->second.direction == dir)
|
||||
{
|
||||
TunnelLink link;
|
||||
link.entryTile = entryPos;
|
||||
link.exitTile = probe;
|
||||
link.length = static_cast<double>(d);
|
||||
|
||||
for (const TunnelLink& old : oldLinks)
|
||||
{
|
||||
if (old.entryTile == entryPos && old.exitTile == probe)
|
||||
{
|
||||
link.items = old.items;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_tunnelLinks.push_back(std::move(link));
|
||||
break;
|
||||
}
|
||||
// Different direction exit — skip, keep searching
|
||||
}
|
||||
}
|
||||
|
||||
m_tunnelLinks.push_back(std::move(link));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user