fix: horizontally flip tile images + negate rotation

UB's tiles were authored for a mirrored-X rendering space. Instead of
mirroring coordinates (which breaks positioning), flip each tile image
horizontally during pre-processing and negate the cell rotation angles
to compensate. Cell and object positions remain direct (no mirroring).

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

View file

@ -3607,13 +3607,18 @@ const DUNGEON_DISPLAY_COLORS = {
stairs: { r: 180, g: 160, b: 80 }, // yellowish stairs
};
// Process a tile image: make white transparent, remap UB colors
// Process a tile image: flip horizontally (UB tiles authored for mirrored-X),
// 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;
@ -3857,13 +3862,14 @@ 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 (same as UB's DungeonCell.cs)
// Raw value is quaternion W component: 1→180°, ~0.707→-90°, ~-0.707→90°, 0→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
function cellRotation(rot) {
if (Math.abs(rot - 1) < 0.01) return Math.PI;
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;
if (rot > 0.70 && rot < 0.8) return -Math.PI / 2;
if (rot < -0.70 && rot > -0.8) return -Math.PI / 2; // negated
if (rot > 0.70 && rot < 0.8) return Math.PI / 2; // negated
return 0;
}