diff --git a/src/AcDream.App/Rendering/RetailPViewRenderer.cs b/src/AcDream.App/Rendering/RetailPViewRenderer.cs index e994a311..5bf7bd45 100644 --- a/src/AcDream.App/Rendering/RetailPViewRenderer.cs +++ b/src/AcDream.App/Rendering/RetailPViewRenderer.cs @@ -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(); - _buildingGroups[buildingId] = group; + _buildingGroups[groupKey] = group; } group.Add(cell); }