Port Repels and the other non-fishing field items

Repel, Super Repel and Max Repel count down 100, 200 or 250 steps where
CountStep does, keep weaker wild Pokémon away from the first party member
that has not fainted, and print "REPEL's effect wore off." on the last
step. The Coin Case and the Blue Card show their balances, Sacred Ash
revives the party once one Pokémon has fainted, and the Normal and
Gorgeous Boxes send their trophy home.

The Itemfinder looks for unfound hidden items on the original's screen
around the player. The Card Key, the Basement Key and the Squirtbottle
run the original's checks for their doors and Sudowoodo, whose maps are
not open yet. Saves gain the Repel's steps, the coins and the Blue Card's
points.

Part of #27

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sébastien QUEROLandClaude Opus 5.5 committed 2026-10-03 00:32:33 +02:00
1 parent 10e1560212
commit 4cb4676c7d
13 files changed
+821 -21

No files matched your search

+30 -4
View File
@@ -32,7 +32,7 @@ These paths refer to the pinned [PRET source](https://github.com/pret/pokecrysta
| Movement interpreter | `macros/scripts/movement.asm`, `engine/overworld/movement.asm`, `engine/overworld/map_objects.asm` | Turns, steps, slides, jumps (two tiles with the original arc), sleeps, facing locks, visibility and emotes. `follow` takes one tile toward the leader's previous square. All movement opcodes decode, including teleport, fishing, skyfall, shake and flicker poses; Controlled reference scenes check spin, teleport, skyfall, fishing and flicker direction, visibility and lift. |
| Specials | `data/events/special_pointers.asm`, `engine/rtc/timeset.asm`, `engine/overworld/decorations.asm` | Selected by routine address from the ROM table: `SetDayOfWeek`, initial DST flags, `RestartMapMusic` (no audio yet), room decoration toggles, `PokemonCenterPC` and `PlayersHousePC` (Bill's, the player's and Oak's PCs), the Town Map, `HealParty`, `HealMachineAnim` (presentation only), `CheckPokerus` and the `StubbedTrainerRankings_Healings` stub. |
| `game/scripts/pc.ts` | `engine/events/pokecenter_pc.asm`, `engine/pokemon/bills_pc_top.asm`, `engine/pokemon/bills_pc.asm`, `engine/events/prof_oaks_pc.asm`, `engine/events/std_collision.asm` | The Pokémon Center and house PCs: Bill's PC (deposit, withdraw, release, change and name boxes, MOVE PKMN W/O MAIL, stats), item storage, the empty mail box and Oak's rating. Menu strings and texts come from the ROM; lists are native. Printing is not ported. |
| `game/scripts/start-menu.ts` | `engine/menus/start_menu.asm`, `engine/pokemon/mon_menu.asm`, `mon_submenu.asm`, `party_menu.asm`, `switchpartymons.asm`, `engine/items/pack.asm`, `engine/items/item_effects.asm` | The start menu, the party menu with the Pokémon submenu (STATS, SWITCH, MOVE, ITEM) and the pack (USE, GIVE, TOSS) with the field item effects listed below, including Rare Candy, stones and vitamins. Menu strings, prompts and texts come from the ROM; screens are native. Field moves from the menu (checked by the world), Softboiled and Milk Drink, SEL and the Select button (`SelectMenu`). MAIL and the other field items give a notice. |
| `game/scripts/start-menu.ts` | `engine/menus/start_menu.asm`, `engine/pokemon/mon_menu.asm`, `mon_submenu.asm`, `party_menu.asm`, `switchpartymons.asm`, `engine/items/pack.asm`, `engine/items/item_effects.asm` | The start menu, the party menu with the Pokémon submenu (STATS, SWITCH, MOVE, ITEM) and the pack (USE, GIVE, TOSS) with the field item effects listed below, including Rare Candy, stones and vitamins. Menu strings, prompts and texts come from the ROM; screens are native. Field moves from the menu (checked by the world), Softboiled and Milk Drink, SEL and the Select button (`SelectMenu`). MAIL and the rods give a notice. |
| `game/scripts/pokegear.ts` | `engine/pokegear/pokegear.asm`, `engine/phone/phone.asm`, `engine/phone/scripts/mom.asm`, `elm.asm`, `engine/rtc/print_hours_mins.asm` | `PokeGear` with each card's joypad handling: the clock (`Pokegear_UpdateClock`, `PrintHoursMins`), the map card's landmark cursor (`TownMap_InitCursorAndPlayerIconPositions`, `TownMap_GetKantoLandmarkLimits`), the phone list (`PokegearPhone_UpdateDisplayList`, `GetCallerClassAndName`, `PokegearPhoneContactSubmenu`, `CheckCanDeletePhoneNumber`) and calls (`MakePhoneCallFromPokegear`, `CheckPhoneContactTimeOfDay`, `GetMapPhoneService`, `HangUp`). Callee scripts run in the event interpreter on the start menu's draft. Screens are native; the radio's stations are not ported. |
| `game/scripts/trainer-card.ts` | `engine/menus/trainer_card.asm`, `engine/gfx/player_gfx.asm` (`GetCardPic`), `engine/gfx/cgb_layouts.asm` (`_CGB_TrainerCard`), `home/game_time.asm` | `TrainerCard`'s two reachable pages with their joypad rules, strings from `.Name_Money`, `.Dex_PlayTime` and `.Badges`, the caught count, and the badges from `TrainerCard_JohtoBadgesOAM` with their eight-frame steps. `rendering/trainer-card.ts` draws the card picture, leader faces and badges from the ROM with the card's palettes and attribute map. `world/game-time.ts` is `GameTimer` (capped at 999:59:59). Text is native; the blinking colon's and badges' phase start at the page load. |
| `game/scripts/options.ts` | `engine/menus/options_menu.asm`, `data/default_options.asm`, `engine/battle/core.asm` (`CheckWhetherToAskSwitch`), `engine/menus/start_menu.asm` | `_Option` with `OptionsControl` and each option's routine on the four option bytes, `DefaultOptions`, and the two settings consumed so far: `BATTLE_SHIFT` and `MENU_ACCOUNT`. Strings come from the ROM; the screen is native. |
@@ -317,7 +317,15 @@ and then `_DoItemEffect` by the `ItemEffects` routine address, with the
field side of `RestoreHPEffect`, `StatusHealingEffect`, `FullRestoreEffect`,
`ReviveEffect`/`RevivalHerbEffect`, `EnergypowderEffect`/`EnergyRootEffect`,
`HealPowderEffect` and `RestorePPEffect` (Ether, Max Ether, Elixer, Max
Elixer, MysteryBerry and PP Up with `ApplyPPUp`). Items are used from the
Elixer, MysteryBerry and PP Up with `ApplyPPUp`), and since the remaining
field items increment `UseRepel` (`UseItemText`), `CoinCaseEffect`,
`BlueCardEffect`, `_SacredAsh` (`CheckAnyFaintedMon`, then the queued
`SacredAshScript`), `OpenBox` (`DecorationIDs`, then the decoration's
event flag), `ItemFinder` (the world's `CheckForHiddenItems` picks the
queued script), `_CardKey`, `_BasementKey` (map and facing tile in
`wPlayerMapX/Y` coordinates) and `_Squirtbottle`, whose
`.CheckCanUseSquirtbottle` asks the world's `GetFacingObject` and leaves the
object in `hLastTalked`. Items are used from the
Items pocket slot they were chosen from (`wCurItemQuantity`).
`ItemActionTextWaitButton` prints `PrintPartyMenuActionText` with the HP
change. `ChangeHappiness` outside battle does not touch a battle Pokémon.
@@ -339,6 +347,24 @@ while the menu is open. A Chromium/WebKit test opens the menu with Start,
switches Pokémon, changes pockets and tosses a Potion. These are not
emulator comparisons.
`DoRepelStep` runs in the world where `CountStep` calls it, after
`CheckSpecialPhoneCall`; the poison, happiness, egg, Day-Care and bike
steps of `CountStep` are not ported yet. `RepelWoreOffScript` starts with
the step's committed position, like a coordinate event, and its committed
save keeps the last Repel step; a wild battle's committed save likewise
keeps the step's count. `TryWildEncounter`'s `CheckRepelEffect` follows
`ChooseWildEncounter`. `text_ram` of `wPlayerName`, `wRivalName` and
`wMomsName` reads the text context's names.
Tests: `tests/field-items.test.ts` (local ROM) uses each Repel, walks with
one through a test-only grass table (weaker Pokémon kept away, a fainted
lead, an equal level let through, the last step's message and its replay
after a reload), and covers the Coin Case, the Blue Card, Sacred Ash with
and without a fainted Pokémon, both boxes, the save migration, the
Itemfinder at each edge of the screen around Route 30's hidden Potion,
the keys (a start-menu run with the unopened maps' positions) and the
Squirtbottle (the interpreter facing a test Sudowoodo on Route 36).
## Evolution
The battle's experience routine sets a party member's bit in
@@ -430,8 +456,8 @@ animations as timed `fly` effects (65 and 33 ticks). The Escape Rope
chamber's wall there (`SpecialKabutoChamber`) and using up one rope; a
failure prints nothing before Oak's warning. `JumpRoamMons` (no roaming
Pokémon yet) and the fades are not modelled. A destination map that is not
ported gives a notice. `TreeMonEncounter` and `RockMonEncounter` are not
ported and give a notice after their checks.
ported gives a notice. `TreeMonEncounter` and `RockMonEncounter` run since
the Headbutt and Rock Smash increment.
`Softboiled_MilkDrinkFunction` runs in the menu with `GetOneFifthMaxHP`,
`RemoveHP` and `RestoreHealth`, refusing the user itself and Pokémon that
fainted or are at full HP.