Checks / web (push) Canceled after 0s
Mr. Pokémon's ROM scene gives the Mystery Egg and Pokédex, heals the party, sets the Cherrygrove spawn with blackoutmod and queues Elm's call. Cherrygrove's rival scene runs both triggers and all three RIVAL1_1 parties as a CANLOSE battle; reloadmap returns to the script. Smart AI is accepted for effects with no AI_Smart_EffectHandlers entry (Normal Hit, Attack Down, Defense Down) and still refuses others before any random draw, including for reserve Pokémon. Special calls read SpecialPhoneCallList: the entry's condition decides, and the ROM's CheckSpecialPhoneCall.script and Script_ReceivePhoneCall run its caller script through memcall, ending with HangUp's timed "Click!". Ringing and the caller box are not presented yet. In Elm's lab, NameRival shows the ROM's "RIVAL'S NAME?" title (the prompt previously had no page and soft-locked) and applies InitName's default to blank names. Handing over the Egg and the aide's Poké Balls run from the ROM. Saves gain rivalName and specialPhoneCall. The quest fixtures use a seeded RNG (a constant byte never ends the damage-variation loop) and no longer carry the house's moved objects into Cherrygrove. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
61 lines
2.8 KiB
TypeScript
61 lines
2.8 KiB
TypeScript
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<number, number> = { 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;
|
|
}
|