36 KiB
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:182map_const ROUTE_21, 10, 18(groupCINNABAR= 6, map id 7). 10x18 blocks = 20x36 tile coordinates. - Attributes / border:
data/maps/attributes.asm:274map_attributes Route21, ROUTE_21, $43 - Connections: north
PALLET_TOWN(offset 0), southCINNABAR_ISLAND(offset 0) - Landmark position:
data/maps/landmarks.asm:96landmark 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, sym4e:4803) -trainer SWIMMERF, NIKKI, EVENT_BEAT_SWIMMERF_NIKKI, SwimmerfNikkiSeenText, SwimmerfNikkiBeatenText, 0, .Script. The0is the loss-text slot (no whiteout text)..Scriptisendifjustbattled+ one after-battle line; no items, no flags beyond the beat flag.TrainerFisherArnold(maps/Route21.asm:33, sym4e:4817) - same shape,EVENT_BEAT_FISHER_ARNOLD.TrainerSwimmermSeth(maps/Route21.asm:11, sym4e: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:183map_const CINNABAR_ISLAND, 10, 9(groupCINNABAR= 6, map id 8). 20x18 tile coordinates. - Attributes / border:
data/maps/attributes.asm:279map_attributes CinnabarIsland, CINNABAR_ISLAND, $43 - Connections: north
ROUTE_21(offset 0), eastROUTE_20(offset 0) - Landmark:
data/maps/landmarks.asm:95landmark 52, 132, CinnabarIslandName - Fly / respawn point:
data/maps/flypoints.asm:28db LANDMARK_CINNABAR_ISLAND, SPAWN_CINNABAR;data/maps/spawn_points.asm:24spawn 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, sym4e:4981), wired ascallback MAPCALLBACK_NEWMAPat:8. Body is exactlysetflag ENGINE_FLYPOINT_CINNABAR/endcallback. Walking in once is the whole unlock for flying here.CinnabarIslandBlue(maps/CinnabarIsland.asm:14, sym4e: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
iftrueat the top: the script is one-shot only becausedisappearsets the object's ownEVENT_BLUE_IN_CINNABAR(seeScript_disappearatengine/overworld/scripting.asm:887,ld b, 1 ; set). CinnabarIslandBlueTeleport(:38) is a two-byte movement stream:teleport_from($4c,macros/scripts/movement.asm:148) thenstep_end. That is the "levitates and flies off" the walkthrough describes.clearevent EVENT_VIRIDIAN_GYM_BLUEis the load-bearing side effect: that flag is set at boot byInitializeEventsScript(engine/events/std_scripts.asm:552) and it hides bothVIRIDIANGYM_BLUEand the Viridian gym guide (maps/ViridianGym.asm:183-184). Talking to Blue here is the only thing that puts Blue in Viridian Gym.
- There is no guard flag and no
CinnabarIslandHiddenRareCandy(maps/CinnabarIsland.asm:35) - ahiddenitemoperand, 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:176map_const CINNABAR_POKECENTER_1F, 5, 4(groupCINNABAR= 6, map id 1) - Attributes:
data/maps/attributes.asm:510map_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:181map_const ROUTE_20, 30, 9(groupCINNABAR= 6, map id 6). 60x18 tile coordinates. - Attributes / border:
data/maps/attributes.asm:283map_attributes Route20, ROUTE_20, $43 - Connections: west
CINNABAR_ISLAND(offset 0), eastROUTE_19(offset -9) - Landmarks in view:
data/maps/landmarks.asm:93Route 20,:94SeafoamIslandsName
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, sym4e:4cfa), wired ascallback MAPCALLBACK_NEWMAPat:10. Body issetevent EVENT_CINNABAR_ROCKS_CLEARED/endcallback. It fires silently the first time the map loads. Consumers:Route19ClearRocksCallback(maps/Route19.asm:15, sym4e:4f09, aMAPCALLBACK_TILEScallback) draws sixchangeblock ... $7a ; rockblocks at (6,6), (8,6), (10,6), (12,8), (4,8), (10,10) while the flag is clear; the officer inmaps/Route19FuchsiaGate.asm:12and the two fishers inmaps/Route19.asm:74/:90swap dialogue on it.TrainerSwimmermCameron(maps/Route20.asm:38, sym4e: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_20row exists indata/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:179map_const SEAFOAM_GYM, 5, 4(groupCINNABAR= 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:513map_attributes SeafoamGym, SEAFOAM_GYM, $09; no connections - There is no
MAP_SEAFOAM_ISLANDSdungeon in Gen 2 -constants/map_constants.asmhas onlySEAFOAM_GYMin 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, sym53:516d). Control flow:faceplayer,opentextcheckflag ENGINE_VOLCANOBADGE/iftrue .FightDone- the entire re-talk guard is the badge engine flag, not an event flag.writetext BlaineIntroText,waitbutton,closetextwinlosstext BlaineWinLossText, 0(no loss text)loadtrainer BLAINE, BLAINE1,startbattleiftrue .ReturnAfterBattle- i.e. if the battle result is non-zero (you lost / drew) it skipsappear SEAFOAMGYM_GYM_GUIDEappear SEAFOAMGYM_GYM_GUIDE- clearsEVENT_SEAFOAM_GYM_GYM_GUIDE, which is how the guide "comes in late".ReturnAfterBattle:reloadmapafterbattle,setevent EVENT_BEAT_BLAINE,opentext,writetext ReceivedVolcanoBadgeText,playsound SFX_GET_BADGE,waitsfx,setflag ENGINE_VOLCANOBADGE,writetext BlaineAfterBattleText,waitbutton,closetext,end
- No
verbosegiveitemanywhere: Blaine gives no TM, only the badge. - Note the ordering quirk:
setevent EVENT_BEAT_BLAINE/setflag ENGINE_VOLCANOBADGEare on the shared.ReturnAfterBattlepath, reached whether or not you won, butstartbattledoes not return to the script on a whiteout, so in practice this is only reached after a win.
SeafoamGymGuideScript(maps/SeafoamGym.asm:46, sym53:51a3) - branches onEVENT_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.
PALLET_TOWN: SURF south across the connection intoROUTE_21 (6,7). Pre: FOGBADGE + SURF in the party. Post: none.ROUTE_21: battleTrainerSwimmerfNikkiat (11,16) - sight radius 3, so she will trigger on approach. Party L28 SEEL x3 + L28 DEWGONG. Post:EVENT_BEAT_SWIMMERF_NIKKI, +560 money.ROUTE_21: battleTrainerFisherArnoldat (14,22) - sight radius 1, faces up. Party L34 TENTACRUEL. Post:EVENT_BEAT_FISHER_ARNOLD, +1360 money.ROUTE_21: surf west then south toTrainerSwimmermSethat (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 areOBJECTTYPE_TRAINERwith a finite sight radius, none are on a coord event.)ROUTE_21: continue south across the connection intoCINNABAR_ISLAND (6,8). Post:MAPCALLBACK_NEWMAPsetsENGINE_FLYPOINT_CINNABAR; respawn point becomesSPAWN_CINNABAR= (11,12).CINNABAR_ISLAND: step on warp 1 at (11,11) ->CINNABAR_POKECENTER_1F (6,1). Talk toCINNABARPOKECENTER1F_NURSEat (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).CINNABAR_ISLAND: optional - face (9,1) and press A for the hidden RARE_CANDY. Pre:EVENT_CINNABAR_ISLAND_HIDDEN_RARE_CANDYclear + a free bag slot. Post: flag set. (Not in the walkthrough.)CINNABAR_ISLAND: walk toCINNABARISLAND_BLUEat (9,6) and talk. Pre:EVENT_BLUE_IN_CINNABARclear. Expect a longwritetext(about 13 pages ofparabreaks - budget A presses accordingly), thenSFX_WARP_TO+ ateleport_frommovement, then the object vanishes. Post:EVENT_BLUE_IN_CINNABARset (viadisappear),EVENT_VIRIDIAN_GYM_BLUEcleared. Do not skip this step: it is the only unlock for the Viridian Gym leader.CINNABAR_ISLAND: optional signs at (12,11), (9,11), (7,7).CINNABAR_ISLAND: SURF east across the connection intoROUTE_20 (6,6). Post:MAPCALLBACK_NEWMAPsetsEVENT_CINNABAR_ROCKS_CLEARED(silent; unseals Route 19 for the next section).ROUTE_20: battleTrainerSwimmermCameronat (12,13) - sight radius 3. Party L34 MARILL. Post:EVENT_BEAT_SWIMMERM_CAMERON, +272 money.ROUTE_20: optional sign at (37,11). Then step onto warp 1 at (38,7) ->SEAFOAM_GYM (6,4).SEAFOAM_GYM: walk toSEAFOAMGYM_BLAINEat (5,2) and talk. Pre:ENGINE_VOLCANOBADGEclear (otherwise you get.FightDoneonly). Battle:loadtrainer BLAINE, BLAINE1- L45 MAGCARGO / L45 MAGMAR / L50 RAPIDASH, AI holds MAX_POTION + FULL_HEAL. Post:EVENT_BEAT_BLAINEset,EVENT_SEAFOAM_GYM_GYM_GUIDEcleared (guide appears at (6,5)),ENGINE_VOLCANOBADGEset, +5000 money. No TM, no item.SEAFOAM_GYM: optional - talk toSEAFOAMGYM_GYM_GUIDEat (6,5). Post:EVENT_TALKED_TO_SEAFOAM_GYM_GUIDE_ONCE.SEAFOAM_GYM: exit via warp 1 at (5,5) back toROUTE_20warp 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-2308gives 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 inconstants/move_constants.asmat 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:276isdb 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_VOLCANOBADGEis 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:1005also has MR__MIME in all three time slots, anddata/wild/kanto_water.asm:61also 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.blkand was not decoded here. - "You should see a small cave at the Seafoam Islands." The only asm anchor is
warp_event 38, 7onmaps/Route20.asm:117plusbg_event 37, 11for the gym sign. The cave mouth graphic itself is block data inmaps/Route20.blk; there is no Seafoam Islands dungeon map in Gen 2 (constants/map_constants.asmhas onlySEAFOAM_GYM), so the walkthrough's "Seafoam Islands" is a landmark name (data/maps/landmarks.asm:94LANDMARK_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 / 7times the 1.5x trainer-battle bonus, but nothing indata/trainers/parties.asmstores 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_BLAINEhas no reader. Greppingmaps/,data/,engine/,home/andconstants/finds it only at its definition (constants/event_flags.asm:721) and its singlesetevent(maps/SeafoamGym.asm:29). If the port needs a "Blaine beaten" predicate for anything,ENGINE_VOLCANOBADGEis the flag the cart actually branches on.