Route 42, Mt. Mortar, Mahogany Town, Route 43 and its gates, the Lake of Rage and its houses, the Rocket Hideout and Route 44 are open. The story plays through the toll, the red Gyarados, Lance, the hideout and Pryce's GLACIERBADGE, which starts the Radio Tower takeover. The fishing guru measures Magikarp (CheckMagikarpLength, MagikarpHouseSign, FindPartyMonThatSpecies); the record is saved. takemoney now leaves a short account at zero as TakeMoney does, and setmapscene/setscene on a map without scenes consume the byte instead of refusing. The playthrough's path search slides on ice and the run gains five stages to Pryce. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
import { JOHTO, RAM, WRAM } from "../rom/profile";
|
||
import { magikarpLength } from "../battle/battle";
|
||
import type { Gen, SpecialContext } from "./special-context";
|
||
|
||
const MAGIKARP = 129;
|
||
|
||
/** MAGIKARPLENGTH_* (constants/script_constants.asm). */
|
||
export const MAGIKARP_LENGTH = {
|
||
notMagikarp: 0,
|
||
refused: 1,
|
||
tooShort: 2,
|
||
beatRecord: 3,
|
||
} as const;
|
||
|
||
/** wBestMagikarpLengthFeet/Inches and wMagikarpRecordHoldersName;
|
||
* InitializeMagikarpHouse starts a new game at 3′6″ by RALPH. */
|
||
export interface MagikarpRecord {
|
||
feet: number;
|
||
inches: number;
|
||
holder: string;
|
||
}
|
||
export const initialMagikarpRecord = (): MagikarpRecord => ({
|
||
feet: 3,
|
||
inches: 6,
|
||
holder: "RALPH",
|
||
});
|
||
|
||
/** PrintMagikarpLength: feet and inches, each a left-aligned number, with
|
||
* the feet and inches marks it loads into tiles $6e and $6f. */
|
||
const lengthString = (feet: number, inches: number) => `${feet}′${inches}″`;
|
||
|
||
/** FindThatSpecies: wPartySpecies holds EGG for an Egg, so an Egg never
|
||
* matches. */
|
||
export const findPartyMonThatSpecies = (c: SpecialContext, species: number) =>
|
||
c.state.party.some((mon) => !mon.egg && mon.species === species) ? 1 : 0;
|
||
|
||
/** CheckMagikarpLength (engine/events/magikarp.asm): pick a party
|
||
* Pokémon; a Magikarp is measured from its DVs and its own OT ID, and a
|
||
* longer one (both bytes compared, feet first) becomes the record, with
|
||
* its OT's name as the holder. */
|
||
export function* checkMagikarpLength(
|
||
c: SpecialContext,
|
||
record: MagikarpRecord,
|
||
): Gen<number> {
|
||
const slot = yield* c.selectMon();
|
||
if (slot < 0) return MAGIKARP_LENGTH.refused;
|
||
const mon = c.state.party[slot];
|
||
// wCurPartySpecies comes from wPartySpecies, EGG for an Egg.
|
||
if (mon.egg || mon.species !== MAGIKARP) return MAGIKARP_LENGTH.notMagikarp;
|
||
const { feet, inches } = magikarpLength(c.reader, mon.dvs, mon.otId);
|
||
c.strings[RAM.stringBuffer1] = lengthString(feet, inches);
|
||
c.write(JOHTO["CheckMagikarpLength.MagikarpGuruMeasureText"]);
|
||
// CompareBytes over wMagikarpLength and the record: carry when the new
|
||
// length is greater.
|
||
if (feet * 256 + inches <= record.feet * 256 + record.inches)
|
||
return MAGIKARP_LENGTH.tooShort;
|
||
record.feet = feet;
|
||
record.inches = inches;
|
||
record.holder = mon.ot;
|
||
return MAGIKARP_LENGTH.beatRecord;
|
||
}
|
||
|
||
/** MagikarpHouseSign: the record and its holder. */
|
||
export function magikarpHouseSign(c: SpecialContext, record: MagikarpRecord) {
|
||
c.strings[RAM.stringBuffer1] = lengthString(record.feet, record.inches);
|
||
c.strings[WRAM.wMagikarpRecordHoldersName] = record.holder;
|
||
c.write(JOHTO["MagikarpHouseSign.KarpGuruRecordText"]);
|
||
}
|