fix: add 180° heading offset for dungeons (from UB line 1013)

UB applies HeadingToQuaternion(heading - 180) for dungeon rendering.
The layer has Y increasing downward, and the 180° offset flips N/S.
Reverted coordinates to Version 1 (X mirror, Y direct) which had
correct tile connections, and added the 180° heading offset that UB
uses to fix N/S orientation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-08 16:17:16 +02:00
parent 203ae0a4fb
commit 6c500f7cdb

View file

@ -3853,7 +3853,9 @@ function updateRadarWindow(msg) {
const dmap = dungeonMapCache[landblock];
const playerRoundedZ = Math.floor((playerRawZ + 3) / 6) * 6;
ctx.translate(cx, cy);
ctx.rotate(-playerHeading * Math.PI / 180); // heading-up rotation
// UB applies (heading - 180) rotation for dungeons (line 1013 DungeonMaps.cs)
// The layer has Y increasing downward; the 180° offset flips N/S
ctx.rotate(-(playerHeading - 180) * Math.PI / 180);
const cellSize = 10 * scale; // each cell is 10 game units
const hasTiles = dungeonTileCanvases && Object.keys(dungeonTileCanvases).length > 0;
@ -3877,9 +3879,9 @@ function updateRadarWindow(msg) {
ctx.globalAlpha = isCurrentFloor ? 0.85 : 0.12;
(level.cells || []).forEach(cell => {
// X mirrored (matches UB's layer rendering), Y negated for north-up
// X mirrored (matches UB's layer rendering), Y direct
const dx = -(cell.x - playerX) * scale;
const dy = -(cell.y - playerY) * scale;
const dy = (cell.y - playerY) * scale;
const tileCanvas = hasTiles ? dungeonTileCanvases[String(cell.env_id)] : null;
if (tileCanvas) {
@ -3967,7 +3969,8 @@ function updateRadarWindow(msg) {
ctx.stroke();
// Rotate world by heading so player facing = up on canvas
const rotAngle = headingRad;
// In dungeons, add 180° to match UB's (heading - 180) rotation
const rotAngle = isDungeon ? headingRad + Math.PI : headingRad;
// Draw objects and cache positions for click hit-testing
const cosA = Math.cos(rotAngle);
@ -3977,7 +3980,7 @@ function updateRadarWindow(msg) {
let dX, dY;
if (isDungeon && obj.raw_x !== undefined) {
dX = -(obj.raw_x - playerX); // X mirrored to match tile space
dY = -(obj.raw_y - playerY); // Y negated for north-up
dY = (obj.raw_y - playerY); // Y direct (180° heading offset handles N/S)
} else {
dX = obj.ew - playerEW;
dY = obj.ns - playerNS;
@ -4040,7 +4043,7 @@ function updateRadarWindow(msg) {
let distMeters, dX, dY;
if (isDungeon && obj.raw_x !== undefined) {
dX = -(obj.raw_x - playerX); // X mirrored
dY = -(obj.raw_y - playerY); // Y negated
dY = (obj.raw_y - playerY); // Y direct
distMeters = Math.sqrt(dX * dX + dY * dY); // raw coords are ~meters
} else {
dX = obj.ew - playerEW;