store belts as buildings and fix issue that belts could not be selected
This commit is contained in:
@@ -241,24 +241,6 @@ EntityId BuildingSystem::place(BuildingType type, QPoint anchor,
|
||||
|
||||
int BuildingSystem::demolish(EntityId id)
|
||||
{
|
||||
// Belt / splitter?
|
||||
const std::map<EntityId, BeltEntry>::iterator beltIt = m_beltEntities.find(id);
|
||||
if (beltIt != m_beltEntities.end())
|
||||
{
|
||||
const QPoint tile = beltIt->second.tile;
|
||||
const BuildingType btype = beltIt->second.type;
|
||||
m_belts.removeTile(tile);
|
||||
m_tileOccupancy.erase({tile.x(), tile.y()});
|
||||
m_beltEntities.erase(beltIt);
|
||||
|
||||
const BuildingDef* def = findBuildingDef(btype);
|
||||
if (def)
|
||||
{
|
||||
return def->cost * m_config.world.refundPercentage / 100;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Construction queue?
|
||||
for (std::deque<ConstructionSite>::iterator it = m_constructionQueue.begin();
|
||||
it != m_constructionQueue.end();
|
||||
@@ -287,6 +269,10 @@ int BuildingSystem::demolish(EntityId id)
|
||||
{
|
||||
if (it->id == id)
|
||||
{
|
||||
if (it->type == BuildingType::Belt || it->type == BuildingType::Splitter)
|
||||
{
|
||||
m_belts.removeTile(it->anchor);
|
||||
}
|
||||
const BuildingDef* def = findBuildingDef(it->type);
|
||||
for (const QPoint& cell : it->bodyCells)
|
||||
{
|
||||
@@ -381,71 +367,65 @@ void BuildingSystem::tickConstruction(Tick currentTick)
|
||||
return;
|
||||
}
|
||||
|
||||
// Promote construction site — belts/splitters go into BeltSystem, others become Buildings.
|
||||
// Promote construction site to an 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)
|
||||
{
|
||||
building.bodyCells.push_back(front.anchor + cell);
|
||||
}
|
||||
for (const Port& port : mask.outputPorts)
|
||||
{
|
||||
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)
|
||||
{
|
||||
initShipyardBuffers(building);
|
||||
}
|
||||
else
|
||||
{
|
||||
const RecipeDef* recipe = findRecipe(building.recipeId, building.type);
|
||||
if (recipe)
|
||||
{
|
||||
initBuffers(building, *recipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register with BeltSystem before the move (mask stays valid).
|
||||
if (front.type == BuildingType::Belt)
|
||||
{
|
||||
m_belts.placeBelt(front.anchor, front.rotation);
|
||||
m_beltEntities[front.id] = BeltEntry{front.anchor, BuildingType::Belt, front.rotation, front.rotation};
|
||||
}
|
||||
else if (front.type == BuildingType::Splitter)
|
||||
{
|
||||
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};
|
||||
m_belts.placeSplitter(front.anchor,
|
||||
mask.outputPorts[0].direction,
|
||||
mask.outputPorts[1].direction);
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
building.bodyCells.push_back(front.anchor + cell);
|
||||
}
|
||||
for (const Port& port : mask.outputPorts)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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();
|
||||
|
||||
@@ -774,15 +754,30 @@ std::vector<ConstructionSite> BuildingSystem::allSites() const
|
||||
std::vector<BuildingSystem::BeltTileInfo> BuildingSystem::allBeltTiles() const
|
||||
{
|
||||
std::vector<BeltTileInfo> result;
|
||||
result.reserve(m_beltEntities.size());
|
||||
for (const std::map<EntityId, BeltEntry>::value_type& kv : m_beltEntities)
|
||||
for (const Building& b : m_buildings)
|
||||
{
|
||||
if (b.type != BuildingType::Belt && b.type != BuildingType::Splitter)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
BeltTileInfo info;
|
||||
info.id = kv.first;
|
||||
info.tile = kv.second.tile;
|
||||
info.type = kv.second.type;
|
||||
info.directionA = kv.second.directionA;
|
||||
info.directionB = kv.second.directionB;
|
||||
info.id = b.id;
|
||||
info.tile = b.bodyCells.empty() ? b.anchor : b.bodyCells[0];
|
||||
info.type = b.type;
|
||||
if (!b.outputPorts.empty())
|
||||
{
|
||||
info.directionA = b.outputPorts[0].direction;
|
||||
info.directionB = b.outputPorts[0].direction;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.directionA = b.rotation;
|
||||
info.directionB = b.rotation;
|
||||
}
|
||||
if (b.type == BuildingType::Splitter && b.outputPorts.size() >= 2)
|
||||
{
|
||||
info.directionB = b.outputPorts[1].direction;
|
||||
}
|
||||
result.push_back(info);
|
||||
}
|
||||
return result;
|
||||
@@ -907,6 +902,10 @@ bool BuildingSystem::removeBuilding(EntityId id)
|
||||
{
|
||||
if (it->id == id)
|
||||
{
|
||||
if (it->type == BuildingType::Belt || it->type == BuildingType::Splitter)
|
||||
{
|
||||
m_belts.removeTile(it->anchor);
|
||||
}
|
||||
for (const QPoint& cell : it->bodyCells)
|
||||
{
|
||||
m_tileOccupancy.erase({cell.x(), cell.y()});
|
||||
|
||||
Reference in New Issue
Block a user