Port the special battle types and contest battles
Checks / web (push) Canceled after 0s

Run the forced-shiny, trap, forced-item, Celebi, Suicune, roaming and Bug-Catching Contest battle types. Roaming battles keep their struct's DVs and HP byte, and every other battle makes CleanUpBattleRAM's roaming roll. The contest shows PARKBALL×, counts down Park Balls, ends when they run out, keeps its catch outside the party and asks before switching. Scripts load the special types with loadvar, and while a contest runs, encounters use BugCatchingContestBattleScript and ContestMons.

Validated with 596 unit tests, 155 browser tests (including the contest menu and switch screen), native/reference builds and reference/vendor/release checks. National Park's contest event, the roaming release and the Ilex Forest Celebi event come with their maps.

Closes #28

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 15:56:30 +02:00
1 parent b547ca29ff
commit 8fae1f0c0f
15 files changed
+787 -42

No files matched your search

+31
View File
@@ -1276,3 +1276,34 @@ Next on #28: the Bug-Catching Contest battle type (Park Ball count,
`BugContest_SetCaughtContestMon`) and the other special battle types.
Neither is reachable yet: National Park and the legendary encounters
are not enabled.
## Special battle types: 2026-10-03
Same session; finishes card #28.
- `BattleOptions.battleType` takes FORCESHINY, TRAP, FORCEITEM, CELEBI,
SUICUNE, CONTEST (with `contest`) and ROAMING (with `roamer`); invalid
combinations raise `UnsupportedBattle` before any draw. `loadvar
VAR_BATTLETYPE` passes the script-set ones; CleanUpBattleRAM's clear
follows `startbattle`.
- `run()` ends with `BattleEnd_HandleRoamMons`: one extra BattleRandom
after every non-roaming battle (`updateRoamMons` in the outcome). The
world ignores the flag until roaming Pokémon exist.
- Contest: `{ kind: "action", parkBalls }` drives the PARKBALL× button;
`{ kind: "contestswitch" }` is answered like Yes/No (world, keyboard and
DOM). `ScriptState.bugContest` is runtime-only (not saved);
`readmem wParkBallsRemaining` reads it. The fixture scenario `contest`
covers it in `tests/battle-world.test.ts` and
`tests/battle-browser.spec.ts`. The browser test found that the switch
text was missing from the text box; it is fixed.
- `tests/battle-types.test.ts` covers each type with the local ROM, plus
a synthetic `loadvar` script.
Validation: 596 unit tests passed (3 skipped); without the ROM 141 passed,
458 skipped. Browser suite: 155 passed, 19 skipped. Both builds,
reference/release/vendor checks and `git diff --check` passed.
Left for the map cards: National Park's contest event (GiveParkBalls,
timer, out-of-balls/time-up scripts, judging, saving the contest state),
Burned Tower's roaming release with UpdateRoamMons/JumpRoamMons and
roaming encounters, and Ilex Forest's CelebiShrineEvent/CheckCaughtCelebi.