Open the Radio Tower takeover, Ice Path, Blackthorn and Dragon's Den (#32)

The Rocket-held Radio Tower, the Underground's switch room and warehouse,
Ice Path, Blackthorn City and its gym, Routes 45 and 46, Dark Cave's
Blackthorn entrance, Dragon's Den and the Dragon Shrine are open. The story
plays through the Basement Key, the switches and the director, the Clear
Bell, Ice Path's falling boulder, Clair's gym and the shrine's test for the
RISINGBADGE, TM24 and the elder's Dratini.

New specials: GiveDratini and MoveDeletion. A save keeps an object that a
script made disappear (or appear against its flag) as Continue does, so the
Radio Tower director no longer blocks the 5F stairs after a reload. A
whiteout from a battle started in an scall no longer refuses.

The playthrough driver pushes boulders into their holes (planned breadth
first), clears whirlpools, chooses the move a TM replaces and heals with
the strongest potion; the run gains six stages to the Rising Badge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kawaandClaude Opus 5.5 committed 2026-10-13 14:19:02 +02:00
1 parent 061ca4d59d
commit 9c3579937c
15 files changed
+855 -43

No files matched your search

+1
View File
@@ -52,6 +52,7 @@ These paths refer to the pinned [PRET source](https://github.com/pret/pokecrysta
| Bug-Catching Contest | `engine/events/bug_contest/*.asm`, `maps/Route35NationalParkGate.asm`, `maps/Route36NationalParkGate.asm`, `engine/menus/start_menu.asm` | Registration, Park Balls, contestant selection, the timer on the game clock, out of balls, QUIT, judging from `BugContestantPointers` with ties to the earlier entry, prizes and `CheckPartyFullAfterContest`. The contest state saves. The status box is a text page above the start menu. No sound. |
| `game/scripts/cianwood.ts`, Routes 38–41, Olivine and Cianwood | `engine/events/shuckle.asm` (`GiveShuckle`, `ReturnShuckie`), `engine/pokemon/bills_pc_top.asm` (`CheckCurPartyMonFainted`), `engine/pokemon/caught_data.asm` (`SetGiftPartyMonCaughtData`), `engine/events/poke_seer.asm`, `engine/events/print_photo.asm`, `engine/printer/printer.asm` (`PrintPartymon`, `CheckPrinterStatus`), `engine/printer/printer_serial.asm`, `engine/events/specials.asm` (`PlaySlowCry`) | Shuckie is a level 15 party-only gift with MANIA's OT, ID 518, nickname, a Berry and `LANDMARK_GIFT` caught data; it sets `ENGINE_GOT_SHUCKIE_TODAY`. `ReturnShuckie` returns all five codes; `CheckCurPartyMonFainted` looks at the rest of the party, and Mania answers `SHUCKIE_FAINTED` with his happiness speech, as the original does. `PokeSeer` follows `ReadCaughtData`, including the missing `cp [hl]` that compares only the OT ID's high byte, `GetCaughtLocation`'s event and gift landmarks, `GetCaughtLevel`'s ??? that leaves `wSeerCaughtLevel` unchanged, and `SeerAdvice`'s inclusive thresholds. `wSeerCaughtLevel` lives in the "Miscellaneous WRAM 1" union: the port keeps the Seer's own last value until a load, while in the original other users of those bytes may change it. `PhotoStudio` has no printer to talk to: the handshake reads $ff, so `CheckPrinterStatus` reports `PRINTER_ERROR_2`, and `SendScreenToPrinter` retries until B sets `hPrinter`. The port shows "Printer Error 2" with "Press B to Cancel" on one page, then the no-photo text; the print page behind the box and its alternation with "CHECKING LINK" are not drawn. `PlaySlowCry` is audio. The story maps run on ported script commands; `tests/olivine-cianwood.test.ts` and six playthrough stages cover them. |
| `game/scripts/lake-of-rage.ts`, Route 42 to Mahogany, the Lake of Rage, the Rocket Hideout and Pryce | `engine/events/magikarp.asm` (`CheckMagikarpLength`, `CalcMagikarpLength`, `PrintMagikarpLength`, `MagikarpHouseSign`), `engine/menus/intro_menu.asm` (`InitializeMagikarpHouse`), `engine/pokemon/search_party.asm` (`FindThatSpecies`), `engine/overworld/scripting.asm` (`DoScene`), `engine/events/money.asm` (`TakeMoney`) | The Magikarp is measured from its own DVs and OT ID with the battle code's `CalcMagikarpLength` (whose `.BCLessThanDE` compares only the high byte). A longer one, compared feet then inches, becomes the record with the Magikarp's OT name as holder; the record starts at 3′6″ by RALPH and is saved as `magikarpRecord`. `FindThatSpecies` reads `wPartySpecies`, where an Egg is EGG, so an Egg is never found. `setmapscene`/`setscene` on a map without a scene variable (Route 43, the Lake of Rage): `GetMapSceneID` leaves `de` alone and `DoScene` still writes the byte through it when it is nonzero. At the Route 43 gate `de` is `EventFlagAction`'s byte offset of `EVENT_CLEARED_ROCKET_HIDEOUT` (4), the MBC3 RAM-enable register, so nothing changes. After the Red Gyarados, `de` is whatever `closetext` left; the port consumes the byte and changes nothing, and that write was not checked in an emulator. `TakeMoney` leaves a short account at zero, so the Route 43 Rockets take all of a smaller balance. The Rocket Hideout's cameras, traps, passwords, executives and Electrodes and Pryce's ice floor run on ported primitives; `PlayCurMonCry` is audio. `tests/mahogany.test.ts` and five playthrough stages cover them. |
| `game/scripts/blackthorn.ts`, the Radio Tower takeover, Ice Path, Blackthorn and Dragon's Den | `engine/events/dratini.asm` (`GiveDratini`), `engine/events/move_deleter.asm` (`MoveDeletion`), `engine/pokemon/mon_menu.asm` (`ChooseMoveToDelete`), `engine/events/whiteout.asm` (`Script_Whiteout`), `data/maps/setup_scripts.asm` (`MapSetupScript_Continue`) | `GiveDratini` searches the party backwards by species and writes `.Movesets` 0 (WRAP, THUNDER WAVE, TWISTER, EXTREMESPEED) or 1 with each move's base PP; a value of 2 or more changes nothing. `MoveDeletion` follows the routine's order of questions; `ChooseMoveToDelete` is shown as a list of the moves, and `.DeleteMove` shifts the later moves and PP bytes, PP Ups included. A save records objects whose visibility no longer matches their flags: `MapSetupScript_Continue` skips `LoadMapObjects`, so a flagless object a script made disappear (the Radio Tower director) stays gone after Continue and one that appeared with its flag set stays visible; a later visit rebuilds them from the map. A battle lost inside an `scall` jumps to `Script_Whiteout` without unwinding; its `newloadmap` is followed by `endall`, which drops the caller. The switch room's doors, the warehouse's reset, the Ice Path and Blackthorn Gym stone tables, whirlpools and the Dragon Shrine quiz run on ported primitives. `tests/blackthorn.test.ts`, `tests/radio-tower.test.ts` and six playthrough stages cover them. |
| `game/scripts/slot-machine.ts`, `game/scripts/card-flip.ts` | `engine/games/slot_machine.asm`, `engine/games/card_flip.asm`, `engine/gfx/cgb_layouts.asm` | Both on a realtime tile screen (two frames per tick, buffered buttons). Slots: reel strips, spin rates and scrolling, bias tables with the lucky machine and seven streak, reel 3's Golem and Chansey replay with their sprites, payouts. Card Flip: deck, 12×11 board, cursor sprites and `ChooseCard_HandleJoypad`, paytable. Tilemaps, all 48 cursor positions, selected reel states and whole Golem/Chansey/Egg sequences are checked against the ROM (`tests/reference-game-corner.spec.ts`, which runs `CardFlip_UpdateCursorOAM`, `Slots_UpdateReelPositionAndOAM`/`.SpinReel` and the sprite-animation engine's own Golem/Chansey/Egg routines): the cursor, the reel symbols and the three creatures each anchor an OAM-relative pixel pair 8 (x) and 16 (y) beyond the screen's, as `cursorSprites` reads; `depixel`'s own two arguments end up swapped by `_InitSpriteAnimStruct` (confirmed against the reference emulator), so Golem/Chansey/Egg's X and Y bases were swapped to match, and Golem's own OAM table X-flips its right half. `PlaySpriteAnimations` is compared frame by frame over a three-Golem run and a Chansey round with two eggs (shadow OAM, `wSlotsDelay` and `hSCY`): frames last 8 ticks (the first draw plus 7 decrements); Golem's frames 3 and 4 flip the whole OAM set (offsets become −8−offset); a sprite removed by `DeinitializeSprite` is still drawn that tick, because `UpdateAnimFrame` runs after the animation function; the Golem's roll toggles `hSCY` by ±2, which the tile screen shows with the space tiles `_SlotMachine` filled the BG map with. The rows scrolled in use palette 0, since the attribute map beyond row 18 is not reproduced. No sound. |
| Text interpreter | `macros/scripts/text.asm`, `constants/charmap.asm`, `home/text.asm` | Literal/far text, RAM names and string buffers from native state, numbers of dots, and sound or pause cues (consumed). `text_asm` and other RAM reads are refused. |
+11 -1
View File
@@ -20,6 +20,7 @@ The emulator-backed prototype is now at `/reference.html`. The default applicati
| Routes 35–37, the National Park, Ecruteak and Morty | Done (Tin Tower closed) |
| Routes 38–41, Olivine, Cianwood, Chuck and Jasmine | Done (port, Battle Tower closed) |
| Route 42 to Mahogany, the Lake of Rage, the Rocket Hideout and Pryce | Done |
| The Radio Tower takeover, Ice Path, Blackthorn, Clair and Dragon's Den | Done |
| Wild and trainer battles, capture and the catching tutorial | Done for the areas that are open |
| 1. Complete the overworld foundation | Done |
| 2. Opening story and first battle slice | Mostly done |
@@ -428,7 +429,16 @@ The numbered sections below keep their full scope. Each one opens with a checkli
- New specials: `CheckMagikarpLength`, `MagikarpHouseSign` and `FindPartyMonThatSpecies` (`game/scripts/lake-of-rage.ts`). The Magikarp record and holder are saved as `magikarpRecord` (3′6″ by RALPH in a new game, and in older saves).
- Engine fixes: `takemoney` leaves a short account at zero, as `TakeMoney` does (it used to leave it unchanged). `setmapscene` and `setscene` on a map without a scene variable consume the scene byte instead of refusing; see NATIVE_PORT.md for where the original writes it.
- The playthrough driver's path search slides on ice. Tests: `tests/mahogany.test.ts` covers the record, its holder and reload, every guru answer, an Egg, the Elixer on standby and the toll. The playthrough continues for five more stages, from Olivine to Pryce.
- Remaining: the Radio Tower takeover, Ice Path, Blackthorn, Clair, Dragon's Den, Routes 45 and 46, Tin Tower, Whirl Islands, radio and rematches (#30), breeding (#29), mobile and link features, and audio.
- Remaining: the Radio Tower takeover, Ice Path, Blackthorn, Clair and Dragon's Den follow in increment F below; Tin Tower, Whirl Islands, radio and rematches (#30), breeding (#29), mobile and link features, and audio.
## Implemented: the Radio Tower takeover, Ice Path, Blackthorn, Clair and Dragon's Den (board #32, increment F)
- Ice Path's five floors, Blackthorn City with its gym, Pokémon Center, Mart, Move Deleter's house, Emy's house and the dragon speech house, Routes 45 and 46, Dark Cave's Blackthorn entrance, Dragon's Den and the Dragon Shrine are open. The Radio Tower, the Underground, its switch room and warehouse change for the takeover.
- The story runs: the Rocket-held Radio Tower to the fake director and the Basement Key, the Underground's locked door, the switch room's doors and the rival, the director and the Card Key, the 3F shutters, the executive and the Clear Bell; Ice Path's falling boulder; Clair's gym, whose 2F boulders fall to bridge 1F; Clair; the Dragon Shrine's five questions, the RISINGBADGE, TM24 and the elder's Dratini.
- New specials (`game/scripts/blackthorn.ts`): `GiveDratini` (the Extremespeed moves after a test without mistakes, the normal ones otherwise, on the last Dratini in the party) and `MoveDeletion` (one-move and Egg refusals, every way to say no, and moves and PP bytes shifting up).
- Engine fixes: a save keeps an object that disappeared without an event flag hidden (the Radio Tower director walks off the 5F stairs), and one that appeared with its flag set shown, as Continue keeps the saved object structs. `Script_Whiteout`'s `newloadmap` may run inside a call (a lost battle started from an `scall`); its `endall` drops the caller.
- The playthrough driver gained `push` and `boulders` (pushes planned breadth first over the boulders and the player's reachable area, each into its own stone-table hole), clears whirlpools in `sail`, can choose the move `teach` forgets, and heals with the strongest potion carried. Tests: `tests/blackthorn.test.ts` (Move Deleter, Dratini) and `tests/radio-tower.test.ts` (switches through a reload and the warehouse reset, a lost rival battle, the director after a save). The playthrough continues for six more stages: the Radio Tower, the Underground, the Clear Bell, Ice Path, training and Clair, and the Dragon Shrine.
- Remaining: Tin Tower and Suicune, Whirl Islands and Lugia, the Battle Tower, radio and rematches (#30, including Buena's password show), breeding (#29), mobile and link features, and audio.
## Native battles: current state