67 KiB
Section 12 - Team Rocket Radio Tower
Source: ../section-12-team-rocket-radio-tower.txt (the FAQ's own heading is
"18 > Team Rocket Radio Tower")
Maps covered: MAP_GOLDENROD_CITY, MAP_RADIO_TOWER_1F, MAP_RADIO_TOWER_2F,
MAP_RADIO_TOWER_3F, MAP_RADIO_TOWER_4F, MAP_RADIO_TOWER_5F,
MAP_GOLDENROD_UNDERGROUND, MAP_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES,
MAP_GOLDENROD_UNDERGROUND_WAREHOUSE, MAP_GOLDENROD_DEPT_STORE_B1F
Badges / key milestones in this section:
- No badge. The section is bracketed by two key items and one story flag:
BASEMENT_KEY(from the fake director,RADIO_TOWER_5F),CARD_KEY(from the real director,GOLDENROD_UNDERGROUND_WAREHOUSE), andEVENT_CLEARED_RADIO_TOWER+RAINBOW_WING(Gold) /SILVER_WING(Silver) fromRadioTower5FRocketBossScript. - The rival's fourth battle (
RIVAL1_4_*) happens in the middle of it. - Entry condition is the 7th badge, not any item: see section 3.
1. Route order
| # | Map constant | asm file | Enter via | Leaves via | Why (walkthrough beat) |
|---|---|---|---|---|---|
| 1 | MAP_GOLDENROD_CITY |
maps/GoldenrodCity.asm |
Fly (ENGINE_FLYPOINT_GOLDENROD, set by GoldenrodCityFlypointCallback) |
warp 12 at (5,15) | Elm's phone call; city is full of Rockets |
| 2 | MAP_RADIO_TOWER_1F |
maps/RadioTower1F.asm |
warps 1/2 at (2,7)/(3,7) | warp 3 at (15,0) | first Grunt (TrainerGruntM3) |
| 3 | MAP_RADIO_TOWER_2F |
maps/RadioTower2F.asm |
warp 2 at (15,0) | warp 1 at (0,0) | four Grunts, head left |
| 4 | MAP_RADIO_TOWER_3F |
maps/RadioTower3F.asm |
warp 1 at (0,0) | warp 2 at (7,0) | two Grunts + Scientist Marc |
| 5 | MAP_RADIO_TOWER_4F |
maps/RadioTower4F.asm |
warp 2 at (9,0) | warp 1 at (0,0) | TrainerGruntM10, TrainerScientistRich |
| 6 | MAP_RADIO_TOWER_5F |
maps/RadioTower5F.asm |
warp 1 at (0,0) | warp 1 at (0,0) | coord_event 0, 3 -> FakeDirectorScript, EXECUTIVEM_3, BASEMENT_KEY |
| 7 | MAP_GOLDENROD_CITY |
maps/GoldenrodCity.asm |
radio tower warp | warp 14 at (9,5) | "northwesternmost building" = north Underground entrance |
| 8 | MAP_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES |
maps/GoldenrodUndergroundSwitchRoomEntrances.asm |
warp 8 at (20,29) | warp 7 at (21,25) | just the stairwell room on this pass |
| 9 | MAP_GOLDENROD_UNDERGROUND |
maps/GoldenrodUnderground.asm |
warp 1 at (3,2) | warp 3 at (18,6) | Pokemon Salon (haircut brothers); the locked door |
| 10 | MAP_GOLDENROD_UNDERGROUND (south half) |
same file | warp 4 at (21,31) | warp 6 at (22,27) | the basement door is a same-map warp pair |
| 11 | MAP_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES |
maps/GoldenrodUndergroundSwitchRoomEntrances.asm |
warp 1 at (23,3) | warps 2/3 at (22,10)/(23,10) | rival battle, three switch Grunts, two Burglars, the shutter puzzle |
| 12 | MAP_GOLDENROD_UNDERGROUND_WAREHOUSE |
maps/GoldenrodUndergroundWarehouse.asm |
warps 1/2 at (2,12)/(3,12) | warp 3 at (17,2) | three Grunts, Max Ether, TM35, the Director + CARD_KEY |
| 13 | MAP_GOLDENROD_DEPT_STORE_B1F |
maps/GoldenrodDeptStoreB1F.asm |
warp 1 at (17,2) | warp 1 back, or elevator warps 2/3 at (9,4)/(10,4) | Amulet Coin at (14,2) |
| 14 | MAP_RADIO_TOWER_3F |
maps/RadioTower3F.asm |
2F warp 1 at (0,0) | warp 3 at (17,0) | bg_event 14, 2, BGEVENT_UP, CardKeySlotScript; TrainerGruntM9 |
| 15 | MAP_RADIO_TOWER_4F |
maps/RadioTower4F.asm |
warp 4 at (17,0) | warp 3 at (12,0) | TrainerGruntF4, TrainerExecutivem2 |
| 16 | MAP_RADIO_TOWER_5F |
maps/RadioTower5F.asm |
warp 2 at (12,0) | warp 2 at (12,0) | TrainerExecutivef1, then coord_event 16, 5 -> RadioTower5FRocketBossScript |
Spill into the next section: the walkthrough's closing party-level lists and the
video link's mention of Route 44 belong to whatever section follows; nothing
after RadioTower5FRocketBossScript is covered here.
2. Maps
MAP_GOLDENROD_CITY
- Script:
maps/GoldenrodCity.asm - Blocks:
maps/GoldenrodCity.blk - Header:
data/maps/maps.asm:269->TILESET_JOHTO_MODERN,TOWN,LANDMARK_GOLDENROD_CITY,MUSIC_GOLDENROD_CITY, phoneFALSE,PALETTE_AUTO,FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:247->map_const GOLDENROD_CITY, 20, 18 - Connections:
data/maps/attributes.asm:139-> northROUTE_35(offset 5), southROUTE_34(offset 5). No east/west.
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 24 | 7 | GOLDENROD_GYM |
1 |
| 2 | 29 | 29 | GOLDENROD_BIKE_SHOP |
1 |
| 3 | 31 | 21 | GOLDENROD_HAPPINESS_RATER |
1 |
| 4 | 5 | 25 | BILLS_FAMILYS_HOUSE |
1 |
| 5 | 9 | 13 | GOLDENROD_MAGNET_TRAIN_STATION |
2 |
| 6 | 33 | 5 | GOLDENROD_FLOWER_SHOP |
1 |
| 7 | 15 | 27 | GOLDENROD_POKECENTER_1F |
1 |
| 8 | 33 | 9 | GOLDENROD_PP_SPEECH_HOUSE |
1 |
| 9 | 15 | 7 | GOLDENROD_NAME_RATER |
1 |
| 10 | 24 | 27 | GOLDENROD_DEPT_STORE_1F |
1 |
| 11 | 14 | 21 | GOLDENROD_GAME_CORNER |
1 |
| 12 | 5 | 15 | RADIO_TOWER_1F |
1 |
| 13 | 19 | 1 | ROUTE_35_GOLDENROD_GATE |
3 |
| 14 | 9 | 5 | GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES |
8 |
| 15 | 11 | 29 | GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES |
5 |
Warp 14 is the "northwesternmost building" the walkthrough sends you to for the Basement Key trip; warp 15 is the southern Underground entrance.
Coord events (def_coord_events) - none.
BG events (def_bg_events)
| x | y | type | script/item |
|---|---|---|---|
| 10 | 14 | BGEVENT_READ |
GoldenrodCityStationSign |
| 4 | 17 | BGEVENT_READ |
GoldenrodCityRadioTowerSign |
| 26 | 27 | BGEVENT_READ |
GoldenrodDeptStoreSign |
| 26 | 9 | BGEVENT_READ |
GoldenrodGymSign |
| 22 | 18 | BGEVENT_READ |
GoldenrodCitySign |
| 28 | 30 | BGEVENT_READ |
GoldenrodCityBikeShopSign |
| 16 | 22 | BGEVENT_READ |
GoldenrodCityGameCornerSign |
| 12 | 7 | BGEVENT_READ |
GoldenrodCityNameRaterSign |
| 8 | 6 | BGEVENT_READ |
GoldenrodCityUndergroundSignNorth |
| 12 | 30 | BGEVENT_READ |
GoldenrodCityUndergroundSignSouth |
| 16 | 27 | BGEVENT_READ |
GoldenrodCityPokecenterSign |
Object events (def_object_events)
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
GOLDENRODCITY_POKEFAN_M1 |
SPRITE_POKEFAN_M |
7 | 18 | STANDING_UP |
SCRIPT |
GoldenrodCityPokefanMScript |
EVENT_GOLDENROD_CITY_CIVILIANS |
GOLDENRODCITY_YOUNGSTER1 |
SPRITE_YOUNGSTER |
30 | 17 | WANDER |
SCRIPT |
GoldenrodCityYoungster1Script |
EVENT_GOLDENROD_CITY_CIVILIANS |
GOLDENRODCITY_COOLTRAINER_F1 |
SPRITE_COOLTRAINER_F |
12 | 16 | STANDING_LEFT |
SCRIPT |
GoldenrodCityCooltrainerF1Script |
EVENT_GOLDENROD_CITY_CIVILIANS |
GOLDENRODCITY_COOLTRAINER_F2 |
SPRITE_COOLTRAINER_F |
20 | 26 | WANDER |
SCRIPT |
GoldenrodCityCooltrainerF2Script |
EVENT_GOLDENROD_CITY_CIVILIANS |
GOLDENRODCITY_YOUNGSTER2 |
SPRITE_YOUNGSTER |
19 | 17 | WANDER |
SCRIPT |
GoldenrodCityYoungster2Script |
EVENT_GOLDENROD_CITY_CIVILIANS |
GOLDENRODCITY_LASS |
SPRITE_LASS |
17 | 10 | WALK_LEFT_RIGHT |
SCRIPT |
GoldenrodCityLassScript |
EVENT_GOLDENROD_CITY_CIVILIANS |
GOLDENRODCITY_GRAMPS |
SPRITE_GRAMPS |
11 | 27 | WALK_LEFT_RIGHT |
SCRIPT |
GoldenrodCityGrampsScript |
EVENT_GOLDENROD_CITY_CIVILIANS |
GOLDENRODCITY_ROCKETSCOUT |
SPRITE_ROCKET |
4 | 16 | STANDING_UP |
SCRIPT |
GoldenrodCityRocketScoutScript |
EVENT_GOLDENROD_CITY_ROCKET_SCOUT |
GOLDENRODCITY_ROCKET1 |
SPRITE_ROCKET |
28 | 20 | STANDING_UP |
SCRIPT |
GoldenrodCityRocket1Script |
EVENT_GOLDENROD_CITY_ROCKET_TAKEOVER |
GOLDENRODCITY_ROCKET2 |
SPRITE_ROCKET |
8 | 15 | STANDING_DOWN |
SCRIPT |
GoldenrodCityRocket2Script |
EVENT_GOLDENROD_CITY_ROCKET_TAKEOVER |
GOLDENRODCITY_ROCKET3 |
SPRITE_ROCKET |
16 | 23 | STANDING_RIGHT |
SCRIPT |
GoldenrodCityRocket3Script |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
GOLDENRODCITY_ROCKET4 |
SPRITE_ROCKET |
29 | 20 | STANDING_UP |
SCRIPT |
GoldenrodCityRocket4Script |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
GOLDENRODCITY_ROCKET5 |
SPRITE_ROCKET |
29 | 7 | STANDING_DOWN |
SCRIPT |
GoldenrodCityRocket5Script |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
GOLDENRODCITY_ROCKET6 |
SPRITE_ROCKET |
30 | 10 | STANDING_LEFT |
SCRIPT |
GoldenrodCityRocket6Script |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
None of the city Rockets are trainers - they are all jumptextfaceplayer.
Scripts of interest
GoldenrodCityFlypointCallback(MAPCALLBACK_NEWMAP):setflag ENGINE_FLYPOINT_GOLDENROD/setflag ENGINE_REACHED_GOLDENROD. This is why the walkthrough can say "fly to the city".
MAP_RADIO_TOWER_1F
- Script:
maps/RadioTower1F.asm - Blocks:
maps/RadioTower1F.blk - Header:
data/maps/maps.asm:95->TILESET_RADIO_TOWER,INDOOR,LANDMARK_RADIO_TOWER,RADIO_TOWER_MUSIC | MUSIC_GOLDENROD_CITY, phoneTRUE,PALETTE_DAY,FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:82->map_const RADIO_TOWER_1F, 9, 4 - Connections: none (
data/maps/attributes.asm:414, environment byte$00)
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 2 | 7 | GOLDENROD_CITY |
12 |
| 2 | 3 | 7 | GOLDENROD_CITY |
12 |
| 3 | 15 | 0 | RADIO_TOWER_2F |
2 |
Coord events - none.
BG events
| x | y | type | script/item |
|---|---|---|---|
| 3 | 0 | BGEVENT_READ |
RadioTower1FDirectory |
| 13 | 0 | BGEVENT_READ |
RadioTower1FLuckyChannelSign |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
RADIOTOWER1F_RECEPTIONIST |
SPRITE_RECEPTIONIST |
5 | 6 | STANDING_LEFT |
SCRIPT |
RadioTower1FReceptionistScript |
-1 |
RADIOTOWER1F_LASS |
SPRITE_LASS |
16 | 4 | STANDING_LEFT |
SCRIPT |
RadioTower1FLassScript |
EVENT_GOLDENROD_CITY_CIVILIANS |
RADIOTOWER1F_YOUNGSTER |
SPRITE_YOUNGSTER |
15 | 4 | STANDING_RIGHT |
SCRIPT |
RadioTower1FYoungsterScript |
EVENT_GOLDENROD_CITY_CIVILIANS |
RADIOTOWER1F_ROCKET |
SPRITE_ROCKET |
14 | 1 | STANDING_DOWN |
TRAINER (sight 3) |
TrainerGruntM3 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER1F_LUCKYNUMBERMAN |
SPRITE_GENTLEMAN |
8 | 6 | STANDING_UP |
SCRIPT |
RadioTower1FLuckyNumberManScript |
EVENT_GOLDENROD_CITY_CIVILIANS |
RADIOTOWER1F_CARD_WOMAN |
SPRITE_COOLTRAINER_F |
12 | 6 | STANDING_UP |
SCRIPT |
RadioTower1FRadioCardWomanScript |
EVENT_GOLDENROD_CITY_CIVILIANS |
Scripts of interest
RadioTower1FReceptionistScript-checkflag ENGINE_ROCKETS_IN_RADIO_TOWER; if set, the "no tours today" line. Pure flavour, no gate.TrainerGruntM3-trainer GRUNTM, GRUNTM_3, EVENT_BEAT_ROCKET_GRUNTM_3, .... Sight range 3 facing down from (14,1): he intercepts the walk to warp 3 at (15,0).RadioTower1FRadioCardWomanScript/RadioTower1FLuckyNumberManScriptare the Radio Card quiz and the Lucky Number Show. Both are hidden whileEVENT_GOLDENROD_CITY_CIVILIANSis set, i.e. for the whole of this section.
MAP_RADIO_TOWER_2F
- Script:
maps/RadioTower2F.asm - Blocks:
maps/RadioTower2F.blk - Header:
data/maps/maps.asm:96-> same row shape as 1F - Dimensions:
constants/map_constants.asm:83->map_const RADIO_TOWER_2F, 9, 4
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 0 | 0 | RADIO_TOWER_3F |
1 |
| 2 | 15 | 0 | RADIO_TOWER_1F |
3 |
Coord events - none.
BG events
| x | y | type | script/item |
|---|---|---|---|
| 3 | 0 | BGEVENT_READ |
RadioTower2FSalesSign |
| 5 | 0 | BGEVENT_READ |
RadioTower2FOaksPKMNTalkSign |
| 9 | 1 | BGEVENT_READ |
RadioTower2FBookshelf |
| 10 | 1 | BGEVENT_READ |
RadioTower2FBookshelf |
| 11 | 1 | BGEVENT_READ |
RadioTower2FBookshelf |
| 13 | 0 | BGEVENT_READ |
RadioTower2FPokemonRadioSign |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
RADIOTOWER2F_SUPER_NERD |
SPRITE_SUPER_NERD |
5 | 6 | WALK_LEFT_RIGHT |
SCRIPT |
RadioTower2FSuperNerdScript |
EVENT_GOLDENROD_CITY_CIVILIANS |
RADIOTOWER2F_TEACHER |
SPRITE_TEACHER |
13 | 2 | WALK_LEFT_RIGHT |
SCRIPT |
RadioTower2FTeacherScript |
-1 |
RADIOTOWER2F_ROCKET1 |
SPRITE_ROCKET |
1 | 4 | STANDING_UP |
TRAINER (sight 3) |
TrainerGruntM4 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER2F_ROCKET2 |
SPRITE_ROCKET |
8 | 4 | STANDING_DOWN |
TRAINER (sight 3) |
TrainerGruntM5 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER2F_ROCKET3 |
SPRITE_ROCKET |
4 | 1 | STANDING_DOWN |
TRAINER (sight 2) |
TrainerGruntM6 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER2F_ROCKET_GIRL |
SPRITE_ROCKET_GIRL |
10 | 5 | STANDING_UP |
TRAINER (sight 3) |
TrainerGruntF2 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER2F_BLACK_BELT1 |
SPRITE_BLACK_BELT |
0 | 1 | STANDING_DOWN |
SCRIPT |
RadioTower2FBlackBelt1Script |
EVENT_RADIO_TOWER_BLACKBELT_BLOCKS_STAIRS |
RADIOTOWER2F_BLACK_BELT2 |
SPRITE_BLACK_BELT |
1 | 1 | STANDING_DOWN |
SCRIPT |
RadioTower2FBlackBelt2Script |
EVENT_RADIO_TOWER_CIVILIANS_AFTER |
RADIOTOWER2F_JIGGLYPUFF |
SPRITE_JIGGLYPUFF |
12 | 1 | POKEMON |
SCRIPT |
RadioTowerJigglypuff |
-1 |
Scripts of interest
RadioTower2FBlackBelt1Scriptat (0,1) is the pre-takeover stairs blocker ("Authorized personnel only beyond this point").RadioTowerRocketsScript(engine/events/std_scripts.asm:255) doessetevent EVENT_RADIO_TOWER_BLACKBELT_BLOCKS_STAIRS, and a SET object event flag MASKS the object (CheckObjectFlag,engine/overworld/map_objects_2.asm:32), so during the takeover he is gone and warp 1 at (0,0) is walkable.- Walkthrough order on this floor is
TrainerGruntF2(10,5) ->TrainerGruntM5(8,4) ->TrainerGruntM6(4,1) ->TrainerGruntM4(1,4).
MAP_RADIO_TOWER_3F
- Script:
maps/RadioTower3F.asm - Blocks:
maps/RadioTower3F.blk - Header:
data/maps/maps.asm:97 - Dimensions:
constants/map_constants.asm:84->map_const RADIO_TOWER_3F, 9, 4
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 0 | 0 | RADIO_TOWER_2F |
1 |
| 2 | 7 | 0 | RADIO_TOWER_4F |
2 |
| 3 | 17 | 0 | RADIO_TOWER_4F |
4 |
Warp 3 is only reachable once the Card Key shutter is open.
Coord events - none.
BG events
| x | y | type | script/item |
|---|---|---|---|
| 3 | 0 | BGEVENT_READ |
RadioTower3FPersonnelSign |
| 9 | 0 | BGEVENT_READ |
RadioTower3FPokemonMusicSign |
| 14 | 2 | BGEVENT_UP |
CardKeySlotScript |
BGEVENT_UP means the player must be FACING UP on the tile below (14,2) for the
press to register (engine/overworld/events.asm:644 .up -> .checkdir
compares wPlayerDirection & %1100 against OW_UP).
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
RADIOTOWER3F_SUPER_NERD |
SPRITE_SUPER_NERD |
7 | 4 | STANDING_UP |
SCRIPT |
RadioTower3FSuperNerdScript |
EVENT_RADIO_TOWER_CIVILIANS_AFTER |
RADIOTOWER3F_GYM_GUIDE |
SPRITE_GYM_GUIDE |
3 | 4 | SPINRANDOM_FAST |
SCRIPT |
RadioTower3FGymGuideScript |
-1 |
RADIOTOWER3F_COOLTRAINER_F |
SPRITE_COOLTRAINER_F |
11 | 3 | WANDER |
SCRIPT |
RadioTower3FCooltrainerFScript |
-1 |
RADIOTOWER3F_ROCKET1 |
SPRITE_ROCKET |
5 | 1 | STANDING_RIGHT |
TRAINER (sight 2) |
TrainerGruntM7 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER3F_ROCKET2 |
SPRITE_ROCKET |
6 | 2 | STANDING_DOWN |
TRAINER (sight 3) |
TrainerGruntM8 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER3F_ROCKET3 |
SPRITE_ROCKET |
16 | 6 | STANDING_UP |
TRAINER (sight 3) |
TrainerGruntM9 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER3F_SCIENTIST |
SPRITE_SCIENTIST |
9 | 6 | STANDING_UP |
TRAINER (sight 5) |
TrainerScientistMarc |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
TrainerGruntM9 at (16,6) sits behind the shutter: he is only reachable on the
second pass.
Scripts of interest
RadioTower3FCardKeyShutterCallback(callback MAPCALLBACK_TILES, label at43:5be1):checkevent EVENT_USED_THE_CARD_KEY_IN_THE_RADIO_TOWER; if true,changeblock 14, 2, $2a(open shutter) andchangeblock 14, 4, $01(floor). This is what makes the opening persist across map loads.CardKeySlotScript(43:5c91, exported with::so other maps can reach it): writesRadioTower3FCardKeySlotText, thencheckevent EVENT_USED_THE_CARD_KEY_IN_THE_RADIO_TOWER(already used -> just close), elsecheckitem CARD_KEY. With the key:InsertedTheCardKeyText,setevent EVENT_USED_THE_CARD_KEY_IN_THE_RADIO_TOWER,playsound SFX_ENTER_DOOR, the same twochangeblocks,refreshmap.RadioTower3FCooltrainerFScript- afterEVENT_CLEARED_RADIO_TOWER,verbosegiveitem TM_SUNNY_DAYandsetevent EVENT_GOT_SUNNY_DAY_FROM_RADIO_TOWER. The walkthrough does not mention this reward.
MAP_RADIO_TOWER_4F
- Script:
maps/RadioTower4F.asm - Blocks:
maps/RadioTower4F.blk - Header:
data/maps/maps.asm:98 - Dimensions:
constants/map_constants.asm:85->map_const RADIO_TOWER_4F, 9, 4
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 0 | 0 | RADIO_TOWER_5F |
1 |
| 2 | 9 | 0 | RADIO_TOWER_3F |
2 |
| 3 | 12 | 0 | RADIO_TOWER_5F |
2 |
| 4 | 17 | 0 | RADIO_TOWER_3F |
3 |
Coord events - none.
BG events
| x | y | type | script/item |
|---|---|---|---|
| 7 | 0 | BGEVENT_READ |
RadioTower4FProductionSign |
| 15 | 0 | BGEVENT_READ |
RadioTower4FStudio2Sign |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
RADIOTOWER4F_FISHER |
SPRITE_FISHER |
6 | 4 | STANDING_UP |
SCRIPT |
RadioTower4FFisherScript |
EVENT_RADIO_TOWER_CIVILIANS_AFTER |
RADIOTOWER4F_TEACHER |
SPRITE_TEACHER |
14 | 6 | SPINRANDOM_SLOW |
SCRIPT |
RadioTower4FDJMaryScript |
-1 |
RADIOTOWER4F_GROWLITHE |
SPRITE_GROWLITHE |
12 | 7 | POKEMON |
SCRIPT |
RadioTowerMeowth |
-1 |
RADIOTOWER4F_ROCKET1 |
SPRITE_ROCKET |
5 | 6 | SPINCLOCKWISE |
TRAINER (sight 3) |
TrainerGruntM10 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER4F_ROCKET2 |
SPRITE_ROCKET |
14 | 1 | STANDING_LEFT (radius 2,0) |
TRAINER (sight 2) |
TrainerExecutivem2 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER4F_ROCKET_GIRL |
SPRITE_ROCKET_GIRL |
12 | 4 | STANDING_RIGHT |
TRAINER (sight 1) |
TrainerGruntF4 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER4F_SCIENTIST |
SPRITE_SCIENTIST |
4 | 2 | STANDING_LEFT |
TRAINER (sight 4) |
TrainerScientistRich |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
Scripts of interest
TrainerExecutivem2at (14,1) guards warp 3 (12,0), the second route to 5F.RadioTower4FDJMaryScript- afterEVENT_CLEARED_RADIO_TOWER,verbosegiveitem PINK_BOWandsetevent EVENT_GOT_PINK_BOW_FROM_MARY. Another reward the walkthrough skips.
MAP_RADIO_TOWER_5F
- Script:
maps/RadioTower5F.asm - Blocks:
maps/RadioTower5F.blk - Header:
data/maps/maps.asm:99 - Dimensions:
constants/map_constants.asm:86->map_const RADIO_TOWER_5F, 9, 4
Scene ids come from this map's own def_scene_scripts block (scene_script
allocates them in order, macros/scripts/maps.asm:25):
SCENE_RADIOTOWER5F_FAKE_DIRECTOR = 0, SCENE_RADIOTOWER5F_ROCKET_BOSS = 1,
SCENE_RADIOTOWER5F_NOOP = 2. All three scene bodies are end; the work is
entirely in the coord events.
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 0 | 0 | RADIO_TOWER_4F |
1 |
| 2 | 12 | 0 | RADIO_TOWER_4F |
3 |
Coord events
| scene | x | y | script label | effect |
|---|---|---|---|---|
SCENE_RADIOTOWER5F_FAKE_DIRECTOR (0) |
0 | 3 | FakeDirectorScript |
fake director battle, BASEMENT_KEY |
SCENE_RADIOTOWER5F_ROCKET_BOSS (1) |
16 | 5 | RadioTower5FRocketBossScript |
final Executive, tower cleared |
BG events
| x | y | type | script/item |
|---|---|---|---|
| 3 | 0 | BGEVENT_READ |
RadioTower5FDirectorsOfficeSign |
| 11 | 0 | BGEVENT_READ |
RadioTower5FStudio1Sign |
| 15 | 0 | BGEVENT_READ |
RadioTower5FStudio1Sign |
| 16 | 1 | BGEVENT_READ |
RadioTower5FBookshelf |
| 17 | 1 | BGEVENT_READ |
RadioTower5FBookshelf |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
RADIOTOWER5F_DIRECTOR |
SPRITE_GENTLEMAN |
3 | 6 | SPINRANDOM_SLOW |
SCRIPT |
Director |
-1 |
RADIOTOWER5F_ROCKET |
SPRITE_ROCKET |
13 | 5 | STANDING_LEFT |
SCRIPT |
ObjectEvent |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER5F_ROCKET_GIRL |
SPRITE_ROCKET_GIRL |
17 | 2 | STANDING_LEFT |
TRAINER (sight 1) |
TrainerExecutivef1 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
RADIOTOWER5F_ROCKER |
SPRITE_ROCKER |
13 | 5 | STANDING_LEFT |
SCRIPT |
Ben |
EVENT_RADIO_TOWER_CIVILIANS_AFTER |
Note the deliberate coordinate collision at (13,5): the Rocket boss and DJ Ben occupy the same cell, masked by complementary flags.
Scripts of interest
-
FakeDirectorScript(43:6748) -turnobject RADIOTOWER5F_DIRECTOR, UP,showemote EMOTE_SHOCK, text,applymovement RADIOTOWER5F_DIRECTOR, FakeDirectorMovement(LEFT x3, UP x2, from (3,6) to (0,4)),playmusic MUSIC_ROCKET_ENCOUNTER,winlosstext FakeDirectorWinText, 0,setlasttalked RADIOTOWER5F_DIRECTOR,loadtrainer EXECUTIVEM, EXECUTIVEM_3,startbattle,reloadmapafterbattle,verbosegiveitem BASEMENT_KEY,setscene SCENE_RADIOTOWER5F_ROCKET_BOSS,setevent EVENT_BEAT_ROCKET_EXECUTIVEM_3. Note theverbosegiveitemresult is not checked - there is no bag-full arm. -
RadioTower5FRocketBossScript(43:67a5) -applymovement PLAYERtwo steps LEFT (from (16,5) to (14,5)),playmusic MUSIC_ROCKET_ENCOUNTER,turnobject RADIOTOWER5F_ROCKET, RIGHT,loadtrainer EXECUTIVEM, EXECUTIVEM_1,startbattle,reloadmapafterbattle. Afterwards it fades out, disappears both Rockets, then does the whole flag cascade:setevent EVENT_BEAT_ROCKET_EXECUTIVEM_1 setevent EVENT_CLEARED_RADIO_TOWER clearflag ENGINE_ROCKETS_IN_RADIO_TOWER setevent EVENT_GOLDENROD_CITY_ROCKET_SCOUT setevent EVENT_GOLDENROD_CITY_ROCKET_TAKEOVER setevent EVENT_RADIO_TOWER_ROCKET_TAKEOVER clearevent EVENT_MAHOGANY_MART_OWNERS clearflag ENGINE_ROCKETS_IN_MAHOGANY clearevent EVENT_GOLDENROD_CITY_CIVILIANS clearevent EVENT_RADIO_TOWER_CIVILIANS_AFTER setevent EVENT_BLACKTHORN_CITY_SUPER_NERD_BLOCKS_GYM clearevent EVENT_BLACKTHORN_CITY_SUPER_NERD_DOES_NOT_BLOCK_GYMThen
moveobject RADIOTOWER5F_DIRECTOR, 12, 0/appear/applymovement RadioTower5FDirectorWalksIn,checkver: Silver takes.SilverWing(verbosegiveitem SILVER_WING,setevent EVENT_GOT_SILVER_WING), Gold falls through (verbosegiveitem RAINBOW_WING,setevent EVENT_GOT_RAINBOW_WING,setevent EVENT_TEAM_ROCKET_DISBANDED). Both armssetscene SCENE_RADIOTOWER5F_NOOPand end withRadioTower5FDirectorWalksOut+disappear. -
Director(the talk-to script) branches onEVENT_CLEARED_RADIO_TOWER.
MAP_GOLDENROD_UNDERGROUND
- Script:
maps/GoldenrodUnderground.asm - Blocks:
maps/GoldenrodUnderground.blk - Header:
data/maps/maps.asm:123->TILESET_GATE,DUNGEON,LANDMARK_GOLDENROD_CITY,MUSIC_UNION_CAVE, phoneTRUE,PALETTE_DAY,FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:110->map_const GOLDENROD_UNDERGROUND, 15, 18
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 3 | 2 | GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES |
7 |
| 2 | 3 | 34 | GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES |
4 |
| 3 | 18 | 6 | GOLDENROD_UNDERGROUND |
4 |
| 4 | 21 | 31 | GOLDENROD_UNDERGROUND |
3 |
| 5 | 22 | 31 | GOLDENROD_UNDERGROUND |
3 |
| 6 | 22 | 27 | GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES |
1 |
Warps 3/4/5 are a same-map pair: the Basement Key door at (18,6) drops you at (21,31), and (22,27) is the stairs into the switch room proper.
Coord events - none.
BG events
| x | y | type | script/item |
|---|---|---|---|
| 18 | 6 | BGEVENT_READ |
BasementDoorScript |
| 19 | 6 | BGEVENT_READ |
GoldenrodUndergroundNoEntrySign |
| 6 | 13 | BGEVENT_ITEM |
hiddenitem PARLYZ_HEAL, EVENT_GOLDENROD_UNDERGROUND_HIDDEN_PARLYZ_HEAL |
| 4 | 18 | BGEVENT_ITEM |
hiddenitem SUPER_POTION, EVENT_GOLDENROD_UNDERGROUND_HIDDEN_SUPER_POTION |
| 17 | 8 | BGEVENT_ITEM |
hiddenitem ANTIDOTE, EVENT_GOLDENROD_UNDERGROUND_HIDDEN_ANTIDOTE |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
GOLDENRODUNDERGROUND_SUPER_NERD1 |
SPRITE_SUPER_NERD |
5 | 31 | STANDING_LEFT |
TRAINER (sight 3) |
TrainerSupernerdEric |
-1 |
GOLDENRODUNDERGROUND_SUPER_NERD2 |
SPRITE_SUPER_NERD |
6 | 9 | STANDING_UP |
TRAINER (sight 2) |
TrainerSupernerdTeru |
-1 |
GOLDENRODUNDERGROUND_SUPER_NERD3 |
SPRITE_SUPER_NERD |
3 | 27 | SPINRANDOM_FAST |
TRAINER (sight 2) |
TrainerPokemaniacIssac |
-1 |
GOLDENRODUNDERGROUND_SUPER_NERD4 |
SPRITE_SUPER_NERD |
2 | 6 | STANDING_RIGHT |
TRAINER (sight 3) |
TrainerPokemaniacDonald |
-1 |
GOLDENRODUNDERGROUND_POKE_BALL |
SPRITE_POKE_BALL |
7 | 25 | STILL |
ITEMBALL |
itemball COIN_CASE |
EVENT_GOLDENROD_UNDERGROUND_COIN_CASE |
GOLDENRODUNDERGROUND_GRAMPS |
SPRITE_GRAMPS |
7 | 11 | STANDING_LEFT |
SCRIPT |
BargainMerchantScript |
EVENT_GOLDENROD_UNDERGROUND_GRAMPS |
GOLDENRODUNDERGROUND_OLDER_HAIRCUT_BROTHER |
SPRITE_SUPER_NERD |
7 | 14 | STANDING_LEFT |
SCRIPT |
OlderHaircutBrotherScript |
EVENT_GOLDENROD_UNDERGROUND_OLDER_HAIRCUT_BROTHER |
GOLDENRODUNDERGROUND_YOUNGER_HAIRCUT_BROTHER |
SPRITE_SUPER_NERD |
7 | 15 | STANDING_LEFT |
SCRIPT |
YoungerHaircutBrotherScript |
EVENT_GOLDENROD_UNDERGROUND_YOUNGER_HAIRCUT_BROTHER |
GOLDENRODUNDERGROUND_GRANNY |
SPRITE_GRANNY |
7 | 21 | STANDING_LEFT |
SCRIPT |
BitterMerchantScript |
EVENT_GOLDENROD_UNDERGROUND_GRANNY |
Scripts of interest
BasementDoorScript(46:429e, exported::) -checkevent EVENT_USED_BASEMENT_KEY(already open -> "The door is open"), elsecheckitem BASEMENT_KEY; with the key:playsound SFX_TRANSACTION,changeblock 18, 6, $2e(unlocked door),refreshmap,setevent EVENT_USED_BASEMENT_KEY. Without it: "The door's locked..."GoldenrodUndergroundCheckBasementKeyCallback(MAPCALLBACK_TILES) re-locks the block on every map load untilEVENT_USED_BASEMENT_KEYis set:changeblock 18, 6, $3d.GoldenrodUndergroundResetSwitchesCallback(MAPCALLBACK_NEWMAP) - clearsEVENT_SWITCH_1..3,EVENT_EMERGENCY_SWITCH,EVENT_DOOR_1_OPEN .. EVENT_DOOR_11_OPEN, andsetval 0/writemem wUndergroundSwitchPositions(01:d6a8). This is the "exit to the stairs then come back up so the switches are reset" step the walkthrough relies on. The warehouse map has an identical callback (GoldenrodUndergroundWarehouseResetSwitchesCallback).OlderHaircutBrotherScript/YoungerHaircutBrotherScript- the "Pokemon Salon" happiness boost. Day-gated byGoldenrodUndergroundCheckDayOfWeekCallback(MAPCALLBACK_OBJECTS): older brother TUE/THU/SAT (500), younger brother SUN/WED/FRI (300). Once per day viaENGINE_GOLDENROD_UNDERGROUND_GOT_HAIRCUT.
MAP_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES
- Script:
maps/GoldenrodUndergroundSwitchRoomEntrances.asm - Blocks:
maps/GoldenrodUndergroundSwitchRoomEntrances.blk - Header:
data/maps/maps.asm:124->TILESET_ELITE_FOUR_ROOM,DUNGEON,LANDMARK_GOLDENROD_CITY,MUSIC_UNION_CAVE, phoneTRUE,PALETTE_DAY,FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:111->map_const GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES, 15, 18
Scene ids from this map's own block:
SCENE_GOLDENRODUNDERGROUNDSWITCHROOMENTRANCES_RIVAL_BATTLE = 0,
..._NOOP = 1.
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 23 | 3 | GOLDENROD_UNDERGROUND |
6 |
| 2 | 22 | 10 | GOLDENROD_UNDERGROUND_WAREHOUSE |
1 |
| 3 | 23 | 10 | GOLDENROD_UNDERGROUND_WAREHOUSE |
2 |
| 4 | 5 | 25 | GOLDENROD_UNDERGROUND |
2 |
| 5 | 4 | 29 | GOLDENROD_CITY |
15 |
| 6 | 5 | 29 | GOLDENROD_CITY |
15 |
| 7 | 21 | 25 | GOLDENROD_UNDERGROUND |
1 |
| 8 | 20 | 29 | GOLDENROD_CITY |
14 |
| 9 | 21 | 29 | GOLDENROD_CITY |
14 |
Coord events
| scene | x | y | script label | effect |
|---|---|---|---|---|
..._RIVAL_BATTLE (0) |
19 | 4 | UndergroundRivalScene1 |
rival appears from (23,3), battle |
..._RIVAL_BATTLE (0) |
19 | 5 | UndergroundRivalScene2 |
same, one row lower |
BG events
| x | y | type | script/item |
|---|---|---|---|
| 16 | 1 | BGEVENT_READ |
Switch1Script |
| 10 | 1 | BGEVENT_READ |
Switch2Script |
| 2 | 1 | BGEVENT_READ |
Switch3Script |
| 20 | 11 | BGEVENT_READ |
EmergencySwitchScript |
| 8 | 9 | BGEVENT_ITEM |
hiddenitem MAX_POTION, EVENT_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES_HIDDEN_MAX_POTION |
| 1 | 8 | BGEVENT_ITEM |
hiddenitem REVIVE, EVENT_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES_HIDDEN_REVIVE |
The two hidden items are not mentioned by the walkthrough.
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
..._PHARMACIST1 |
SPRITE_PHARMACIST |
9 | 12 | STANDING_RIGHT |
TRAINER (sight 2) |
TrainerBurglarDuncan |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
..._PHARMACIST2 |
SPRITE_PHARMACIST |
4 | 8 | STANDING_LEFT |
TRAINER (sight 2) |
TrainerBurglarEddie |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
..._ROCKET1 |
SPRITE_ROCKET |
17 | 2 | STANDING_DOWN |
TRAINER (sight 3) |
TrainerGruntM13 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
..._ROCKET2 |
SPRITE_ROCKET |
11 | 2 | STANDING_DOWN |
TRAINER (sight 3) |
TrainerGruntM11 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
..._ROCKET3 |
SPRITE_ROCKET |
3 | 2 | STANDING_DOWN |
TRAINER (sight 3) |
TrainerGruntM25 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
..._ROCKET_GIRL |
SPRITE_ROCKET_GIRL |
19 | 12 | STANDING_DOWN |
TRAINER (sight 1) |
TrainerGruntF3 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
..._TEACHER |
SPRITE_TEACHER |
3 | 27 | STANDING_DOWN |
SCRIPT |
GoldenrodUndergroundSwitchRoomEntrancesTeacherScript |
-1 |
..._SUPER_NERD |
SPRITE_SUPER_NERD |
19 | 27 | STANDING_DOWN |
SCRIPT |
GoldenrodUndergroundSwitchRoomEntrancesSuperNerdScript |
-1 |
..._POKE_BALL1 |
SPRITE_POKE_BALL |
1 | 12 | STILL |
ITEMBALL |
itemball SMOKE_BALL |
EVENT_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES_SMOKE_BALL |
..._POKE_BALL2 |
SPRITE_POKE_BALL |
14 | 9 | STILL |
ITEMBALL |
itemball FULL_HEAL |
EVENT_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES_FULL_HEAL |
..._RIVAL |
SPRITE_RIVAL |
23 | 3 | STANDING_DOWN |
SCRIPT |
ObjectEvent |
EVENT_RIVAL_GOLDENROD_UNDERGROUND |
Scripts of interest - the shutter puzzle
This is the load-bearing part of the section, and the asm behaves differently from how the walkthrough describes it.
The eleven shutters are declared at the top of the file by the local
ugdoor_def macro (coordinates are changeblock coordinates, i.e. the same
cell units the script uses):
| door | x, y | closed block | open block | second half (x, y, closed, open) |
|---|---|---|---|---|
| 1 | 16, 6 | $3e |
$2d |
- |
| 2 | 10, 6 | $3e |
$2d |
- |
| 3 | 2, 6 | $3e |
$2d |
- |
| 4 | 2, 10 | $3e |
$2d |
- |
| 5 | 10, 10 | $3e |
$2d |
- |
| 6 | 16, 10 | $3e |
$2d |
- |
| 7 | 12, 6 | $3f |
$2a |
12, 8, $3d, $2d |
| 8 | 6, 6 | $3f |
$2a |
6, 8, $3d, $2d |
| 9 | 12, 10 | $3f |
$2a |
12, 12, $3d, $2d |
| 10 | 6, 10 | $3f |
$2a |
6, 12, $3d, $2d |
| 11 | 18, 10 | $3f |
$2a |
18, 12, $3d, $2d |
Switch1Script / Switch2Script / Switch3Script each readmem wUndergroundSwitchPositions (01:d6a8), addval +N when turning ON or
addval -N when turning OFF (N = 1, 2, 3 respectively), writemem it back,
set/clear EVENT_SWITCH_N, then sjump GoldenrodUndergroundSwitchRoomEntrances_UpdateDoors (46:4c57).
EmergencySwitchScript at (20,11) is different: ON does setval 7 (not an
add), sets EVENT_EMERGENCY_SWITCH and all three EVENT_SWITCH_*; OFF does
setval 0 and clears all four.
..._UpdateDoors dispatches on the stored byte. Crucially each position only
touches SOME doors - the rest keep whatever state the previous position left
them in, which is the entire reason order matters:
| value | opens | closes | untouched |
|---|---|---|---|
| 0 | - | 1..11 | - |
| 1 | 1, 7, 10 | 6, 8, 9, 11 | 2, 3, 4, 5 |
| 2 | 2, 8, 9 | 5, 7, 10, 11 | 1, 3, 4, 6 |
| 3 | 3, 7, 10 | 4, 8, 9, 11 | 1, 2, 5, 6 |
| 4 | 4, 8, 9 | 3, 7, 10, 11 | 1, 2, 5, 6 |
| 5 | 5, 7, 10 | 2, 8, 9, 11 | 1, 3, 4, 6 |
| 6 | 6, 8, 9, 11 | 1, 7, 10 | 2, 3, 4, 5 |
| 7 (emergency) | 3, 5, 6, 8, 9, 11 | 1, 2, 4, 7, 10 | - |
The emergency arm ends with setval 6 / writemem, so the stored byte becomes
6 afterwards even though the door layout is the emergency one.
Consequences a bot needs (derived by tracing the table, from the reset state where the stored byte is 0 and all doors closed):
- Flip 1, then 2, then 3 (values 1 -> 3 -> 6). Final open doors: 3, 6, 8, 9, 11.
Door 8 at (6,6)/(6,8) is what lets you drop south from the switch-3 alcove to
TrainerBurglarEddieat (4,8). - From there flip 3 off then 2 off (values 6 -> 3 -> 1). Final open doors: 1, 3, 7, 10. Door 7 at (12,6)/(12,8) is what opens the way to the Full Heal ball at (14,9).
- Reset (leave via a warp so the
MAPCALLBACK_NEWMAPreset runs) and flip 3, then 2, then 1 (values 3 -> 5 -> 6). Final open doors: 3, 5, 6, 8, 9, 11 - the same set as 1/2/3 PLUS door 5 at (10,10). Door 5 is the one that opens the route south toTrainerBurglarDuncan(9,12),TrainerGruntF3(19,12) and the warehouse warps at (22,10)/(23,10).
So the walkthrough's "turn them on in the opposite direction" is correct in effect, but the mechanism is not "order is remembered": the stored byte is a plain SUM (1+2+3 = 3+2+1 = 6), and what differs is which doors the intermediate positions left untouched.
UndergroundRivalBattleScript (46:4a9e):
checkevent EVENT_RIVAL_BURNED_TOWER
iftrue .Continue
setevent EVENT_RIVAL_BURNED_TOWER
setmapscene BURNED_TOWER_1F, SCENE_BURNEDTOWER1F_FIREBREATHER_DICK
.Continue:
playmusic MUSIC_RIVAL_ENCOUNTER
... setevent EVENT_RIVAL_GOLDENROD_UNDERGROUND
checkevent EVENT_GOT_TOTODILE_FROM_ELM -> loadtrainer RIVAL1, RIVAL1_4_CHIKORITA
checkevent EVENT_GOT_CHIKORITA_FROM_ELM -> loadtrainer RIVAL1, RIVAL1_4_CYNDAQUIL
else -> loadtrainer RIVAL1, RIVAL1_4_TOTODILE
i.e. the rival's starter is the one with type advantage over yours, as usual.
winlosstext UndergroundRivalWinText, UndergroundRivalLossText - this battle is
LOSABLE (a real loss text exists), unlike the Executive fights.
MAP_GOLDENROD_UNDERGROUND_WAREHOUSE
- Script:
maps/GoldenrodUndergroundWarehouse.asm - Blocks:
maps/GoldenrodUndergroundWarehouse.blk - Header:
data/maps/maps.asm:126->TILESET_UNDERGROUND,DUNGEON,LANDMARK_GOLDENROD_CITY,MUSIC_UNION_CAVE, phoneTRUE,PALETTE_DAY,FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:113->map_const GOLDENROD_UNDERGROUND_WAREHOUSE, 10, 9
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 2 | 12 | GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES |
2 |
| 2 | 3 | 12 | GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES |
3 |
| 3 | 17 | 2 | GOLDENROD_DEPT_STORE_B1F |
1 |
Coord events - none. BG events - none.
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
..._ROCKET1 |
SPRITE_ROCKET |
9 | 8 | STANDING_UP |
TRAINER (sight 3) |
TrainerGruntM24 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
..._ROCKET2 |
SPRITE_ROCKET |
8 | 15 | STANDING_UP |
TRAINER (sight 3) |
TrainerGruntM14 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
..._ROCKET3 |
SPRITE_ROCKET |
14 | 3 | STANDING_RIGHT |
TRAINER (sight 4) |
TrainerGruntM15 |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
..._GENTLEMAN |
SPRITE_GENTLEMAN |
12 | 8 | SPINRANDOM_SLOW |
SCRIPT |
GoldenrodUndergroundWarehouseDirectorScript |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
..._POKE_BALL1 |
SPRITE_POKE_BALL |
18 | 15 | STILL |
ITEMBALL |
itemball MAX_ETHER |
EVENT_GOLDENROD_UNDERGROUND_WAREHOUSE_MAX_ETHER |
..._POKE_BALL2 |
SPRITE_POKE_BALL |
13 | 9 | STILL |
ITEMBALL |
itemball TM_SLEEP_TALK |
EVENT_GOLDENROD_UNDERGROUND_WAREHOUSE_TM_SLEEP_TALK |
Note the Director object is masked by EVENT_RADIO_TOWER_ROCKET_TAKEOVER the
same way the Grunts are: once the tower is cleared he is gone from here.
Scripts of interest
GoldenrodUndergroundWarehouseDirectorScript(46:598a) -checkevent EVENT_RECEIVED_CARD_KEY; if not:DirectorIntroText,verbosegiveitem CARD_KEY,setevent EVENT_RECEIVED_CARD_KEY,setevent EVENT_GOLDENROD_DEPT_STORE_B1F_LAYOUT_1,clearevent ..._LAYOUT_2,clearevent ..._LAYOUT_3,DirectorCardKeyText("Use that to open the shutters on 3F"), thenDirectorAfterText. Theverbosegiveitemresult is again unchecked.
MAP_GOLDENROD_DEPT_STORE_B1F
- Script:
maps/GoldenrodDeptStoreB1F.asm - Blocks:
maps/GoldenrodDeptStoreB1F.blk - Header:
data/maps/maps.asm:125->TILESET_UNDERGROUND,DUNGEON,LANDMARK_GOLDENROD_CITY,MUSIC_GOLDENROD_CITY, phoneTRUE,PALETTE_DAY,FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:112->map_const GOLDENROD_DEPT_STORE_B1F, 10, 9
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 17 | 2 | GOLDENROD_UNDERGROUND_WAREHOUSE |
3 |
| 2 | 9 | 4 | GOLDENROD_DEPT_STORE_ELEVATOR |
1 |
| 3 | 10 | 4 | GOLDENROD_DEPT_STORE_ELEVATOR |
2 |
Coord events - none. BG events - none.
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
..._POKE_BALL1 |
SPRITE_POKE_BALL |
10 | 15 | STILL |
ITEMBALL |
itemball ETHER |
EVENT_GOLDENROD_DEPT_STORE_B1F_ETHER |
..._POKE_BALL2 |
SPRITE_POKE_BALL |
14 | 2 | STILL |
ITEMBALL |
itemball AMULET_COIN |
EVENT_GOLDENROD_DEPT_STORE_B1F_AMULET_COIN |
..._POKE_BALL3 |
SPRITE_POKE_BALL |
6 | 3 | STILL |
ITEMBALL |
itemball BURN_HEAL |
EVENT_GOLDENROD_DEPT_STORE_B1F_BURN_HEAL |
..._POKE_BALL4 |
SPRITE_POKE_BALL |
15 | 15 | STILL |
ITEMBALL |
itemball ULTRA_BALL |
EVENT_GOLDENROD_DEPT_STORE_B1F_ULTRA_BALL |
..._BLACK_BELT1 |
SPRITE_BLACK_BELT |
9 | 10 | WALK_UP_DOWN |
SCRIPT |
GoldenrodDeptStoreB1FBlackBelt1Script |
-1 |
..._BLACK_BELT2 |
SPRITE_BLACK_BELT |
4 | 8 | SPINRANDOM_SLOW |
SCRIPT |
GoldenrodDeptStoreB1FBlackBelt2Script |
-1 |
..._BLACK_BELT3 |
SPRITE_BLACK_BELT |
6 | 13 | WALK_LEFT_RIGHT |
SCRIPT |
GoldenrodDeptStoreB1FBlackBelt3Script |
-1 |
..._MACHOP |
SPRITE_MACHOP |
7 | 7 | POKEMON |
SCRIPT |
GoldenrodDeptStoreB1FMachopScript |
-1 |
Scripts of interest
GoldenRodDeptStoreB1FClearBoxesCallback(MAPCALLBACK_TILES) -checkevent EVENT_RECEIVED_CARD_KEY->changeblock 16, 4, $0d(floor). Then the crate layout:EVENT_GOLDENROD_DEPT_STORE_B1F_LAYOUT_2->changeblock 4, 10, $0d;..._LAYOUT_3->changeblock 10, 12, $0d; default (LAYOUT_1) ->changeblock 10, 8, $0d.GoldenRodDeptStoreUnblockCallback(MAPCALLBACK_NEWMAP) -clearevent EVENT_GOLDENROD_UNDERGROUND_WAREHOUSE_BLOCKED_OFF. That event starts SET (InitializeEventsScript,engine/events/std_scripts.asm:518) and is whatGoldenrodDeptStoreElevatorScript(maps/GoldenrodDeptStoreElevator.asm:15) checks before rotating the crate layout - so the layout only ever changes once you have entered B1F on foot from the warehouse.
Flags and events (whole section)
| constant | defined in | read/written by | meaning for a bot |
|---|---|---|---|
ENGINE_ROCKETS_IN_RADIO_TOWER |
constants/engine_flags.asm:28 |
set by RadioTowerRocketsScript; cleared by RadioTower5FRocketBossScript; read by RadioTower1FReceptionistScript, RadioTower2FTeacherScript, MahoganyRedGyaradosSpeechHouse, engine/phone/scripts/trainers.asm |
"the takeover arc is live"; also switches the radio programming |
EVENT_RADIO_TOWER_ROCKET_TAKEOVER |
constants/event_flags.asm:1136 |
CLEARED by RadioTowerRocketsScript, SET again by RadioTower5FRocketBossScript |
object mask for every Rocket trainer in this section; SET = hidden |
EVENT_GOLDENROD_CITY_ROCKET_TAKEOVER |
:1135 |
cleared by GoldenrodRocketsScript (6 badges), set by RadioTower5FRocketBossScript |
the two earliest city Rockets |
EVENT_GOLDENROD_CITY_ROCKET_SCOUT |
:1134 |
set by RadioTower5FRocketBossScript |
hides the scout at (4,16) once cleared |
EVENT_GOLDENROD_CITY_CIVILIANS |
:1137 |
set by RadioTowerRocketsScript, cleared by RadioTower5FRocketBossScript |
SET hides the city + 1F/2F civilians for the whole section |
EVENT_RADIO_TOWER_CIVILIANS_AFTER |
:1138 |
set at InitializeEventsScript, cleared by RadioTower5FRocketBossScript |
the "after" NPCs (Ben, 3F super nerd, 4F fisher, 2F black belt 2) |
EVENT_RADIO_TOWER_BLACKBELT_BLOCKS_STAIRS |
:1139 |
set by RadioTowerRocketsScript |
SET removes the 2F stairs blocker, i.e. the takeover is what opens 3F |
EVENT_USED_THE_CARD_KEY_IN_THE_RADIO_TOWER |
:46 |
cleared by RadioTowerRocketsScript, set by CardKeySlotScript, read by RadioTower3FCardKeyShutterCallback and RadioTower3FCooltrainerFScript |
the 3F shutter |
EVENT_CLEARED_RADIO_TOWER |
:42 |
set by RadioTower5FRocketBossScript |
section-complete flag; gates the TM Sunny Day / Pink Bow rewards |
EVENT_USED_BASEMENT_KEY |
:82 |
set by BasementDoorScript, read by GoldenrodUndergroundCheckBasementKeyCallback |
the Underground locked door |
EVENT_RECEIVED_CARD_KEY |
:83 |
set by GoldenrodUndergroundWarehouseDirectorScript, read by GoldenRodDeptStoreB1FClearBoxesCallback |
one-shot on the Card Key |
EVENT_SWITCH_1/2/3, EVENT_EMERGENCY_SWITCH |
:386-389 |
the four switch scripts; cleared by both reset callbacks | which switch is lit |
EVENT_DOOR_1_OPEN .. EVENT_DOOR_11_OPEN |
:390-400 |
..._UpdateDoors .OpenDoorN / .CloseDoorN; replayed by ..._UpdateDoorPositionsCallback (MAPCALLBACK_TILES) |
per-shutter persistent state |
EVENT_RIVAL_GOLDENROD_UNDERGROUND |
:1123 |
set inside UndergroundRivalBattleScript |
masks the rival object afterwards |
EVENT_RIVAL_BURNED_TOWER |
grep constants/event_flags.asm |
set by UndergroundRivalBattleScript if not already |
side effect: sets BURNED_TOWER_1F scene to SCENE_BURNEDTOWER1F_FIREBREATHER_DICK |
EVENT_GOLDENROD_DEPT_STORE_B1F_LAYOUT_1/2/3 |
:435-437 |
director script, GoldenrodDeptStoreElevatorScript |
which crate row is open on B1F |
EVENT_GOLDENROD_UNDERGROUND_WAREHOUSE_BLOCKED_OFF |
:438 |
set by InitializeEventsScript, cleared by GoldenRodDeptStoreUnblockCallback |
freezes the crate rotation until you have walked B1F |
EVENT_TEAM_ROCKET_DISBANDED |
:1283 |
set by RadioTower5FRocketBossScript only on the Gold branch; also set in maps/PewterCity.asm:51 |
masks the TIN_TOWER_1F sage at (10,2) |
EVENT_GOT_RAINBOW_WING / EVENT_GOT_SILVER_WING |
:129-130 |
RadioTower5FRocketBossScript checkver arms |
Gold vs Silver reward |
SCENE_RADIOTOWER5F_FAKE_DIRECTOR = 0, _ROCKET_BOSS = 1, _NOOP = 2 |
maps/RadioTower5F.asm:9-11 |
setscene in both coord scripts |
which 5F cutscene is armed |
SCENE_GOLDENRODUNDERGROUNDSWITCHROOMENTRANCES_RIVAL_BATTLE = 0, _NOOP = 1 |
maps/GoldenrodUndergroundSwitchRoomEntrances.asm:57-58 |
setscene at the end of both rival scenes |
one-shot rival trip-wire |
SPECIALCALL_WEIRDBROADCAST = 4 |
constants/phone_constants.asm:48 |
queued by RadioTowerRocketsScript; row 4 of data/phone/special_calls.asm is SpecialCallOnlyWhenOutside, PHONECONTACT_ELM, ElmPhoneCallerScript; consumed at engine/phone/scripts/elm.asm:68 .rocket |
Elm's call the walkthrough opens with. Only rings OUTDOORS. |
Items
| item | how obtained | source (label / bg_event / hidden) | one-time flag |
|---|---|---|---|
BASEMENT_KEY |
verbosegiveitem after EXECUTIVEM_3 |
FakeDirectorScript, maps/RadioTower5F.asm |
EVENT_BEAT_ROCKET_EXECUTIVEM_3 (scene also advances) |
SMOKE_BALL |
ground ball at (1,12) | GoldenrodUndergroundSwitchRoomEntrancesSmokeBall |
EVENT_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES_SMOKE_BALL |
FULL_HEAL |
ground ball at (14,9) | GoldenrodUndergroundSwitchRoomEntrancesFullHeal |
EVENT_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES_FULL_HEAL |
MAX_POTION |
hidden at (8,9) | bg_event 8, 9, BGEVENT_ITEM |
EVENT_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES_HIDDEN_MAX_POTION |
REVIVE |
hidden at (1,8) | bg_event 1, 8, BGEVENT_ITEM |
EVENT_GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES_HIDDEN_REVIVE |
MAX_ETHER |
ground ball at (18,15) | GoldenrodUndergroundWarehouseMaxEther |
EVENT_GOLDENROD_UNDERGROUND_WAREHOUSE_MAX_ETHER |
TM_SLEEP_TALK (TM35) |
ground ball at (13,9) | GoldenrodUndergroundWarehouseTMSleepTalk |
EVENT_GOLDENROD_UNDERGROUND_WAREHOUSE_TM_SLEEP_TALK |
CARD_KEY |
talk to Director at (12,8) | GoldenrodUndergroundWarehouseDirectorScript |
EVENT_RECEIVED_CARD_KEY |
AMULET_COIN |
ground ball at (14,2) on B1F | GoldenrodDeptStoreB1FAmuletCoin |
EVENT_GOLDENROD_DEPT_STORE_B1F_AMULET_COIN |
RAINBOW_WING (Gold) / SILVER_WING (Silver) |
director cutscene | RadioTower5FRocketBossScript checkver |
EVENT_GOT_RAINBOW_WING / EVENT_GOT_SILVER_WING |
TM_SUNNY_DAY (TM11) |
talk 3F cooltrainer_f (11,3) after clearing | RadioTower3FCooltrainerFScript |
EVENT_GOT_SUNNY_DAY_FROM_RADIO_TOWER |
PINK_BOW |
talk DJ Mary (14,6) after clearing | RadioTower4FDJMaryScript |
EVENT_GOT_PINK_BOW_FROM_MARY |
TM numbering checked against constants/item_constants.asm:219 (TM01 =
DYNAMICPUNCH): SUNNY_DAY is TM11 and SLEEP_TALK is TM35.
Trainers
All parties from data/trainers/parties.asm; class group labels named in the
"party" column. Constants from constants/trainer_constants.asm.
| const | class | id | party (data/trainers/parties.asm) |
script label | map |
|---|---|---|---|---|---|
GRUNTM_3 |
GRUNTM |
3 | GruntMGroup "; GRUNTM (3)": 24 RATICATE, 24 RATICATE |
TrainerGruntM3 |
RADIO_TOWER_1F (14,1) |
GRUNTF_2 |
GRUNTF |
2 | GruntFGroup (2): 26 ARBOK |
TrainerGruntF2 |
RADIO_TOWER_2F (10,5) |
GRUNTM_5 |
GRUNTM |
5 | (5): 21 RATTATA, 21 RATTATA, 23 RATTATA, 23 RATTATA, 23 RATTATA |
TrainerGruntM5 |
RADIO_TOWER_2F (8,4) |
GRUNTM_6 |
GRUNTM |
6 | (6): 26 ZUBAT, 26 ZUBAT |
TrainerGruntM6 |
RADIO_TOWER_2F (4,1) |
GRUNTM_4 |
GRUNTM |
4 | (4): 23 GRIMER, 23 GRIMER, 25 MUK |
TrainerGruntM4 |
RADIO_TOWER_2F (1,4) |
GRUNTM_8 |
GRUNTM |
8 | (8): 26 WEEZING |
TrainerGruntM8 |
RADIO_TOWER_3F (6,2) |
GRUNTM_7 |
GRUNTM |
7 | (7): 23 KOFFING, 23 GRIMER, 23 ZUBAT, 23 RATTATA |
TrainerGruntM7 |
RADIO_TOWER_3F (5,1) |
MARC |
SCIENTIST |
4 | ScientistGroup (4) "MARC": 27 MAGNEMITE x3 |
TrainerScientistMarc |
RADIO_TOWER_3F (9,6) |
GRUNTM_10 |
GRUNTM |
10 | (10): 22 ZUBAT, 24 GOLBAT, 22 GRIMER |
TrainerGruntM10 |
RADIO_TOWER_4F (5,6) |
RICH |
SCIENTIST |
5 | ScientistGroup (5) "RICH", TRAINERTYPE_MOVES: 30 PORYGON (Conversion, Conversion2, Recover, Tri Attack) |
TrainerScientistRich |
RADIO_TOWER_4F (4,2) |
EXECUTIVEM_3 |
EXECUTIVEM |
3 | ExecutiveMGroup (3), TRAINERTYPE_MOVES: 30 KOFFING x3 (Tackle/Selfdestruct/Sludge/Smokescreen), 32 WEEZING (Tackle/Explosion/Sludge/Smokescreen), 30 KOFFING, 30 KOFFING (Tackle/Smog/Sludge/Smokescreen) |
FakeDirectorScript (loadtrainer) |
RADIO_TOWER_5F coord (0,3) |
RIVAL1_4_CHIKORITA |
RIVAL1 |
10 | Rival1Group (10): 30 GOLBAT, 28 MAGNEMITE, 30 HAUNTER, 32 SNEASEL, 32 MEGANIUM |
UndergroundRivalBattleScript |
switch room coord (19,4)/(19,5) |
RIVAL1_4_CYNDAQUIL |
RIVAL1 |
11 | (11): same first four, 32 QUILAVA |
as above | as above |
RIVAL1_4_TOTODILE |
RIVAL1 |
12 | (12): same first four, 32 FERALIGATR |
as above | as above |
GRUNTM_13 |
GRUNTM |
13 | (13): 27 RATTATA |
TrainerGruntM13 |
switch room (17,2) |
GRUNTM_11 |
GRUNTM |
11 | (11): 23 MUK, 23 KOFFING, 25 RATTATA |
TrainerGruntM11 |
switch room (11,2) |
GRUNTM_25 |
GRUNTM |
25 | (25): 24 KOFFING, 24 MUK |
TrainerGruntM25 |
switch room (3,2) |
EDDIE |
BURGLAR |
2 | BurglarGroup (2) "EDDIE", TRAINERTYPE_MOVES: 26 GROWLITHE (Roar/Ember/Leer/Take Down), 24 KOFFING (Tackle/Smog/Sludge/Smokescreen) |
TrainerBurglarEddie |
switch room (4,8) |
DUNCAN |
BURGLAR |
1 | BurglarGroup (1) "DUNCAN": 23 KOFFING, 25 MAGMAR, 23 KOFFING |
TrainerBurglarDuncan |
switch room (9,12) |
GRUNTF_3 |
GRUNTF |
3 | (3): 25 GLOOM, 25 GLOOM |
TrainerGruntF3 |
switch room (19,12) |
GRUNTM_14 |
GRUNTM |
14 | (14): 24 RATICATE, 24 GOLBAT |
TrainerGruntM14 |
warehouse (8,15) |
GRUNTM_15 |
GRUNTM |
15 | (15): 26 GRIMER, 23 WEEZING |
TrainerGruntM15 |
warehouse (14,3) |
GRUNTM_24 |
GRUNTM |
24 | (24): 25 KOFFING, 25 KOFFING |
TrainerGruntM24 |
warehouse (9,8) |
GRUNTM_9 |
GRUNTM |
9 | (9): 24 RATICATE, 26 KOFFING |
TrainerGruntM9 |
RADIO_TOWER_3F (16,6), behind the shutter |
GRUNTF_4 |
GRUNTF |
4 | (4): 21 EKANS, 23 ODDISH, 21 EKANS, 24 GLOOM |
TrainerGruntF4 |
RADIO_TOWER_4F (12,4) |
EXECUTIVEM_2 |
EXECUTIVEM |
2 | ExecutiveMGroup (2), TRAINERTYPE_MOVES: 36 GOLBAT (Leech Life/Bite/Confuse Ray/Wing Attack) |
TrainerExecutivem2 |
RADIO_TOWER_4F (14,1) |
EXECUTIVEF_1 |
EXECUTIVEF |
1 | ExecutiveFGroup (1), TRAINERTYPE_MOVES: 32 ARBOK (Wrap/Poison Sting/Bite/Glare), 32 VILEPLUME (Absorb/Sweet Scent/Sleep Powder/Acid), 32 MURKROW (Peck/Pursuit/Haze/Night Shade) |
TrainerExecutivef1 |
RADIO_TOWER_5F (17,2) |
EXECUTIVEM_1 |
EXECUTIVEM |
1 | ExecutiveMGroup (1), TRAINERTYPE_MOVES: 33 HOUNDOUR (Ember/Roar/Bite/Faint Attack), 33 KOFFING (Tackle/Sludge/Smokescreen/Haze), 35 HOUNDOOM (Ember/Smog/Bite/Faint Attack) |
RadioTower5FRocketBossScript (loadtrainer) |
RADIO_TOWER_5F coord (16,5) |
Also present but optional in this stretch (MAP_GOLDENROD_UNDERGROUND, all
event flag -1 so always visible): TrainerSupernerdEric (SUPER_NERD,
ERIC), TrainerSupernerdTeru (SUPER_NERD, TERU),
TrainerPokemaniacIssac, TrainerPokemaniacDonald.
Neither Executive fight nor the fake director fight has a loss text
(winlosstext ..., 0), so a whiteout there is a normal blackout, not a scripted
loss. The rival fight DOES have one (UndergroundRivalLossText).
Wild encounters
None. Grepping data/wild/johto_grass.asm, johto_water.asm, fish.asm and
treemons.asm for RADIO_TOWER or GOLDENROD returns nothing: every map in
this section is INDOOR or DUNGEON with no wild table.
3. Blockers and gates
| Gate | Enforced by (file:label) | Requirement | Unlock condition |
|---|---|---|---|
| The whole arc does not exist yet | maps/*Gym.asm <Gym>ActivateRockets -> engine/events/std_scripts.asm:255 RadioTowerRocketsScript (40:41dc) |
readvar VAR_BADGES equals 7 immediately after a badge is set |
Earn the 7th badge (normally Pryce's Glacierbadge). That script sets ENGINE_ROCKETS_IN_RADIO_TOWER, clears EVENT_RADIO_TOWER_ROCKET_TAKEOVER (spawns every Grunt) and queues SPECIALCALL_WEIRDBROADCAST. ifequal 6 instead runs GoldenrodRocketsScript, which only clears EVENT_GOLDENROD_CITY_ROCKET_TAKEOVER. |
| Elm's call never rings | data/phone/special_calls.asm row 4 = SpecialCallOnlyWhenOutside |
Player must be on an outdoor map | Walk outside; the call is cosmetic, not a gate on anything |
| 2F -> 3F stairs (pre-takeover only) | maps/RadioTower2F.asm object RADIOTOWER2F_BLACK_BELT1 at (0,1), masked by EVENT_RADIO_TOWER_BLACKBELT_BLOCKS_STAIRS |
Flag must be SET for him to vanish (CheckObjectFlag, engine/overworld/map_objects_2.asm) |
RadioTowerRocketsScript sets it |
3F -> 4F east stairs (warp 3 at (17,0)) and TrainerGruntM9 |
maps/RadioTower3F.asm:127 CardKeySlotScript (43:5c91) + RadioTower3FCardKeyShutterCallback (43:5be1) |
checkitem CARD_KEY, and you must press A facing up on the tile below (14,2) because the bg event is BGEVENT_UP |
EVENT_USED_THE_CARD_KEY_IN_THE_RADIO_TOWER, which rewrites blocks (14,2) and (14,4) |
| 5F Rocket boss unreachable on the first visit | maps/RadioTower5F.asm scene: setscene SCENE_RADIOTOWER5F_ROCKET_BOSS only at the end of FakeDirectorScript |
Beat EXECUTIVEM_3 |
The (16,5) coord event only fires on scene 1 |
| Underground locked door at (18,6) | maps/GoldenrodUnderground.asm:372 BasementDoorScript (46:429e) + GoldenrodUndergroundCheckBasementKeyCallback |
checkitem BASEMENT_KEY |
EVENT_USED_BASEMENT_KEY; changeblock 18, 6, $2e |
| The eleven shutters in the switch room | maps/GoldenrodUndergroundSwitchRoomEntrances.asm:346 ..._UpdateDoors (46:4c57), driven by wUndergroundSwitchPositions (01:d6a8) |
No item. A pure state puzzle over a single byte | See the position table in section 2. Resets to 0 on any MAPCALLBACK_NEWMAP of GOLDENROD_UNDERGROUND or GOLDENROD_UNDERGROUND_WAREHOUSE; the emergency switch at (20,11) forces the "everything useful open" layout |
| Rival ambush | coord_event 19, 4 / 19, 5 on scene 0 |
Walking onto either cell | Scene set to ..._NOOP at the end of UndergroundRivalScene1/2 |
| Dept store B1F crate layout | GoldenRodDeptStoreB1FClearBoxesCallback |
EVENT_RECEIVED_CARD_KEY opens block (16,4); layout events pick one of three crate gaps |
Card Key from the Director; the elevator only rotates the layout once EVENT_GOLDENROD_UNDERGROUND_WAREHOUSE_BLOCKED_OFF is cleared by walking into B1F |
No HM field move is required anywhere in this section - no Cut, Surf, Strength, Whirlpool, Waterfall or Flash check appears in any of these maps.
4. Bot checklist
Coordinates are asm cell coordinates. "talk" means face the target and press A.
Pass 1 - Radio Tower up to the Basement Key:
MAP_GOLDENROD_CITY: preconditionENGINE_ROCKETS_IN_RADIO_TOWERset (7 badges). Walk to (5,15), warp 12 ->RADIO_TOWER_1F(2,7).RADIO_TOWER_1F: walk toward (15,0).TrainerGruntM3at (14,1) sights you (range 3, facing down). BattleGRUNTM_3. Post:EVENT_BEAT_ROCKET_GRUNTM_3.- Warp 3 at (15,0) ->
RADIO_TOWER_2F(15,0). RADIO_TOWER_2F: walk left. Fight in this order:TrainerGruntF2(10,5),TrainerGruntM5(8,4),TrainerGruntM6(4,1),TrainerGruntM4(1,4). Precondition for all:EVENT_RADIO_TOWER_ROCKET_TAKEOVERclear.- Warp 1 at (0,0) ->
RADIO_TOWER_3F(0,0). RADIO_TOWER_3F:TrainerGruntM8(6,2),TrainerGruntM7(5,1),TrainerScientistMarc(9,6, sight 5). Do NOT try (14,2) yet - no Card Key.- Warp 2 at (7,0) ->
RADIO_TOWER_4F(9,0). RADIO_TOWER_4F:TrainerGruntM10(5,6),TrainerScientistRich(4,2).- Warp 1 at (0,0) ->
RADIO_TOWER_5F(0,0). Walk DOWN to (0,3): coord event firesFakeDirectorScripton scene 0. BattleEXECUTIVEM_3(6 mons, four of them know Selfdestruct/Explosion). Post:BASEMENT_KEYin bag,EVENT_BEAT_ROCKET_EXECUTIVEM_3, 5F scene = 1. - Retrace: 5F warp 1 -> 4F warp 1 -> 4F warp 2 (9,0) -> 3F warp 2 -> 3F warp 1
(0,0) -> 2F warp 1 -> 2F warp 2 (15,0) -> 1F warp 3 -> 1F warps 1/2 (2,7) ->
GOLDENROD_CITY(5,15).
Pass 2 - Underground to the Card Key:
GOLDENROD_CITY: heal at warp 7 (15,27) if wanted. Walk to (9,5), warp 14 ->GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES(20,29).- Walk to (21,25), warp 7 ->
GOLDENROD_UNDERGROUND(3,2). - Optional: haircut brothers at (7,14)/(7,15) (day-gated); Coin Case ball at (7,25) if not taken.
- Walk to the tile below/beside (18,6) and A-press it:
BasementDoorScriptwithBASEMENT_KEY->EVENT_USED_BASEMENT_KEY. Then step onto (18,6) -> warp 3 ->GOLDENROD_UNDERGROUND(21,31). - Walk to (22,27), warp 6 ->
GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES(23,3). SAVE HERE (the walkthrough's advice; the rival battle is losable). - Walk west to (19,4) or (19,5):
UndergroundRivalScene1/2fires on scene 0. BattleRIVAL1, memberRIVAL1_4_CHIKORITA/_CYNDAQUIL/_TOTODILEpicked by which starter you took. Post:EVENT_RIVAL_GOLDENROD_UNDERGROUND, scene -> 1. (Side effect:EVENT_RIVAL_BURNED_TOWER+ Burned Tower scene.) - Fight
TrainerGruntM13(17,2),TrainerGruntM11(11,2),TrainerGruntM25(3,2) - west along the top corridor. - Switch byte starts at 0. A-press
Switch1Scriptat (16,1) -> ON (byte 1), thenSwitch2Scriptat (10,1) -> ON (byte 3), thenSwitch3Scriptat (2,1) -> ON (byte 6). Doors 3, 6, 8, 9, 11 now open. - Go south through door 8 at (6,6)/(6,8) to
TrainerBurglarEddieat (4,8). BattleBURGLAR EDDIE. - A-press Switch3 (2,1) -> OFF (byte 3), then Switch2 (10,1) -> OFF (byte 1).
Doors 1, 3, 7, 10 open. Take the
FULL_HEALball at (14,9). - Leave and re-enter the map so
..._ResetSwitchesCallbackzeroes everything (e.g. warp 1 at (23,3) intoGOLDENROD_UNDERGROUNDand back through (22,27)). - Now A-press Switch3 (2,1) ON (byte 3), Switch2 (10,1) ON (byte 5), Switch1 (16,1) ON (byte 6). Doors 3, 5, 6, 8, 9, 11 open - door 5 at (10,10) is the new one.
- Go south through door 5 to
TrainerBurglarDuncan(9,12), then east toTrainerGruntF3(19,12). Optionally theSMOKE_BALLball at (1,12) and the two hidden items at (8,9) and (1,8). - Warps 2/3 at (22,10)/(23,10) ->
GOLDENROD_UNDERGROUND_WAREHOUSE(2,12). - Warehouse:
TrainerGruntM14(8,15),MAX_ETHERball at (18,15),TrainerGruntM15(14,3). Optional side trip: warp 3 at (17,2) ->GOLDENROD_DEPT_STORE_B1F(17,2), takeAMULET_COINat (14,2), warp back. TrainerGruntM24(9,8). TakeTM_SLEEP_TALK(TM35) at (13,9). Talk to the Director at (12,8):verbosegiveitem CARD_KEY, postEVENT_RECEIVED_CARD_KEY+EVENT_GOLDENROD_DEPT_STORE_B1F_LAYOUT_1.- Exit back through warps 1/2 (2,12)/(3,12). If a shutter blocks the way out,
A-press
EmergencySwitchScriptat (20,11) (forces doors 3,5,6,8,9,11 open). Then warp 1 at (23,3) or warps 8/9 at (20,29)/(21,29) to leave.
Pass 3 - retake the tower:
GOLDENROD_CITY->RADIO_TOWER_1F(warp 12) -> 2F -> 3F as in steps 2-5.RADIO_TOWER_3F: stand at (14,3) FACING UP and press A on (14,2) (BGEVENT_UP).CardKeySlotScript->EVENT_USED_THE_CARD_KEY_IN_THE_RADIO_TOWER, blocks (14,2)/(14,4) rewritten.- Walk east/south to
TrainerGruntM9at (16,6). BattleGRUNTM_9. - Warp 3 at (17,0) ->
RADIO_TOWER_4F(17,0). BattleTrainerGruntF4(12,4), thenTrainerExecutivem2(14,1) who guards warp 3. - Warp 3 at (12,0) ->
RADIO_TOWER_5F(12,0). BattleTrainerExecutivef1(17,2). - Walk to (16,5): coord event on scene 1 fires
RadioTower5FRocketBossScript. The script moves the PLAYER two cells left first. BattleEXECUTIVEM_1. - Post-conditions:
EVENT_CLEARED_RADIO_TOWER,ENGINE_ROCKETS_IN_RADIO_TOWERcleared, all Rocket objects masked, civilians restored, Blackthorn gym blocker swapped,RAINBOW_WING(Gold) orSILVER_WING(Silver) received, 5F scene -> 2. - Optional pickups now unlocked:
TM_SUNNY_DAYfrom the 3F cooltrainer at (11,3);PINK_BOWfrom DJ Mary at (14,6) on 4F.
5. Port coverage
The Gen 2 side of this repo is data-driven: maps, warps, coord events, bg events,
object events and scripts all come out of src/import/RomExtractorGen2.lua and
run through src/script/gen2/Vm.lua, so "implemented" below means the generic
machinery this section needs exists, not that anyone has walked the section.
| Beat | Port file | Status |
|---|---|---|
| Map/warp/object/bg/coord tables for all nine maps | src/import/RomExtractorGen2.lua (def_* readers), src/world/gen2/Map.lua |
implemented (generic extractor; not spot-checked against these maps) |
| Coord-event trip-wires gated by scene id | src/world/gen2/World.lua:5011 (coordEvents scan against World:scene()), :5025 scene scripts |
implemented |
setscene / checkmapscene / setmapscene, scene persistence in the save |
src/script/gen2/Vm.lua:274, src/world/gen2/World.lua:740-748, src/core/gen2/Save.lua mapScenes |
implemented |
Trainer sight range + approach + startbattle |
src/world/gen2/Trainers.lua, src/world/gen2/World.lua SEEN_BY_TRAINER_SCRIPT, src/script/gen2/Vm.lua:806/817 |
implemented |
loadtrainer for the three scripted Executive/rival fights |
src/script/gen2/Vm.lua:806 |
implemented |
Rival starter branch (checkevent EVENT_GOT_*_FROM_ELM) |
src/script/gen2/Vm.lua checkevent/iftrue |
implemented |
Switch puzzle byte (readmem/addval/writemem on wUndergroundSwitchPositions) |
src/script/gen2/Vm.lua:706-740 (sparse WRAM store, explicitly documented for this map), persisted as scriptMem in src/core/gen2/Save.lua:186 |
implemented |
Switch reset on map entry (MAPCALLBACK_NEWMAP) |
src/world/gen2/World.lua:5659 + assertion driver tests/drivers/gold_map_callbacks.lua:59 which loads GOLDENROD_UNDERGROUND for real and checks all 15 events clear |
implemented and covered by a driver |
changeblock + refreshmap (shutters, basement door, dept store crates) |
src/script/gen2/Vm.lua:1002, :887; MAPCALLBACK_TILES at src/world/gen2/World.lua:5664 |
implemented |
checkitem BASEMENT_KEY / checkitem CARD_KEY |
src/script/gen2/Vm.lua:523 |
implemented |
Card Key slot (bg_event ... BGEVENT_UP) |
src/world/gen2/World.lua:5147 World:bgEventAt matches only (ev.kind or 0) == 0, i.e. BGEVENT_READ |
missing - the directional bg-event arms (BGEVENT_UP/DOWN/RIGHT/LEFT, and BGEVENT_IFSET/IFNOTSET/COPY) are not dispatched, so CardKeySlotScript can never fire and the 3F shutter cannot be opened. This blocks pass 3 entirely. |
Ground item balls (OBJECTTYPE_ITEMBALL) |
extracted as obj.itemball (src/import/RomExtractorGen2.lua:2968) but nothing consumes it: World:interact (src/world/gen2/World.lua:5257) has arms for trainers, strength boulders, scriptKey NPCs, BGEVENT_READ and BGEVENT_ITEM only |
missing - Smoke Ball, Full Heal, Max Ether, TM35 Sleep Talk and Amulet Coin are all unobtainable. src/script/gen2/CallAsm.lua:547 stubs TryReceiveItem on the assumption this path exists. |
Hidden items (BGEVENT_ITEM: Max Potion, Revive, and the three in GOLDENROD_UNDERGROUND) |
src/world/gen2/HiddenItems.lua, wired at src/world/gen2/World.lua:5285 |
implemented |
verbosegiveitem (Basement Key, Card Key, wings, TM Sunny Day, Pink Bow) |
src/script/gen2/Vm.lua:490 |
implemented |
checkver Gold/Silver split on the wing |
src/script/gen2/Vm.lua:774 |
implemented |
disappear / appear / moveobject / applymovement / turnobject / showemote for the 5F director cutscene |
src/script/gen2/Vm.lua:297-380 |
implemented |
special FadeOutToBlack / FadeInFromBlack / ReloadSpritesNoPalettes / PlayMapMusic / FadeOutMusic |
src/script/gen2/Specials.lua:999-1066 |
implemented |
| Object masking by event flag (every Rocket in this section) | src/world/gen2/Npc.lua + the extracted eventFlag field |
implemented (semantics: SET = hidden, per CheckObjectFlag) |
Elm's SPECIALCALL_WEIRDBROADCAST call |
src/core/gen2/Phone.lua:392 ([4] = { name = "SPECIALCALL_WEIRDBROADCAST", condition = "outside" }), src/script/gen2/Vm.lua:1364 specialphonecall |
implemented |
Radio programming change while ENGINE_ROCKETS_IN_RADIO_TOWER is set |
src/ui/gen2/Pokegear.lua:348, :1249 |
implemented |
Dept store elevator (elevator opcode + crate layout rotation) |
src/script/gen2/Vm.lua:1302, src/ui/gen2/ElevatorMenu.lua |
implemented |
| Haircut brothers / bargain + bitter merchants (day gating) | src/script/gen2/Specials.lua (OlderHaircutBrother / YoungerHaircutBrother), src/ui/gen2/MartMenu.lua:170 (MARTTYPE_BITTER) |
implemented |
| A scripted driver that walks this section | none (tests/drivers/gold_*.lua has no radio tower / underground runner) |
missing |
6. Unresolved / verify by hand
- "He gives you a Clear Bell." The asm does not give a Clear Bell here.
RadioTower5FRocketBossScript(maps/RadioTower5F.asm:122-139) branches oncheckver: Silver getsSILVER_WING, Gold getsRAINBOW_WING. The Clear Bell is a Crystal item and does not appear in this script. Treat the walkthrough line as wrong for Gold/Silver. - Switch ordering explanation. The walkthrough says the shutters remember
the ORDER you flipped the switches in.
wUndergroundSwitchPositionsis a single byte that switches 1/2/3 add 1/2/3 to, so 1-2-3 and 3-2-1 both end at 6. The observable difference comes from which doors the INTERMEDIATE positions left untouched (position 3 vs position 5 differ on door 5 at (10,10)). The end result the walkthrough describes is correct; the stated reason is not. The derivation above was done by hand from the.PositionNarms - worth re-checking on hardware or an emulator before a bot depends on it. - Party orderings. The walkthrough lists
GRUNTF_4as Ekans/Ekans/Gloom/Oddish andEXECUTIVEF_1as Arbok/Murkrow/Vileplume. The asm orders are21 EKANS, 23 ODDISH, 21 EKANS, 24 GLOOMand32 ARBOK, 32 VILEPLUME, 32 MURKROW. Same mons, different send-out order; a bot that hard-codes lead expectations should use the asm order. - "the northwesternmost building" - resolved to
warp_event 9, 5, GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES, 8and the adjacentbg_event 8, 6 GoldenrodCityUndergroundSignNorth, but the walkthrough never names it, so this is an inference from the map geometry rather than a quoted label. - EXP and money figures ("595 EXP", "960G", etc.) were not verified. Money
is
base money x levelfrom the trainer class table, which was not opened; EXP depends on the player's party. Nothing in this document depends on them. EVENT_TEAM_ROCKET_DISBANDEDis set only on the Gold branch ofRadioTower5FRocketBossScript(line 130), not on the Silver branch. Its only other consumers aremaps/PewterCity.asm:51(alsosetevent) and theTIN_TOWER_1Fsage object mask atmaps/TinTower1F.asm:56. This looks intentional (Gold gets the Rainbow Wing and therefore Ho-Oh access), but it is an asymmetry a port could easily get wrong, so it is flagged rather than asserted.verbosegiveitemwith noiffalseinFakeDirectorScript(Basement Key) andGoldenrodUndergroundWarehouseDirectorScript(Card Key). If the Key Items pocket were full the scripts would continue as if the item had been given. Gen 2's Key Items pocket is large enough that this is presumably unreachable, but the guard genuinely is not there.- Radio Tower 3F
TrainerGruntM9reacts with "Why did the shutter open?" and his after-battle text mentions the Underground, which confirms he is meant for the post-Card-Key pass; but nothing in the asm prevents reaching (16,6) some other way if the block edit were bypassed. Not verified against the.blkcollision data.