implement belts are now added to the build queue

This commit is contained in:
2026-04-22 21:54:07 +02:00
parent fbbd0a582f
commit 807ccc2ddf
2 changed files with 62 additions and 56 deletions

View File

@@ -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<std::string>{},
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<std::string>{},
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.

View File

@@ -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<int>(secondsToTicks(1.0)) + 1, tick);
REQUIRE(belts.tryPutItem(QPoint(5, 5), makeItem("iron_ore")));
REQUIRE(bs.allBuildings().empty()); // belts do not create Building instances
}