Ring with trainers' calls, rematch them and play the radio (Closes #30)
Checks / web (push) Successful in 2m38s
Private ROM checks / private-rom (push) Successful in 20m37s

Every registered trainer's callee and caller scripts run, with the
missing specials and commands (RandomPhoneWildMon, RandomUnseenWildMon,
swarms, gettrainerclassname, Kenji's break, the Blue Card and Buena's
password variables). Fight counts are saved, so rematches and gifts work
on every open map, and the daily reset clears the phone's flags.

Random calls follow CheckPhoneCall and the 20/10/5/3-minute call timer;
received calls ring twice with the caller's name, and calls play their
ringing, hang-up and no-signal sounds. Grass and fishing swarms use the
swarm tables.

The radio ports PlayRadioShow and every station frame by frame, with its
music: the Pokégear's radio card tunes by knob, house radios play through
MapRadio, and Buena's show takes the day's password for Blue Card points
that her receptionist exchanges for prizes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kawaandClaude Opus 5.5 committed 2026-10-16 11:10:02 +02:00
1 parent 7f30c3f450
commit 7c12c81a27
21 files changed
+2021 -64

No files matched your search

+17
View File
@@ -0,0 +1,17 @@
import { CrystalAssets } from "../src/game/rom/assets";
import { generatePartyMon } from "../src/game/party/pokemon";
import { GameWorld } from "../src/game/world/world";
/** Route 30 at noon with a Cyndaquil, the Pokégear and its radio card. */
export function radioFixtureWorld(assets: CrystalAssets) {
const world = new GameWorld(assets, () => new Date("2026-09-22T12:00:00"), () => 0x42);
world.state.party = [
generatePartyMon(assets.pokemon, {
species: 155, level: 8, item: 0, otId: world.playerId,
ot: "CHRIS", dvs: 0x9abc, caughtData: 0,
}),
];
for (const flag of [0, 4]) world.state.flags.add(flag); // ENGINE_RADIO_CARD, ENGINE_POKEGEAR
world.restore({ ...world.save(), map: "26:1", x: 7, y: 30, direction: "down", objects: [] });
return world;
}