From 807ccc2ddf9440ad1d44868ca7409666a9029494 Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Wed, 22 Apr 2026 21:54:07 +0200 Subject: [PATCH] implement belts are now added to the build queue --- src/lib/sim/BuildingSystem.cpp | 108 ++++++++++++++++----------------- src/test/BuildingTest.cpp | 10 ++- 2 files changed, 62 insertions(+), 56 deletions(-) diff --git a/src/lib/sim/BuildingSystem.cpp b/src/lib/sim/BuildingSystem.cpp index d6fd12c..7822313 100644 --- a/src/lib/sim/BuildingSystem.cpp +++ b/src/lib/sim/BuildingSystem.cpp @@ -202,28 +202,6 @@ EntityId BuildingSystem::place(BuildingType type, QPoint anchor, { const EntityId id = m_allocateId(); - if (type == BuildingType::Belt) - { - m_belts.placeBelt(anchor, rotation); - m_tileOccupancy[{anchor.x(), anchor.y()}] = id; - m_beltEntities[id] = BeltEntry{anchor, BuildingType::Belt, rotation, rotation}; - return id; - } - - if (type == BuildingType::Splitter) - { - const BuildingDef* def = findBuildingDef(type); - assert(def != nullptr); - const ParsedSurfaceMask mask = parseSurfaceMask(def->surfaceMask, rotation); - assert(mask.outputPorts.size() >= 2); - const Rotation outA = mask.outputPorts[0].direction; - const Rotation outB = mask.outputPorts[1].direction; - m_belts.placeSplitter(anchor, outA, outB); - m_tileOccupancy[{anchor.x(), anchor.y()}] = id; - m_beltEntities[id] = BeltEntry{anchor, BuildingType::Splitter, outA, outB}; - return id; - } - const BuildingDef* def = findBuildingDef(type); assert(def != nullptr); const ParsedSurfaceMask mask = parseSurfaceMask(def->surfaceMask, rotation); @@ -403,52 +381,72 @@ void BuildingSystem::tickConstruction(Tick currentTick) return; } - // Promote construction site to operational building. - const BuildingDef* def = findBuildingDef(front.type); - const ParsedSurfaceMask mask = parseSurfaceMask( - def ? def->surfaceMask : std::vector{}, - front.rotation); - - Building building; - building.id = front.id; - building.anchor = front.anchor; - building.footprint = front.footprint; - building.rotation = front.rotation; - building.type = front.type; - building.hp = 100.0f; - building.maxHp = 100.0f; - building.recipeId = front.recipeId; - - for (const QPoint& cell : mask.bodyCells) + // Promote construction site — belts/splitters go into BeltSystem, others become Buildings. + if (front.type == BuildingType::Belt) { - building.bodyCells.push_back(front.anchor + cell); + m_belts.placeBelt(front.anchor, front.rotation); + m_beltEntities[front.id] = BeltEntry{front.anchor, BuildingType::Belt, front.rotation, front.rotation}; } - for (const Port& port : mask.outputPorts) + else if (front.type == BuildingType::Splitter) { - Port absPort; - absPort.tile = front.anchor + port.tile; - absPort.direction = port.direction; - building.outputPorts.push_back(absPort); + const BuildingDef* def = findBuildingDef(front.type); + assert(def != nullptr); + const ParsedSurfaceMask mask = parseSurfaceMask(def->surfaceMask, front.rotation); + assert(mask.outputPorts.size() >= 2); + const Rotation outA = mask.outputPorts[0].direction; + const Rotation outB = mask.outputPorts[1].direction; + m_belts.placeSplitter(front.anchor, outA, outB); + m_beltEntities[front.id] = BeltEntry{front.anchor, BuildingType::Splitter, outA, outB}; } - building.inputPorts = computeInputPorts(building); - - if (!building.recipeId.empty()) + else { - if (building.type == BuildingType::Shipyard) + const BuildingDef* def = findBuildingDef(front.type); + const ParsedSurfaceMask mask = parseSurfaceMask( + def ? def->surfaceMask : std::vector{}, + front.rotation); + + Building building; + building.id = front.id; + building.anchor = front.anchor; + building.footprint = front.footprint; + building.rotation = front.rotation; + building.type = front.type; + building.hp = 100.0f; + building.maxHp = 100.0f; + building.recipeId = front.recipeId; + + for (const QPoint& cell : mask.bodyCells) { - initShipyardBuffers(building); + building.bodyCells.push_back(front.anchor + cell); } - else + for (const Port& port : mask.outputPorts) { - const RecipeDef* recipe = findRecipe(building.recipeId, building.type); - if (recipe) + Port absPort; + absPort.tile = front.anchor + port.tile; + absPort.direction = port.direction; + building.outputPorts.push_back(absPort); + } + building.inputPorts = computeInputPorts(building); + + if (!building.recipeId.empty()) + { + if (building.type == BuildingType::Shipyard) { - initBuffers(building, *recipe); + initShipyardBuffers(building); + } + else + { + const RecipeDef* recipe = findRecipe(building.recipeId, building.type); + if (recipe) + { + initBuffers(building, *recipe); + } } } + + m_buildings.push_back(std::move(building)); } - m_buildings.push_back(std::move(building)); m_constructionQueue.pop_front(); // Start next queued site if present. diff --git a/src/test/BuildingTest.cpp b/src/test/BuildingTest.cpp index 5b7eeb5..959520f 100644 --- a/src/test/BuildingTest.cpp +++ b/src/test/BuildingTest.cpp @@ -92,7 +92,8 @@ TEST_CASE("BuildingSystem: place miner occupies expected body tiles", "[building REQUIRE_FALSE(bs.isTileOccupied(QPoint(1, 1))); } -TEST_CASE("BuildingSystem: placing a belt registers it with BeltSystem", "[building]") +TEST_CASE("BuildingSystem: placing a belt registers it with BeltSystem after construction", + "[building]") { const GameConfig cfg = loadConfig(); BeltSystem belts(cfg.world.beltSpeedTilesPerSecond); @@ -107,6 +108,13 @@ TEST_CASE("BuildingSystem: placing a belt registers it with BeltSystem", "[build bs.place(BuildingType::Belt, QPoint(5, 5), Rotation::East, 0); + // Belt is queued — not yet in BeltSystem. + REQUIRE_FALSE(belts.tryPutItem(QPoint(5, 5), makeItem("iron_ore"))); + + // Complete construction (1 s). + Tick tick = 0; + runTicks(bs, belts, static_cast(secondsToTicks(1.0)) + 1, tick); + REQUIRE(belts.tryPutItem(QPoint(5, 5), makeItem("iron_ore"))); REQUIRE(bs.allBuildings().empty()); // belts do not create Building instances }