import { CrystalAssets } from "../src/game/rom/assets"; import { generatePartyMon } from "../src/game/party/pokemon"; import { GameWorld } from "../src/game/world/world"; import { settle } from "./world-driver"; // EVENT_GOT_CYNDAQUIL/TOTODILE/CHIKORITA_FROM_ELM. const STARTER_EVENTS: Record = { 155: 27, 158: 28, 152: 29 }; /** Only the starting position and earlier starter choice are fixtures. * The house rewards and return scenes come from the untouched ROM scripts. */ export function questFixtureWorld(assets: CrystalAssets, species = 158) { // A seeded Random: a constant byte never ends BattleRandom retry loops // such as BattleCommand_DamageVariation's. let seed = 1; const world = new GameWorld(assets, () => new Date("2026-09-22T12:00:00"), () => { seed = (seed * 1103515245 + 12345) >>> 0; return (seed >>> 16) & 255; }); const mon = generatePartyMon(assets.pokemon, { species, level: 20, item: 0, otId: world.playerId, ot: "CHRIS", dvs: 0xffff, caughtData: 0, }); mon.moves = [10, 0, 0, 0]; mon.pp = [35, 0, 0, 0]; mon.hp = 1; // Mr. Pokémon must actually heal the party. world.state.party = [mon]; world.state.pokedex.seen.add(species); world.state.pokedex.caught.add(species); world.state.events.add(26); // GOT_A_POKEMON_FROM_ELM world.state.events.add(STARTER_EVENTS[species]); world.restore({ ...world.save(), map: "26:1", x: 17, y: 6, direction: "up" }); return world; } /** Independent rival UI fixture, derived from completing the actual house * scene, then relocated to the city's return trigger. This is not a full walk. */ export function questRivalFixtureWorld(assets: CrystalAssets, species = 158) { const world = questFixtureWorld(assets, species); if (!world.move("up")) throw new Error("Could not enter Mr. Pokémon's house."); settle(world); if (world.notice || !world.state.events.has(30)) throw new Error(`House fixture did not complete: ${world.diagnostic}`); // The house's moved objects (Mr. Pokémon, Oak) must not carry over. The // Guide Gent still stands at 32,6; one step right reaches 33,7's trigger. world.restore({ ...world.save(), map: "26:3", x: 32, y: 7, direction: "right", objects: [] }); return world; } /** The house scene completed for real, then relocated below Elm's lab door * in New Bark Town. Elm's robbed call stays queued: the door step warps, * and calls do not ring indoors. */ export function questLabFixtureWorld(assets: CrystalAssets) { const world = questFixtureWorld(assets); if (!world.move("up")) throw new Error("Could not enter Mr. Pokémon's house."); settle(world); if (world.notice || !world.state.events.has(30)) throw new Error(`House fixture did not complete: ${world.diagnostic}`); world.restore({ ...world.save(), map: "24:4", x: 6, y: 4, direction: "up", objects: [] }); return world; }