Allow direct output-to-input port coupling between adjacent buildings
This commit is contained in:
@@ -807,6 +807,84 @@ TEST_CASE("BuildingSystem: miner output buffer drains onto adjacent belt", "[bui
|
||||
REQUIRE(item->type.id == "iron_ore");
|
||||
}
|
||||
|
||||
// Two directly adjacent buildings whose ports meet transfer items with no belt in
|
||||
// between: a miner's iron_ore output feeds straight into a smelter, which smelts it
|
||||
// (REQ-MAT-DIRECT-COUPLE).
|
||||
TEST_CASE("BuildingSystem: output port couples directly into an adjacent input port",
|
||||
"[building]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
BeltSystem belts(cfg.world.beltSpeed_tps);
|
||||
int stock = 0;
|
||||
std::mt19937 rng(0);
|
||||
BuildingId nextBuildingId = 1;
|
||||
BuildingSystem bs(cfg, belts,
|
||||
[&nextBuildingId]() { return nextBuildingId++; },
|
||||
[&stock](int n) { stock += n; },
|
||||
[](const std::string&, QVector2D, const std::optional<ShipLayoutConfig>&) {},
|
||||
[](const std::string&) -> bool { return true; },
|
||||
rng);
|
||||
|
||||
// Miner at (0,0): body (0,0),(1,0),(0,1); output port tile (1,1) flowing East.
|
||||
const BuildingId minerId = bs.place(BuildingType::Miner, QPoint(0, 0), Rotation::East, 0);
|
||||
bs.setRecipe(minerId, "mine_iron_ore");
|
||||
// Smelter anchored at (1,1): body (1,1),(2,1),(1,2),(2,2). Its body cell (1,1) is
|
||||
// the miner's output-port tile, and its west input edge there faces East, so the
|
||||
// two ports meet — no belt placed anywhere.
|
||||
const BuildingId smelterId = bs.place(BuildingType::Smelter, QPoint(1, 1), Rotation::East, 0);
|
||||
|
||||
Tick tick = 0;
|
||||
// Smelter build (15s) + margin for coupling and a smelt cycle.
|
||||
runTicks(bs, belts, static_cast<int>(secondsToTicks(30.0)), tick);
|
||||
|
||||
const Building* smelter = bs.findBuilding(smelterId);
|
||||
REQUIRE(smelter != nullptr);
|
||||
// iron_ore reached the smelter over the direct coupling and was smelted.
|
||||
bool hasIronIngot = false;
|
||||
for (const Item& produced : outputSideItems(*smelter))
|
||||
{
|
||||
if (produced.type.id == "iron_ingot") { hasIronIngot = true; }
|
||||
}
|
||||
REQUIRE(hasIronIngot);
|
||||
}
|
||||
|
||||
// A producer coupled to a building that cannot accept its item delivers nothing; the
|
||||
// item stays stuck at the producer's output port (REQ-MAT-DIRECT-COUPLE acceptance).
|
||||
TEST_CASE("BuildingSystem: direct coupling to a non-consumer leaves the item stuck",
|
||||
"[building]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
BeltSystem belts(cfg.world.beltSpeed_tps);
|
||||
int stock = 0;
|
||||
std::mt19937 rng(0);
|
||||
BuildingId nextBuildingId = 1;
|
||||
BuildingSystem bs(cfg, belts,
|
||||
[&nextBuildingId]() { return nextBuildingId++; },
|
||||
[&stock](int n) { stock += n; },
|
||||
[](const std::string&, QVector2D, const std::optional<ShipLayoutConfig>&) {},
|
||||
[](const std::string&) -> bool { return true; },
|
||||
rng);
|
||||
|
||||
// Producing miner at (0,0), output port (1,1) East.
|
||||
const BuildingId minerId = bs.place(BuildingType::Miner, QPoint(0, 0), Rotation::East, 0);
|
||||
bs.setRecipe(minerId, "mine_iron_ore");
|
||||
// A second, idle miner anchored at (1,1) occupies the output-port tile but takes
|
||||
// no inputs, so it cannot accept the iron_ore.
|
||||
const BuildingId sinkId = bs.place(BuildingType::Miner, QPoint(1, 1), Rotation::East, 0);
|
||||
|
||||
Tick tick = 0;
|
||||
// Both miners build sequentially (10s each), then the producer runs and jams.
|
||||
runTicks(bs, belts, static_cast<int>(secondsToTicks(25.0)), tick);
|
||||
|
||||
const Building* miner = bs.findBuilding(minerId);
|
||||
const Building* sink = bs.findBuilding(sinkId);
|
||||
REQUIRE(miner != nullptr);
|
||||
REQUIRE(sink != nullptr);
|
||||
// Nothing was delivered, and the producer's output side has backed up to its cap.
|
||||
REQUIRE(sink->pendingInputCount(ItemType{"iron_ore"}) == 0);
|
||||
REQUIRE(miner->outputItemCount() == miner->outputBuffer.capacity);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// setRecipe clears buffers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user