extract WorldRenderer

This commit is contained in:
2026-08-05 20:53:43 +02:00
parent dc83add5c6
commit e5dcb9de5f
10 changed files with 1531 additions and 1342 deletions

View File

@@ -153,3 +153,13 @@ std::optional<QPoint> findTunnelPartner(const TunnelLookup& lookup, QPoint tile,
return std::nullopt;
}
TunnelLookup 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;
};
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include <functional>
#include <map>
#include <optional>
#include <QPoint>
@@ -9,6 +10,17 @@
#include "BuildingType.h"
#include "Rotation.h"
// QPoint has no operator<, so an explicit ordering is needed to key a map or set
// by tile.
struct QPointCompare
{
bool operator()(const QPoint& a, const QPoint& b) const
{
if (a.x() != b.x()) { return a.x() < b.x(); }
return a.y() < b.y();
}
};
// A tunnel building occupying a single tile: whether it is an entry or an exit and
// the direction it faces. Used by the tunnel pairing scan (REQ-BLD-TUNNEL-PAIR) and
// the unified tunnel build mode (REQ-BLD-TUNNEL-MODE).
@@ -22,6 +34,13 @@ struct TunnelTileInfo
// direction, or std::nullopt when the tile holds no tunnel building.
using TunnelLookup = std::function<std::optional<TunnelTileInfo>(QPoint)>;
// Tunnel entries/exits indexed by their single-cell tile (REQ-BLD-TUNNEL-MODE).
using TunnelTileMap = std::map<QPoint, TunnelTileInfo, QPointCompare>;
// Wraps a tunnel tile index in the lookup functor the helpers below take. The
// returned functor references `tunnels`, which must outlive it.
TunnelLookup makeTunnelLookup(const TunnelTileMap& tunnels);
// Steps from `start` in `stepDir` over the tiles at distance 1..maxDistance and
// returns the first tile whose tunnel faces `targetFacing`. Tunnel buildings facing
// any other direction are skipped, mirroring the "stop at the first same-direction

View File

@@ -1,5 +1,6 @@
#include "FactoryQueries.h"
#include <algorithm>
#include <limits>
#include "PortGeometry.h"
@@ -179,3 +180,61 @@ getSiteSplitterInfo(const FactoryState& state, const GameConfig& config, Buildin
return std::nullopt;
}
std::vector<BuildingId> buildingsInBox(const FactoryState& state,
QPoint cornerA, QPoint cornerB)
{
const int x0 = std::min(cornerA.x(), cornerB.x());
const int y0 = std::min(cornerA.y(), cornerB.y());
const int x1 = std::max(cornerA.x(), cornerB.x());
const int y1 = std::max(cornerA.y(), cornerB.y());
const auto covers = [&](const std::vector<QPoint>& bodyCells)
{
for (const QPoint& cell : bodyCells)
{
if (cell.x() >= x0 && cell.x() <= x1
&& cell.y() >= y0 && cell.y() <= y1)
{
return true;
}
}
return false;
};
std::vector<BuildingId> ids;
for (const Building& building : getAllBuildings(state))
{
if (covers(building.bodyCells)) { ids.push_back(building.id); }
}
for (const ConstructionSite& site : getAllSites(state))
{
if (covers(site.bodyCells)) { ids.push_back(site.id); }
}
return ids;
}
TunnelTileMap collectTunnelTiles(const FactoryState& state)
{
// 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
// (REQ-BLD-TUNNEL-MODE, REQ-BLD-TUNNEL-SELECT-HIGHLIGHT).
TunnelTileMap tunnels;
for (const Building& building : getAllBuildings(state))
{
if (building.type == BuildingType::TunnelEntry
|| building.type == BuildingType::TunnelExit)
{
tunnels[building.anchor] = TunnelTileInfo{building.type, building.rotation};
}
}
for (const ConstructionSite& site : getAllSites(state))
{
if (site.type == BuildingType::TunnelEntry
|| site.type == BuildingType::TunnelExit)
{
tunnels[site.anchor] = TunnelTileInfo{site.type, site.rotation};
}
}
return tunnels;
}

View File

@@ -12,6 +12,7 @@
#include "FactoryState.h"
#include "GameConfig.h"
#include "Port.h"
#include "TunnelCompletion.h"
// Queries and operations over the factory's world data that need nothing but that
// data — no config, no belts, no RNG. Free functions rather than BuildingSystem
@@ -69,3 +70,13 @@ std::vector<Port> getInputPorts(const FactoryState& state, const GameConfig& con
std::optional<BeltSystem::SplitterInfo> getSiteSplitterInfo(const FactoryState& state,
const GameConfig& config,
BuildingId id);
// Ids of all buildings and construction sites whose footprint intersects the tile
// box spanned by the two (unordered) corner tiles (REQ-UI-MULTI-SELECT,
// REQ-BLD-DECONSTRUCT-BOX).
std::vector<BuildingId> buildingsInBox(const FactoryState& state,
QPoint cornerA, QPoint cornerB);
// Every tunnel entry and exit, built or still a construction site, indexed by its
// single-cell tile. Shared by the placement preview and the selection highlight.
TunnelTileMap collectTunnelTiles(const FactoryState& state);