Breed at the Day-Care, hatch Eggs, draw MAIL stationery and browse the Hall of Fame (Closes #29)
- Day-Care and breeding: deposits, withdrawal pricing and growth, compatibility, egg species, DVs and moves, DayCareStep, egg collection and the Odd Egg, compared with the cartridge's routines. - CountStep: walking happiness, DoEggStep, DayCareStep and DoBikeStep in the original's order; HatchEggs with the ROM's hatch animation, compared frame by frame with the original. - MAIL: all ten stationery types and the Portrait MAIL picture, compared with the cartridge's tilemaps, graphics and palettes. - Printing: Bill's PC boxes, Pokedex PRNT, MAIL and the Photo Studio take the original's absent-printer path. - Hall of Fame records (saved apart from the League flag, ready for the League to call) and the Hall of Fame PC, compared with the cartridge's _HallOfFamePC on 255 pages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7d03f5c5ca
commit
e49bc6de9a
49 files changed
+6028
-88
No files matched your search
+37
-10
@@ -133,8 +133,8 @@ The numbered sections below keep their full scope. Each one opens with a checkli
|
||||
## Implemented: the PC and boxes
|
||||
|
||||
- `TileCollisionStdScripts` is read from the ROM, so facing a `COLL_PC` tile (in any direction, as in the original) runs `PCScript`. Bookshelves, TVs and similar tiles no longer need the player to face up.
|
||||
- `PokemonCenterPC` checks for a Pokémon, then lists the PCs from `PokemonCenterPC.WhichPC`: Bill's PC and the player's PC, plus Oak's PC once the Pokédex is owned. The Hall of Fame PC is refused, since no Hall of Fame entry can exist yet.
|
||||
- Bill's PC: deposit (`BillsPC_CheckMail_PreventBlackout` keeps the last Pokémon and the last one that has not fainted; `RestorePPOfDepositedPokemon`), withdraw (`CalcLevel`, then `CalcMonStats` with stat experience, full HP and no status), release with confirmation ("Bye," with the species name), and change box: switch with the ROM's confirmation, name (a blank name keeps the old one) and print (only the empty-box message). Menus and messages come from the ROM; lists are presented natively with each Pokémon's level or each box's count.
|
||||
- `PokemonCenterPC` checks for a Pokémon, then lists the PCs from `PokemonCenterPC.WhichPC`: Bill's PC and the player's PC, plus Oak's PC once the Pokédex is owned. The Hall of Fame PC joins them once a team is recorded (see the Hall of Fame PC increment below).
|
||||
- Bill's PC: deposit (`BillsPC_CheckMail_PreventBlackout` keeps the last Pokémon and the last one that has not fainted; `RestorePPOfDepositedPokemon`), withdraw (`CalcLevel`, then `CalcMonStats` with stat experience, full HP and no status), release with confirmation ("Bye," with the species name), and change box: switch with the ROM's confirmation, name (a blank name keeps the old one) and print (the empty-box message, or the absent printer's error since the printer increment below). Menus and messages come from the ROM; lists are presented natively with each Pokémon's level or each box's count.
|
||||
- The player's PC withdraws, deposits (from every pocket; untossable items move one at a time) and tosses items (up to 50 stacks, `RemoveItemFromPocket` slot rules), and holds MAIL since the remaining field items section. The house PC adds DECORATION, which closes the PC after a change.
|
||||
- Oak's PC rates the Pokédex from `OakRatings`.
|
||||
- Capture with a full party runs `SendMonIntoBox`: the Pokémon goes first in the current box, with restored PP and `SetBoxMonCaughtData`, can be nicknamed and shows `BallSentToPCText`. If the box is already full the ball is not used (`Ball_BoxIsFullMessage`). A catch that fills the box sets `BATTLERESULT_BOX_FULL`; `reloadmapafterbattle` then queues Bill's call (`Script_SpecialBillCall`) as a memory script that runs at the next `PlayerEvents` and is not saved, as in the original.
|
||||
@@ -234,7 +234,7 @@ The numbered sections below keep their full scope. Each one opens with a checkli
|
||||
- `DisplayDexEntry` shows the name, category and number of every seen Pokémon. The height, weight and page text appear only once it is caught; otherwise `.Height` and `.Weight` keep their question marks. The picture takes the species' palette, and the footprint comes from `Footprints`. Left and right move the arrow over PAGE, AREA, CRY and PRNT without wrapping. A on PAGE turns the page. Up and down step to the previous or next seen Pokémon, back on page 1 with the arrow on PAGE. B returns to the list where the entries left the cursor.
|
||||
- The Pokédex tab reads the loaded game's state. It lists New mode's order up to the last seen Pokémon and shows a selected entry with the same rules: unseen Pokémon stay unnamed, and uncaught ones show no measurements or text. Without a ROM or before the Pokédex is received, it says so.
|
||||
- `tests/pokedex.test.ts` compares the order, all 251 entries and every footprint with the pinned PRET source.
|
||||
- Not ported: AREA (`Pokedex_GetArea`), CRY (no audio), PRNT (no printer), the option screen (SELECT), the search screen (START), Old and A to Z modes (`wLastDexMode` stays New), Unown mode and the arrow's blink. Screens are native; the strings, entries and graphics come from the ROM.
|
||||
- Not ported: AREA (`Pokedex_GetArea`), CRY (no audio), PRNT (no printer; it now shows the absent printer's error, see below), the option screen (SELECT), the search screen (START), Old and A to Z modes (`wLastDexMode` stays New), Unown mode and the arrow's blink. Screens are native; the strings, entries and graphics come from the ROM.
|
||||
|
||||
## Implemented: the region atlas
|
||||
|
||||
@@ -294,14 +294,14 @@ The numbered sections below keep their full scope. Each one opens with a checkli
|
||||
- The Old, Good and Super Rods fish facing water, never while surfing (Oak objects otherwise; the facing tile may hold an object, as in the original). The map header's fish group decides: none gives "Not even a nibble!" at once; otherwise `Fish` bites below 50% + 1 and picks the rod's `FishGroups` entry, with `TimeFishGroups` for the morning and day or the night. The player casts with the fishing frames (`LoadFishingGFX`'s body and rod tiles), jiggles four times on a bite, shows "!", and after "Oh! A bite!" puts the rod away before a `BATTLETYPE_FISH` battle: "The hooked MAGIKARP attacked!". Qwilfish and Remoraid swarms come from trainer calls, which are not ported. New Bark Town, Route 30 and Cherrygrove City have fish.
|
||||
- In the start menu's pack, Select marks an item and asks "Where should this be moved to?"; A or Select on another row of the same pocket moves it there (the rows between shift), merging it into a stack of the same item unless either holds 99 (what exceeds 99 stays behind), and B ends the move without leaving the pack. Left and right keep the pocket meanwhile. The packs that GIVE and the PC open ignore Select, as `DepositSellPack` does.
|
||||
- On the MOVE screen, left and right show the previous or next party member's moves, skipping Eggs (`MoveScreenLoop`'s `.cycle_left` and `.cycle_right`, which come back to the same Pokémon past either end), with the cursor back on the first move; not while a move is being moved. The party menu's cursor follows.
|
||||
- MAIL: giving MAIL (from the pack, or swapped for a held item) opens the mail entry, two lines of up to 16 characters with the second after a full first one (`_ComposeMailMessage`), and keeps the message with the player's name and ID, the holder's species and the MAIL (`ComposeMailMessage`). A Pokémon holding MAIL shows MAIL in its submenu: READ shows the letter (the message and the author; the stationery's graphics are not drawn yet), TAKE asks "Send the removed MAIL to your PC?" (`SendMailToPC`: up to ten in the MAILBOX, else "Your PC's MAILBOX is full."), or on NO "The MAIL will lose its message. OK?" and puts the item in the pack. SWITCH carries the MAIL with its Pokémon; another item still needs "Please remove the MAIL first."; Bill's PC refuses to deposit or release a Pokémon holding MAIL ("Remove MAIL."). The player's PC MAIL BOX lists the MAIL by author with READ MAIL, PUT IN PACK (the message is lost) and ATTACH MAIL (not to an Egg or a Pokémon holding an item). The mail entry offers the original's characters that have one of their own; `<PK>`, `<MN>`, `<PO>`, `<KE>` and the 'd-'v ligatures are left out. Save format 3 gained each Pokémon's `mail` and the `mailbox`, migrated by absence to none.
|
||||
- MAIL: giving MAIL (from the pack, or swapped for a held item) opens the mail entry, two lines of up to 16 characters with the second after a full first one (`_ComposeMailMessage`), and keeps the message with the player's name and ID, the holder's species and the MAIL (`ComposeMailMessage`). A Pokémon holding MAIL shows MAIL in its submenu: READ shows the letter with its ROM stationery and the Portrait MAIL picture, TAKE asks "Send the removed MAIL to your PC?" (`SendMailToPC`: up to ten in the MAILBOX, else "Your PC's MAILBOX is full."), or on NO "The MAIL will lose its message. OK?" and puts the item in the pack. SWITCH carries the MAIL with its Pokémon; another item still needs "Please remove the MAIL first."; Bill's PC refuses to deposit or release a Pokémon holding MAIL ("Remove MAIL."). The player's PC MAIL BOX lists the MAIL by author with READ MAIL, PUT IN PACK (the message is lost) and ATTACH MAIL (not to an Egg or a Pokémon holding an item). The mail entry offers the original's characters that have one of their own; `<PK>`, `<MN>`, `<PO>`, `<KE>` and the 'd-'v ligatures are left out. Save format 3 gained each Pokémon's `mail` and the `mailbox`, migrated by absence to none.
|
||||
- Wild Magikarp now battle: `LoadEnemyMon` draws their DVs again as the original does, through `CalcMagikarpLength` (compared with the original routine) and its filters, whose millimetre limits only work as a floor of four feet that about 39% of draws skip (39 percent + 1), nowhere in map group 9 or on maps numbered 6 (the Lake of Rage check). Unown are still refused.
|
||||
- Save format 3 gained `repel`, `coins` and `blueCardBalance`, migrated by absence to 0.
|
||||
|
||||
## Implemented: multi-hit and special-damage moves
|
||||
|
||||
- Multi-hit moves loop as `BattleCommand_EndLoop` does: back to the script's `critical`, so accuracy is checked once; two to five hits (a second draw above two), two for Double Kick, Bonemerang and Twineedle, one to three kicks for Triple Kick with growing damage (its count lives in `wBattleAnimParam`). "Hit n times!" reads the high byte of the user's `wDamageTaken`, which the loop borrows; effectiveness is said on the first hit only. A target that faints mid-loop ends the move without the count.
|
||||
- Beat Up hits once per party member that is neither fainted nor statused, with its base Attack and level against the target's base Defense. The original's bugs are kept: the player's active member is recognised by comparing `wCurBattleMon` with the HP's low byte, a lone Pokémon skips King's Rock, and a wild user says "But it failed!" after hitting. A party with an Egg is refused until eggs exist.
|
||||
- Beat Up hits once per party member that is neither fainted nor statused, with its base Attack and level against the target's base Defense. The original's bugs are kept: the player's active member is recognised by comparing `wCurBattleMon` with the HP's low byte, a lone Pokémon skips King's Rock, and a wild user says "But it failed!" after hitting. Eggs follow their stored HP and status too: the routine never reads the EGG marker.
|
||||
- `ConstantDamage`: Seismic Toss and Night Shade (the level), Sonicboom and Dragon Rage, Psywave (below 1.5 × level; a level-1 user is refused, as the original loops forever), Super Fang and Flail/Reversal (HP bar pixels into `FlailReversalPower`, then the move's power becomes 1). Immune types make them miss (`ResetTypeMatchup`).
|
||||
- One-hit KO moves, Counter and Mirror Coat (twice the opponent's last physical or special damage when it moved first, still working after the opponent used an item), False Swipe, Magnitude, Present (a full target refuses the gift, said only with battle animations off), Hidden Power, Return and Frustration (no damage at the extremes of happiness, a kept bug), Selfdestruct and Explosion, Dream Eater, Thief (not MAIL; a trainer's Pokémon keeps the player's item), Pay Day (paid out after a win, doubled by an Amulet Coin, which is now checked at every send-out), freezing, Tri Attack, added confusion, Swagger, Flame Wheel and Sacred Fire thawing their user, fire moves thawing their target, Jump Kick's crash damage, Minimize with Stomp's double damage, Earthquake against a digging target and Thunder's weather accuracy.
|
||||
- A Focus Band now hangs on at 1 HP even when the hit would only take that 1 HP, and cancels a one-hit KO's text.
|
||||
@@ -367,7 +367,7 @@ The numbered sections below keep their full scope. Each one opens with a checkli
|
||||
|
||||
- Route 31 and its Violet gate, Dark Cave's Violet entrance, Violet City with its Mart, gym, Earl's Pokémon Academy, the nickname speech house, the Pokémon Center and Kyle's house, and Sprout Tower's three floors are open, with their scripts, trainers, items, fruit trees and encounters. Route 32, Route 36, Dark Cave's other entrances and the Pokémon Center's second floor stay closed.
|
||||
- New script commands: `gettrainername`, `askforphonenumber` (AddPhoneNumber keeps room for Mom and Elm; `addcellnum` now reports failure as the original does), `checkpokemail`, `loadmenu`/`_2dmenu`/`closewindow` (Earl's blackboard, shown as a list), `giveegg`, `trade` (NPCTrade with saved `wTradeFlags`), `loadvar VAR_CALLERID` and the `RandomPhoneMon` special. The trade animation is not presented.
|
||||
- Eggs keep their species with an `egg` flag, as `wPartySpecies` holds EGG: the party menu shows no level or HP, the stats screen shows the Egg page with its hatching hint, healing skips them, and `checkpoke` does not count them. Eggs do not hatch yet (board #29).
|
||||
- Eggs keep their species with an `egg` flag, as `wPartySpecies` holds EGG: the party menu shows no level or HP, the stats screen shows the Egg page with its hatching hint, healing skips them, and `checkpoke` does not count them. Eggs now hatch through the walking routine described below.
|
||||
- The pack's TM/HM pocket holds counts by number: TMs and HMs are received, listed with their moves, given (TMs) and taught with ABLE/NOT ABLE, the compatibility and "already knows" checks and LearnMove. A TM is used up and makes the Pokémon happier; an HM stays.
|
||||
- The Johto badges raise the battle Pokémon's stats (BadgeStatBoosts, with the PlainBadge/MineralBadge swap and the Glacier Badge register bug), compared against the unmodified routine for all 256 badge bytes in `tests/reference-badges.spec.ts`.
|
||||
- `tests/playthrough.test.ts` now continues to Route 31 (Mom's call), Sprout Tower (Elder Li's Flash), Falkner (the ZEPHYRBADGE, TM31 and the aide's call), the Togepi Egg, Kyle's Onix, Flash in Dark Cave, Wade's number and Earl's blackboard. `tests/violet.test.ts` covers the other answers.
|
||||
@@ -383,7 +383,7 @@ The numbered sections below keep their full scope. Each one opens with a checkli
|
||||
- The chamber puzzles (`_UnownPuzzle`) run as a tile screen with the ROM's graphics: the random border layout, the cursor's moves around START/CANCEL, picking up and placing pieces, the solved check, then the chamber's floor opens and the player falls into the inner chamber. The wall patterns (`DisplayUnownWords`) draw their word in Unown letters from the chamber's tileset in a menu box over the map. `HoOhChamber` and `OmanyteChamber` open their walls.
|
||||
- Tile screens are a general effect for minigames and specials that draw a whole Game Boy screen in tiles (`scripts/screen.ts`, `rendering/tile-screen.ts`): a tilemap with palettes and sprites, answered with buttons. `rom/font.ts` supplies the standard font and the chosen textbox frame for them.
|
||||
- `tests/playthrough.test.ts` continues through Route 32, Union Cave, Azalea Town, the Slowpoke Well, Bugsy, the rival and Ilex Forest to the Route 34 gate; its helpers now live in `tests/playthrough-driver.ts`, and `PLAYTHROUGH_SAVES` keeps each stage's save. `tests/ruins.test.ts` solves the Kabuto puzzle through the world and catches Unown; `tests/azalea.test.ts` covers Kurt's apricorns.
|
||||
- Still closed or refused here: the Day-Care's deposits and Eggs (board #29), the radios' `MapRadio` and trainers' rematch counts (board #30), the research center's `UnownPrinter` (it needs all 26 letters), the Pokédex's Unown mode, the GS Ball and Celebi shrine (not reachable without the mobile event), and sound.
|
||||
- Still closed or refused here: the radios' `MapRadio` and trainers' rematch counts (board #30), the research center's `UnownPrinter` (it needs all 26 letters), the Pokédex's Unown mode, the GS Ball and Celebi shrine (not reachable without the mobile event), and sound.
|
||||
|
||||
## Implemented: Goldenrod City (board #32, increment B)
|
||||
|
||||
@@ -447,9 +447,9 @@ The numbered sections below keep their full scope. Each one opens with a checkli
|
||||
## Implemented: Tin Tower and Whirl Islands (board #32, increment G)
|
||||
|
||||
- Tin Tower's nine floors and roof and the Whirl Islands' eight maps are open. The Clear Bell lets the player past the entrance's sages and through the Wise Trio's room; in Tin Tower 1F Raikou and Entei flee unless caught, and Suicune battles (`BATTLETYPE_SUICUNE`), followed by Eusine.
|
||||
- New specials (`game/scripts/tin-tower.ts`): `MonCheck` and `BeastsCheck` over `CheckOwnMonAnywhere`: the party and every box, the player's ID and the first five letters of the OT, an empty party finding nothing, the Day-Care left out. After the League with all three beasts, the second Wise Trio appears and gives the Rainbow Wing; its stairs lead up to Ho-Oh on the roof. Lugia waits at the bottom of the Whirl Islands for a player with the Silver Wing. Both battles use `BATTLETYPE_FORCEITEM`.
|
||||
- New specials (`game/scripts/tin-tower.ts`): `MonCheck` and `BeastsCheck` over `CheckOwnMonAnywhere`: the party and every box, the player's ID and the first five letters of the OT, an empty party finding nothing, the Day-Care omitted by the original's documented bug. After the League with all three beasts, the second Wise Trio appears and gives the Rainbow Wing; its stairs lead up to Ho-Oh on the roof. Lugia waits at the bottom of the Whirl Islands for a player with the Silver Wing. Both battles use `BATTLETYPE_FORCEITEM`.
|
||||
- The playthrough driver plans ledge jumps (for the later stages only, so the earlier seeded stages keep their recorded paths), waterfalls carrying a surfer down, warp panels landing elsewhere on a map, and Surf and Whirlpool between warps in `travel`. Tests: `tests/tin-tower.test.ts` (MonCheck's rules, the Rainbow Wing and the climb to Ho-Oh, the Whirl Islands to Lugia). The playthrough continues for two more stages: Routes 45 and 46 back to Ecruteak, and Tin Tower's Suicune.
|
||||
- Remaining: the Battle Tower (increment H below), Olivine's port and the S.S. Aqua (board #33), radio and rematches (#30), breeding (#29), mobile and link features, and audio. `CheckOwnMonAnywhere` in the original also reads the current box's own SRAM copy, which can be stale; the port keeps no stale copy.
|
||||
- Remaining: the Battle Tower (increment H below), Olivine's port and the S.S. Aqua (board #33), radio and rematches (#30), breeding (#29), mobile and link features, and audio. `CheckOwnMonAnywhere` searches the current box and skips its numbered SRAM copy; the port searches each logical box once.
|
||||
|
||||
## Implemented: the Battle Tower (board #32, increment H)
|
||||
|
||||
@@ -492,6 +492,33 @@ The numbered sections below keep their full scope. Each one opens with a checkli
|
||||
- Import preview (`previewImport`) checks the envelope, cartridge, player, base64 and the game state in a scratch world (`NativeRuntime.inspectState`) before anything changes, and shows the trainer and ID, place, play time, badges, caught count, saved time, the game data version (and its upgrade) and the slots of the same trainer, marking one with identical progress. The player adds the backup as a new save or replaces the running save or a conflicting one; a replaced slot keeps its previous record.
|
||||
- Tests: `tests/save-slots.test.ts` (migration once, a newer singleton kept, slot lifecycle, autosave isolation, recovery from a damaged or missing newest record, an interrupted write, rollback when a slot cannot be opened, rejected imports, conflicts and both import targets), `tests/native.test.ts` (`describe` on saves of schema 1, 2 and 3) and `tests/save-slots-browser.spec.ts` (the migration and every Savegames action in Chromium and WebKit).
|
||||
|
||||
## Implemented: MAIL stationery and printer cancellation
|
||||
|
||||
- `ReadAnyMail` now draws all ten stationery types from the ROM, including their color planes, palettes, message/author positions and the mirrored Portrait MAIL picture (Unown A). A/B return; Start opens printing, and B cancels back to the unchanged letter. The accessible message and author remain available with the canvas.
|
||||
- Nonempty Bill's PC boxes, Pokédex PRNT, MAIL and the Photo Studio share `SendScreenToPrinter`'s absent-printer result (`PRINTER_ERROR_2`). A does not dismiss the error; B cancels. Empty boxes still show their original refusal. The print preview, printer music and alternating link-check status are not presented. Unown stamps and the diploma remain unreachable with the unported Unown mode and Kanto maps.
|
||||
- Controlled cartridge comparisons cover all ten stationery tilemaps, used graphics, message/author placement and palettes; the font is loaded separately from ROM. Chromium and mobile WebKit checks cover writing, reading, printing and returning to MAIL. Unit checks cover the four reachable print paths and unchanged stored data.
|
||||
|
||||
## Implemented: Day-Care and breeding (board #29, egg creation)
|
||||
|
||||
- `DayCareMan`, `DayCareLady`, `DayCareAskDepositPokemon`, withdrawal pricing/text, deposits and `RetrieveBreedmon` run through the ROM map scripts. The last Pokémon, last usable Pokémon, Eggs and MAIL holders are refused; retrieval restores HP/PP, learns intervening moves and charges ¥100 plus ¥100 per gained level. The cartridge's loss of experience beyond the retrieved level is preserved.
|
||||
- `CheckBreedmonCompatibility`, `DayCare_InitBreeding`, `InitEggMoves`, `GetHeritableMoves`, `GetBreedmonMovePointer` and `DayCareStep` preserve Ditto, gender, egg-group, matching-DV and trainer-ID rules, Nidoran species selection, inherited DVs/moves, random-byte order and egg-chance thresholds. The Day-Care gains experience on counted steps. Route 34's callbacks place the man inside/outside and show deposited species using ROM party icons; its compatibility texts and egg collection/full-party/refusal paths run.
|
||||
- `GiveOddEgg` selects the ROM probability row and copies its species, DVs, moves, stats, name and OT; the Egg Ticket is consumed when held. The stored parents, prepared egg, active/compatible bits, step countdown and mother index live in version-3 saves, migrate by absence and are validated alongside the three engine flags. A refused egg follows the cartridge script's flag-clearing behavior. Tin Tower ownership deliberately continues to omit deposited Pokémon: `engine/pokemon/search_owned.asm` labels this an original bug.
|
||||
- Validation: 47 Day-Care unit cases plus the Tin Tower ownership regression; the full unit suite passes 916 tests (three skipped), with typecheck and pinned reference-address verification passing; six Chromium reference checks compare compatibility, level growth, egg construction, step experience/chance, retrieval and Odd Egg results, including RNG-byte consumption. These execute the cartridge routines with only Random replaced by controlled bytes. They do not establish frame-perfect keeper UI/audio or fence-sprite OAM/palette parity. Hatching and the full `CountStep` sequence follow below.
|
||||
|
||||
## Implemented: walking counters and Egg hatching
|
||||
|
||||
- `CountStep` runs after coordinate events and before random encounters. Special calls and an expired Repel consume the step event first. The saved byte counter wraps every 256 steps; `StepHappiness` increases non-Egg happiness on alternate wraps (512 steps), saturating at 255. At byte 128, `DoEggStep` decrements Eggs in order and stops at the first reaching zero; an already-zero byte wraps to 255. `DoBikeStep` counts eligible Bicycle steps and queues the Bike Shop call from 1024 steps. `DayCareStep` follows the Egg check, as in the original, so the step that starts a hatch gives the Day-Care nothing; overworld poison damage/fainting remains unported.
|
||||
- `HatchEggs` hatches every zero-cycle Egg in party order on a script draft: happiness 120, caught time/place at level 1, full recalculated HP, cleared status, player OT/ID, seen/caught registration, Togepi's event, and the ROM nickname question. Mid-hatch saves rewind the triggering tile and counters; failed presentation restores the step and party. Save format 3 gained `stepCount`, `poisonStepCount`, `happinessStepCount`, `bikeStep`, defaulting to zero in older saves.
|
||||
- The ROM's Egg and hatchling pictures, palettes, 344 wobble frames, three cracks and ten shell fragments run on a realtime tile screen. Horizontal scrolling extends the existing screen renderer. `tests/reference-hatching.spec.ts` checks all wobble OAM/tilemap/attribute/scroll frames, shell OAM states and normal Togepi/shiny Pichu palettes against the original. Object palettes 0/1 remain the overworld colors, as `_CGB_Evolution` only reloads 2–7. Hardware loading waits and the final species-specific `AnimateFrontpic` are not reproduced; the hatchling holds its base frame and cries. A hypothetical Unown Egg uses letter A rather than the original's stale battle-DV letter bug.
|
||||
- `tests/egg-hatching.test.ts` covers byte rules, 512-step happiness, walking Togepi cycles, multiple Eggs, caught data, naming, mid-hatch replay, rollback, expired Repel and migration; Beat Up tests include Eggs. The continuous playthrough now waits through realtime screens and hatches Togepi naturally. No physical-device or listening validation.
|
||||
|
||||
## Implemented: the Hall of Fame PC (board #29)
|
||||
|
||||
- `wHallOfFameCount` and `sHallOfFame` are saved as `hallOfFameCount` and `hallOfFameTeams` (newest first, at most 30 teams of up to six Pokémon with species, ID, DVs, level and nickname), migrated by absence to none and validated against each other. They are separate from `hallOfFame` (`STATUSFLAGS_HALL_OF_FAME_F`), which the Battle Tower, radio, Pokégear and marts read.
|
||||
- `GetHallOfFameParty` (Eggs left out) and `AddHallOfFameEntry` (the oldest of 30 teams drops off, the count stops at 200) are ported as `addHallOfFameEntry`, but nothing calls it until the League's ceremony is ported.
|
||||
- `PokemonCenterPC.ChooseWhichPCListToUse` picks `PCPC_POSTGAME` from the count, as the original does, so HALL OF FAME appears once a team is recorded. `_HallOfFamePC`, `LoadHOFTeam` and `DisplayHOFMon` show each Pokémon's page with its cry: A shows the next Pokémon, then the next team; Start skips to the next team; B returns to the PC. The original's unreachable "HOF Master!" title (it needs a count of 201) is kept.
|
||||
- `tests/reference-hall-of-fame.spec.ts` writes 255 teams (every species, Unown, level 100, the Nidorans, win 200, all eight frames) into the cartridge's SRAM, runs its `_HallOfFamePC`, and compares the tilemap, attributes, graphics and palette with the port's page. `HOF_AnimateFrontpic` is the one routine stubbed: the port shows the picture at rest, without the `ANIM_MON_HOF` animation. `tests/hall-of-fame.test.ts` covers the records, the PC menu with and without them, browsing, and save, reload and migration.
|
||||
|
||||
## 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. Every ball can be thrown; only the contest's Park Ball handling remains.
|
||||
@@ -585,7 +612,7 @@ Acceptance: finish the opening quest, including encounters and the rival battle,
|
||||
- [x] Pokémon Center healing, standard Poké Marts and Reflect/Light Screen
|
||||
- [x] Remaining battle commands, move and item effects, AI layers and special battles (board #28)
|
||||
- [x] Evolution by level, happiness, Tyrogue's stats and stones, with Rare Candy and vitamins (trade evolutions need Link)
|
||||
- [ ] Breeding, eggs and the rest of PC storage
|
||||
- [x] Breeding, eggs and the rest of PC storage (board #29)
|
||||
- [ ] Field moves, gyms, Rocket events, the phone and Pokégear, puzzles, minigames, daily events, roaming Pokémon and the postgame
|
||||
- [x] Johto beyond Route 30: every city, gym, Rocket event, puzzle and minigame to the Rising Badge, Tin Tower, Whirl Islands and the Battle Tower
|
||||
- [ ] The League, Kanto and the final battle
|
||||
|
||||
Reference in new issue
Block a user