move the placement rules and the config-dependent queries off BuildingSystem

isPlacementValid, findRotateInPlaceTarget and the bodyCellsWithinWorldBounds
helper become PlacementRules.h — where a building may go and what already sits
on those tiles, answered from the factory state and the config. getInputPorts
and getSiteSplitterInfo join FactoryQueries.h, whose header comment now says
plainly that the last two also take the config because answering them means
reading a building definition.

computeInputPorts goes to PortGeometry.h alongside outputBodyTile/inputBodyTile:
it needs only Port and QPoint, so it belongs in core rather than in sim.

BuildingSystem is left with no query that reads the factory — its remaining const
methods are the emerging/incoming item walks, the checksum fold, and the buffer
initialisers. It changes the factory now; it no longer describes it.

Verified with a golden-checksum capture before and after — all four sample ticks
identical.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
This commit is contained in:
2026-08-04 22:31:16 +02:00
parent ade716edf2
commit b3d6264ed3
14 changed files with 340 additions and 267 deletions

View File

@@ -16,6 +16,7 @@
#include "BeltSystem.h"
#include "Building.h"
#include "FactoryState.h"
#include "PlacementRules.h"
#include "ProductionRules.h"
#include "BuildingType.h"
#include "BuildingId.h"
@@ -60,8 +61,6 @@ public:
// other body (A) cell sits on the asteroid (x < 0 and x >= the left edge),
// and every cell has 0 <= y < world.height_tiles. There is no right-side
// bound — space extends rightward. Tile occupancy is NOT checked here.
bool isPlacementValid(BuildingType type, QPoint anchor,
Rotation rotation) const;
// Sets the current buildable asteroid width in tiles. Grows the left
// placement bound as the player unlocks asteroid expansions (REQ-EXP-UNLOCK).
@@ -99,7 +98,6 @@ public:
// output directions (derived from its surface mask) and stored filters, or
// nullopt if the id is not a Splitter site. The stored filters are applied
// to BeltSystem when the splitter finishes building (tickConstruction).
std::optional<BeltSystem::SplitterInfo> getSiteSplitterInfo(BuildingId id) const;
void setSiteSplitterFilters(BuildingId id,
const std::vector<ItemType>& filterA,
const std::vector<ItemType>& filterB);
@@ -162,7 +160,6 @@ public:
// (REQ-BLD-BELT-DRAG, REQ-MAT-INPUT-PORTS): each returned Port.tile is the
// outside adjacent tile and Port.direction is the belt facing that points into
// the target. Output-port edges are excluded. Empty for an unknown id.
std::vector<Port> getInputPorts(BuildingId id) const;
// Register / unregister tile occupancy for ECS station entities.
void registerTileOccupancy(const std::vector<QPoint>& cells, BuildingId ownerPlaceholder);
@@ -238,14 +235,8 @@ private:
void initAutoBuffers(Building& b) const;
void initShipyardBuffers(Building& b) const;
void initSalvageBayBuffer(Building& b) const;
std::vector<Port> computeInputPorts(const Building& b) const;
// Core input-edge scan shared by operational buildings and construction sites.
std::vector<Port> computeInputPorts(const std::vector<QPoint>& bodyCells,
const std::vector<Port>& outputPorts) const;
std::vector<Item> rollReprocessingOutput(const RecipeDef& recipe);
bool bodyCellsWithinWorldBounds(
const std::vector<QPoint>& bodyCells,
QPoint anchor) const;
const GameConfig& m_config;