mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-15 07:41:21 +02:00
571 lines
36 KiB
Markdown
571 lines
36 KiB
Markdown
# Section 27 - Cinnabar Island and Seafoam Islands Gym
|
|
|
|
Source: `../section-27-cinnabar-island-and-seafoam-islands-gym.txt`
|
|
(the FAQ numbers this chapter "33 > Cinnabar Island and Seafoam Islands Gym"; the
|
|
file index is 27)
|
|
|
|
Maps covered: `MAP_ROUTE_21`, `MAP_CINNABAR_ISLAND`, `MAP_CINNABAR_POKECENTER_1F`,
|
|
`MAP_ROUTE_20`, `MAP_SEAFOAM_GYM`
|
|
|
|
Badges / key milestones in this section:
|
|
|
|
- `ENGINE_FLYPOINT_CINNABAR` (set on first entry to Cinnabar Island)
|
|
- Blue's one-off speech on Cinnabar Island, which is what unlocks him in Viridian Gym
|
|
(`clearevent EVENT_VIRIDIAN_GYM_BLUE`)
|
|
- Hidden RARE_CANDY on Cinnabar Island
|
|
- `EVENT_CINNABAR_ROCKS_CLEARED` (set silently by walking onto Route 20; this is what
|
|
clears the boulders that seal Route 19 to the east)
|
|
- **VOLCANOBADGE** from BLAINE in the Seafoam Islands cave (`ENGINE_VOLCANOBADGE`,
|
|
`EVENT_BEAT_BLAINE`)
|
|
|
|
---
|
|
|
|
## 1. Route order
|
|
|
|
| # | Map constant | asm file | Enter via | Leaves via | Why (walkthrough beat) |
|
|
|---|---|---|---|---|---|
|
|
| 0 | `PALLET_TOWN` | - | - | south connection to `ROUTE_21` (`data/maps/attributes.asm:270-272`) | **Pallet Town belongs to the previous section; only the hop south is listed here.** |
|
|
| 1 | `ROUTE_21` | `maps/Route21.asm` | north connection from `PALLET_TOWN` (`data/maps/attributes.asm:274-275`) | south connection to `CINNABAR_ISLAND` (`attributes.asm:277`) | Surf south. Three trainers: Nikki, Arnold, Seth |
|
|
| 2 | `CINNABAR_ISLAND` | `maps/CinnabarIsland.asm` | north connection from `ROUTE_21` (`attributes.asm:279-280`) | warp 1 at (11,11) -> `CINNABAR_POKECENTER_1F` 1; east connection to `ROUTE_20` (`attributes.asm:281`) | Sets `ENGINE_FLYPOINT_CINNABAR`; heal; talk to Blue; hidden RARE_CANDY |
|
|
| 3 | `CINNABAR_POKECENTER_1F` | `maps/CinnabarPokecenter1F.asm` | Cinnabar warp 1 | warps 1/2 at (3,7)/(4,7) back to `CINNABAR_ISLAND` 1 | Heal; the two flavour NPCs the walkthrough quotes ("a year since the volcano erupted", "BLAINE lives alone in the SEAFOAM ISLANDS cave") |
|
|
| 4 | `ROUTE_20` | `maps/Route20.asm` | west connection from `CINNABAR_ISLAND` (`attributes.asm:283-284`) | warp 1 at (38,7) -> `SEAFOAM_GYM` 1 | `MAPCALLBACK_NEWMAP` sets `EVENT_CINNABAR_ROCKS_CLEARED`; Swimmer Cameron at (12,13) |
|
|
| 5 | `SEAFOAM_GYM` | `maps/SeafoamGym.asm` | Route 20 warp 1 | warp 1 at (5,5) back to `ROUTE_20` 1 | BLAINE -> **VOLCANOBADGE** |
|
|
|
|
Spillover: Route 20 continues east past the gym to Swimmer Lori (45,13) and Swimmer
|
|
Nicole (52,8) and then over the `connection east, Route19, ROUTE_19, -9` boundary into
|
|
Fuchsia territory; the walkthrough does not visit them here and they belong to the
|
|
following section.
|
|
|
|
---
|
|
|
|
## 2. Maps
|
|
|
|
### MAP_ROUTE_21
|
|
|
|
- Script: `maps/Route21.asm`
|
|
- Blocks: `maps/Route21.blk`
|
|
- Header: `data/maps/maps.asm:198` -> `TILESET_KANTO, ROUTE, LANDMARK_ROUTE_21, MUSIC_ROUTE_3, FALSE (phone calls allowed), PALETTE_AUTO, FISHGROUP_OCEAN`
|
|
- Dimensions: `constants/map_constants.asm:182` `map_const ROUTE_21, 10, 18` (group `CINNABAR` = 6, map id 7). 10x18 blocks = 20x36 tile coordinates.
|
|
- Attributes / border: `data/maps/attributes.asm:274` `map_attributes Route21, ROUTE_21, $43`
|
|
- Connections: north `PALLET_TOWN` (offset 0), south `CINNABAR_ISLAND` (offset 0)
|
|
- Landmark position: `data/maps/landmarks.asm:96` `landmark 52, 120, Route21Name`
|
|
|
|
**Warps** (`def_warp_events`)
|
|
|
|
None (`def_warp_events` at `maps/Route21.asm:95` is empty).
|
|
|
|
**Coord events** (`def_coord_events`)
|
|
|
|
None (`maps/Route21.asm:97`).
|
|
|
|
**BG events** (`def_bg_events`)
|
|
|
|
None (`maps/Route21.asm:99`).
|
|
|
|
**Object events** (`def_object_events`, `maps/Route21.asm:101-104`)
|
|
|
|
| const | sprite | x | y | movement | type | sight | script label | event flag |
|
|
|---|---|---|---|---|---|---|---|---|
|
|
| `ROUTE21_SWIMMER_GIRL` | `SPRITE_SWIMMER_GIRL` | 11 | 16 | `SPRITEMOVEDATA_SPINRANDOM_FAST` | `OBJECTTYPE_TRAINER` | 3 | `TrainerSwimmerfNikki` | -1 (always) |
|
|
| `ROUTE21_SWIMMER_GUY` | `SPRITE_SWIMMER_GUY` | 2 | 30 | `SPRITEMOVEDATA_STANDING_RIGHT` | `OBJECTTYPE_TRAINER` | 4 | `TrainerSwimmermSeth` | -1 (always) |
|
|
| `ROUTE21_FISHER` | `SPRITE_FISHER` | 14 | 22 | `SPRITEMOVEDATA_STANDING_UP` | `OBJECTTYPE_TRAINER` | 1 | `TrainerFisherArnold` | -1 (always) |
|
|
|
|
The walkthrough's order (Nikki, then the fisherman, then "head way left then down") is
|
|
exactly the y ordering 16 -> 22 -> 30, with Seth in the far south-west corner at x=2.
|
|
|
|
**Scripts of interest**
|
|
|
|
- `TrainerSwimmerfNikki` (`maps/Route21.asm:22`, sym `4e:4803`) -
|
|
`trainer SWIMMERF, NIKKI, EVENT_BEAT_SWIMMERF_NIKKI, SwimmerfNikkiSeenText, SwimmerfNikkiBeatenText, 0, .Script`.
|
|
The `0` is the loss-text slot (no whiteout text). `.Script` is `endifjustbattled` +
|
|
one after-battle line; no items, no flags beyond the beat flag.
|
|
- `TrainerFisherArnold` (`maps/Route21.asm:33`, sym `4e:4817`) - same shape,
|
|
`EVENT_BEAT_FISHER_ARNOLD`.
|
|
- `TrainerSwimmermSeth` (`maps/Route21.asm:11`, sym `4e:47ef`) - same shape,
|
|
`EVENT_BEAT_SWIMMERM_SETH`.
|
|
|
|
There are no scene scripts and no callbacks on this map (`def_scene_scripts` /
|
|
`def_callbacks` at `maps/Route21.asm:7-9` are both empty).
|
|
|
|
**Flags and events**
|
|
|
|
| constant | defined in | read/written by | meaning for a bot |
|
|
|---|---|---|---|
|
|
| `EVENT_BEAT_SWIMMERF_NIKKI` | `constants/event_flags.asm:490` | `trainer` macro row, `maps/Route21.asm:23` | set once Nikki is beaten; suppresses re-battle |
|
|
| `EVENT_BEAT_FISHER_ARNOLD` | `constants/event_flags.asm:587` | `maps/Route21.asm:34` | as above |
|
|
| `EVENT_BEAT_SWIMMERM_SETH` | `constants/event_flags.asm:958` | `maps/Route21.asm:12` | as above |
|
|
|
|
**Items**
|
|
|
|
None on this map.
|
|
|
|
**Trainers**
|
|
|
|
| const | class | id | party (`data/trainers/parties.asm`) | script label | rematch/phone |
|
|
|---|---|---|---|---|---|
|
|
| `SWIMMERF, NIKKI` | SWIMMERF ($27) | 17 | `; SWIMMERF (17)` at `parties.asm:1872`: L28 SEEL, L28 SEEL, L28 SEEL, L28 DEWGONG (`TRAINERTYPE_NORMAL`) | `TrainerSwimmerfNikki` | no |
|
|
| `FISHER, ARNOLD` | FISHER ($25) | 3 | `; FISHER (3)` at `parties.asm:1511`: L34 TENTACRUEL | `TrainerFisherArnold` | no |
|
|
| `SWIMMERM, SETH` | SWIMMERM ($26) | 18 | `; SWIMMERM (18)` at `parties.asm:1754`: L29 QUAGSIRE, L29 OCTILLERY, L32 QUAGSIRE | `TrainerSwimmermSeth` | no |
|
|
|
|
Payouts (base reward x last-mon level x 4, see section 3 for the citation):
|
|
Nikki 5 x 28 x 4 = **560**, Arnold 10 x 34 x 4 = **1360**, Seth 2 x 32 x 4 = **256**.
|
|
All three match the walkthrough exactly.
|
|
Base rewards: `data/trainers/attributes.asm:223` (Fisher, 10), `:229` (Swimmerm, 2),
|
|
`:235` (Swimmerf, 5).
|
|
|
|
**Wild encounters**
|
|
|
|
- Water (`data/wild/kanto_water.asm:61-66`), 6% rate: L35 TENTACOOL / L30 TENTACOOL / L35 TENTACRUEL.
|
|
- Grass (`data/wild/kanto_grass.asm:1005-1031`), 6/6/6% morn/day/nite. There *is* a
|
|
grass table, on the small land tiles:
|
|
- morn: 30 TANGELA, 25 TANGELA, 35 TANGELA, 20 TANGELA, 30 TANGELA, 28 MR__MIME, 28 MR__MIME
|
|
- day: 30 TANGELA, 25 TANGELA, 35 TANGELA, 20 TANGELA, 28 MR__MIME, 30 MR__MIME, 30 MR__MIME
|
|
- nite: 30 TANGELA, 25 TANGELA, 35 TANGELA, 20 TANGELA, 30 TANGELA, 28 MR__MIME, 28 MR__MIME
|
|
- Fishing: `FISHGROUP_OCEAN` (`data/wild/fish.asm:13`). Old rod `.Ocean_Old` (`:42`)
|
|
MAGIKARP/MAGIKARP/TENTACOOL L10; Good rod `.Ocean_Good` (`:46`) MAGIKARP L20 /
|
|
TENTACOOL L20 / CHINCHOU L20 / `time_group 2` = SHELLDER L20 day and nite
|
|
(`fish.asm:214`); Super rod `.Ocean_Super` (`:51`) CHINCHOU L40 / `time_group 3` =
|
|
SHELLDER L40 (`fish.asm:215`) / TENTACRUEL L40 / LANTURN L40.
|
|
- No headbutt tree rows and no rock smash on this map.
|
|
|
|
---
|
|
|
|
### MAP_CINNABAR_ISLAND
|
|
|
|
- Script: `maps/CinnabarIsland.asm`
|
|
- Blocks: `maps/CinnabarIsland.blk`
|
|
- Header: `data/maps/maps.asm:199` -> `TILESET_KANTO, TOWN, LANDMARK_CINNABAR_ISLAND, MUSIC_VIRIDIAN_CITY, FALSE, PALETTE_AUTO, FISHGROUP_OCEAN`
|
|
- Dimensions: `constants/map_constants.asm:183` `map_const CINNABAR_ISLAND, 10, 9` (group `CINNABAR` = 6, map id 8). 20x18 tile coordinates.
|
|
- Attributes / border: `data/maps/attributes.asm:279` `map_attributes CinnabarIsland, CINNABAR_ISLAND, $43`
|
|
- Connections: north `ROUTE_21` (offset 0), east `ROUTE_20` (offset 0)
|
|
- Landmark: `data/maps/landmarks.asm:95` `landmark 52, 132, CinnabarIslandName`
|
|
- Fly / respawn point: `data/maps/flypoints.asm:28` `db LANDMARK_CINNABAR_ISLAND, SPAWN_CINNABAR`;
|
|
`data/maps/spawn_points.asm:24` `spawn CINNABAR_ISLAND, 11, 12`
|
|
|
|
**Warps** (`def_warp_events`, `maps/CinnabarIsland.asm:131-132`)
|
|
|
|
| idx | x | y | destination map | dest warp |
|
|
|---|---|---|---|---|
|
|
| 1 | 11 | 11 | `CINNABAR_POKECENTER_1F` | 1 |
|
|
|
|
**Coord events** (`def_coord_events`)
|
|
|
|
None (`maps/CinnabarIsland.asm:134`). Blue is a talk-to NPC, not a trip-wire.
|
|
|
|
**BG events** (`def_bg_events`, `maps/CinnabarIsland.asm:136-140`)
|
|
|
|
| x | y | type | script/item |
|
|
|---|---|---|---|
|
|
| 12 | 11 | `BGEVENT_READ` | `CinnabarIslandPokecenterSign` -> `jumpstd PokecenterSignScript` |
|
|
| 9 | 11 | `BGEVENT_READ` | `CinnabarIslandGymSign` -> "CINNABAR GYM has relocated to SEAFOAM ISLANDS. BLAINE" |
|
|
| 7 | 7 | `BGEVENT_READ` | `CinnabarIslandSign` -> town sign |
|
|
| 9 | 1 | `BGEVENT_ITEM` | `CinnabarIslandHiddenRareCandy` -> `hiddenitem RARE_CANDY, EVENT_CINNABAR_ISLAND_HIDDEN_RARE_CANDY` (sym `4e:49a2`) |
|
|
|
|
**Object events** (`def_object_events`, `maps/CinnabarIsland.asm:142-143`)
|
|
|
|
| const | sprite | x | y | movement | type | sight | script label | event flag |
|
|
|---|---|---|---|---|---|---|---|---|
|
|
| `CINNABARISLAND_BLUE` | `SPRITE_BLUE` | 9 | 6 | `SPRITEMOVEDATA_SPINRANDOM_SLOW` | `OBJECTTYPE_SCRIPT` | 0 | `CinnabarIslandBlue` | `EVENT_BLUE_IN_CINNABAR` |
|
|
|
|
**Scripts of interest**
|
|
|
|
- `CinnabarIslandFlypointCallback` (`maps/CinnabarIsland.asm:10`, sym `4e:4981`), wired
|
|
as `callback MAPCALLBACK_NEWMAP` at `:8`. Body is exactly
|
|
`setflag ENGINE_FLYPOINT_CINNABAR` / `endcallback`. Walking in once is the whole
|
|
unlock for flying here.
|
|
- `CinnabarIslandBlue` (`maps/CinnabarIsland.asm:14`, sym `4e:4985`). Control flow, in
|
|
order: `faceplayer`, `opentext`, `writetext CinnabarIslandBlueText`, `waitbutton`,
|
|
`closetext`, `playsound SFX_WARP_TO`,
|
|
`applymovement CINNABARISLAND_BLUE, CinnabarIslandBlueTeleport`,
|
|
`disappear CINNABARISLAND_BLUE`, `clearevent EVENT_VIRIDIAN_GYM_BLUE`, `end`.
|
|
- There is **no guard flag and no `iftrue`** at the top: the script is one-shot only
|
|
because `disappear` sets the object's own `EVENT_BLUE_IN_CINNABAR` (see
|
|
`Script_disappear` at `engine/overworld/scripting.asm:887`, `ld b, 1 ; set`).
|
|
- `CinnabarIslandBlueTeleport` (`:38`) is a two-byte movement stream:
|
|
`teleport_from` (`$4c`, `macros/scripts/movement.asm:148`) then `step_end`. That is
|
|
the "levitates and flies off" the walkthrough describes.
|
|
- `clearevent EVENT_VIRIDIAN_GYM_BLUE` is the load-bearing side effect: that flag is
|
|
set at boot by `InitializeEventsScript` (`engine/events/std_scripts.asm:552`) and it
|
|
hides both `VIRIDIANGYM_BLUE` and the Viridian gym guide
|
|
(`maps/ViridianGym.asm:183-184`). **Talking to Blue here is the only thing that
|
|
puts Blue in Viridian Gym.**
|
|
- `CinnabarIslandHiddenRareCandy` (`maps/CinnabarIsland.asm:35`) - a `hiddenitem`
|
|
operand, not a script body: `dwb EVENT_CINNABAR_ISLAND_HIDDEN_RARE_CANDY, RARE_CANDY`.
|
|
|
|
**Flags and events**
|
|
|
|
| constant | defined in | read/written by | meaning for a bot |
|
|
|---|---|---|---|
|
|
| `ENGINE_FLYPOINT_CINNABAR` | `constants/engine_flags.asm:77` | set by `CinnabarIslandFlypointCallback` | Fly destination unlocked; also the wVisitedSpawns bit for respawn |
|
|
| `EVENT_BLUE_IN_CINNABAR` | `constants/event_flags.asm:1303` | *set* implicitly by `disappear CINNABARISLAND_BLUE`; read by `maps/ViridianCity.asm:37` and `maps/ViridianPokecenter1F.asm:18` for "Blue returned" dialogue | clear = Blue is standing on Cinnabar; set = you have heard the speech |
|
|
| `EVENT_VIRIDIAN_GYM_BLUE` | `constants/event_flags.asm:1304` | set at `engine/events/std_scripts.asm:552`; cleared by `CinnabarIslandBlue` | while set, Viridian Gym is empty |
|
|
| `EVENT_CINNABAR_ISLAND_HIDDEN_RARE_CANDY` | `constants/event_flags.asm:254` | the `hiddenitem` at `maps/CinnabarIsland.asm:36` | one-shot guard on the hidden candy |
|
|
|
|
Note: `EVENT_BLUE_IN_CINNABAR` is **not** in the `InitializeEventsScript` list, so it
|
|
starts clear and Blue is visible from the first time you reach the island.
|
|
|
|
**Items**
|
|
|
|
| item | how obtained | source | one-time flag |
|
|
|---|---|---|---|
|
|
| `RARE_CANDY` | face tile (9,1) and press A (or ITEMFINDER) | `bg_event 9, 1, BGEVENT_ITEM, CinnabarIslandHiddenRareCandy` | `EVENT_CINNABAR_ISLAND_HIDDEN_RARE_CANDY` |
|
|
|
|
The walkthrough never mentions this candy.
|
|
|
|
**Trainers**
|
|
|
|
None.
|
|
|
|
**Wild encounters**
|
|
|
|
No `def_grass_wildmons`/`def_water_wildmons` row for `CINNABAR_ISLAND` in
|
|
`data/wild/kanto_grass.asm` or `data/wild/kanto_water.asm`. The surrounding water belongs
|
|
to Route 20 / Route 21. Fishing on the map's own water uses `FISHGROUP_OCEAN`
|
|
(`data/maps/maps.asm:199`).
|
|
|
|
---
|
|
|
|
### MAP_CINNABAR_POKECENTER_1F
|
|
|
|
- Script: `maps/CinnabarPokecenter1F.asm`
|
|
- Header: `data/maps/maps.asm:192` -> `TILESET_POKECENTER, INDOOR, LANDMARK_CINNABAR_ISLAND, MUSIC_POKEMON_CENTER, FALSE, PALETTE_DAY, FISHGROUP_SHORE`
|
|
- Dimensions: `constants/map_constants.asm:176` `map_const CINNABAR_POKECENTER_1F, 5, 4` (group `CINNABAR` = 6, map id 1)
|
|
- Attributes: `data/maps/attributes.asm:510` `map_attributes CinnabarPokecenter1F, CINNABAR_POKECENTER_1F, $00`; no connections
|
|
|
|
**Warps** (`def_warp_events`, `maps/CinnabarPokecenter1F.asm:38-41`)
|
|
|
|
| idx | x | y | destination map | dest warp |
|
|
|---|---|---|---|---|
|
|
| 1 | 3 | 7 | `CINNABAR_ISLAND` | 1 |
|
|
| 2 | 4 | 7 | `CINNABAR_ISLAND` | 1 |
|
|
| 3 | 0 | 7 | `POKECENTER_2F` | 1 |
|
|
|
|
**Coord events / BG events**
|
|
|
|
None (`maps/CinnabarPokecenter1F.asm:43`, `:45`).
|
|
|
|
**Object events** (`maps/CinnabarPokecenter1F.asm:47-50`)
|
|
|
|
| const | sprite | x | y | movement | type | script label | event flag |
|
|
|---|---|---|---|---|---|---|---|
|
|
| `CINNABARPOKECENTER1F_NURSE` | `SPRITE_NURSE` | 3 | 1 | `SPRITEMOVEDATA_STANDING_DOWN` | `OBJECTTYPE_SCRIPT` | `CinnabarPokecenter1FNurseScript` -> `jumpstd PokecenterNurseScript` | -1 |
|
|
| `CINNABARPOKECENTER1F_COOLTRAINER_F` | `SPRITE_COOLTRAINER_F` | 7 | 6 | `SPRITEMOVEDATA_WALK_LEFT_RIGHT` (radius x 2) | `OBJECTTYPE_SCRIPT` | `CinnabarPokecenter1FCooltrainerFScript` (BLAINE lives in the Seafoam cave) | -1 |
|
|
| `CINNABARPOKECENTER1F_FISHER` | `SPRITE_FISHER` | 2 | 4 | `SPRITEMOVEDATA_STANDING_DOWN` | `OBJECTTYPE_SCRIPT` | `CinnabarPokecenter1FFisherScript` ("It's been a year since the volcano erupted.") | -1 |
|
|
|
|
Both flavour NPCs are unconditional `jumptextfaceplayer` - no flags, no branches. These
|
|
are the two people the walkthrough tells you to talk to.
|
|
|
|
---
|
|
|
|
### MAP_ROUTE_20
|
|
|
|
- Script: `maps/Route20.asm`
|
|
- Blocks: `maps/Route20.blk`
|
|
- Header: `data/maps/maps.asm:197` -> `TILESET_KANTO, ROUTE, LANDMARK_ROUTE_20, MUSIC_ROUTE_3, FALSE, PALETTE_AUTO, FISHGROUP_OCEAN`
|
|
- Dimensions: `constants/map_constants.asm:181` `map_const ROUTE_20, 30, 9` (group `CINNABAR` = 6, map id 6). 60x18 tile coordinates.
|
|
- Attributes / border: `data/maps/attributes.asm:283` `map_attributes Route20, ROUTE_20, $43`
|
|
- Connections: west `CINNABAR_ISLAND` (offset 0), east `ROUTE_19` (offset -9)
|
|
- Landmarks in view: `data/maps/landmarks.asm:93` Route 20, `:94` `SeafoamIslandsName`
|
|
|
|
**Warps** (`def_warp_events`, `maps/Route20.asm:116-117`)
|
|
|
|
| idx | x | y | destination map | dest warp |
|
|
|---|---|---|---|---|
|
|
| 1 | 38 | 7 | `SEAFOAM_GYM` | 1 |
|
|
|
|
**Coord events**
|
|
|
|
None (`maps/Route20.asm:119`).
|
|
|
|
**BG events** (`maps/Route20.asm:121-122`)
|
|
|
|
| x | y | type | script/item |
|
|
|---|---|---|---|
|
|
| 37 | 11 | `BGEVENT_READ` | `CinnabarGymSign` -> "CINNABAR GYM / LEADER: BLAINE" |
|
|
|
|
**Object events** (`maps/Route20.asm:124-127`)
|
|
|
|
| const | sprite | x | y | movement | type | sight | script label | event flag |
|
|
|---|---|---|---|---|---|---|---|---|
|
|
| `ROUTE20_SWIMMER_GIRL1` | `SPRITE_SWIMMER_GIRL` | 52 | 8 | `SPRITEMOVEDATA_SPINRANDOM_FAST` | `OBJECTTYPE_TRAINER` | 3 | `TrainerSwimmerfNicole` | -1 |
|
|
| `ROUTE20_SWIMMER_GIRL2` | `SPRITE_SWIMMER_GIRL` | 45 | 13 | `SPRITEMOVEDATA_SPINRANDOM_FAST` | `OBJECTTYPE_TRAINER` | 3 | `TrainerSwimmerfLori` | -1 |
|
|
| `ROUTE20_SWIMMER_GUY` | `SPRITE_SWIMMER_GUY` | 12 | 13 | `SPRITEMOVEDATA_SPINRANDOM_FAST` | `OBJECTTYPE_TRAINER` | 3 | `TrainerSwimmermCameron` | -1 |
|
|
|
|
Cameron at x=12 is the only one west of the gym door at x=38, which is why the
|
|
walkthrough sees "one trainer" on the way in. Lori (45) and Nicole (52) are east of it.
|
|
|
|
**Scripts of interest**
|
|
|
|
- `Route20ClearRocksCallback` (`maps/Route20.asm:12`, sym `4e:4cfa`), wired as
|
|
`callback MAPCALLBACK_NEWMAP` at `:10`. Body is `setevent EVENT_CINNABAR_ROCKS_CLEARED`
|
|
/ `endcallback`. It fires silently the first time the map loads.
|
|
Consumers: `Route19ClearRocksCallback` (`maps/Route19.asm:15`, sym `4e:4f09`, a
|
|
`MAPCALLBACK_TILES` callback) draws six `changeblock ... $7a ; rock` blocks at
|
|
(6,6), (8,6), (10,6), (12,8), (4,8), (10,10) **while the flag is clear**; the officer
|
|
in `maps/Route19FuchsiaGate.asm:12` and the two fishers in `maps/Route19.asm:74`/`:90`
|
|
swap dialogue on it.
|
|
- `TrainerSwimmermCameron` (`maps/Route20.asm:38`, sym `4e:4d26`) - plain trainer,
|
|
`EVENT_BEAT_SWIMMERM_CAMERON`, `endifjustbattled` + one line.
|
|
|
|
**Flags and events**
|
|
|
|
| constant | defined in | read/written by | meaning for a bot |
|
|
|---|---|---|---|
|
|
| `EVENT_CINNABAR_ROCKS_CLEARED` | `constants/event_flags.asm:214` | set by `Route20ClearRocksCallback`; read by `maps/Route19.asm:16`, `:74`, `:90` and `maps/Route19FuchsiaGate.asm:12` | while clear, six rock blocks seal the Route 19 water path from the Fuchsia side |
|
|
| `EVENT_BEAT_SWIMMERM_CAMERON` | `constants/event_flags.asm:957` | `maps/Route20.asm:39` | beat flag |
|
|
| `EVENT_BEAT_SWIMMERF_NICOLE` | `constants/event_flags.asm:487` | `maps/Route20.asm:17` | beat flag (next section) |
|
|
| `EVENT_BEAT_SWIMMERF_LORI` | `constants/event_flags.asm:488` | `maps/Route20.asm:28` | beat flag (next section) |
|
|
|
|
**Items**
|
|
|
|
None on this map.
|
|
|
|
**Trainers**
|
|
|
|
| const | class | id | party (`data/trainers/parties.asm`) | script label | rematch/phone |
|
|
|---|---|---|---|---|---|
|
|
| `SWIMMERM, CAMERON` | SWIMMERM ($26) | 17 | `; SWIMMERM (17)` at `parties.asm:1749`: L34 MARILL | `TrainerSwimmermCameron` | no |
|
|
| `SWIMMERF, NICOLE` | SWIMMERF ($27) | 14 | `; SWIMMERF (14)` at `parties.asm:1854`: L29 MARILL, L29 MARILL, L32 LAPRAS | `TrainerSwimmerfNicole` | no |
|
|
| `SWIMMERF, LORI` | SWIMMERF ($27) | 15 | `; SWIMMERF (15)` at `parties.asm:1861`: L32 STARMIE, L32 STARMIE | `TrainerSwimmerfLori` | no |
|
|
|
|
Cameron pays 2 x 34 x 4 = **272**, matching the walkthrough.
|
|
|
|
**Wild encounters**
|
|
|
|
- Water (`data/wild/kanto_water.asm:54-59`), 6% rate: L35 TENTACOOL / L30 TENTACOOL / L35 TENTACRUEL.
|
|
- No `def_grass_wildmons ROUTE_20` row exists in `data/wild/kanto_grass.asm` - there is
|
|
no land grass on this route.
|
|
- Fishing: `FISHGROUP_OCEAN`, same three rod tables as Route 21 above.
|
|
|
|
---
|
|
|
|
### MAP_SEAFOAM_GYM
|
|
|
|
- Script: `maps/SeafoamGym.asm`
|
|
- Blocks: `maps/SeafoamGym.blk`
|
|
- Header: `data/maps/maps.asm:195` -> `TILESET_CAVE, INDOOR, LANDMARK_SEAFOAM_ISLANDS, MUSIC_GYM, TRUE (phone calls blocked), PALETTE_DAY, FISHGROUP_SHORE`
|
|
- Dimensions: `constants/map_constants.asm:179` `map_const SEAFOAM_GYM, 5, 4` (group `CINNABAR` = 6, map id 4). 10x8 tile coordinates - smaller than the 20x18 screen, which is the walkthrough's "this gym doesn't even fit the entire screen".
|
|
- Attributes / border: `data/maps/attributes.asm:513` `map_attributes SeafoamGym, SEAFOAM_GYM, $09`; no connections
|
|
- There is **no** `MAP_SEAFOAM_ISLANDS` dungeon in Gen 2 - `constants/map_constants.asm`
|
|
has only `SEAFOAM_GYM` in the whole Seafoam family.
|
|
|
|
**Warps** (`def_warp_events`, `maps/SeafoamGym.asm:161-162`)
|
|
|
|
| idx | x | y | destination map | dest warp |
|
|
|---|---|---|---|---|
|
|
| 1 | 5 | 5 | `ROUTE_20` | 1 |
|
|
|
|
**Coord events**
|
|
|
|
None (`maps/SeafoamGym.asm:164`). The map does declare one scene script,
|
|
`scene_script SeafoamGymNoopScene` (`:7`), and the asm itself annotates it
|
|
`; unusable` - the body at `:11` is a bare `end`.
|
|
|
|
**BG events**
|
|
|
|
None (`maps/SeafoamGym.asm:166`).
|
|
|
|
**Object events** (`maps/SeafoamGym.asm:168-170`)
|
|
|
|
| const | sprite | x | y | movement | type | sight | script label | event flag |
|
|
|---|---|---|---|---|---|---|---|---|
|
|
| `SEAFOAMGYM_BLAINE` | `SPRITE_BLAINE` | 5 | 2 | `SPRITEMOVEDATA_STANDING_DOWN` | `OBJECTTYPE_SCRIPT` | 0 | `SeafoamGymBlaineScript` | -1 (always present) |
|
|
| `SEAFOAMGYM_GYM_GUIDE` | `SPRITE_GYM_GUIDE` | 6 | 5 | `SPRITEMOVEDATA_STANDING_UP` | `OBJECTTYPE_SCRIPT` | 0 | `SeafoamGymGuideScript` | `EVENT_SEAFOAM_GYM_GYM_GUIDE` |
|
|
|
|
**Scripts of interest**
|
|
|
|
- `SeafoamGymBlaineScript` (`maps/SeafoamGym.asm:14`, sym `53:516d`). Control flow:
|
|
1. `faceplayer`, `opentext`
|
|
2. `checkflag ENGINE_VOLCANOBADGE` / `iftrue .FightDone` - the entire re-talk guard is
|
|
the badge engine flag, **not** an event flag.
|
|
3. `writetext BlaineIntroText`, `waitbutton`, `closetext`
|
|
4. `winlosstext BlaineWinLossText, 0` (no loss text)
|
|
5. `loadtrainer BLAINE, BLAINE1`, `startbattle`
|
|
6. `iftrue .ReturnAfterBattle` - i.e. if the battle result is non-zero (you lost /
|
|
drew) it *skips* `appear SEAFOAMGYM_GYM_GUIDE`
|
|
7. `appear SEAFOAMGYM_GYM_GUIDE` - clears `EVENT_SEAFOAM_GYM_GYM_GUIDE`, which is how
|
|
the guide "comes in late"
|
|
8. `.ReturnAfterBattle`: `reloadmapafterbattle`, `setevent EVENT_BEAT_BLAINE`,
|
|
`opentext`, `writetext ReceivedVolcanoBadgeText`, `playsound SFX_GET_BADGE`,
|
|
`waitsfx`, **`setflag ENGINE_VOLCANOBADGE`**, `writetext BlaineAfterBattleText`,
|
|
`waitbutton`, `closetext`, `end`
|
|
- No `verbosegiveitem` anywhere: **Blaine gives no TM**, only the badge.
|
|
- Note the ordering quirk: `setevent EVENT_BEAT_BLAINE` / `setflag ENGINE_VOLCANOBADGE`
|
|
are on the shared `.ReturnAfterBattle` path, reached whether or not you won, but
|
|
`startbattle` does not return to the script on a whiteout, so in practice this is
|
|
only reached after a win.
|
|
- `SeafoamGymGuideScript` (`maps/SeafoamGym.asm:46`, sym `53:51a3`) - branches on
|
|
`EVENT_TALKED_TO_SEAFOAM_GYM_GUIDE_ONCE`, first line is the apology
|
|
("CINNABAR GYM was gone, so I didn't know where to find you"), then a second line
|
|
forever after.
|
|
|
|
**Flags and events**
|
|
|
|
| constant | defined in | read/written by | meaning for a bot |
|
|
|---|---|---|---|
|
|
| `ENGINE_VOLCANOBADGE` | `constants/engine_flags.asm:53` (Kanto badge 7; `wKantoBadges` bit 6 per `constants/ram_constants.asm:270`) | checked at `maps/SeafoamGym.asm:17`, set at `:34` | the badge itself; also gates the re-talk branch |
|
|
| `EVENT_BEAT_BLAINE` | `constants/event_flags.asm:721` | set at `maps/SeafoamGym.asm:29` | not read by any other map in the checkout; it is the record, not the gate |
|
|
| `EVENT_SEAFOAM_GYM_GYM_GUIDE` | `constants/event_flags.asm:1305` | set at boot (`engine/events/std_scripts.asm:553`), cleared by `appear` at `maps/SeafoamGym.asm:26` | while set, the guide object does not exist |
|
|
| `EVENT_TALKED_TO_SEAFOAM_GYM_GUIDE_ONCE` | `constants/event_flags.asm:212` | `maps/SeafoamGym.asm:49`, `:54` | first-talk vs repeat text |
|
|
|
|
What VOLCANOBADGE actually does mechanically: `data/types/badge_type_boosts.asm:19`
|
|
`db FIRE ; VOLCANOBADGE`, consumed by `DoBadgeTypeBoosts` (`engine/battle/misc.asm:146`,
|
|
called from `engine/battle/effect_commands.asm:1261`) - a +12.5% damage boost on the
|
|
player's FIRE-type moves. It grants no field move.
|
|
|
|
**Items**
|
|
|
|
None.
|
|
|
|
**Trainers**
|
|
|
|
| const | class | id | party (`data/trainers/parties.asm`) | script label | rematch/phone |
|
|
|---|---|---|---|---|---|
|
|
| `BLAINE, BLAINE1` | BLAINE ($2e), `constants/trainer_constants.asm:469-470` | 1 | `BlaineGroup` (sym `0e:6e70`) at `parties.asm:2303`, `TRAINERTYPE_MOVES`: **L45 MAGCARGO** (CURSE, SMOG, FLAMETHROWER, ROCK_SLIDE), **L45 MAGMAR** (THUNDERPUNCH, FIRE_PUNCH, SUNNY_DAY, CONFUSE_RAY), **L50 RAPIDASH** (QUICK_ATTACK, FIRE_SPIN, FURY_ATTACK, FIRE_BLAST) | `SeafoamGymBlaineScript` | no rematch, no phone |
|
|
|
|
Class attributes (`data/trainers/attributes.asm:275-279`): AI items are
|
|
**`MAX_POTION, FULL_HEAL`** (not two Full Restores); base reward 25; AI mask
|
|
`AI_BASIC | AI_SETUP | AI_SMART | AI_AGGRESSIVE | AI_CAUTIOUS | AI_STATUS | AI_RISKY`,
|
|
`CONTEXT_USE | SWITCH_SOMETIMES`. Payout 25 x 50 x 4 = **5000**, matching the walkthrough.
|
|
`BLAINE` is in `KantoGymLeaders` (`data/trainers/leaders.asm`), so the battle uses the
|
|
gym-leader music and awards `HAPPINESS_GYMBATTLE`.
|
|
|
|
**Wild encounters**
|
|
|
|
None. The map is `INDOOR` with `TILESET_CAVE`; its `FISHGROUP_SHORE` header entry is the
|
|
default and has no reachable water.
|
|
|
|
---
|
|
|
|
## 3. Blockers and gates
|
|
|
|
| Gate | Enforced by (file:label) | Requirement | Unlock condition |
|
|
|---|---|---|---|
|
|
| Everything in this section is across open sea (Pallet -> Route 21 -> Cinnabar -> Route 20 -> gym door) | `engine/events/overworld.asm:469` `TrySurfOW` (walk-into-water path): `ld de, ENGINE_FOGBADGE` / `CheckEngineFlag` at `:490`, then `ld d, SURF` / `CheckPartyMove`. Menu path is `SurfFunction` `.TrySurf` at `:340` with the same `ENGINE_FOGBADGE`. `CheckBadge` itself is at `:50`. | FOGBADGE + a party mon that knows SURF | already held long before Kanto (Johto badge 4) |
|
|
| Fly to Cinnabar Island | `data/maps/flypoints.asm:28`; the flag is `ENGINE_FLYPOINT_CINNABAR`, set by `CinnabarIslandFlypointCallback` (`maps/CinnabarIsland.asm:10`) | STORMBADGE + FLY + having stood on Cinnabar Island once | walk in once |
|
|
| Blue is not in Viridian Gym | `maps/ViridianGym.asm:183-184` object rows carry `EVENT_VIRIDIAN_GYM_BLUE`, set at `engine/events/std_scripts.asm:552` | - | `clearevent EVENT_VIRIDIAN_GYM_BLUE` at the tail of `CinnabarIslandBlue` (`maps/CinnabarIsland.asm:23`) - **this section is a hard prerequisite for the Viridian Gym leader** |
|
|
| Route 19 (east of Route 20) is sealed by six boulder blocks | `maps/Route19.asm:15` `Route19ClearRocksCallback`, a `MAPCALLBACK_TILES` callback that lays `changeblock` rock blocks while `EVENT_CINNABAR_ROCKS_CLEARED` is clear | - | `setevent EVENT_CINNABAR_ROCKS_CLEARED` in `Route20ClearRocksCallback` (`maps/Route20.asm:13`), i.e. simply loading Route 20 once from the Cinnabar side |
|
|
| Blaine will not re-battle | `maps/SeafoamGym.asm:17` `checkflag ENGINE_VOLCANOBADGE` / `iftrue .FightDone` | - | none in vanilla; `.FightDone` is terminal |
|
|
| The gym guide does not exist until Blaine is beaten | object row event flag `EVENT_SEAFOAM_GYM_GYM_GUIDE` (`maps/SeafoamGym.asm:170`), set at `engine/events/std_scripts.asm:553` | beat Blaine | `appear SEAFOAMGYM_GYM_GUIDE` (`maps/SeafoamGym.asm:26`), only on the win branch |
|
|
|
|
Nothing in this section needs CUT, STRENGTH, WHIRLPOOL, WATERFALL, FLASH or a key item.
|
|
|
|
## 4. Bot checklist
|
|
|
|
Ordered, machine-actionable. `(g,m)` is `(map group, map id)` from
|
|
`constants/map_constants.asm`. All coordinates are the raw asm map-event values.
|
|
|
|
1. `PALLET_TOWN`: SURF south across the connection into `ROUTE_21 (6,7)`.
|
|
Pre: FOGBADGE + SURF in the party. Post: none.
|
|
2. `ROUTE_21`: battle `TrainerSwimmerfNikki` at (11,16) - sight radius 3, so she will
|
|
trigger on approach. Party L28 SEEL x3 + L28 DEWGONG. Post: `EVENT_BEAT_SWIMMERF_NIKKI`, +560 money.
|
|
3. `ROUTE_21`: battle `TrainerFisherArnold` at (14,22) - sight radius 1, faces up.
|
|
Party L34 TENTACRUEL. Post: `EVENT_BEAT_FISHER_ARNOLD`, +1360 money.
|
|
4. `ROUTE_21`: surf west then south to `TrainerSwimmermSeth` at (2,30) - sight radius 4,
|
|
faces right. Party L29 QUAGSIRE / L29 OCTILLERY / L32 QUAGSIRE.
|
|
Post: `EVENT_BEAT_SWIMMERM_SETH`, +256 money.
|
|
(Both trainers are avoidable - all three are `OBJECTTYPE_TRAINER` with a finite sight
|
|
radius, none are on a coord event.)
|
|
5. `ROUTE_21`: continue south across the connection into `CINNABAR_ISLAND (6,8)`.
|
|
Post: `MAPCALLBACK_NEWMAP` sets `ENGINE_FLYPOINT_CINNABAR`; respawn point becomes
|
|
`SPAWN_CINNABAR` = (11,12).
|
|
6. `CINNABAR_ISLAND`: step on warp 1 at (11,11) -> `CINNABAR_POKECENTER_1F (6,1)`.
|
|
Talk to `CINNABARPOKECENTER1F_NURSE` at (3,1) to heal. Optional: the two flavour NPCs
|
|
at (7,6) and (2,4). Exit via warp 1/2 at (3,7)/(4,7).
|
|
7. `CINNABAR_ISLAND`: optional - face (9,1) and press A for the hidden **RARE_CANDY**.
|
|
Pre: `EVENT_CINNABAR_ISLAND_HIDDEN_RARE_CANDY` clear + a free bag slot.
|
|
Post: flag set. (Not in the walkthrough.)
|
|
8. `CINNABAR_ISLAND`: walk to `CINNABARISLAND_BLUE` at (9,6) and talk.
|
|
Pre: `EVENT_BLUE_IN_CINNABAR` clear. Expect a long `writetext` (about 13 pages of
|
|
`para` breaks - budget A presses accordingly), then `SFX_WARP_TO` + a `teleport_from`
|
|
movement, then the object vanishes.
|
|
Post: `EVENT_BLUE_IN_CINNABAR` set (via `disappear`), `EVENT_VIRIDIAN_GYM_BLUE`
|
|
**cleared**. Do not skip this step: it is the only unlock for the Viridian Gym leader.
|
|
9. `CINNABAR_ISLAND`: optional signs at (12,11), (9,11), (7,7).
|
|
10. `CINNABAR_ISLAND`: SURF east across the connection into `ROUTE_20 (6,6)`.
|
|
Post: `MAPCALLBACK_NEWMAP` sets `EVENT_CINNABAR_ROCKS_CLEARED` (silent; unseals
|
|
Route 19 for the next section).
|
|
11. `ROUTE_20`: battle `TrainerSwimmermCameron` at (12,13) - sight radius 3.
|
|
Party L34 MARILL. Post: `EVENT_BEAT_SWIMMERM_CAMERON`, +272 money.
|
|
12. `ROUTE_20`: optional sign at (37,11). Then step onto warp 1 at (38,7) ->
|
|
`SEAFOAM_GYM (6,4)`.
|
|
13. `SEAFOAM_GYM`: walk to `SEAFOAMGYM_BLAINE` at (5,2) and talk.
|
|
Pre: `ENGINE_VOLCANOBADGE` clear (otherwise you get `.FightDone` only).
|
|
Battle: `loadtrainer BLAINE, BLAINE1` - L45 MAGCARGO / L45 MAGMAR / L50 RAPIDASH,
|
|
AI holds MAX_POTION + FULL_HEAL.
|
|
Post: `EVENT_BEAT_BLAINE` set, `EVENT_SEAFOAM_GYM_GYM_GUIDE` cleared (guide appears
|
|
at (6,5)), **`ENGINE_VOLCANOBADGE` set**, +5000 money. No TM, no item.
|
|
14. `SEAFOAM_GYM`: optional - talk to `SEAFOAMGYM_GYM_GUIDE` at (6,5).
|
|
Post: `EVENT_TALKED_TO_SEAFOAM_GYM_GUIDE_ONCE`.
|
|
15. `SEAFOAM_GYM`: exit via warp 1 at (5,5) back to `ROUTE_20` warp 1.
|
|
|
|
Follow-up (next section): Route 20 continues east past Lori (45,13) and Nicole (52,8)
|
|
into `ROUTE_19`, whose rock blocks are now gone because step 10 set
|
|
`EVENT_CINNABAR_ROCKS_CLEARED`.
|
|
|
|
## 5. Port coverage
|
|
|
|
| Beat | Port file | Status |
|
|
|---|---|---|
|
|
| Kanto map headers, dimensions, connections, warp / coord / bg / object tables | `src/import/RomExtractorGen2.lua` (all 26 map groups, `MAP_GROUP_COUNT = 26` at `:47`, `MapGroupPointers` walk at `:728`) | implemented - fully data-driven, nothing Cinnabar-specific needed |
|
|
| `MAPCALLBACK_NEWMAP` (`CinnabarIslandFlypointCallback`, `Route20ClearRocksCallback`) | `src/world/gen2/World.lua:5659` `self:runMapCallback("MAPCALLBACK_NEWMAP")`, in `HandleNewMap` order (`:5646`) | implemented; asserted end-to-end by `tests/drivers/gold_map_callbacks.lua` |
|
|
| `MAPCALLBACK_TILES` + `changeblock` (the Route 19 rocks that this section unseals) | `src/world/gen2/World.lua:5662`; `changeblock` opcode at `src/script/gen2/Opcodes.lua:127` | implemented |
|
|
| `setflag ENGINE_FLYPOINT_CINNABAR` -> flyable | `src/world/gen2/FieldMoves.lua:367` (`LANDMARK_CINNABAR_ISLAND` / `SPAWN_CINNABAR` / flag 62), `World:setEngineFlag` at `src/world/gen2/World.lua:1326` | implemented |
|
|
| `checkevent` / `setevent` / `clearevent`, `checkflag` / `setflag` | `src/script/gen2/Vm.lua:187-229` | implemented - id-keyed stores, `engineFlags` kept separate from `wEventFlags` |
|
|
| `appear` / `disappear` writing the object's event flag (Blue vanishing, the guide arriving) | `src/script/gen2/Opcodes.lua:115-116`, handled in `src/script/gen2/Vm.lua` | implemented |
|
|
| Hidden item `BGEVENT_ITEM` (Cinnabar RARE_CANDY at 9,1) | `src/world/gen2/HiddenItems.lua` (`BGEVENT_ITEM = 7` at `:22`), extractor branch at `src/import/RomExtractorGen2.lua:2986` | implemented |
|
|
| `loadtrainer` / `startbattle` / `winlosstext` / `reloadmapafterbattle` / `endifjustbattled` (the whole Blaine script) | `src/script/gen2/Vm.lua:806`, `:817`, `:886`, `:918` | implemented, incl. the `iftrue` on `wBattleResult` that guards `appear SEAFOAMGYM_GYM_GUIDE` |
|
|
| Gym-leader battle music / victory music for BLAINE | `src/battle/gen2/BattleMusic.lua:21`, `src/battle/gen2/Battle.lua:82` (both list `BLAINE = true`) | implemented |
|
|
| Prize money = base x last-mon level x 4 (560 / 1360 / 256 / 272 / 5000) | `src/battle/gen2/Prize.lua` (header documents `ComputeTrainerReward` and the `ld c, 4` loop; `Prize.reward`) | implemented, incl. the Mom's-savings split |
|
|
| Trainer sight radii (3 / 4 / 1 on Route 21) | `src/world/gen2/Trainers.lua` | implemented |
|
|
| SURF gate on FOGBADGE + party move | `src/world/gen2/FieldMoves.lua:106` (`SURF = "FOG"`), `:481` `surfFromMenu`, `:678` overworld path | implemented; driven by `tests/drivers/gold_water_moves.lua` |
|
|
| Ocean wild/fish tables for Routes 20/21 | extracted by `src/import/RomExtractorGen2.lua`, consumed by `src/battle/gen2/Encounter.lua` | implemented - correct by construction from the ROM |
|
|
| Radio "Place & Name" un-hiding BLAINE after the Kanto badge sweep | `src/ui/gen2/Pokegear.lua:172` (`PNP_HIDDEN`), `:178` `PNP_HIDDEN_BEAT_KANTO`, `:1265` | implemented |
|
|
| `setflag ENGINE_VOLCANOBADGE` reaching the trainer card / `VAR_BADGES` count | `src/script/gen2/Vm.lua:208-229` writes `save.engineFlags[53]`; but `VAR_BADGES` (`src/world/gen2/World.lua:1243-1244`) counts `save.player.badges` + `save.player.kantoBadges`, and `src/ui/gen2/TrainerCard.lua:395` reads `player.badges`. Nothing in `src/` ever writes `player.kantoBadges` (only initialised at `src/core/gen2/Save.lua:119`). | **partial** - Blaine's own re-talk guard works (same `engineFlags` id is read back by `checkflag`), but the badge does not show on the trainer card and does not increment `VAR_BADGES` |
|
|
| `BadgeTypeBoosts` (VOLCANOBADGE = +12.5% FIRE damage) | no Gen 2 implementation - `grep -rn "badge" src/battle/gen2/` returns nothing; the only badge-boost code is the Gen 1 `src/battle/Damage.lua:35` | **missing** |
|
|
| `teleport_from` (`$4c`) movement for Blue's exit | `src/script/gen2/Movement.lua:22` `decodeByte` - `$4c` matches no family branch and falls through to `{ kind = "nop" }` | **partial** - Blue disappears with the sound but without the rise-and-vanish animation |
|
|
| End-to-end driver coverage for this stretch | `tests/drivers/gold_*.lua` (25 drivers, all Johto: boot, walk, warp, trainer, ice path, roamers, ...) | **missing** - no Cinnabar / Route 20 / Route 21 / Seafoam Gym driver exists |
|
|
|
|
## 6. Unresolved / verify by hand
|
|
|
|
- **Blaine's movesets in the walkthrough are not the pokegold movesets.** The FAQ
|
|
describes Magcargo with Yawn / Recover / Overheat, Magmar with Confuse Ray, and
|
|
Rapidash with Flare Blitz / Bounce. `data/trainers/parties.asm:2303-2308` gives
|
|
MAGCARGO (CURSE, SMOG, FLAMETHROWER, ROCK_SLIDE), MAGMAR (THUNDERPUNCH, FIRE_PUNCH,
|
|
SUNNY_DAY, CONFUSE_RAY) and RAPIDASH (QUICK_ATTACK, FIRE_SPIN, FURY_ATTACK,
|
|
FIRE_BLAST). Only CONFUSE_RAY overlaps; Overheat, Flare Blitz, Bounce and Yawn do not
|
|
exist in `constants/move_constants.asm` at all for this generation. **Species and
|
|
levels match exactly** (L45 / L45 / L50), so treat the strategy prose as written
|
|
against a different (modernised) build and the asm as authoritative.
|
|
- **"Blaine will have two Full Restores available."** `data/trainers/attributes.asm:276`
|
|
is `db MAX_POTION, FULL_HEAL`. Two different items, neither of them a Full Restore.
|
|
The count of *uses* is AI-driven, not a fixed two.
|
|
- **"You now have 15 badges!"** Nothing in the asm counts badges as an ordinal; Kanto
|
|
gyms have no enforced order (`ENGINE_VOLCANOBADGE` is one bit,
|
|
`constants/engine_flags.asm:53`). The 15 is walkthrough prose that assumes a specific
|
|
visiting order.
|
|
- **Route 21 wild list is abridged in the walkthrough.** The FAQ lists Tentacool and
|
|
Tangela. `data/wild/kanto_grass.asm:1005` also has **MR__MIME** in all three
|
|
time slots, and `data/wild/kanto_water.asm:61` also has **TENTACRUEL**. Route 20's
|
|
list is likewise incomplete (TENTACRUEL is there too).
|
|
- **"Surf south on Route 21 ... head way left then down."** The trainer coordinates
|
|
confirm the shape of the route (16 -> 22 -> 30, then far west), but the actual walkable
|
|
water path is block data in `maps/Route21.blk` and was not decoded here.
|
|
- **"You should see a small cave at the Seafoam Islands."** The only asm anchor is
|
|
`warp_event 38, 7` on `maps/Route20.asm:117` plus `bg_event 37, 11` for the gym sign.
|
|
The cave mouth graphic itself is block data in `maps/Route20.blk`; there is no
|
|
Seafoam Islands dungeon map in Gen 2 (`constants/map_constants.asm` has only
|
|
`SEAFOAM_GYM`), so the walkthrough's "Seafoam Islands" is a landmark name
|
|
(`data/maps/landmarks.asm:94` `LANDMARK_SEAFOAM_ISLANDS`) rather than a walkable
|
|
dungeon.
|
|
- **EXP figures.** The per-mon EXP numbers in the FAQ (600 for a L28 Seel, 1056 for a
|
|
L28 Dewgong, 1492 for a L34 Tentacruel) are consistent with the vanilla
|
|
`base_exp * level / 7` times the 1.5x trainer-battle bonus, but nothing in
|
|
`data/trainers/parties.asm` stores them and they still vary with participation, so
|
|
they are not reproducible from the asm as written. The **money** figures all reproduce
|
|
exactly and are recorded above.
|
|
- **`EVENT_BEAT_BLAINE` has no reader.** Grepping `maps/`, `data/`, `engine/`, `home/`
|
|
and `constants/` finds it only at its definition (`constants/event_flags.asm:721`) and
|
|
its single `setevent` (`maps/SeafoamGym.asm:29`). If the port needs a "Blaine beaten"
|
|
predicate for anything, `ENGINE_VOLCANOBADGE` is the flag the cart actually branches on.
|