Open Route 29 and Cherrygrove City
Checks / web (push) Canceled after 0s

- Enable Route 29, its Route 46 gate, Cherrygrove City and its buildings.
- Run item balls through FindItemInBallScript and fruit trees through
  FruitTreeScript, with a native daily reset of the daily engine flags.
- Port the Pokémon Center nurse (HealParty with the PP Up clamp,
  CheckPokerus, phone-call checks) and record the whiteout spawn on
  entering a Pokémon Center, as EnterMapWarp does.
- Port standard Poké Marts with keyboard, D-pad and pointer menus.
- Add the recoil battle command (Struggle) and VAR_BOXSPACE.
- Save fruit trees, the daily reset day and the last spawn map; older
  version-3 backups migrate by absence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sébastien QUEROLandClaude Opus 5.5 committed 2026-09-23 17:25:02 +02:00
1 parent 11d1153802
commit 796fe8f6d5
24 files changed
+1549 -59

No files matched your search

+47
View File
@@ -40,6 +40,7 @@ export const SYMBOLS = {
giveItemScript: 0x96f77,
putItemInPocketText: 0x9705b,
pocketIsFullText: 0x97060,
findItemInBallScript: 0x122ce,
caughtAskNicknameText: 0x4db44,
nicknameStrings: 0x11780,
wildBattleScript: 0x97cf9,
@@ -48,6 +49,22 @@ export const SYMBOLS = {
johtoGrassWildMons: 0x2a5e9,
grassMonProbTable: 0x2a1cb,
grassCollisions: 0x149ea,
fruitTreeScript: 0x44000,
fruitTreeItems: 0x44097,
engineFlags: 0x80462,
marts: 0x160a9,
martWelcomeText: 0x15f83,
martAskMoreText: 0x15fb9,
martComeAgainText: 0x15fb4,
martHowManyText: 0x15e0e,
martFinalPriceText: 0x15e13,
martNoMoneyText: 0x15fa5,
martPackFullText: 0x15faa,
martThanksText: 0x15fa0,
martCantBuyText: 0x15faf,
martSellHowManyText: 0x15f73,
martSellPriceText: 0x15f78,
martBoughtText: 0x15fbe,
} as const;
/** Assembly routines that scripts `callasm` but that do nothing. */
@@ -60,6 +77,11 @@ export const EMPTY_ROUTINES = {
export const NATIVE_ROUTINES = {
halveMoney: 0x12513,
getWhiteoutSpawn: 0x12527,
tryReceiveItem: 0x122f8,
getCurTreeFruit: 0x44041,
tryResetFruitTrees: 0x4404c,
checkFruitTree: 0x44055,
pickedFruitTree: 0x4405f,
} as const;
/** Native handlers are selected by the routine a special index points to,
@@ -73,6 +95,9 @@ export const SPECIAL_ROUTINES = {
toggleMaptileDecorations: 0x26feb,
fadeOutToWhite: 0x8c084,
healParty: 0xc658,
healMachineAnim: 0x12324,
checkPokerus: 0xc419,
stubbedTrainerRankingsHealings: 0x1060a2,
warpToSpawnPoint: 0x97c28,
} as const;
@@ -90,6 +115,12 @@ export const RAM = {
enemyMonNickname: 0xc616,
curPartyLevel: 0xd143,
monOrItemNameBuffer: 0xd050,
curFruit: 0xd03f,
dailyFlags1: 0xdc1e,
unusedDailyFlag: 0xdc21,
itemQuantityChange: 0xd10c,
/** hMoneyTemp: HRAM, not WRAM like the other entries above. */
moneyTemp: 0xffc3,
} as const;
/** Event constants named directly by translated special routines. */
@@ -101,6 +132,11 @@ export const EVENTS = {
playersHouseBigDoll: 1860,
} as const;
/** Engine flag indices named directly by translated routines. */
export const ENGINE_FLAGS = {
allFruitTrees: 84,
} as const;
/** Battle engine tables and texts, keyed by their PRET labels so that
* \`npm run check:reference\` can verify each address by name. */
export const BATTLE = {
@@ -187,6 +223,7 @@ export const BATTLE = {
ProtectedByText: 0x815a9,
ProtectingItselfText: 0x8167a,
RageBuildingText: 0x810f3,
RecoilText: 0x8134d,
RecoveredUsingText: 0x80bc2,
RegainedHealthText: 0x8100c,
SafeguardProtectText: 0x81733,
@@ -217,6 +254,8 @@ export const BATTLE = {
export const MAP_GROUP_COUNT = 26;
export const NUM_POKEMON = 251;
export const NUM_ITEMS = 190;
export const NUM_ENGINE_FLAGS = 162;
export const NUM_FRUIT_TREES = 30;
/** The last group has no following pointer to bound it. */
export const LAST_MAP_GROUP_SIZE = 11;
@@ -224,11 +263,19 @@ export const LAST_MAP_GROUP_SIZE = 11;
* maps remain unavailable; the label only distinguishes interiors that share
* a ROM landmark name. */
export const NATIVE_MAPS: Record<string, string> = {
"24:3": "Route 29",
"24:13": "Route 29 gate",
"24:4": "New Bark Town",
"24:5": "Elm’s lab",
"24:6": "Your home",
"24:7": "Your room",
"24:8": "Neighbor’s house",
"24:9": "Elm’s house",
"26:3": "Cherrygrove City",
"26:4": "Poké Mart",
"26:5": "Pokémon Center",
"26:6": "Gym speech house",
"26:7": "Guide Gent’s house",
"26:8": "Evolution speech house",
};
export const INITIAL_POSITION = { map: "24:7", x: 3, y: 3 } as const;