Port the fishing rods and wild Magikarp
The Old, Good and Super Rods run FishFunction facing water: the map's fish group and Fish pick no fish, no bite, or a Pokémon from FishGroups and the time of day's TimeFishGroups. The player casts and jiggles with the fishing frames drawn from LoadFishingGFX's tiles, shows "!" on a bite, and the hooked Pokémon attacks as BATTLETYPE_FISH. Facing pieces now use signed offsets, which the rod above and left of the player needs. Wild Magikarp no longer stop a battle: LoadEnemyMon redraws their DVs through CalcMagikarpLength and its filters, as the original does. The length routine matches the original in the reference emulator. Part of #27 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4cb4676c7d
commit
397dcef44c
20 files changed
+681
-47
No files matched your search
+29
-3
@@ -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 rods 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 gives 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. |
|
||||
@@ -325,7 +325,8 @@ 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
|
||||
object in `hLastTalked`, and the rods (`UseRod`, below). 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.
|
||||
@@ -356,6 +357,24 @@ keeps the step's count. `TryWildEncounter`'s `CheckRepelEffect` follows
|
||||
`ChooseWildEncounter`. `text_ram` of `wPlayerName`, `wRivalName` and
|
||||
`wMomsName` reads the text context's names.
|
||||
|
||||
`FishFunction` runs in the world (`.TryFish`'s surf and `WATER_TILE` checks,
|
||||
`GetFishingGroup` from the map header's `MAP_FISHGROUP`) and queues
|
||||
`Script_GotABite`, `Script_NotEvenANibble` or `Script_NotEvenANibble2`;
|
||||
`scripts/fish.ts` is `Fish` over `FishGroups` and `TimeFishGroups`
|
||||
(`GetFishGroupIndex`'s swarm groups need `wFishingSwarmFlag`, which only
|
||||
trainer calls set). The interpreter gained `loademote` (an emote loaded to
|
||||
the bubble's tiles is what `show_emote` shows next), `loadmem hBGMapMode`
|
||||
(ignored), `Fishing_CheckFacingUp`, `PutTheRodAway` (after the pending
|
||||
text) and an accepted `LoadFishingGFX`. `fish_cast_rod` and `fish_got_bite`
|
||||
set the actor's `OBJECT_ACTION_FISHING` until `PutTheRodAway`; the renderer
|
||||
then draws `FACING_FISH_*` from the player's tiles with `FishingGFX` or
|
||||
`KrisFishingGFX` over tiles 2-3, 6-7 and 10-11 and the rod at $fc-$fd,
|
||||
all in VRAM bank 1 like the player's sprite (`.InitSprite` sets
|
||||
`OAM_BANK1` below tile $80). Facing offsets are now read as signed bytes.
|
||||
The battle's `BATTLETYPE_FISH` prints `HookedPokemonAttackedText`.
|
||||
`LoadEnemyMon`'s `.Magikarp` filters and `CalcMagikarpLength` (with its
|
||||
`.BCLessThanDE` high-byte comparison) replace the Magikarp refusal.
|
||||
|
||||
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
|
||||
@@ -363,7 +382,14 @@ 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).
|
||||
Squirtbottle (the interpreter facing a test Sudowoodo on Route 36),
|
||||
`Fish` against the Shore tables, a bite, no bite and no fish in New Bark
|
||||
Town with the poses and the bubble, the surf and water refusals, and the
|
||||
Magikarp DV filters. `tests/reference-parity.spec.ts` compares
|
||||
`magikarpLength` with `CalcMagikarpLength` in the reference emulator over
|
||||
1,509 DV and ID pairs. A Chromium/WebKit test hooks a Magikarp with the
|
||||
Old Rod; the four fishing directions were checked in close-up
|
||||
screenshots, not against the original.
|
||||
|
||||
## Evolution
|
||||
|
||||
|
||||
Reference in new issue
Block a user