fix: revert to Version 1 approach (tiles connected) + just add Y negate

Version 1 (X mirror, Y direct) had correct tile connections but N/S
flipped. Previous attempts to fix N/S also changed rotation handling
which broke tiles. This commit reverts tile processing (no flip),
reverts rotation (exact UB values), and only adds Y negation to
Version 1's working coordinates. No other changes.

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

View file

@ -3607,18 +3607,13 @@ const DUNGEON_DISPLAY_COLORS = {
stairs: { r: 180, g: 160, b: 80 }, // yellowish stairs
};
// Process a tile image: flip horizontally (UB tiles authored for mirrored-X),
// make white transparent, remap UB colors
// Process a tile image: make white transparent, remap UB colors
function processTileImage(img) {
const c = document.createElement('canvas');
c.width = 10;
c.height = 10;
const ctx = c.getContext('2d');
// Flip horizontally: tiles were designed for UB's mirrored-X coordinate system
ctx.translate(10, 0);
ctx.scale(-1, 1);
ctx.drawImage(img, 0, 0, 10, 10);
ctx.setTransform(1, 0, 0, 1, 0, 0);
const imageData = ctx.getImageData(0, 0, 10, 10);
const d = imageData.data;
@ -3862,14 +3857,11 @@ function updateRadarWindow(msg) {
const cellSize = 10 * scale; // each cell is 10 game units
const hasTiles = dungeonTileCanvases && Object.keys(dungeonTileCanvases).length > 0;
// Normalize rotation value to radians (from UB's DungeonCell.cs)
// Negated because tile images are horizontally flipped to compensate
// for UB's mirrored-X authoring space
// Normalize rotation value to radians (exact copy of UB's DungeonCell.cs)
function cellRotation(rot) {
if (Math.abs(rot - 1) < 0.01) return Math.PI; // 180° = -180°, same
if (Math.abs(rot + 1) < 0.01) return Math.PI;
if (rot < -0.70 && rot > -0.8) return -Math.PI / 2; // negated
if (rot > 0.70 && rot < 0.8) return Math.PI / 2; // negated
if (rot === 1) return Math.PI;
if (rot < -0.70 && rot > -0.8) return Math.PI / 2;
if (rot > 0.70 && rot < 0.8) return -Math.PI / 2;
return 0;
}
@ -3885,9 +3877,8 @@ function updateRadarWindow(msg) {
ctx.globalAlpha = isCurrentFloor ? 0.85 : 0.12;
(level.cells || []).forEach(cell => {
// Direct relative position (UB mirrors both cell and player, cancels out)
// Y negated for north-up (AC Y+ = north, canvas Y+ = down)
const dx = (cell.x - playerX) * scale;
// X mirrored (matches UB's layer rendering), Y negated for north-up
const dx = -(cell.x - playerX) * scale;
const dy = -(cell.y - playerY) * scale;
const tileCanvas = hasTiles ? dungeonTileCanvases[String(cell.env_id)] : null;
@ -3985,8 +3976,8 @@ function updateRadarWindow(msg) {
// Use raw physics coords in dungeons (X mirrored), EW/NS on surface
let dX, dY;
if (isDungeon && obj.raw_x !== undefined) {
dX = (obj.raw_x - playerX);
dY = -(obj.raw_y - playerY); // Y flipped for north-up
dX = -(obj.raw_x - playerX); // X mirrored to match tile space
dY = -(obj.raw_y - playerY); // Y negated for north-up
} else {
dX = obj.ew - playerEW;
dY = obj.ns - playerNS;
@ -4048,8 +4039,8 @@ function updateRadarWindow(msg) {
const withDist = objects.map(obj => {
let distMeters, dX, dY;
if (isDungeon && obj.raw_x !== undefined) {
dX = (obj.raw_x - playerX);
dY = -(obj.raw_y - playerY);
dX = -(obj.raw_x - playerX); // X mirrored
dY = -(obj.raw_y - playerY); // Y negated
distMeters = Math.sqrt(dX * dX + dY * dY); // raw coords are ~meters
} else {
dX = obj.ew - playerEW;