implement belts are now added to the build queue
This commit is contained in:
@@ -202,28 +202,6 @@ EntityId BuildingSystem::place(BuildingType type, QPoint anchor,
|
|||||||
{
|
{
|
||||||
const EntityId id = m_allocateId();
|
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);
|
const BuildingDef* def = findBuildingDef(type);
|
||||||
assert(def != nullptr);
|
assert(def != nullptr);
|
||||||
const ParsedSurfaceMask mask = parseSurfaceMask(def->surfaceMask, rotation);
|
const ParsedSurfaceMask mask = parseSurfaceMask(def->surfaceMask, rotation);
|
||||||
@@ -403,52 +381,72 @@ void BuildingSystem::tickConstruction(Tick currentTick)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Promote construction site to operational building.
|
// Promote construction site — belts/splitters go into BeltSystem, others become Buildings.
|
||||||
const BuildingDef* def = findBuildingDef(front.type);
|
if (front.type == BuildingType::Belt)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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;
|
const BuildingDef* def = findBuildingDef(front.type);
|
||||||
absPort.tile = front.anchor + port.tile;
|
assert(def != nullptr);
|
||||||
absPort.direction = port.direction;
|
const ParsedSurfaceMask mask = parseSurfaceMask(def->surfaceMask, front.rotation);
|
||||||
building.outputPorts.push_back(absPort);
|
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);
|
else
|
||||||
|
|
||||||
if (!building.recipeId.empty())
|
|
||||||
{
|
{
|
||||||
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);
|
Port absPort;
|
||||||
if (recipe)
|
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();
|
m_constructionQueue.pop_front();
|
||||||
|
|
||||||
// Start next queued site if present.
|
// Start next queued site if present.
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ TEST_CASE("BuildingSystem: place miner occupies expected body tiles", "[building
|
|||||||
REQUIRE_FALSE(bs.isTileOccupied(QPoint(1, 1)));
|
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();
|
const GameConfig cfg = loadConfig();
|
||||||
BeltSystem belts(cfg.world.beltSpeedTilesPerSecond);
|
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);
|
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(belts.tryPutItem(QPoint(5, 5), makeItem("iron_ore")));
|
||||||
REQUIRE(bs.allBuildings().empty()); // belts do not create Building instances
|
REQUIRE(bs.allBuildings().empty()); // belts do not create Building instances
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user