Port the remaining battle items, the stats screen and hBattleTurn at the menu

- Run every non-ball item effect usable in battle from the ROM's
  ItemEffects: Full Restore, revives, bitter medicine, Bitter Berry, Ethers
  and Elixers, X items, X Accuracy, Guard Spec, Dire Hit and Poké Doll.
- Read happiness changes from HappinessChanges, including the larger
  level-up gain where a Pokémon was caught.
- Model hBattleTurn at the battle menu, including the trainer AI's writes,
  and drop the status-heal refusal.
- Port the stats screen for battles and Bill's PC.
- Compare the send-out and withdraw texts, RestoreHealth, RestorePP,
  ChangeHappiness and CalcPlayerStats with the original routines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sébastien QUEROLandClaude Opus 5.5 committed 2026-09-30 11:24:55 +02:00
1 parent cfd083c16d
commit b13e09ec20
22 files changed
+1547 -171

No files matched your search

+28 -1
View File
@@ -229,7 +229,7 @@ test("battle PKMN switches through the party menu and its submenu, then shares t
await expect(menu.getByRole("button", { name: /^CYNDAQUIL/ })).toBeVisible();
await menu.getByRole("button", { name: /^TOTODILE/ }).click();
// BattleMonMenu: B returns to the party list.
await expect(menu.getByRole("button", { name: "STATS", exact: true })).toBeDisabled();
await expect(menu.getByRole("button", { name: "STATS", exact: true })).toBeEnabled();
await page.keyboard.press("KeyZ");
await menu.getByRole("button", { name: /^TOTODILE/ }).click();
await menu.getByRole("button", { name: "SWITCH", exact: true }).click();
@@ -273,3 +273,30 @@ test("battle PACK uses a Potion from the Items pocket on the Pokémon out", asyn
const { state } = await exportState(page);
expect(state.bag.items).toEqual([]);
});
test("battle PKMN STATS shows the stats screen's three pages and returns with B", async ({ page }) => {
await start(page, "switch");
const menu = page.locator("#battle-menu");
for (let tick = 0; tick < 10 && !(await menu.getByRole("button", { name: "PKMN", exact: true }).count()); tick++) {
if (await menu.getByRole("button", { name: /Continue/ }).count()) await page.keyboard.press("KeyX");
await page.clock.runFor(1200);
}
await menu.getByRole("button", { name: "PKMN", exact: true }).click();
await menu.getByRole("button", { name: /^TOTODILE/ }).click();
await menu.getByRole("button", { name: "STATS", exact: true }).click();
const stats = page.locator("#stats-screen");
await expect(stats).toBeVisible();
await expect(page.locator("#stats-header")).toContainText("№.158");
await expect(page.locator("#stats-header")).toContainText("/TOTODILE");
await expect(page.locator("#stats-page")).toContainText("WATER");
await expect(page.locator("#stats-page")).toContainText("EXP POINTS");
await page.keyboard.press("ArrowRight");
await expect(page.locator("#stats-page")).toContainText("SCRATCH");
await page.locator("#stats-next").click();
await expect(page.locator("#stats-page")).toContainText("SPCL.ATK");
await expect(page.locator("#stats-page")).toContainText("OT/");
await page.keyboard.press("KeyZ");
await expect(stats).toBeHidden();
// BattleMenuPKMN_ReturnFromStats: back to the party menu.
await expect(menu.getByRole("button", { name: /^CYNDAQUIL/ })).toBeVisible();
});