give tile occupancy its own class, BuildingGrid

Eleven methods maintained m_tileOccupancy by hand — place, deconstruct,
removeBuilding, placeImmediate, tickDeconstruction, findRotateInPlaceTarget and
tryDirectCoupleDeposit all indexed a raw std::map<std::pair<int,int>, BuildingId>
directly, so the invariant "occupancy stays in sync with placement" was
re-implemented at every call site. They now ask and tell a small owned index
instead: occupy / release / isOccupied / findOwner.

BuildingGrid is a member of BuildingSystem, not a peer system: it has no
per-tick behaviour and nothing outside BuildingSystem touches it.

The internal keying stays std::pair<int,int> rather than moving to QPoint. The
checksum folds the entries in map iteration order, so the comparator is part of
the determinism contract; changing it is a separate decision, not a side effect
of this move. Verified with a golden-checksum capture before and after — all
four sample ticks identical.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
This commit is contained in:
2026-08-04 17:22:40 +02:00
parent fda88fe75c
commit 71d0dad3f2
5 changed files with 121 additions and 43 deletions

View File

@@ -15,6 +15,7 @@
#include "BeltSystem.h"
#include "Building.h"
#include "BuildingGrid.h"
#include "BuildingType.h"
#include "BuildingId.h"
#include "GameConfig.h"
@@ -309,6 +310,7 @@ private:
};
std::deque<DeconstructionEntry> m_deconstructionQueue;
// Maps every occupied body-cell coordinate to the entity that owns it.
std::map<std::pair<int, int>, BuildingId> m_tileOccupancy;
// The authority on which building owns which tile; every placement and removal
// path claims and releases its body cells here.
BuildingGrid m_grid;
};