add BuildingGrid to manage tile occupancy

This commit is contained in:
2026-08-04 18:26:01 +02:00
parent 3990351a16
commit 60cc187d92
5 changed files with 121 additions and 43 deletions

View File

@@ -308,7 +308,7 @@ std::optional<BuildingId> BuildingSystem::place(BuildingType type, QPoint anchor
for (const QPoint& cell : mask.bodyCells)
{
const QPoint absCell = anchor + cell;
m_tileOccupancy[{absCell.x(), absCell.y()}] = id;
m_grid.occupy(absCell, id);
}
// Build construction site.
@@ -412,10 +412,7 @@ int BuildingSystem::deconstruct(BuildingId id, Tick currentTick)
if (it->id == id)
{
const BuildingDef* def = m_config.buildings.findBuildingDef(it->type);
for (const QPoint& cell : it->bodyCells)
{
m_tileOccupancy.erase({cell.x(), cell.y()});
}
m_grid.release(it->bodyCells);
m_constructionQueue.erase(it);
if (def)
{
@@ -799,10 +796,7 @@ void BuildingSystem::tickDeconstruction(Tick currentTick)
if (it->id != front.id) { continue; }
const BuildingDef* def = m_config.buildings.findBuildingDef(it->type);
for (const QPoint& cell : it->bodyCells)
{
m_tileOccupancy.erase({cell.x(), cell.y()});
}
m_grid.release(it->bodyCells);
m_buildings.erase(it);
if (def)
{
@@ -938,14 +932,13 @@ bool BuildingSystem::tryDirectCoupleDeposit(BuildingId producerId,
const Port& outputPort,
const Item& item)
{
const std::map<std::pair<int, int>, BuildingId>::const_iterator occIt =
m_tileOccupancy.find({outputPort.tile.x(), outputPort.tile.y()});
if (occIt == m_tileOccupancy.end() || occIt->second == producerId)
const std::optional<BuildingId> ownerId = m_grid.findOwner(outputPort.tile);
if (!ownerId.has_value() || *ownerId == producerId)
{
return false;
}
Building* consumer = findBuildingMutable(occIt->second);
Building* consumer = findBuildingMutable(*ownerId);
if (!consumer)
{
return false; // an unbuilt construction site, or not an operational building
@@ -1527,7 +1520,7 @@ std::vector<BuildingSystem::BeltTileInfo> BuildingSystem::getAllBeltTiles() cons
bool BuildingSystem::isTileOccupied(QPoint tile) const
{
return m_tileOccupancy.count({tile.x(), tile.y()}) > 0;
return m_grid.isOccupied(tile);
}
std::optional<BuildingId> BuildingSystem::findRotateInPlaceTarget(
@@ -1548,15 +1541,14 @@ std::optional<BuildingId> BuildingSystem::findRotateInPlaceTarget(
// All body cells must be occupied by the same entity.
const QPoint firstAbs = anchor + mask.bodyCells[0];
const auto firstIt = m_tileOccupancy.find({firstAbs.x(), firstAbs.y()});
if (firstIt == m_tileOccupancy.end()) { return std::nullopt; }
const BuildingId candidateId = firstIt->second;
const std::optional<BuildingId> firstOwner = m_grid.findOwner(firstAbs);
if (!firstOwner.has_value()) { return std::nullopt; }
const BuildingId candidateId = *firstOwner;
for (const QPoint& rel : mask.bodyCells)
{
const QPoint abs = anchor + rel;
const auto it = m_tileOccupancy.find({abs.x(), abs.y()});
if (it == m_tileOccupancy.end() || it->second != candidateId)
const std::optional<BuildingId> owner = m_grid.findOwner(anchor + rel);
if (!owner.has_value() || *owner != candidateId)
{
return std::nullopt;
}
@@ -1716,7 +1708,7 @@ BuildingId BuildingSystem::placeImmediate(BuildingType type,
{
const QPoint absCell = anchor + cell;
building.bodyCells.push_back(absCell);
m_tileOccupancy[{absCell.x(), absCell.y()}] = id;
m_grid.occupy(absCell, id);
}
for (const Port& port : mask.outputPorts)
{
@@ -1751,10 +1743,7 @@ bool BuildingSystem::removeBuilding(BuildingId id)
{
m_belts.removeTile(it->anchor);
}
for (const QPoint& cell : it->bodyCells)
{
m_tileOccupancy.erase({cell.x(), cell.y()});
}
m_grid.release(it->bodyCells);
m_buildings.erase(it);
return true;
}
@@ -1773,18 +1762,12 @@ void BuildingSystem::forEachBuilding(std::function<void(Building&)> fn)
void BuildingSystem::registerTileOccupancy(const std::vector<QPoint>& cells,
BuildingId ownerPlaceholder)
{
for (const QPoint& cell : cells)
{
m_tileOccupancy[{cell.x(), cell.y()}] = ownerPlaceholder;
}
m_grid.occupy(cells, ownerPlaceholder);
}
void BuildingSystem::unregisterTileOccupancy(const std::vector<QPoint>& cells)
{
for (const QPoint& cell : cells)
{
m_tileOccupancy.erase({cell.x(), cell.y()});
}
m_grid.release(cells);
}
namespace
@@ -1893,12 +1876,5 @@ void BuildingSystem::appendChecksum(Hasher& hasher) const
for (const ItemType& type : e.splitterFilterB) { hasher.append(type.id); }
}
// std::map iterates in sorted key order.
hasher.append(m_tileOccupancy.size());
for (const std::pair<const std::pair<int, int>, BuildingId>& entry : m_tileOccupancy)
{
hasher.append(entry.first.first);
hasher.append(entry.first.second);
hasher.append(entry.second);
}
m_grid.appendChecksum(hasher);
}