Port Fly, Dig, Teleport and the Escape Rope

FLY opens _FlyMap in the party menu: the region's Town Map with "Where?",
the visited flypoints in turn and the Fly user's icon, then FlyScript flies
the icon off along SpriteAnimFunc_FlyFrom's path, enters the spawn point and
lands it with SpriteAnimFunc_FlyTo. Teleport returns to the last Pokémon
Center's town through IsSpawnPoint. Dig and the Escape Rope lead out of a
cave to the warp EnterMapWarp's SaveDigWarp recorded, which saves now keep.

newloadmap stops its script as StopScript does and the world resumes it on
the new map, which the landing and return movements need. A destination
that is not ported yet gives a notice.

Closes #25

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sébastien QUEROLandClaude Opus 5.5 committed 2026-10-02 11:18:57 +02:00
1 parent c4cc0e756c
commit a7aceda089
21 files changed
+1166 -97

No files matched your search

+12 -3
View File
@@ -169,7 +169,7 @@ The numbered sections below keep their full scope. Each one opens with a checkli
- PACK: the Items, Balls, Key and TM pockets (left and right change pockets; there are no TMs or HMs yet), and each item's submenu chosen by its permissions and field menu (`USE`, `GIVE`, `TOSS`, `SEL`, `QUIT`). TOSS asks how many and confirms. USE follows `UseItem`: Oak's warning without a field use, "You don't have a POKéMON!" for party items without one, and `_DoItemEffect` by the item's `ItemEffects` address: Potions and the other `HealingHPAmounts` items, status healers, Full Restore, Revive and Max Revive, the bitter Energypowder, Energy Root, Heal Powder and Revival Herb, Ethers, Elixers, the MysteryBerry and PP Up. The Bicycle closes the menu and runs `Script_GetOnBike` or `Script_GetOffBike` outdoors; elsewhere Oak objects, because `wFieldMoveSucceeded` shares `wItemEffectSucceeded`'s byte.
- PP Up keeps a quirk: `wUsePPUp` shares `wTempPP`'s byte, so `ComputeMaxPP` adds one step (a fifth of the base PP, at most 7) to the current PP as well as the maximum. Sketch and moves with three PP Ups are "maxed out".
- The menu runs on a script draft, like the PC. Changes commit when it closes; a save made while it is open keeps the state from before it. The start menu cursor, the party menu cursor and the last pocket stay in memory between openings and are cleared after a battle, as `CleanUpBattleRAM` does. The party cursor reaches the next battle's `ChangeHappiness`.
- Not ported: MAIL, moving a Pokémon's moves to another party member with left and right, item reordering with Select and the remaining field items such as Repel and Escape Rope (each gives a notice and changes nothing). Rare Candy, evolution stones and vitamins run since the evolution section below; field moves, SEL and Select since the section after it.
- Not ported: MAIL, moving a Pokémon's moves to another party member with left and right, item reordering with Select and the remaining field items such as Repel (each gives a notice and changes nothing; the Escape Rope runs since the Fly section below). Rare Candy, evolution stones and vitamins run since the evolution section below; field moves, SEL and Select since the section after it.
## Implemented: evolution
@@ -185,7 +185,7 @@ The numbered sections below keep their full scope. Each one opens with a checkli
- Field moves in the Pokémon submenu run their menu functions: the world checks the badge (`CheckBadge`: "Sorry! A new BADGE is required."), the facing tile, water or object, then the menu closes and the ROM's `…FromMenu` script runs for the chosen Pokémon (no "Want to …?" question): Cut (`CheckMapForSomethingToCut`), Surf (including "already surfing" and forced cycling), Strength, Flash (a `PALETTE_DARK` map or the Aerodactyl chamber; `BlindingFlash` sets the Flash flag), Whirlpool and Waterfall. Failures print the ROM's messages and return to the party menu.
- Sweet Scent runs `SweetScentFromMenu`: where wild Pokémon can appear and the map has a rate, `ChooseWildEncounter` picks one without the rate roll and a battle starts; elsewhere "Looks like there's nothing here…".
- Softboiled and Milk Drink give a fifth of the user's maximum HP to another Pokémon that has not fainted and is not at full HP; the user needs more than that fifth.
- Fly (outdoors with the Storm Badge), Dig (in caves), Teleport (outdoors with a spawn point), Headbutt (facing a tree) and Rock Smash (facing a rock) run their checks and messages, then give a notice: the Fly map, dungeon and spawn warps, tree encounters and rock encounters are not ported.
- Headbutt (facing a tree) and Rock Smash (facing a rock) run their checks and messages, then give a notice: tree and rock encounters are not ported. Fly, Dig and Teleport run since the section below.
- SEL registers an item that `CANT_SELECT` allows (in practice key items) in `wWhichRegisteredItem` and `wRegisteredItem`, which saves keep. Select runs `SelectMenu`: `CheckRegisteredItem` (a slot that no longer holds the item clears the registration; a registered ball is never found, as in the original) and `UseRegisteredItem` by field menu. The Bicycle uses `Script_GetOnBike_Register` and `Script_GetOffBike_Register`, without a message; elsewhere Oak objects. Without a registration Select explains SEL. This replaces the earlier Key Items shortcut.
- Bill's PC's MOVE PKMN W/O MAIL: refused while a party Pokémon holds MAIL, then "Each time you move a POKéMON, data will be saved. OK?". Choose the party or a box, a Pokémon (MOVE, STATS, CANCEL), then a box and the position to insert before. The party keeps its last Pokémon and its last healthy one, a different full box or party has "no room", a Pokémon moved down its own list lands one place earlier (`.CheckTrivialMove`), a boxed Pokémon joining the party gets its stats with full HP and no status (`CalcBufferMonStats`), and one entering a box gets its PP restored. The original's left/right box switching is presented as a list of boxes; after "no room" the box is chosen again rather than the position.
- Save format 3 gained `registeredItem`, migrated by absence to none.
@@ -223,6 +223,15 @@ The numbered sections below keep their full scope. Each one opens with a checkli
- The four bytes (`wOptions`, `wTextboxFrame`, `wGBPrinterBrightness`, `wOptions2`) are kept in the script state, so they change on the start menu's draft and commit when it closes. Save format 3 gained `options`, migrated by absence to `DefaultOptions`.
- In effect: the battle style (`CheckWhetherToAskSwitch`: SET makes no offer when a trainer sends out its next Pokémon) and the menu account (`StartMenu`'s descriptions). Not yet: text speed (native text appears at once), the battle scene (no move animations), sound (no audio), printing and the textbox frame. The catching tutorial's temporary medium text speed has nothing to change.
## Implemented: Fly, Dig, Teleport and the Escape Rope
- Fly needs the Storm Badge and an outdoor map, then opens `_FlyMap`: the Johto map (Kanto's only once Indigo Plateau's flypoint is visited; before that the Johto map shows no player icon), "Where?" with the flypoint's name, the player's place and the Fly user's party icon on the selected flypoint. New Bark Town (or Indigo Plateau in Kanto) is the default, visited or not; up and down move to the next or previous visited flypoint with wrapping, A flies there, B returns to the party menu. Flypoints are read from `Flypoints` and visits from `wVisitedSpawns`, the `ENGINE_FLYPOINT_*` flags that town callbacks set.
- `FlyScript`: `FlyFromAnim` hides every object while the party icon waits 64 frames and rises off the screen, swaying (`SpriteAnimFunc_FlyFrom`), the player arrives at the flypoint's `SpawnPoints` entry facing down (`MAPSETUP_FLY`), and `FlyToAnim` brings the icon down onto the player (`SpriteAnimFunc_FlyTo`). The icon flaps its wings with `SPRITE_ANIM_OBJ_RED_WALK`'s frames. The leaves and the sound are not presented.
- Teleport works outdoors when `wLastSpawnMapGroup/Number` is a spawn point (`IsSpawnPoint`): "Return to the last POKéMON CENTER.", `teleport_from`, the spawn point facing down, then `teleport_to`. Otherwise "Can't use that here.".
- Dig and the Escape Rope work in caves and dungeons once `wDigWarpNumber` is set: `EnterMapWarp`'s `SaveDigWarp` records the warp of any step from an outdoor map into an indoor one (houses included, as in the original; not from Mount Moon Square or Tin Tower's roof). The ROM's `UsedDigScript` or `UsedEscapeRopeScript` digs out (`step_dig`, hidden), arrives on that warp through `MAPSETUP_DOOR` and returns (`return_dig`); a cave entrance then walks the player out. Dig elsewhere says "Can't use that here."; the Escape Rope fails silently, then Oak warns, and is used up only on success. In the Kabuto chamber the rope opens the wall (`SpecialKabutoChamber`).
- `newloadmap` now stops its script and resumes it on the new map, which these scripts need for their landing movements. Save format 3 gained `digWarp`, migrated by absence to none.
- Unreachable in normal play so far: the Storm Badge, caves (Dark Cave is beyond Route 31) and flypoints beyond Cherrygrove. A destination that is not ported gives a notice. `JumpRoamMons` waits for roaming Pokémon.
## Native battles: current state
The battle core, ROM tables, encounter hooks, battle UI and whiteout hooks are present. Unit tests cover wins, escape, loss, experience, move learning and capture; reference tests compare damage, type effectiveness, stat calculation and experience curves. Browser tests drive a test-only wild encounter through the real UI: victory with level-up and move learning, escape, whiteout, catching with a nickname, keyboard and on-screen D-pad menu navigation, mid-battle backup restore, rollback of unsupported effects, switching through the party menu and a Potion from the Items pocket. Real Route 29 encounters now use the ROM's encounter tables. Only the special Kurt and Park balls remain unported among battle items.
@@ -305,7 +314,7 @@ Introduce native player, party, Pokémon, inventory, money and quest models. Rea
Expand script calls, choices, scene state, inventory commands and native special handlers. Translate routines reached through assembly calls into explicit native services; never fall back to emulator execution in the shipping game.
Meeting Mom, Elm's introduction, the starter, the aide's Potion, Route 29, Cherrygrove, Route 30's trainers, Mr. Pokémon's house, the Cherrygrove rival battle, the return to Elm, capture, the catching tutorial, the PC, the introduction's naming and clock screens, and switching and healing items in battle run now. The opening milestone is complete within the recorded acceptance boundaries. The start menu, party menu and pack now run outside battle, and Pokémon evolve. Field moves from the menu, SEL/Select and MOVE PKMN W/O MAIL run too, and the Pokégear's clock, map and phone cards, with calls to Mom and Elm, Mom's bank at home and her purchases, the trainer card with the play time, and the options. Next: the Fly map and Teleport/Dig warps.
Meeting Mom, Elm's introduction, the starter, the aide's Potion, Route 29, Cherrygrove, Route 30's trainers, Mr. Pokémon's house, the Cherrygrove rival battle, the return to Elm, capture, the catching tutorial, the PC, the introduction's naming and clock screens, and switching and healing items in battle run now. The opening milestone is complete within the recorded acceptance boundaries. The start menu, party menu and pack now run outside battle, and Pokémon evolve. Field moves from the menu, SEL/Select and MOVE PKMN W/O MAIL run too, and the Pokégear's clock, map and phone cards, with calls to Mom and Elm, Mom's bank at home and her purchases, the trainer card with the play time, the options, and Fly, Dig, Teleport and the Escape Rope. Next: Headbutt and Rock Smash encounters.
Complete and validate the native battle engine: deterministic randomness, stats, move selection, accuracy/critical checks, damage, status, turn order, switching, fainting, experience, capture and rewards. Compare controlled seeds and states with the original, including integer rounding and overflow behavior.