fix(render): R-A2 seam fix — flood null-BuildingId cells instead of dropping them

MergeNearbyBuildingFloods skipped cells whose BuildingId is null; the pre-R-A2 outdoor-node reverse-portal flood reached them, so dropping left holes at building/terrain seams. Key by (BuildingId ?? CellId) so unstamped/outdoor-adjacent exit-portal cells still seed a per-entrance flood; cells without an exit portal contribute nothing as before. App Rendering 207/207.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-08 19:08:14 +02:00
parent c62663d7cb
commit 2ec189c106

View file

@ -110,12 +110,17 @@ public sealed class RetailPViewRenderer
foreach (var cell in ctx.NearbyBuildingCells!)
{
if (cell.BuildingId is not uint buildingId)
continue; // outdoor surface cells (no building) don't flood
if (!_buildingGroups.TryGetValue(buildingId, out var group))
// R-A2 seam fix: a cell without a BuildingId (unstamped, or outdoor-adjacent with an exit
// portal) must STILL flood — the pre-R-A2 node flood reached it via a reverse portal, so
// dropping it (the original `continue`) left holes at building/terrain seams. Key it by its
// own CellId → a singleton per-entrance flood: a cell with an exit portal seeds from it, a
// cell with none contributes nothing (same as before). BuildingId/CellId key collisions are
// harmless — BuildFromExterior seeds each exit-portal cell in a group independently.
uint groupKey = cell.BuildingId ?? cell.CellId;
if (!_buildingGroups.TryGetValue(groupKey, out var group))
{
group = new List<LoadedCell>();
_buildingGroups[buildingId] = group;
_buildingGroups[groupKey] = group;
}
group.Add(cell);
}