Add deconstruction queue

This commit is contained in:
2026-07-22 21:37:56 +02:00
parent a9082c57f3
commit b2ce20e6ad
17 changed files with 551 additions and 85 deletions

View File

@@ -1977,6 +1977,17 @@ void GameWorldView::drawOverlays(QPainter& painter)
}
}
// Queued for deconstruction: tint every building currently in the
// deconstruction queue, regardless of mode (REQ-BLD-DECON-QUEUE).
for (const Building& b : m_sim->getBuildings().getAllBuildings())
{
if (!b.queuedForDeconstruction) { continue; }
for (const QPoint& cell : b.bodyCells)
{
painter.fillRect(tileRect(cell), m_visuals->overlays.demolishTint);
}
}
// Demolish tint: while dragging a demolish box, tint every covered
// building/site (REQ-BLD-DEMOLISH-BOX); otherwise tint the hovered one.
if (m_demolishMode && m_boxSelecting)
@@ -2623,17 +2634,62 @@ void GameWorldView::mouseReleaseEvent(QMouseEvent* event)
if (m_demolishMode)
{
// Demolish every covered building/site; the HQ is protected
// (REQ-BLD-DEMOLISH, REQ-BLD-DEMOLISH-BOX).
const BuildingSystem& buildings = m_sim->getBuildings();
// Split covered ids into construction sites (removed instantly) and
// operational demolishable buildings (the HQ is protected; player
// defence stations are not Buildings and never appear in the box).
std::vector<BuildingId> sites;
std::vector<BuildingId> operational;
for (BuildingId id : boxIds)
{
const Building* b = m_sim->getBuildings().findBuilding(id);
if (b && b->type == BuildingType::Hq) { continue; }
if (const Building* b = buildings.findBuilding(id))
{
if (b->type == BuildingType::Hq) { continue; }
operational.push_back(id);
}
else if (buildings.findSite(id))
{
sites.push_back(id);
}
}
// Sites: instant demolition with the full refund (REQ-BLD-DEMOLISH).
for (BuildingId id : sites)
{
std::shared_ptr<DemolishCommand> command =
std::make_shared<DemolishCommand>();
command->id = id;
enqueueCommand(command);
}
// Operational buildings: if every covered one is already queued,
// un-queue them all; otherwise queue each one not yet queued. A plain
// click is the one-element case, giving the queue/un-queue toggle
// (REQ-BLD-DEMOLISH-BOX, REQ-BLD-DEMOLISH-CLICK).
bool allQueued = !operational.empty();
for (BuildingId id : operational)
{
if (!buildings.isQueuedForDeconstruction(id)) { allQueued = false; break; }
}
for (BuildingId id : operational)
{
if (allQueued)
{
std::shared_ptr<CancelDeconstructionCommand> command =
std::make_shared<CancelDeconstructionCommand>();
command->id = id;
enqueueCommand(command);
}
else if (!buildings.isQueuedForDeconstruction(id))
{
std::shared_ptr<DemolishCommand> command =
std::make_shared<DemolishCommand>();
command->id = id;
enqueueCommand(command);
}
}
m_demolishHoverBuildingId = std::nullopt;
return;
}