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); }