Open Routes 35 to 37, the National Park and Ecruteak to the Fog Badge (#32)
Enable Route 35, Route 36, Route 37, the National Park and its gates, Ecruteak City and its buildings, the Tin Tower entrance, the Wise Trio's room and both floors of the Burned Tower. The story runs from Floria, the SquirtBottle and Sudowoodo through the Kimono Girls' HM03 Surf, the rival in the Burned Tower and the beasts' release to Ecruteak Gym, Morty, the FOGBADGE and TM30. Port roaming Pokémon (InitRoamMons, UpdateRoamMons, JumpRoamMons, CheckEncounterRoamMon) with their state in the save; only Continue moves them on restore, so a failed import's rollback keeps them in place. Port the Bug-Catching Contest: registration on contest days, Park Balls, contestants, the timer, QUIT, the catch-and-swap prompt, judging from the ROM's contestant table, prizes and the saved contest state. Port the Game Corner's SlotMachine and CardFlip on a new realtime tile screen that advances two frames per tick with buffered buttons: reel strips and scrolling, bias tables, the seven streak, Golem and Chansey, payouts, the Card Flip board, cursor and navigation. Their tilemaps are checked against the ROM's own data. Also port getnum, a plain warp that continues its script on the new map, and PokemonNames' EGG entry. A trainer whose script is ObjectEvent (the Burned Tower rival) is no longer sighted once its own flag is set, as the original's read of bit 1 of wNumKeyItems gives with the usual key items. The playthrough walks through the National Park and continues to Morty; its driver chooses moves by type matchup, buys at Marts and uses Super Potions and Awakenings in trainer battles. New tests cover roaming, the contest, the Game Corner and Ecruteak's side content. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0930b780fc
commit
2640fa2725
31 files changed
+4743
-91
No files matched your search
@@ -4,7 +4,7 @@ import { CrystalAssets } from "../src/game/rom/assets";
|
||||
import { battleFixtureWorld, ENCOUNTER_WALK, type BattleScenario } from "./battle-fixture";
|
||||
import type { GameWorld } from "../src/game/world/world";
|
||||
import { generatePartyMon, calcStats } from "../src/game/party/pokemon";
|
||||
import { withoutPlayTime } from "./world-driver";
|
||||
import { afterRestore, withoutPlayTime } from "./world-driver";
|
||||
|
||||
const romPath = process.env.CRYSTAL_ROM_PATH ?? "Pokemon - Crystal Version (UE) (V1.1) [C][!].gbc";
|
||||
const fixture = (scenario: BattleScenario = "win") =>
|
||||
@@ -95,7 +95,8 @@ describe.skipIf(!existsSync(romPath))("world battle integration with the local R
|
||||
expect(world.state.pokedex.caught.has(16)).toBe(false);
|
||||
const saved = world.save();
|
||||
world.restore(saved);
|
||||
expect(world.save()).toEqual(saved);
|
||||
const reloaded = world.save();
|
||||
expect(reloaded).toEqual(afterRestore(saved, reloaded));
|
||||
});
|
||||
|
||||
it("evolves a Pokémon that levelled up once the battle is won", () => {
|
||||
@@ -118,7 +119,8 @@ describe.skipIf(!existsSync(romPath))("world battle integration with the local R
|
||||
expect(world.state.pokedex.caught.has(156)).toBe(true);
|
||||
const saved = world.save();
|
||||
world.restore(saved);
|
||||
expect(world.save()).toEqual(saved);
|
||||
const reloaded = world.save();
|
||||
expect(reloaded).toEqual(afterRestore(saved, reloaded));
|
||||
});
|
||||
|
||||
it("considers only the Pokémon that levelled up (wEvolvableFlags)", () => {
|
||||
@@ -174,7 +176,8 @@ describe.skipIf(!existsSync(romPath))("world battle integration with the local R
|
||||
expect(saved.party[0].statExp.some((value) => value > 0)).toBe(true);
|
||||
expect(saved.party[0].stats).not.toEqual(calcStats(world.assets.pokemon, 155, mon.dvs, 100, saved.party[0].statExp));
|
||||
expect(() => world.restore(saved)).not.toThrow();
|
||||
expect(world.save()).toEqual(saved);
|
||||
const reloaded = world.save();
|
||||
expect(reloaded).toEqual(afterRestore(saved, reloaded));
|
||||
const corrupt = structuredClone(saved);
|
||||
corrupt.party[0].stats[1] = 999;
|
||||
expect(() => world.restore(corrupt)).toThrow("Invalid native save");
|
||||
@@ -208,7 +211,8 @@ describe.skipIf(!existsSync(romPath))("world battle integration with the local R
|
||||
expect(withoutPlayTime(world.save())).toEqual(withoutPlayTime(committed));
|
||||
world.restore(committed);
|
||||
expect(world.battle).toBeUndefined();
|
||||
expect(world.save()).toEqual(committed);
|
||||
const reloaded = world.save();
|
||||
expect(reloaded).toEqual(afterRestore(committed, reloaded));
|
||||
expect(world.move("right")).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user