import { emptyDecorations } from "../src/game/world/decorations"; import { CrystalAssets } from "../src/game/rom/assets"; import { GameWorld } from "../src/game/world/world"; import type { GameMap } from "../src/game/world/types"; /** Synthetic maps and script bytes: these tests run without a private ROM. */ export class MovementAssets extends CrystalAssets { readonly fixtures = new Map(); readonly tiles = new Map(); readonly bytes: Uint8Array; constructor() { const bytes = new Uint8Array(0xa0000); bytes[0] = 0x50; // Empty weekday name for synthetic script hosts. super(bytes); this.bytes = bytes; for (const id of ["24:7", "24:6"]) { this.fixtures.set(id, { id, group: 24, number: Number(id.split(":")[1]), name: id, location: id, landmark: 1, width: 8, height: 8, border: 0, tileset: 1, environment: 1, paletteMode: 1, blocks: new Uint8Array(16), warps: [], backgroundEvents: [], objects: [], connections: [], sceneScripts: [], callbacks: [], coordinateEvents: [], }); } } override map(id: string) { return this.fixtures.get(id)!; } override isPorted(id: string) { return this.fixtures.has(id); } override sceneOwner() { return undefined; } override collision(map: GameMap, x: number, y: number) { if (x < 0 || y < 0 || x >= map.width || y >= map.height) return 7; return this.tiles.get(`${map.id}:${x},${y}`) ?? 0; } /** CollisionPermissionTable in brief: walls, then the water rows * ($2x, $3x, buoys $cx) apart from ice and the wall-like buoy tiles. */ override permission(collision: number) { if (collision === 7 || collision === 0x27 || collision === 0x2f) return 15; if (collision === 0x23 || collision === 0x2b) return 0; return [0x20, 0x30, 0xc0].includes(collision & 0xf0) ? 1 : 0; } override grassCollisions() { return []; } override sprite(id: number) { return id ? { graphics: new Uint8Array(0), palette: 0, walking: false } : undefined; } tile(x: number, y: number, collision: number, map = "24:7") { this.tiles.set(`${map}:${x},${y}`, collision); } } export function fixture() { const assets = new MovementAssets(); const world = new GameWorld( assets, () => new Date("2026-09-22T12:00:00"), () => 0, ); world.state.decorations = emptyDecorations(); return { assets, world }; } export function connectWarp(assets: MovementAssets, x = 3, y = 4) { assets.map("24:7").warps.push({ x, y, targetMap: "24:6", targetWarp: 1 }); assets .map("24:6") .warps.push({ x: 2, y: 2, targetMap: "24:7", targetWarp: 1 }); assets.tile(2, 2, 0x70, "24:6"); }