move the placement rules and the config-dependent queries off BuildingSystem
This commit is contained in:
@@ -20,6 +20,7 @@ SET(HDRS
|
||||
SET(SRCS
|
||||
${SRCS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BuildingType.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PortGeometry.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/EntityAdmin.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/DisplayName.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BeltDragPath.cpp
|
||||
|
||||
57
src/lib/core/PortGeometry.cpp
Normal file
57
src/lib/core/PortGeometry.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "PortGeometry.h"
|
||||
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
std::vector<Port> computeInputPorts(
|
||||
const std::vector<QPoint>& bodyCells,
|
||||
const std::vector<Port>& outputPorts)
|
||||
{
|
||||
// Build lookup sets for quick membership checks.
|
||||
std::set<std::pair<int, int>> bodySet;
|
||||
for (const QPoint& cell : bodyCells)
|
||||
{
|
||||
bodySet.insert({cell.x(), cell.y()});
|
||||
}
|
||||
|
||||
std::set<std::pair<int, int>> outputPortTiles;
|
||||
for (const Port& port : outputPorts)
|
||||
{
|
||||
outputPortTiles.insert({port.tile.x(), port.tile.y()});
|
||||
}
|
||||
|
||||
// Neighbour deltas and the corresponding "inward" belt direction.
|
||||
const int dx[4] = {-1, 1, 0, 0};
|
||||
const int dy[4] = { 0, 0, -1, 1};
|
||||
const Rotation inward[4] = {
|
||||
Rotation::East, // neighbour is to the West; belt flows East toward building
|
||||
Rotation::West, // neighbour is to the East; belt flows West toward building
|
||||
Rotation::South, // neighbour is above (row-1); belt flows South toward building
|
||||
Rotation::North // neighbour is below (row+1); belt flows North toward building
|
||||
};
|
||||
|
||||
std::set<std::pair<int, int>> seen;
|
||||
std::vector<Port> inputPorts;
|
||||
|
||||
for (const QPoint& cell : bodyCells)
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
const int nx = cell.x() + dx[i];
|
||||
const int ny = cell.y() + dy[i];
|
||||
const std::pair<int, int> neighbor = {nx, ny};
|
||||
|
||||
if (bodySet.count(neighbor)) { continue; }
|
||||
if (outputPortTiles.count(neighbor)){ continue; }
|
||||
if (seen.count(neighbor)) { continue; }
|
||||
|
||||
seen.insert(neighbor);
|
||||
Port port;
|
||||
port.tile = QPoint(nx, ny);
|
||||
port.direction = inward[i];
|
||||
inputPorts.push_back(port);
|
||||
}
|
||||
}
|
||||
|
||||
return inputPorts;
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
#include "Port.h"
|
||||
#include "Rotation.h"
|
||||
|
||||
// Geometry of a building's input/output ports. A Port names the tile *outside* the
|
||||
@@ -43,3 +46,10 @@ inline QPoint inputBodyTile(QPoint portTile, Rotation inwardDirection)
|
||||
}
|
||||
return portTile;
|
||||
}
|
||||
|
||||
// Every belt-facing edge of a footprint that is not already an output port — the
|
||||
// tiles a belt can feed the building from, with the direction items must flow to
|
||||
// enter (REQ-MAT-INPUT-PORTS, REQ-BLD-BELT-DRAG). bodyCells and outputPorts are
|
||||
// in absolute tile coordinates, and so is the result.
|
||||
std::vector<Port> computeInputPorts(const std::vector<QPoint>& bodyCells,
|
||||
const std::vector<Port>& outputPorts);
|
||||
|
||||
Reference in New Issue
Block a user