From 53e22a350dc67744d952ab65364ea7c8472418c5 Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 14 Jun 2026 09:52:01 +0200 Subject: [PATCH] fix(G.3): relocate the player entity to its CELL landblock indoors, not position-derived (#133) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the dungeon-collapse fix the local player avatar stopped rendering: the per-frame RelocateEntity moved the player entity to its position-derived landblock floor(pp/192), which for a dungeon's negative-local-Y cell is the off-by-one (0,6) — the very landblock the collapse unloads. So the player entity sat in an unloaded landblock and was never drawn (the dungeon itself, in 0x0007, rendered fine). Fix: when the player is in an indoor cell (CellId low word >= 0x0100), relocate to the cell's OWN landblock (CellId >> 16), matching the streaming-collapse pin. The cell id is authoritative for ocean-placed dungeon geometry. Outdoor entities keep the position-derived path. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/AcDream.App/Rendering/GameWindow.cs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 71a6f558..a2531674 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -7073,10 +7073,24 @@ public sealed class GameWindow : IDisposable // so it doesn't get frustum-culled when the player walks away from // the spawn landblock. Without this, the entity stays in the spawn // landblock's entity list and disappears when that landblock is culled. - var pp = _playerController.Position; - int plx = _liveCenterX + (int)System.Math.Floor(pp.X / 192f); - int ply = _liveCenterY + (int)System.Math.Floor(pp.Y / 192f); - uint currentLb = (uint)((plx << 24) | (ply << 16) | 0xFFFF); + uint currentLb; + if (result.CellId != 0 && (result.CellId & 0xFFFFu) >= 0x0100u) + { + // Indoor cell (dungeon/building EnvCell): the entity's landblock is + // the CELL's landblock. Dungeon EnvCells sit at arbitrary "ocean" + // world coords with negative local-Y, so floor(pp.Y/192) lands one + // landblock off (the Bug-A class) — relocating the player into the + // landblock the dungeon collapse unloaded, making the avatar + // invisible. The cell id is authoritative. + currentLb = (result.CellId & 0xFFFF0000u) | 0xFFFFu; + } + else + { + var pp = _playerController.Position; + int plx = _liveCenterX + (int)System.Math.Floor(pp.X / 192f); + int ply = _liveCenterY + (int)System.Math.Floor(pp.Y / 192f); + currentLb = (uint)((plx << 24) | (ply << 16) | 0xFFFF); + } _worldState.RelocateEntity(pe, currentLb); }