67 KiB
Section 19 - S.S. Aqua and Vermilion City Gym
Source: ../section-19-s-s-aqua-and-vermilion-city-gym.txt
Maps covered: NEW_BARK_TOWN, ELMS_LAB, OLIVINE_PORT_PASSAGE, OLIVINE_PORT,
FAST_SHIP_1F, FAST_SHIP_CABINS_NNW_NNE_NE, FAST_SHIP_CABINS_SW_SSW_NW,
FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN, FAST_SHIP_B1F, VERMILION_PORT,
VERMILION_PORT_PASSAGE, VERMILION_CITY, POKEMON_FAN_CLUB, VERMILION_GYM
Badges / key milestones in this section: S.S. TICKET from Prof. Elm, first Kanto
crossing on the Fast Ship, METAL COAT from the grandpa on the S.S. Aqua,
ENGINE_FLYPOINT_VERMILION, RARE CANDY from the Fan Club Chairman,
THUNDERBADGE (ENGINE_THUNDERBADGE) from Lt. Surge.
This section begins immediately after the Hall of Fame. maps/HallOfFame.asm
HallOfFameEnterScript is what arms it: it sets EVENT_BEAT_ELITE_FOUR, sets
EVENT_OLIVINE_PORT_SPRITES_BEFORE_HALL_OF_FAME (hiding the "no entry" sailor
pair), clears EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME (revealing the
boarding sailor), and, if EVENT_GOT_SS_TICKET_FROM_ELM is still clear, queues
specialphonecall SPECIALCALL_SSTICKET (the Elm call the walkthrough mentions).
1. Route order
| # | Map constant | asm file | Enter via | Leaves via | Why (walkthrough beat) |
|---|---|---|---|---|---|
| 1 | NEW_BARK_TOWN |
maps/NewBarkTown.asm |
post-credits respawn | warp 1 (6,3) -> ELMS_LAB 1 |
Elm phones you to come back |
| 2 | ELMS_LAB |
maps/ElmsLab.asm |
warp 1/2 (4,11)/(5,11) |
same warps back to NEW_BARK_TOWN 1 |
talk to ProfElmScript -> ElmGiveTicketScript -> S.S. TICKET |
| 3 | OLIVINE_CITY |
maps/OlivineCity.asm |
Fly (ENGINE_FLYPOINT_OLIVINE) |
warp 10 (19,27) / warp 11 (20,27) -> OLIVINE_PORT_PASSAGE 1/2 |
"go south from the Pokemon Center" to the port entrance |
| 4 | OLIVINE_PORT_PASSAGE |
maps/OlivinePortPassage.asm |
warps 1/2 (15,0)/(16,0) |
warp 3 (15,4) -> warp 4 (3,2), then warp 5 (3,14) -> OLIVINE_PORT 1 |
"take the stairs down twice" |
| 5 | OLIVINE_PORT |
maps/OlivinePort.asm |
warp 1 (11,7) |
coord_event (7,15) -> OlivinePortWalkUpToShipScript -> warp FAST_SHIP_1F, 25, 1 |
show the S.S. TICKET, board |
| 6 | FAST_SHIP_1F |
maps/FastShip1F.asm |
scripted warp to (25,1) |
12 warps (see below) | ship deck hub; grandpa bumps you at (24,6)/(25,6) |
| 7 | FAST_SHIP_CABINS_NNW_NNE_NE |
maps/FastShipCabins_NNW_NNE_NE.asm |
1F warps 2/3/4 ((27,8), (23,8), (19,8)) |
same | Hiker Noland; later the lazy Sailor Stanly |
| 8 | FAST_SHIP_CABINS_SW_SSW_NW |
maps/FastShipCabins_SW_SSW_NW.asm |
1F warps 5/6/7 ((15,8), (15,15), (19,15)) |
same | your cabin + healing bed; Firebreather Lyle |
| 9 | FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN |
maps/FastShipCabins_SE_SSE_CaptainsCabin.asm |
1F warps 8/9/10 ((23,15), (27,15), (3,13)) |
same | PoKeFan Colin + Twins; grandpa; captain's cabin + granddaughter |
| 10 | FAST_SHIP_B1F |
maps/FastShipB1F.asm |
1F warps 11/12 ((6,12), (30,14)) |
same | on-duty sailor blocks; Fritz, Jeff, Debra |
| 11 | VERMILION_PORT |
maps/VermilionPort.asm |
FastShip1FSailor1Script -> warp VERMILION_PORT, 7, 17 |
warp 1 (9,5) -> VERMILION_PORT_PASSAGE 5 |
ship docks in Kanto |
| 12 | VERMILION_PORT_PASSAGE |
maps/VermilionPortPassage.asm |
warp 5 (3,14) |
warp 4 (3,2) -> warp 3 (15,4), then warps 1/2 (15,0)/(16,0) -> VERMILION_CITY 8/9 |
"down the stairs, then up the stairs and out the door" |
| 13 | VERMILION_CITY |
maps/VermilionCity.asm |
warps 8/9 (19,31)/(20,31) |
warp 3 (7,13), warp 7 (10,19) |
first look at Kanto |
| 14 | POKEMON_FAN_CLUB |
maps/PokemonFanClub.asm |
warp 1/2 (2,7)/(3,7) |
same | Chairman's speech -> RARE CANDY |
| 15 | VERMILION_GYM |
maps/VermilionGym.asm |
warps 1/2 (4,17)/(5,17) |
same | Vincent, Horton, Gregory, then Lt. Surge -> THUNDERBADGE |
Spill-over note: the walkthrough's closing line ("Congrats on your first badge in
Kanto") ends the section; Saffron City / Route 6 are handled by the next
section's agent. VERMILION_CITY connects north Route6 (+5) and
east Route11 (0) (data/maps/attributes.asm:342-344), and warp 10 (34,7) to
DIGLETTS_CAVE sits behind the sleeping Snorlax; none of those are used here.
2. Maps
MAP_ELMS_LAB
- Script:
maps/ElmsLab.asm - Blocks:
maps/ElmsLab.blk - Header:
data/maps/maps.asm:476->map ElmsLab, TILESET_LAB, INDOOR, LANDMARK_NEW_BARK_TOWN, MUSIC_PROF_ELM, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:441map_const ELMS_LAB, 5, 6(10 x 12 cells) - Connections: none (indoor)
Only the S.S. TICKET beat is in scope. Full warp/object tables for the early-game scenes belong to section 1; the rows below are the ones this section touches.
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 4 | 11 | NEW_BARK_TOWN |
1 |
| 2 | 5 | 11 | NEW_BARK_TOWN |
1 |
Object events (def_object_events) - relevant row only
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
ELMSLAB_ELM |
SPRITE_ELM |
5 | 2 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
ProfElmScript |
-1 |
Scripts of interest
ProfElmScript(maps/ElmsLab.asm:50, sym60:427bforElmGiveTicketScript). First two opcodes afterfaceplayer/opentextare the ticket gate:checkevent EVENT_GOT_SS_TICKET_FROM_ELM/iftrue ElmCheckMasterBall, thencheckevent EVENT_BEAT_ELITE_FOUR/iftrue ElmGiveTicketScript. So the ticket is handed out on the first post-Hall-of-Fame conversation and never again.ElmGiveTicketScript:writetext ElmGiveTicketText1->verbosegiveitem S_S_TICKET->setevent EVENT_GOT_SS_TICKET_FROM_ELM->writetext ElmGiveTicketText2->closetext/end. Note there is noiffalsebag-full guard on thisverbosegiveitem, unlike every other Elm gift in the same file - the flag is set unconditionally.engine/phone/scripts/elm.asm:69ElmPhoneCallerScriptroutesSPECIALCALL_SSTICKETto.gift, which printsElmPhoneGiftTextand clears the pending call withspecialphonecall SPECIALCALL_NONE. The call is only the nudge; it does not give the item.
Flags and events
| constant | defined in | read/written by | meaning for a bot |
|---|---|---|---|
EVENT_BEAT_ELITE_FOUR |
constants/event_flags.asm:77 |
set by maps/HallOfFame.asm:33; read by ProfElmScript |
precondition for the ticket |
EVENT_GOT_SS_TICKET_FROM_ELM |
constants/event_flags.asm:45 |
set by ElmGiveTicketScript; read by ProfElmScript and HallOfFame.asm:41 |
one-time ticket guard |
SPECIALCALL_SSTICKET |
constants/phone_constants.asm:49 |
queued by HallOfFame.asm:43, consumed in engine/phone/scripts/elm.asm |
the phone nudge; ignorable |
Items
| item | how obtained | source (label / bg_event / hidden) | one-time flag |
|---|---|---|---|
S_S_TICKET |
talk to Elm | ElmGiveTicketScript verbosegiveitem S_S_TICKET |
EVENT_GOT_SS_TICKET_FROM_ELM |
MAP_OLIVINE_PORT_PASSAGE
- Script:
maps/OlivinePortPassage.asm - Blocks:
maps/PortPassage.blk(shared withVermilionPortPassage; there is noOlivinePortPassage.blk) - Header:
data/maps/maps.asm:340->map OlivinePortPassage, TILESET_UNDERGROUND, INDOOR, LANDMARK_OLIVINE_CITY, MUSIC_VIOLET_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:314map_const OLIVINE_PORT_PASSAGE, 10, 9(20 x 18 cells) - Connections: none
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 15 | 0 | OLIVINE_CITY |
10 |
| 2 | 16 | 0 | OLIVINE_CITY |
11 |
| 3 | 15 | 4 | OLIVINE_PORT_PASSAGE |
4 |
| 4 | 3 | 2 | OLIVINE_PORT_PASSAGE |
3 |
| 5 | 3 | 14 | OLIVINE_PORT |
1 |
Coord events - none.
BG events - none.
Object events (def_object_events)
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
OLIVINEPORTPASSAGE_POKEFAN_M |
SPRITE_POKEFAN_M |
17 | 1 | SPRITEMOVEDATA_STANDING_LEFT |
OBJECTTYPE_SCRIPT |
OlivinePortPassagePokefanMScript |
EVENT_OLIVINE_PORT_PASSAGE_POKEFAN_M |
The Pokefan is hidden at new game (InitializeEventsScript,
engine/events/std_scripts.asm:530 sets the flag) and revealed by
VermilionPortLeaveShipScript (clearevent EVENT_OLIVINE_PORT_PASSAGE_POKEFAN_M)
once you have made the crossing once. His text is the Monday/Friday schedule.
MAP_OLIVINE_PORT
- Script:
maps/OlivinePort.asm - Blocks:
maps/OlivinePort.blk - Header:
data/maps/maps.asm:333->map OlivinePort, TILESET_PORT, ROUTE, LANDMARK_OLIVINE_CITY, MUSIC_VIOLET_CITY, FALSE, PALETTE_AUTO, FISHGROUP_OCEAN - Dimensions:
constants/map_constants.asm:307map_const OLIVINE_PORT, 10, 18(20 x 36 cells) - Attributes:
data/maps/attributes.asm:586map_attributes OlivinePort, OLIVINE_PORT, $0a- no connections
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 11 | 7 | OLIVINE_PORT_PASSAGE |
5 |
| 2 | 7 | 23 | FAST_SHIP_1F |
1 |
Coord events (def_coord_events)
| scene | x | y | script label | effect |
|---|---|---|---|---|
SCENE_OLIVINEPORT_ASK_ENTER_SHIP (0) |
7 | 15 | OlivinePortWalkUpToShipScript (sym 5b:407d) |
boarding prompt + ticket check |
BG events (def_bg_events)
| x | y | type | script/item |
|---|---|---|---|
| 1 | 22 | BGEVENT_ITEM |
OlivinePortHiddenProtein -> hiddenitem PROTEIN, EVENT_OLIVINE_PORT_HIDDEN_PROTEIN |
Object events (def_object_events)
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
OLIVINEPORT_SAILOR1 |
SPRITE_SAILOR |
7 | 23 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
OlivinePortSailorAtGangwayScript |
EVENT_OLIVINE_PORT_SAILOR_AT_GANGWAY |
OLIVINEPORT_SAILOR2 |
SPRITE_SAILOR |
7 | 15 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
OlivinePortSailorBeforeHOFScript |
EVENT_OLIVINE_PORT_SPRITES_BEFORE_HALL_OF_FAME |
OLIVINEPORT_SAILOR3 |
SPRITE_SAILOR |
6 | 15 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
OlivinePortSailorAfterHOFScript |
EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME |
OLIVINEPORT_FISHING_GURU1 |
SPRITE_FISHING_GURU |
4 | 14 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
OlivinePortFishingGuru1Script |
EVENT_OLIVINE_PORT_SPRITES_BEFORE_HALL_OF_FAME |
OLIVINEPORT_FISHING_GURU2 |
SPRITE_FISHING_GURU |
13 | 14 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
OlivinePortFishingGuru2Script |
EVENT_OLIVINE_PORT_SPRITES_BEFORE_HALL_OF_FAME |
OLIVINEPORT_YOUNGSTER |
SPRITE_YOUNGSTER |
4 | 15 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
OlivinePortYoungsterScript |
EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME |
OLIVINEPORT_COOLTRAINER_F |
SPRITE_COOLTRAINER_F |
11 | 15 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
OlivinePortCooltrainerFScript |
EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME |
Object event flags hide when set. Post-Hall-of-Fame, SAILOR2 and the two
fishing gurus are gone and SAILOR3 / youngster / cooltrainer are present.
Scripts of interest
OlivinePortWalkUpToShipScript(coord event at(7,15)): turnsSAILOR3right, bails via.skipif eitherEVENT_TEMPORARY_UNTIL_MAP_RELOAD_1or_2is set, else asksOlivinePortAskBoardTextwithyesorno. IfEVENT_FAST_SHIP_FIRST_TIMEis clear it jumps straight past the weekday gate (.FirstTime) - the maiden voyage sails any day. Otherwisereadvar VAR_WEEKDAY:SUNDAY/SATURDAY->.NextShipMonday,TUESDAY/WEDNESDAY/THURSDAY->.NextShipFriday. So from Olivine the ship sails Monday and Friday. Thencheckitem S_S_TICKET;iffalse .NoTicket. On success it setsEVENT_TEMPORARY_UNTIL_MAP_RELOAD_2, walks the player 7 steps down (OlivinePortApproachFastShipFirstTimeMovement) andsjumps intoOlivinePortSailorAtGangwayScript.OlivinePortSailorAtGangwayScript:disappear OLIVINEPORT_SAILOR1, one step down,special FadeOutToWhite, then the passenger-roster bookkeeping. On repeat trips only (checkevent EVENT_FAST_SHIP_FIRST_TIME/iffalse .FirstTime) it doesclearevent EVENT_FAST_SHIP_PASSENGERS_EASTBOUND,setevent EVENT_FAST_SHIP_PASSENGERS_WESTBOUNDand clears the eight eastboundEVENT_BEAT_*rematch flags. Always:clearevent EVENT_FAST_SHIP_DESTINATION_OLIVINE,appear OLIVINEPORT_SAILOR1,setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_ENTER_SHIP,warp FAST_SHIP_1F, 25, 1.OlivinePortLeaveShipScript(sceneSCENE_OLIVINEPORT_LEAVE_SHIP, 1): the arrival cutscene for the return trip - one step up,appearthe sailor,setscene SCENE_OLIVINEPORT_ASK_ENTER_SHIP,setevent EVENT_TEMPORARY_UNTIL_MAP_RELOAD_1,blackoutmod OLIVINE_CITY.
Wild encounters
data/wild/johto_water.asm:278 def_water_wildmons OLIVINE_PORT, encounter rate
2 percent: 20 TENTACOOL / 15 TENTACOOL / 20 TENTACRUEL.
Fishing group FISHGROUP_OCEAN (data/wild/fish.asm:13, .Ocean_* at lines
42-55). No grass, no headbutt table.
MAP_FAST_SHIP_1F
- Script:
maps/FastShip1F.asm - Blocks:
maps/FastShip1F.blk - Header:
data/maps/maps.asm:335->map FastShip1F, TILESET_LIGHTHOUSE, INDOOR, LANDMARK_FAST_SHIP, MUSIC_SS_AQUA, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:309map_const FAST_SHIP_1F, 16, 9(32 x 18 cells) - Connections: none
Scene ids are declared inline by scene_script (macros/scripts/maps.asm:25):
SCENE_FASTSHIP1F_NOOP = 0, SCENE_FASTSHIP1F_ENTER_SHIP = 1,
SCENE_FASTSHIP1F_MEET_GRANDPA = 2.
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 25 | 1 | FAST_SHIP_1F |
-1 (arrival tile only) |
| 2 | 27 | 8 | FAST_SHIP_CABINS_NNW_NNE_NE |
1 |
| 3 | 23 | 8 | FAST_SHIP_CABINS_NNW_NNE_NE |
2 |
| 4 | 19 | 8 | FAST_SHIP_CABINS_NNW_NNE_NE |
3 |
| 5 | 15 | 8 | FAST_SHIP_CABINS_SW_SSW_NW |
1 |
| 6 | 15 | 15 | FAST_SHIP_CABINS_SW_SSW_NW |
2 |
| 7 | 19 | 15 | FAST_SHIP_CABINS_SW_SSW_NW |
4 |
| 8 | 23 | 15 | FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN |
1 |
| 9 | 27 | 15 | FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN |
3 |
| 10 | 3 | 13 | FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN |
5 |
| 11 | 6 | 12 | FAST_SHIP_B1F |
1 |
| 12 | 30 | 14 | FAST_SHIP_B1F |
2 |
Warp 5 (15,8) is "your cabin" (the one with the healing bed). Warp 10 (3,13)
is the staircase to the captain's cabin.
Coord events (def_coord_events)
| scene | x | y | script label | effect |
|---|---|---|---|---|
SCENE_FASTSHIP1F_MEET_GRANDPA (2) |
24 | 6 | WorriedGrandpaSceneLeft (sym 5b:495d) |
grandpa runs in and bumps you |
SCENE_FASTSHIP1F_MEET_GRANDPA (2) |
25 | 6 | WorriedGrandpaSceneRight |
moveobject FASTSHIP1F_GENTLEMAN, 20, 6 then falls through into WorriedGrandpaSceneLeft |
BG events - none.
Object events (def_object_events)
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
FASTSHIP1F_SAILOR1 |
SPRITE_SAILOR |
25 | 2 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
FastShip1FSailor1Script |
-1 |
FASTSHIP1F_SAILOR2 |
SPRITE_SAILOR |
14 | 7 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
FastShip1FSailor2Script |
-1 |
FASTSHIP1F_SAILOR3 |
SPRITE_SAILOR |
22 | 17 | SPRITEMOVEDATA_WALK_LEFT_RIGHT (radius 2,0) |
OBJECTTYPE_SCRIPT |
FastShip1FSailor3Script |
-1 |
FASTSHIP1F_GENTLEMAN |
SPRITE_GENTLEMAN |
19 | 6 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
ObjectEvent |
EVENT_FAST_SHIP_1F_GENTLEMAN |
Scripts of interest
FastShip1FEnterShipScript(sym5b:48ad, scene 1, run viasdefer): sailor steps aside, player walks 2 down, sailor steps back and blocks the door,playsound SFX_BOAT,earthquake 30,blackoutmod FAST_SHIP_CABINS_SW_SSW_NW(your blackout respawn becomes your cabin),clearevent EVENT_FAST_SHIP_HAS_ARRIVED. Thencheckevent EVENT_FAST_SHIP_FIRST_TIME/iftrue .SkipGrandpa: on the first crossing it setsSCENE_FASTSHIP1F_MEET_GRANDPA, otherwiseSCENE_FASTSHIP1F_NOOP.WorriedGrandpaSceneLeft:appear FASTSHIP1F_GENTLEMAN, fourbig_step RIGHT,playsound SFX_TACKLE, knocks the player one step right,writetext FastShip1FGrandpaText("My granddaughter is missing!"), then the gentleman runs off,disappears and the scene is reset toSCENE_FASTSHIP1F_NOOP. Purely informational - it sets no quest flag.FastShip1FSailor1Script(the door guard at(25,2)): ifEVENT_FAST_SHIP_HAS_ARRIVEDis clear it just says "en route", branching onEVENT_FAST_SHIP_DESTINATION_OLIVINEfor the destination name. Once arrived it runs.LetThePlayerOut(readvar VAR_FACING, two step-up variants), thensetevent EVENT_VERMILION_PORT_SAILOR_AT_GANGWAY(note: set hides that object),setmapscene VERMILION_PORT, SCENE_VERMILIONPORT_LEAVE_SHIPandwarp VERMILION_PORT, 7, 17. The Olivine-bound mirror is._Olivine->warp OLIVINE_PORT, 7, 23.
Flags and events
| constant | defined in | read/written by | meaning for a bot |
|---|---|---|---|
EVENT_FAST_SHIP_FIRST_TIME |
constants/event_flags.asm:57 |
set by VermilionPortLeaveShipScript; read by both port scripts, FastShip1FEnterShipScript, FastShip1FSailor2Script, SSAquaCaptain, FastShipBed, FastShipB1FSailorScript |
"the maiden crossing is finished"; gates the weekday schedule and the grandpa quest |
EVENT_FAST_SHIP_HAS_ARRIVED |
constants/event_flags.asm:58 |
cleared on boarding, set by SSAquaMetalCoatAndDocking / FastShipBed.CanArrive; read by FastShip1FSailor1Script |
the door guard will only let you off once this is set |
EVENT_FAST_SHIP_DESTINATION_OLIVINE |
constants/event_flags.asm:56 |
cleared at Olivine, set at Vermilion | which port the ship is heading for |
EVENT_FAST_SHIP_1F_GENTLEMAN |
constants/event_flags.asm:1230 |
set at new game (std_scripts.asm:497), appear/disappear in WorriedGrandpaSceneLeft |
grandpa sprite visibility |
MAP_FAST_SHIP_CABINS_NNW_NNE_NE
- Script:
maps/FastShipCabins_NNW_NNE_NE.asm - Blocks:
maps/FastShipCabins_NNW_NNE_NE.blk - Header:
data/maps/maps.asm:336->map FastShipCabins_NNW_NNE_NE, TILESET_LIGHTHOUSE, INDOOR, LANDMARK_FAST_SHIP, MUSIC_SS_AQUA, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:310map_const FAST_SHIP_CABINS_NNW_NNE_NE, 4, 16(8 x 32 cells) - Layout: three stacked sub-rooms,
y0-11, 12-23, 24-31.
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 2 | 0 | FAST_SHIP_1F |
2 |
| 2 | 2 | 12 | FAST_SHIP_1F |
3 |
| 3 | 2 | 24 | FAST_SHIP_1F |
4 |
Coord events - none.
BG events (def_bg_events)
| x | y | type | script/item |
|---|---|---|---|
| 6 | 13 | BGEVENT_READ |
FastShipCabins_NNW_NNE_NETrashcan (jumpstd TrashCanScript) |
| 7 | 19 | BGEVENT_READ |
FastShipCabins_NNW_NNE_NETrashcan |
| 7 | 31 | BGEVENT_READ |
FastShipCabins_NNW_NNE_NETrashcan |
Object events (def_object_events)
| const | sprite | x | y | movement | type | sight | script label | event flag |
|---|---|---|---|---|---|---|---|---|
..._COOLTRAINER_M |
SPRITE_COOLTRAINER_M |
4 | 3 | SPRITEMOVEDATA_SPINRANDOM_FAST |
OBJECTTYPE_TRAINER |
2 | TrainerCooltrainermSean |
EVENT_FAST_SHIP_PASSENGERS_EASTBOUND |
..._COOLTRAINER_F |
SPRITE_COOLTRAINER_F |
1 | 5 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_TRAINER |
3 | TrainerCooltrainerfCarol |
EVENT_FAST_SHIP_PASSENGERS_EASTBOUND |
..._SUPER_NERD |
SPRITE_SUPER_NERD |
1 | 5 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_TRAINER |
3 | TrainerPokemaniacEthan |
EVENT_FAST_SHIP_PASSENGERS_WESTBOUND |
..._POKEFAN_M |
SPRITE_POKEFAN_M |
4 | 17 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_TRAINER |
3 | TrainerHikerNoland |
EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP |
..._SAILOR |
SPRITE_SAILOR |
4 | 26 | SPRITEMOVEDATA_SPINRANDOM_SLOW |
OBJECTTYPE_SCRIPT |
0 | FastShipLazySailorScript |
EVENT_FAST_SHIP_CABINS_NNW_NNE_NE_SAILOR |
..._GENTLEMAN |
SPRITE_GENTLEMAN |
7 | 30 | SPRITEMOVEDATA_SPINRANDOM_SLOW |
OBJECTTYPE_TRAINER |
1 | TrainerGentlemanEdward |
EVENT_FAST_SHIP_PASSENGERS_EASTBOUND |
..._PHARMACIST |
SPRITE_PHARMACIST |
2 | 30 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_TRAINER |
4 | TrainerBurglarCorey |
EVENT_FAST_SHIP_PASSENGERS_WESTBOUND |
On the maiden voyage only EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP is clear, so
Hiker Noland is the only trainer visible on this map - exactly what the
walkthrough describes.
Scripts of interest
FastShipLazySailorScript(sym5b:4d68): not atrainerobject, a scripted battle.playmusic MUSIC_HIKER_ENCOUNTER->SailorStanlySeenText->winlosstext SailorStanlyBeatenText, 0->loadtrainer SAILOR, STANLY->startbattle->reloadmap->special HealParty->setevent EVENT_BEAT_SAILOR_STANLY-> after-battle text ->setevent EVENT_FAST_SHIP_LAZY_SAILOR->setmapscene FAST_SHIP_B1F, SCENE_FASTSHIPB1F_NOOP(this is what unblocks B1F) ->readvar VAR_FACING, walk him out,disappear. Notespecial HealPartyfires unconditionally after the fight.
Trainers
| const | class | id | party (data/trainers/parties.asm) |
script label | notes |
|---|---|---|---|---|---|
HIKER, NOLAND |
HIKER ($2c) |
14 | ; HIKER (14) db "NOLAND@", TRAINERTYPE_NORMAL -> L31 SANDSLASH, L33 GOLEM |
TrainerHikerNoland |
flag EVENT_BEAT_HIKER_NOLAND |
SAILOR, STANLY |
SAILOR ($28) |
9 | ; SAILOR (9) db "STANLY@", TRAINERTYPE_NORMAL -> L31 MACHOP, L33 MACHOKE, L26 PSYDUCK |
FastShipLazySailorScript |
scripted loadtrainer, not an OBJECTTYPE_TRAINER |
MAP_FAST_SHIP_CABINS_SW_SSW_NW
- Script:
maps/FastShipCabins_SW_SSW_NW.asm - Blocks:
maps/FastShipCabins_SW_SSW_NW.blk - Header:
data/maps/maps.asm:337->map FastShipCabins_SW_SSW_NW, TILESET_LIGHTHOUSE, INDOOR, LANDMARK_FAST_SHIP, MUSIC_SS_AQUA, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:311map_const FAST_SHIP_CABINS_SW_SSW_NW, 4, 16(8 x 32 cells)
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 2 | 0 | FAST_SHIP_1F |
5 |
| 2 | 2 | 19 | FAST_SHIP_1F |
6 |
| 3 | 3 | 19 | FAST_SHIP_1F |
6 |
| 4 | 2 | 31 | FAST_SHIP_1F |
7 |
| 5 | 3 | 31 | FAST_SHIP_1F |
7 |
Coord events - none.
BG events (def_bg_events)
| x | y | type | script/item |
|---|---|---|---|
| 7 | 1 | BGEVENT_READ |
FastShipBed (sym 5b:521b) |
| 7 | 2 | BGEVENT_READ |
FastShipBed |
| 7 | 7 | BGEVENT_READ |
FastShipCabinsNorthwestCabinTrashcan |
Object events (def_object_events)
| const | sprite | x | y | movement | type | sight | script label | event flag |
|---|---|---|---|---|---|---|---|---|
..._FISHER |
SPRITE_FISHER |
1 | 15 | SPRITEMOVEDATA_SPINCOUNTERCLOCKWISE |
OBJECTTYPE_TRAINER |
2 | TrainerFirebreatherLyle |
EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP |
..._BUG_CATCHER |
SPRITE_BUG_CATCHER |
6 | 15 | SPRITEMOVEDATA_SPINRANDOM_FAST |
OBJECTTYPE_TRAINER |
2 | TrainerBugCatcherKen |
EVENT_FAST_SHIP_PASSENGERS_WESTBOUND |
..._BEAUTY |
SPRITE_BEAUTY |
1 | 26 | SPRITEMOVEDATA_SPINRANDOM_FAST |
OBJECTTYPE_TRAINER |
3 | TrainerBeautyCassie |
EVENT_FAST_SHIP_PASSENGERS_EASTBOUND |
..._ROCKER |
SPRITE_ROCKER |
3 | 28 | SPRITEMOVEDATA_SPINCOUNTERCLOCKWISE |
OBJECTTYPE_TRAINER |
2 | TrainerGuitaristClyde |
EVENT_FAST_SHIP_PASSENGERS_WESTBOUND |
Scripts of interest
FastShipBed(bg_event at(7,1)/(7,2), warp-1 sub-room = your cabin): text,FadeOutToBlack,ReloadSpritesNoPalettes,special HealParty,playmusic MUSIC_HEAL,pause 60,RestartMapMusic,FadeInFromBlack. Then a docking check: skip ifEVENT_FAST_SHIP_HAS_ARRIVED; otherwisecheckevent EVENT_FAST_SHIP_FOUND_GIRLorcheckevent EVENT_FAST_SHIP_FIRST_TIME->.CanArrive, which playsSFX_ELEVATOR_END, prints the arrival text andsetevent EVENT_FAST_SHIP_HAS_ARRIVED. Bot-relevant: on the maiden voyage, sleeping in the bed does not dock the ship, because bothEVENT_FAST_SHIP_FOUND_GIRLandEVENT_FAST_SHIP_FIRST_TIMEare still clear. You must finish the granddaughter errand.
Trainers
| const | class | id | party | script label | notes |
|---|---|---|---|---|---|
FIREBREATHER, LYLE |
FIREBREATHER ($30) |
8 | ; FIREBREATHER (8) db "LYLE@", TRAINERTYPE_NORMAL -> L28 KOFFING, L31 FLAREON, L28 KOFFING |
TrainerFirebreatherLyle |
flag EVENT_BEAT_FIREBREATHER_LYLE |
MAP_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN
- Script:
maps/FastShipCabins_SE_SSE_CaptainsCabin.asm - Blocks:
maps/FastShipCabins_SE_SSE_CaptainsCabin.blk - Header:
data/maps/maps.asm:338->map FastShipCabins_SE_SSE_CaptainsCabin, TILESET_LIGHTHOUSE, INDOOR, LANDMARK_FAST_SHIP, MUSIC_SS_AQUA, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:312map_const FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN, 5, 17(10 x 34 cells) - Layout: sub-room 1
y0-11 (Colin + Twins), sub-room 2y12-23 (grandpa), sub-room 3y24-33 (captain's cabin).
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 2 | 7 | FAST_SHIP_1F |
8 |
| 2 | 3 | 7 | FAST_SHIP_1F |
8 |
| 3 | 2 | 19 | FAST_SHIP_1F |
9 |
| 4 | 3 | 19 | FAST_SHIP_1F |
9 |
| 5 | 2 | 33 | FAST_SHIP_1F |
10 |
| 6 | 3 | 33 | FAST_SHIP_1F |
10 |
Coord events - none.
BG events (def_bg_events)
| x | y | type | script/item |
|---|---|---|---|
| 4 | 25 | BGEVENT_READ |
FastShipCaptainsCabinTrashcan |
Object events (def_object_events)
| const | sprite | x | y | movement | type | sight | script label | event flag |
|---|---|---|---|---|---|---|---|---|
..._CAPTAIN |
SPRITE_CAPTAIN |
3 | 25 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
0 | SSAquaCaptain |
-1 |
..._GENTLEMAN |
SPRITE_GENTLEMAN |
2 | 17 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
0 | SSAquaGrandpa (sym 5b:561b) |
EVENT_FAST_SHIP_CABINS_SE_SSE_GENTLEMAN |
..._TWIN1 |
SPRITE_TWIN |
3 | 17 | SPRITEMOVEDATA_SPINRANDOM_FAST |
OBJECTTYPE_SCRIPT |
0 | SSAquaGranddaughterAfter |
EVENT_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN_TWIN_1 |
..._TWIN2 |
SPRITE_TWIN |
2 | 25 | SPRITEMOVEDATA_SPINRANDOM_FAST |
OBJECTTYPE_SCRIPT |
0 | SSAquaGranddaughterBefore |
EVENT_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN_TWIN_2 |
..._POKEFAN_M1 |
SPRITE_POKEFAN_M |
5 | 6 | SPRITEMOVEDATA_STANDING_LEFT |
OBJECTTYPE_TRAINER |
5 | TrainerPokefanmColin |
EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP |
..._TWIN3 |
SPRITE_TWIN |
2 | 4 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_TRAINER |
1 | TrainerTwinsMegandpeg1 |
EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP |
..._TWIN4 |
SPRITE_TWIN |
3 | 4 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_TRAINER |
1 | TrainerTwinsMegandpeg2 |
EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP |
..._SUPER_NERD1 |
SPRITE_SUPER_NERD |
5 | 5 | SPRITEMOVEDATA_STANDING_LEFT |
OBJECTTYPE_TRAINER |
5 | TrainerPsychicRodney |
EVENT_FAST_SHIP_PASSENGERS_EASTBOUND |
..._POKEFAN_M2 |
SPRITE_POKEFAN_M |
2 | 3 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_TRAINER |
3 | TrainerPokefanmJeremy |
EVENT_FAST_SHIP_PASSENGERS_WESTBOUND |
..._POKEFAN_F |
SPRITE_POKEFAN_F |
5 | 5 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_TRAINER |
1 | TrainerPokefanfGeorgia |
EVENT_FAST_SHIP_PASSENGERS_WESTBOUND |
..._SUPER_NERD2 |
SPRITE_SUPER_NERD |
1 | 15 | SPRITEMOVEDATA_SPINRANDOM_SLOW |
OBJECTTYPE_TRAINER |
2 | TrainerSupernerdShawn |
EVENT_FAST_SHIP_PASSENGERS_EASTBOUND |
Scripts of interest
SSAquaGrandpa(talk to..._GENTLEMANat(2,17)):checkevent EVENT_GOT_METAL_COAT_FROM_GRANDPA_ON_SS_AQUA->SSAquaGotMetalCoat;checkevent EVENT_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN_TWIN_2(i.e. the granddaughter object is hidden = already found) ->SSAquaFoundGranddaughter; otherwise the "I can't find my granddaughter" text plussetmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_NOOP.SSAquaGranddaughterBefore(talk to..._TWIN2at(2,25)in the captain's cabin) - the payoff scene:FadeOutToBlack,disappearTWIN2, teleport the player withSSAquaCaptainsCabinWarpsToGrandpasCabinMovement(big_step RIGHT+ sixbig_step UP),moveobject TWIN1, 3, 19+appear,showemote EMOTE_SHOCKon the gentleman, dialogue, thensetevent EVENT_VERMILION_PORT_SAILOR_AT_GANGWAY,setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_NOOP,sjump SSAquaMetalCoatAndDocking.SSAquaMetalCoatAndDocking(sym5b:5633):verbosegiveitem METAL_COAT,iffalse .NoRoom,setevent EVENT_GOT_METAL_COAT_FROM_GRANDPA_ON_SS_AQUA, thenplaysound SFX_ELEVATOR_END,pause 30, arrival text,setevent EVENT_FAST_SHIP_HAS_ARRIVED,setevent EVENT_FAST_SHIP_FOUND_GIRL. This is the docking trigger for the maiden voyage. A full bag skips the item but still docks the ship.
Items
| item | how obtained | source (label / bg_event / hidden) | one-time flag |
|---|---|---|---|
METAL_COAT |
finish the granddaughter errand | SSAquaMetalCoatAndDocking / SSAquaFoundGranddaughter verbosegiveitem METAL_COAT |
EVENT_GOT_METAL_COAT_FROM_GRANDPA_ON_SS_AQUA |
Trainers
| const | class | id | party | script label | notes |
|---|---|---|---|---|---|
POKEFANM, COLIN |
POKEFANM ($3b) |
9 | ; POKEFANM (9) db "COLIN@", TRAINERTYPE_ITEM -> L32 DELIBIRD holding BERRY |
TrainerPokefanmColin |
EVENT_BEAT_POKEFANM_COLIN |
TWINS, MEGANDPEG1 |
TWINS ($3d) |
7 | ; TWINS (7) db "MEG & PEG@", TRAINERTYPE_NORMAL -> L31 TEDDIURSA, L31 PHANPY |
TrainerTwinsMegandpeg1 |
shares flag EVENT_BEAT_TWINS_MEG_AND_PEG |
TWINS, MEGANDPEG2 |
TWINS ($3d) |
8 | ; TWINS (8) -> L31 PHANPY, L31 TEDDIURSA |
TrainerTwinsMegandpeg2 |
same flag - beating either removes both |
MAP_FAST_SHIP_B1F
- Script:
maps/FastShipB1F.asm - Blocks:
maps/FastShipB1F.blk - Header:
data/maps/maps.asm:339->map FastShipB1F, TILESET_LIGHTHOUSE, INDOOR, LANDMARK_FAST_SHIP, MUSIC_SS_AQUA, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:313map_const FAST_SHIP_B1F, 16, 8(32 x 16 cells)
Scene ids: SCENE_FASTSHIPB1F_SAILOR_BLOCKS = 0, SCENE_FASTSHIPB1F_NOOP = 1.
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 5 | 11 | FAST_SHIP_1F |
11 |
| 2 | 31 | 13 | FAST_SHIP_1F |
12 |
Coord events (def_coord_events)
| scene | x | y | script label | effect |
|---|---|---|---|---|
SCENE_FASTSHIPB1F_SAILOR_BLOCKS (0) |
30 | 7 | FastShipB1FSailorBlocksLeft |
if EVENT_FAST_SHIP_B1F_SAILOR_RIGHT set -> no-op; else move sailor2 left, moveobject FASTSHIPB1F_SAILOR1, 30, 6 + appear, disappear sailor2 |
SCENE_FASTSHIPB1F_SAILOR_BLOCKS (0) |
31 | 7 | FastShipB1FSailorBlocksRight |
mirror: moveobject FASTSHIPB1F_SAILOR2, 31, 6 + appear, disappear sailor1 |
BG events (def_bg_events)
| x | y | type | script/item |
|---|---|---|---|
| 27 | 9 | BGEVENT_READ |
FastShipB1FTrashcan |
Object events (def_object_events)
| const | sprite | x | y | movement | type | sight | script label | event flag |
|---|---|---|---|---|---|---|---|---|
FASTSHIPB1F_SAILOR1 |
SPRITE_SAILOR |
30 | 6 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
0 | FastShipB1FSailorScript |
EVENT_FAST_SHIP_B1F_SAILOR_LEFT |
FASTSHIPB1F_SAILOR2 |
SPRITE_SAILOR |
31 | 6 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
0 | FastShipB1FSailorScript |
EVENT_FAST_SHIP_B1F_SAILOR_RIGHT |
FASTSHIPB1F_SAILOR3 |
SPRITE_SAILOR |
9 | 11 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_TRAINER |
3 | TrainerSailorJeff |
EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP |
FASTSHIPB1F_LASS |
SPRITE_LASS |
6 | 4 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_TRAINER |
1 | TrainerPicnickerDebra |
EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP |
FASTSHIPB1F_SUPER_NERD |
SPRITE_SUPER_NERD |
26 | 9 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_TRAINER |
1 | TrainerJugglerFritz |
EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP |
FASTSHIPB1F_SAILOR4 |
SPRITE_SAILOR |
17 | 4 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_TRAINER |
4 | TrainerSailorGarrett |
EVENT_FAST_SHIP_PASSENGERS_EASTBOUND |
FASTSHIPB1F_FISHER |
SPRITE_FISHER |
25 | 8 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_TRAINER |
3 | TrainerFisherJonah |
EVENT_FAST_SHIP_PASSENGERS_EASTBOUND |
FASTSHIPB1F_BLACK_BELT |
SPRITE_BLACK_BELT |
15 | 11 | SPRITEMOVEDATA_SPINCLOCKWISE |
OBJECTTYPE_TRAINER |
3 | TrainerBlackbeltWai |
EVENT_FAST_SHIP_PASSENGERS_EASTBOUND |
FASTSHIPB1F_SAILOR5 |
SPRITE_SAILOR |
23 | 4 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_TRAINER |
4 | TrainerSailorKenneth |
EVENT_FAST_SHIP_PASSENGERS_WESTBOUND |
FASTSHIPB1F_TEACHER |
SPRITE_TEACHER |
9 | 11 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_TRAINER |
3 | TrainerTeacherShirley |
EVENT_FAST_SHIP_PASSENGERS_WESTBOUND |
FASTSHIPB1F_YOUNGSTER1 |
SPRITE_YOUNGSTER |
14 | 9 | SPRITEMOVEDATA_SPINRANDOM_SLOW |
OBJECTTYPE_TRAINER |
1 | TrainerSchoolboyNate |
EVENT_FAST_SHIP_PASSENGERS_WESTBOUND |
FASTSHIPB1F_YOUNGSTER2 |
SPRITE_YOUNGSTER |
14 | 11 | SPRITEMOVEDATA_SPINRANDOM_FAST |
OBJECTTYPE_TRAINER |
1 | TrainerSchoolboyRicky |
EVENT_FAST_SHIP_PASSENGERS_WESTBOUND |
Scripts of interest
FastShipB1FSailorScript(sym5b:5e37), shared by both blocking sailors:checkevent EVENT_FAST_SHIP_FIRST_TIME/iftrue .FirstTime-> on repeat trips he just gives directions and does not block the story.checkevent EVENT_FAST_SHIP_LAZY_SAILOR/iftrue .LazySailor-> thanks you; ifEVENT_FAST_SHIP_FOUND_GIRLis still clear he also printsFastShipB1FOnDutySailorSawLittleGirlText(the "a little girl went by" hint).checkevent EVENT_FAST_SHIP_INFORMED_ABOUT_LAZY_SAILOR/iftrue .AlreadyInformed.- First talk: prints the request,
setevent EVENT_FAST_SHIP_INFORMED_ABOUT_LAZY_SAILORandclearevent EVENT_FAST_SHIP_CABINS_NNW_NNE_NE_SAILOR- this is what spawns the lazy sailor in the NNW/NNE/NE cabins map.
- The physical block is the sailor object standing on
(30,6)or(31,6); the coord events at(30,7)/(31,7)shuffle whichever sailor is active onto the tile you approached. OnceFastShipLazySailorScriptrunssetmapscene FAST_SHIP_B1F, SCENE_FASTSHIPB1F_NOOP, the coord events stop firing and only one of the two tiles stays occupied.
Trainers
| const | class | id | party | script label | notes |
|---|---|---|---|---|---|
SAILOR, JEFF |
SAILOR ($28) |
6 | ; SAILOR (6) db "JEFF@", TRAINERTYPE_NORMAL -> L32 RATICATE, L32 RATICATE |
TrainerSailorJeff |
EVENT_BEAT_SAILOR_JEFF |
PICNICKER, DEBRA |
PICNICKER ($35) |
8 | ; PICNICKER (8) db "DEBRA@", TRAINERTYPE_NORMAL -> L33 SEAKING |
TrainerPicnickerDebra |
EVENT_BEAT_PICNICKER_DEBRA |
JUGGLER, FRITZ |
JUGGLER ($31) |
2 | ; JUGGLER (2) db "FRITZ@", TRAINERTYPE_NORMAL -> L29 MR__MIME, L29 MAGMAR, L29 MACHOKE |
TrainerJugglerFritz |
EVENT_BEAT_JUGGLER_FRITZ |
Note the party order in the asm is Mr. Mime, Magmar, Machoke - the walkthrough lists Mr. Mime, Machoke, Magmar.
MAP_VERMILION_PORT
- Script:
maps/VermilionPort.asm - Blocks:
maps/VermilionPort.blk - Header:
data/maps/maps.asm:334->map VermilionPort, TILESET_PORT, ROUTE, LANDMARK_VERMILION_CITY, MUSIC_VERMILION_CITY, FALSE, PALETTE_AUTO, FISHGROUP_OCEAN - Dimensions:
constants/map_constants.asm:308map_const VERMILION_PORT, 10, 18(20 x 36 cells) - Attributes:
data/maps/attributes.asm:587map_attributes VermilionPort, VERMILION_PORT, $0a- no connections - Callback:
callback MAPCALLBACK_NEWMAP, VermilionPortFlypointCallback->setflag ENGINE_FLYPOINT_VERMILION
Scene ids: SCENE_VERMILIONPORT_ASK_ENTER_SHIP = 0,
SCENE_VERMILIONPORT_LEAVE_SHIP = 1.
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 9 | 5 | VERMILION_PORT_PASSAGE |
5 |
| 2 | 7 | 17 | FAST_SHIP_1F |
1 |
Coord events (def_coord_events)
| scene | x | y | script label | effect |
|---|---|---|---|---|
SCENE_VERMILIONPORT_ASK_ENTER_SHIP (0) |
7 | 11 | VermilionPortWalkUpToShipScript |
boarding prompt on the way back to Johto |
BG events (def_bg_events)
| x | y | type | script/item |
|---|---|---|---|
| 16 | 13 | BGEVENT_ITEM |
VermilionPortHiddenIron -> hiddenitem IRON, EVENT_VERMILION_PORT_HIDDEN_IRON |
Object events (def_object_events)
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
VERMILIONPORT_SAILOR1 |
SPRITE_SAILOR |
7 | 17 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
VermilionPortSailorAtGangwayScript |
EVENT_VERMILION_PORT_SAILOR_AT_GANGWAY |
VERMILIONPORT_SAILOR2 |
SPRITE_SAILOR |
6 | 11 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
VermilionPortSailorScript |
-1 |
VERMILIONPORT_SUPER_NERD |
SPRITE_SUPER_NERD |
11 | 11 | SPRITEMOVEDATA_WALK_LEFT_RIGHT (radius 2,0) |
OBJECTTYPE_SCRIPT |
VermilionPortSuperNerdScript |
-1 |
Scripts of interest
VermilionPortLeaveShipScript(sym5b:450e, scene 1,sdefer): the arrival cutscene. Onestep UP,appear VERMILIONPORT_SAILOR1,setscene SCENE_VERMILIONPORT_ASK_ENTER_SHIP, then the end-of-voyage bookkeeping:setevent EVENT_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN_TWIN_1,setevent EVENT_FAST_SHIP_CABINS_SE_SSE_GENTLEMAN(grandpa and granddaughter vanish from the ship for good),setevent EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP(the eight maiden-voyage trainers never appear again),clearevent EVENT_OLIVINE_PORT_PASSAGE_POKEFAN_M,setevent EVENT_FAST_SHIP_FIRST_TIME,setevent EVENT_TEMPORARY_UNTIL_MAP_RELOAD_1,blackoutmod VERMILION_CITY.VermilionPortWalkUpToShipScript/VermilionPortSailorScript:readvar VAR_WEEKDAY;MONDAY/TUESDAY->.NextShipWednesday,THURSDAY/FRIDAY/SATURDAY->.NextShipSunday. So from Vermilion the ship sails Wednesday and Sunday, matching the walkthrough. There is no first-time bypass on this side. Boarding setsEVENT_FAST_SHIP_PASSENGERS_EASTBOUND, clears..._WESTBOUND, clears the ten westboundEVENT_BEAT_*flags, setsEVENT_FAST_SHIP_DESTINATION_OLIVINE,setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_ENTER_SHIP,warp FAST_SHIP_1F, 25, 1.
Items
| item | how obtained | source | one-time flag |
|---|---|---|---|
IRON |
hidden, face (16,13) |
VermilionPortHiddenIron |
EVENT_VERMILION_PORT_HIDDEN_IRON |
Wild encounters
data/wild/kanto_water.asm:166 def_water_wildmons VERMILION_PORT, rate
2 percent: 35 TENTACOOL / 30 TENTACOOL / 35 TENTACRUEL. Fishing
FISHGROUP_OCEAN.
MAP_VERMILION_PORT_PASSAGE
- Script:
maps/VermilionPortPassage.asm - Blocks:
maps/PortPassage.blk(shared) - Header:
data/maps/maps.asm:341->map VermilionPortPassage, TILESET_UNDERGROUND, INDOOR, LANDMARK_VERMILION_CITY, MUSIC_VERMILION_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:315map_const VERMILION_PORT_PASSAGE, 10, 9(20 x 18 cells)
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 15 | 0 | VERMILION_CITY |
8 |
| 2 | 16 | 0 | VERMILION_CITY |
9 |
| 3 | 15 | 4 | VERMILION_PORT_PASSAGE |
4 |
| 4 | 3 | 2 | VERMILION_PORT_PASSAGE |
3 |
| 5 | 3 | 14 | VERMILION_PORT |
1 |
Coord events - none. BG events - none.
Object events (def_object_events)
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
VERMILIONPORTPASSAGE_TEACHER |
SPRITE_TEACHER |
17 | 1 | SPRITEMOVEDATA_STANDING_LEFT |
OBJECTTYPE_SCRIPT |
VermilionPortPassageTeacherScript |
-1 |
MAP_VERMILION_CITY
- Script:
maps/VermilionCity.asm - Blocks:
maps/VermilionCity.blk - Header:
data/maps/maps.asm:296->map VermilionCity, TILESET_KANTO, TOWN, LANDMARK_VERMILION_CITY, MUSIC_VERMILION_CITY, FALSE, PALETTE_AUTO, FISHGROUP_OCEAN - Dimensions:
constants/map_constants.asm:273map_const VERMILION_CITY, 20, 18(40 x 36 cells) - Attributes:
data/maps/attributes.asm:342map_attributes VermilionCity, VERMILION_CITY, $43 - Connections:
connection north, Route6, ROUTE_6, 5;connection east, Route11, ROUTE_11, 0 - Callback:
callback MAPCALLBACK_NEWMAP, VermilionCityFlypointCallback->setflag ENGINE_FLYPOINT_VERMILION
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 5 | 5 | VERMILION_FISHING_SPEECH_HOUSE |
1 |
| 2 | 9 | 5 | VERMILION_POKECENTER_1F |
1 |
| 3 | 7 | 13 | POKEMON_FAN_CLUB |
1 |
| 4 | 13 | 13 | VERMILION_MAGNET_TRAIN_SPEECH_HOUSE |
1 |
| 5 | 21 | 13 | VERMILION_MART |
2 |
| 6 | 21 | 17 | VERMILION_DIGLETTS_CAVE_SPEECH_HOUSE |
1 |
| 7 | 10 | 19 | VERMILION_GYM |
1 |
| 8 | 19 | 31 | VERMILION_PORT_PASSAGE |
1 |
| 9 | 20 | 31 | VERMILION_PORT_PASSAGE |
2 |
| 10 | 34 | 7 | DIGLETTS_CAVE |
1 |
Coord events - none.
BG events (def_bg_events)
| x | y | type | script/item |
|---|---|---|---|
| 25 | 3 | BGEVENT_READ |
VermilionCitySign |
| 5 | 19 | BGEVENT_READ |
VermilionGymSign |
| 5 | 13 | BGEVENT_READ |
PokemonFanClubSign |
| 33 | 9 | BGEVENT_READ |
VermilionCityDiglettsCaveSign |
| 27 | 15 | BGEVENT_READ |
VermilionCityPortSign |
| 10 | 5 | BGEVENT_READ |
VermilionCityPokecenterSign (jumpstd PokecenterSignScript) |
| 22 | 13 | BGEVENT_READ |
VermilionCityMartSign (jumpstd MartSignScript) |
| 12 | 19 | BGEVENT_ITEM |
VermilionCityHiddenFullHeal -> hiddenitem FULL_HEAL, EVENT_VERMILION_CITY_HIDDEN_FULL_HEAL |
Object events (def_object_events)
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
VERMILIONCITY_TEACHER |
SPRITE_TEACHER |
18 | 9 | SPRITEMOVEDATA_WANDER (radius 1,1) |
OBJECTTYPE_SCRIPT |
VermilionCityTeacherScript |
-1 |
VERMILIONCITY_GRAMPS |
SPRITE_GRAMPS |
23 | 6 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
VermilionMachopOwner |
-1 |
VERMILIONCITY_MACHOP |
SPRITE_MACHOP |
26 | 7 | SPRITEMOVEDATA_POKEMON |
OBJECTTYPE_SCRIPT |
VermilionMachop |
-1 |
VERMILIONCITY_SUPER_NERD |
SPRITE_SUPER_NERD |
14 | 16 | SPRITEMOVEDATA_WANDER (radius 1,1) |
OBJECTTYPE_SCRIPT |
VermilionCitySuperNerdScript |
-1 |
VERMILIONCITY_BIG_SNORLAX |
SPRITE_BIG_SNORLAX |
34 | 8 | SPRITEMOVEDATA_BIGDOLLSYM |
OBJECTTYPE_SCRIPT |
VermilionSnorlax |
EVENT_VERMILION_CITY_SNORLAX |
VERMILIONCITY_POKEFAN_M |
SPRITE_POKEFAN_M |
31 | 12 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
VermilionGymBadgeGuy |
-1 |
Scripts of interest
VermilionGymBadgeGuyat(31,12):readvar VAR_BADGES,ifequal NUM_BADGES, .AllBadges(16 badges ->verbosegiveitem HP_UP,EVENT_GOT_HP_UP_FROM_VERMILION_GUY),ifgreater 13,ifgreater 9for the intermediate lines. Not reachable this section.VermilionSnorlaxat(34,8):special SnorlaxAwake; asleep unless the Poke Flute radio channel is playing. Awake ->loadvar VAR_BATTLETYPE, BATTLETYPE_FORCEITEM,loadwildmon SNORLAX, 50,startbattle,setevent EVENT_FOUGHT_SNORLAX. Gates warp 10 toDIGLETTS_CAVE; out of scope here but it is the reason the east side is closed.- The cut tree:
maps/VermilionCity.blkblock index(6,9)holdsTILESET_KANTOblock$35, whose collision quad istilecoll FLOOR, CUT_TREE, WALL, FLOOR(data/tilesets/kanto_collision.asmrow$35). That puts the cuttable tile at cell(13,18), replacement block$4c, animation0(data/collision/field_move_blocks.asm:31). It is the only cut tree on the map. The hidden Full Heal bg_event at(12,19)is theWALLquadrant of the same block.
Items
| item | how obtained | source | one-time flag |
|---|---|---|---|
FULL_HEAL |
hidden, face (12,19) |
VermilionCityHiddenFullHeal |
EVENT_VERMILION_CITY_HIDDEN_FULL_HEAL |
HP_UP |
all 16 badges (not this section) | VermilionGymBadgeGuy .AllBadges |
EVENT_GOT_HP_UP_FROM_VERMILION_GUY |
Wild encounters
data/wild/kanto_water.asm:138 def_water_wildmons VERMILION_CITY, rate
6 percent: 35 TENTACOOL / 30 TENTACOOL / 35 TENTACRUEL. Fishing
FISHGROUP_OCEAN (data/wild/fish.asm .Ocean_Old/Good/Super, lines 42-55).
No entry in kanto_grass.asm and no treemons.asm row.
MAP_POKEMON_FAN_CLUB
- Script:
maps/PokemonFanClub.asm - Blocks:
maps/PokemonFanClub.blk - Header:
data/maps/maps.asm:300->map PokemonFanClub, TILESET_HOUSE, INDOOR, LANDMARK_VERMILION_CITY, MUSIC_VERMILION_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:277map_const POKEMON_FAN_CLUB, 5, 4(10 x 8 cells)
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 2 | 7 | VERMILION_CITY |
3 |
| 2 | 3 | 7 | VERMILION_CITY |
3 |
Coord events - none.
BG events (def_bg_events)
| x | y | type | script/item |
|---|---|---|---|
| 7 | 0 | BGEVENT_READ |
PokemonFanClubListenSign |
| 9 | 0 | BGEVENT_READ |
PokemonFanClubBraggingSign |
Object events (def_object_events)
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
POKEMONFANCLUB_CHAIRMAN |
SPRITE_GENTLEMAN |
3 | 1 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
PokemonFanClubChairmanScript (sym 59:4340) |
-1 |
POKEMONFANCLUB_RECEPTIONIST |
SPRITE_RECEPTIONIST |
4 | 1 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
PokemonFanClubReceptionistScript |
-1 |
POKEMONFANCLUB_CLEFAIRY_GUY |
SPRITE_FISHER |
2 | 3 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
PokemonFanClubClefairyGuyScript |
-1 |
POKEMONFANCLUB_TEACHER |
SPRITE_TEACHER |
7 | 2 | SPRITEMOVEDATA_STANDING_LEFT |
OBJECTTYPE_SCRIPT |
PokemonFanClubTeacherScript |
-1 |
POKEMONFANCLUB_FAIRY |
SPRITE_FAIRY |
2 | 4 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
PokemonFanClubClefairyDollScript |
EVENT_VERMILION_FAN_CLUB_DOLL |
POKEMONFANCLUB_ODDISH |
SPRITE_ODDISH |
7 | 3 | SPRITEMOVEDATA_POKEMON |
OBJECTTYPE_SCRIPT |
PokemonFanClubBayleefScript |
-1 |
Scripts of interest
PokemonFanClubChairmanScript:checkevent EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT->.HeardSpeech;checkevent EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT_BUT_BAG_WAS_FULL->.HeardSpeechButBagFull(skips the speech, retries the gift). Otherwiseyesornoon...DidYouVisitToHearAboutMyMonText; answering No goes to.NotListeningand gives nothing. Yes -> the Rapidash speech ->verbosegiveitem RARE_CANDY,iffalse .BagFull,setevent EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT. (Nothing in this file ever setsEVENT_LISTENED_TO_FAN_CLUB_PRESIDENT_BUT_BAG_WAS_FULL; it is only read.)PokemonFanClubClefairyGuyScripthandles theLOST_ITEM/ Copycat doll chain (EVENT_RETURNED_MACHINE_PART,EVENT_MET_COPYCAT_FOUND_OUT_ABOUT_LOST_ITEM,EVENT_GOT_LOST_ITEM_FROM_FAN_CLUB) - a later section.
Items
| item | how obtained | source | one-time flag |
|---|---|---|---|
RARE_CANDY |
answer "Yes" and sit through the speech | PokemonFanClubChairmanScript verbosegiveitem RARE_CANDY |
EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT |
MAP_VERMILION_GYM
- Script:
maps/VermilionGym.asm - Blocks:
maps/VermilionGym.blk - Header:
data/maps/maps.asm:304->map VermilionGym, TILESET_GAME_CORNER, INDOOR, LANDMARK_VERMILION_CITY, MUSIC_GYM, TRUE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm:281map_const VERMILION_GYM, 5, 9(10 x 18 cells) - No scene scripts, no callbacks, no coord events.
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 4 | 17 | VERMILION_CITY |
7 |
| 2 | 5 | 17 | VERMILION_CITY |
7 |
Coord events - none. (The Gen 1 trash-can/switch puzzle is gone - the guide
NPC even lampshades it in VermilionGymGuideText.)
BG events (def_bg_events)
| x | y | type | script/item |
|---|---|---|---|
| 1 | 7 | BGEVENT_READ |
VermilionGymTrashCan |
| 3 | 7 | BGEVENT_READ |
VermilionGymTrashCan |
| 5 | 7 | BGEVENT_READ |
VermilionGymTrashCan |
| 7 | 7 | BGEVENT_READ |
VermilionGymTrashCan |
| 9 | 7 | BGEVENT_READ |
VermilionGymTrashCan |
| 1 | 9 | BGEVENT_READ |
VermilionGymTrashCan |
| 3 | 9 | BGEVENT_READ |
VermilionGymTrashCan |
| 5 | 9 | BGEVENT_READ |
VermilionGymTrashCan |
| 7 | 9 | BGEVENT_READ |
VermilionGymTrashCan |
| 9 | 9 | BGEVENT_READ |
VermilionGymTrashCan |
| 1 | 11 | BGEVENT_READ |
VermilionGymTrashCan |
| 3 | 11 | BGEVENT_READ |
VermilionGymTrashCan |
| 5 | 11 | BGEVENT_READ |
VermilionGymTrashCan |
| 7 | 11 | BGEVENT_READ |
VermilionGymTrashCan |
| 9 | 11 | BGEVENT_READ |
VermilionGymTrashCan |
| 3 | 15 | BGEVENT_READ |
VermilionGymStatue |
| 6 | 15 | BGEVENT_READ |
VermilionGymStatue |
VermilionGymStatue: checkflag ENGINE_THUNDERBADGE -> if set,
gettrainername STRING_BUFFER_4, LT_SURGE, LT_SURGE1 + jumpstd GymStatue2Script,
else jumpstd GymStatue1Script.
Object events (def_object_events)
| const | sprite | x | y | movement | type | sight | script label | event flag |
|---|---|---|---|---|---|---|---|---|
VERMILIONGYM_SURGE |
SPRITE_SURGE |
5 | 2 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
0 | VermilionGymSurgeScript (sym 59:4bfc) |
-1 |
VERMILIONGYM_GENTLEMAN |
SPRITE_GENTLEMAN |
8 | 8 | SPRITEMOVEDATA_STANDING_LEFT |
OBJECTTYPE_TRAINER |
4 | TrainerGentlemanGregory |
-1 |
VERMILIONGYM_ROCKER |
SPRITE_ROCKER |
4 | 7 | SPRITEMOVEDATA_STANDING_DOWN (radius x 3) |
OBJECTTYPE_TRAINER |
3 | TrainerGuitaristVincent |
-1 |
VERMILIONGYM_SUPER_NERD |
SPRITE_SUPER_NERD |
0 | 10 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_TRAINER |
4 | TrainerJugglerHorton |
-1 |
VERMILIONGYM_GYM_GUIDE |
SPRITE_GYM_GUIDE |
7 | 15 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
1 | VermilionGymGuideScript |
-1 |
Scripts of interest
VermilionGymSurgeScript:checkflag ENGINE_THUNDERBADGE/iftrue .FightDone; elseLtSurgeIntroText,winlosstext LtSurgeWinLossText, 0,loadtrainer LT_SURGE, LT_SURGE1,startbattle,reloadmapafterbattle, thensetevent EVENT_BEAT_LTSURGEandsetevent EVENT_BEAT_GENTLEMAN_GREGORY,setevent EVENT_BEAT_GUITARIST_VINCENT,setevent EVENT_BEAT_JUGGLER_HORTON- beating Surge retroactively clears the three gym trainers, so a bot may legally skip them. ThenReceivedThunderBadgeText,playsound SFX_GET_BADGE,waitsfx,setflag ENGINE_THUNDERBADGE,LtSurgeThunderBadgeText. There is no TM award in this gym script.VermilionGymGuideScriptbranches onEVENT_BEAT_LTSURGE.
Flags and events
| constant | defined in | read/written by | meaning for a bot |
|---|---|---|---|
ENGINE_THUNDERBADGE |
constants/engine_flags.asm:49 |
set by VermilionGymSurgeScript; read there and by VermilionGymStatue |
the section's terminal milestone |
EVENT_BEAT_LTSURGE |
constants/event_flags.asm:717 |
set by VermilionGymSurgeScript; read by VermilionGymGuideScript |
post-win dialogue switch |
EVENT_BEAT_GUITARIST_VINCENT / EVENT_BEAT_JUGGLER_HORTON / EVENT_BEAT_GENTLEMAN_GREGORY |
constants/event_flags.asm |
set by each trainer macro and also by Surge's script |
trainer already-beaten guards |
Trainers
| const | class | id | party (data/trainers/parties.asm) |
script label | rematch/phone |
|---|---|---|---|---|---|
GUITARIST, VINCENT |
GUITARIST ($2b) |
2 | ; GUITARIST (2) db "VINCENT@", TRAINERTYPE_NORMAL -> L27 MAGNEMITE, L33 VOLTORB, L32 MAGNEMITE, L32 MAGNEMITE |
TrainerGuitaristVincent |
none |
JUGGLER, HORTON |
JUGGLER ($31) |
3 | ; JUGGLER (3) db "HORTON@", TRAINERTYPE_NORMAL -> 4x L33 ELECTRODE |
TrainerJugglerHorton |
none |
GENTLEMAN, GREGORY |
GENTLEMAN ($20) |
3 | ; GENTLEMAN (3) db "GREGORY@", TRAINERTYPE_NORMAL -> L37 PIKACHU, L33 FLAAFFY |
TrainerGentlemanGregory |
none |
LT_SURGE, LT_SURGE1 |
LT_SURGE ($13) |
1 | data/trainers/parties.asm:289-296, TRAINERTYPE_MOVES: L44 RAICHU (Thunder Wave / Quick Attack / Thunderbolt / Thunder); L40 ELECTRODE (Screech / Double Team / Swift / Explosion); L40 MAGNETON (Lock-On / Double Team / Swift / Zap Cannon); L40 ELECTRODE (same set); L46 ELECTABUZZ (Quick Attack / ThunderPunch / Light Screen / Thunder) |
VermilionGymSurgeScript |
none |
Party order is Raichu, Electrode, Magneton, Electrode, Electabuzz - the walkthrough lists Raichu, Magneton, Electabuzz, Electrode, Electrode.
Wild encounters - none (indoor).
3. Blockers and gates
| Gate | Enforced by (file:label) | Requirement | Unlock condition |
|---|---|---|---|
| Elm will not hand over the ticket | maps/ElmsLab.asm ProfElmScript checkevent EVENT_BEAT_ELITE_FOUR |
Hall of Fame done | maps/HallOfFame.asm:33 setevent EVENT_BEAT_ELITE_FOUR |
| Cannot board the Fast Ship | maps/OlivinePort.asm OlivinePortWalkUpToShipScript / OlivinePortSailorAfterHOFScript checkitem S_S_TICKET, iffalse .NoTicket |
S_S_TICKET in the bag |
ElmGiveTicketScript |
| Boarding sailor absent before HOF | maps/OlivinePort.asm object rows with EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME; the pre-HOF sailor's OlivinePortSailorBeforeHOFScript says "you're not allowed in" |
Hall of Fame done | HallOfFame.asm:38 clearevent EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME |
| Ship only sails on certain days (repeat trips) | OlivinePortWalkUpToShipScript readvar VAR_WEEKDAY (Mon/Fri from Olivine); VermilionPortWalkUpToShipScript (Wed/Sun from Vermilion) |
correct weekday | maiden voyage bypasses via checkevent EVENT_FAST_SHIP_FIRST_TIME / iffalse .FirstTime |
| Sailor blocks the B1F corridor | maps/FastShipB1F.asm coord events (30,7)/(31,7) -> FastShipB1FSailorBlocksLeft/Right plus the physical object at (30,6)/(31,6); FastShipB1FSailorScript |
find and beat the lazy sailor | FastShipLazySailorScript -> setevent EVENT_FAST_SHIP_LAZY_SAILOR + setmapscene FAST_SHIP_B1F, SCENE_FASTSHIPB1F_NOOP |
| Lazy sailor does not exist yet | object flag EVENT_FAST_SHIP_CABINS_NNW_NNE_NE_SAILOR, set at new game (engine/events/std_scripts.asm:499) |
talk to the on-duty sailor first | FastShipB1FSailorScript clearevent EVENT_FAST_SHIP_CABINS_NNW_NNE_NE_SAILOR |
| Ship will not dock (maiden voyage) | maps/FastShip1F.asm FastShip1FSailor1Script checkevent EVENT_FAST_SHIP_HAS_ARRIVED; FastShipBed .CanArrive needs EVENT_FAST_SHIP_FOUND_GIRL or EVENT_FAST_SHIP_FIRST_TIME |
finish the granddaughter errand | SSAquaMetalCoatAndDocking setevent EVENT_FAST_SHIP_HAS_ARRIVED / EVENT_FAST_SHIP_FOUND_GIRL |
| Chairman's Rare Candy | maps/PokemonFanClub.asm PokemonFanClubChairmanScript yesorno -> .NotListening |
answer Yes | setevent EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT |
| Cut tree in Vermilion City | tile collision CUT_TREE at cell (13,18) + data/collision/field_move_blocks.asm:31 db $35, $4c, 0; engine/events/overworld.asm:133 CheckAble requires ENGINE_HIVEBADGE, :169 CheckMapForSomethingToCut |
HM01 CUT + HIVEBADGE | already held long before Kanto. Does not gate the gym - see section 6 |
Snorlax blocks DIGLETTS_CAVE (warp 10, (34,7)) |
maps/VermilionCity.asm VermilionSnorlax special SnorlaxAwake |
Poke Flute radio channel | out of scope for this section |
| Lt. Surge re-battle refused | VermilionGymSurgeScript checkflag ENGINE_THUNDERBADGE -> .FightDone |
- | one-shot badge |
4. Bot checklist
NEW_BARK_TOWN-> walk to(6,3), warp 1, enterELMS_LAB. Pre:EVENT_BEAT_ELITE_FOURset. (AnSPECIALCALL_SSTICKETphone call may fire on the way; answering it is optional.)ELMS_LAB-> walk to(5,3)and face up to talk toELMSLAB_ELMat(5,2). Intent: talk. Pre:EVENT_BEAT_ELITE_FOUR,!EVENT_GOT_SS_TICKET_FROM_ELM. Post:EVENT_GOT_SS_TICKET_FROM_ELM, bag holdsS_S_TICKET.- Fly to
OLIVINE_CITY; walk to warp 10(19,27)->OLIVINE_PORT_PASSAGE. OLIVINE_PORT_PASSAGE: warp 3(15,4)-> lands at warp 4(3,2); then walk to warp 5(3,14)->OLIVINE_PORTwarp 1 at(11,7).OLIVINE_PORT: walk onto(7,15). Intent: walk (coord event). Post: yes/no prompt -> answer Yes;checkitem S_S_TICKETpasses; the script auto-walks you 7 south and warps you toFAST_SHIP_1F (25,1). Post-flags:EVENT_TEMPORARY_UNTIL_MAP_RELOAD_2,!EVENT_FAST_SHIP_DESTINATION_OLIVINE, sceneFAST_SHIP_1F= 1. (Alternative: talk toOLIVINEPORT_SAILOR3at(6,15)for the same flow.)FAST_SHIP_1F: the boarding cutscene runs on entry (scene 1). Then walk south to(24,6)or(25,6). Intent: walk (coord eventWorriedGrandpaSceneLeft). Post: scene ->SCENE_FASTSHIP1F_NOOP; nothing else changes.FAST_SHIP_1Fwarp 3 at(23,8)->FAST_SHIP_CABINS_NNW_NNE_NE (2,12). BattleTrainerHikerNolandat(4,17)(sight 3, faces up). Post:EVENT_BEAT_HIKER_NOLAND.- Back to 1F; warp 5 at
(15,8)->FAST_SHIP_CABINS_SW_SSW_NW (2,0); face the bed bg_event at(7,1)/(7,2)to heal (FastShipBed->special HealParty). Do not expect the ship to dock yet. - 1F warp 6 at
(15,15)->..._SW_SSW_NW (2,19). BattleTrainerFirebreatherLyleat(1,15). Post:EVENT_BEAT_FIREBREATHER_LYLE. - 1F warp 8 at
(23,15)->..._SE_SSE (2,7). BattleTrainerPokefanmColinat(5,6)and the twins at(2,4)/(3,4). Post:EVENT_BEAT_POKEFANM_COLIN,EVENT_BEAT_TWINS_MEG_AND_PEG. - 1F warp 9 at
(27,15)->..._SE_SSE (2,19). Talk toSSAquaGrandpaat(2,17). Post:setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_NOOP(flavour only; the errand is not flagged here). - 1F warp 12 at
(30,14)->FAST_SHIP_B1F (31,13). Walk north onto(31,7)(or(30,7)). Intent: walk (coord event) -> a sailor moves in front of you. Talk to him. Post:EVENT_FAST_SHIP_INFORMED_ABOUT_LAZY_SAILORset,EVENT_FAST_SHIP_CABINS_NNW_NNE_NE_SAILORcleared. - Back to 1F; warp 4 at
(19,8)->..._NNW_NNE_NE (2,24). Talk to the sailor at(4,26). Intent: talk -> forced battleSAILOR STANLY. Post:EVENT_BEAT_SAILOR_STANLY,EVENT_FAST_SHIP_LAZY_SAILOR,FAST_SHIP_B1Fscene ->SCENE_FASTSHIPB1F_NOOP, party healed. FAST_SHIP_B1Fagain (1F warp 12 ->(31,13)): the corridor is now passable. BattleTrainerJugglerFritzat(26,9),TrainerSailorJeffat(9,11),TrainerPicnickerDebraat(6,4).FAST_SHIP_B1Fwarp 1 at(5,11)->FAST_SHIP_1F (6,12); then 1F warp 10 at(3,13)->..._SE_SSE (2,33), the captain's cabin.- Talk to the granddaughter (
..._TWIN2) at(2,25). Intent: talk. Pre:!EVENT_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN_TWIN_2. Post: teleport cutscene,verbosegiveitem METAL_COAT,EVENT_GOT_METAL_COAT_FROM_GRANDPA_ON_SS_AQUA,EVENT_FAST_SHIP_HAS_ARRIVED,EVENT_FAST_SHIP_FOUND_GIRL,EVENT_VERMILION_PORT_SAILOR_AT_GANGWAY, 1F scene -> NOOP. You end up standing in the grandpa's sub-room; leave via warp 3/4(2,19)/(3,19). FAST_SHIP_1F: walk to(25,3)and talk toFASTSHIP1F_SAILOR1at(25,2). Pre:EVENT_FAST_SHIP_HAS_ARRIVED. Post:warp VERMILION_PORT, 7, 17,VERMILION_PORTscene ->SCENE_VERMILIONPORT_LEAVE_SHIP.VERMILION_PORT: the arrival scene runs (one step up). Post-flags includeEVENT_FAST_SHIP_FIRST_TIME,EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP,blackoutmod VERMILION_CITY,ENGINE_FLYPOINT_VERMILION(map callback). Optional: face(16,13)for the hiddenIRON.- Walk to warp 1
(9,5)->VERMILION_PORT_PASSAGE (3,14); warp 4(3,2)-> warp 3(15,4); walk to warps 1/2(15,0)/(16,0)->VERMILION_CITY(19,31)/(20,31). VERMILION_CITY-> warp 3 at(7,13)->POKEMON_FAN_CLUB (2,7). Talk to the chairman at(3,1); answer Yes. Post:EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT, bag holdsRARE_CANDY.- Optional:
VERMILION_POKECENTER_1Fvia warp 2(9,5)to heal. - Optional: face cell
(13,18)and use CUT (needsENGINE_HIVEBADGE), then face(12,19)for the hiddenFULL_HEAL. VERMILION_CITYwarp 7 at(10,19)->VERMILION_GYM (4,17).- Gym:
TrainerGuitaristVincentat(4,7)(sight 3, faces down),TrainerJugglerHortonat(0,10)(sight 4, faces right),TrainerGentlemanGregoryat(8,8)(sight 4, faces left). All three are optional - Surge's win script sets their flags. - Walk to
(5,3)and talk toVERMILIONGYM_SURGEat(5,2). Pre:!ENGINE_THUNDERBADGE. Intent: talk -> battleLT_SURGE, LT_SURGE1. Post:EVENT_BEAT_LTSURGE,EVENT_BEAT_GENTLEMAN_GREGORY,EVENT_BEAT_GUITARIST_VINCENT,EVENT_BEAT_JUGGLER_HORTON,ENGINE_THUNDERBADGE. Section complete.
5. Port coverage
Everything in this section is data-driven: the Gen 2 side of this repo extracts
map headers, blocks, warps, coord/bg/object events and scene scripts generically
(src/import/RomExtractorGen2.lua:804-977) and runs the scripts through
src/script/gen2/Vm.lua. There is no per-map hand-port for any of these maps, so
"implemented" below means the generic mechanism exists and the ROM data drives
it, not that the beat has been played through.
| Beat | Port file | Status |
|---|---|---|
| Map load: blocks, collision quads, warps by cell | src/world/gen2/Map.lua |
implemented (generic) |
| Warp / coord / bg event dispatch | src/world/gen2/World.lua:5013 (coord), :5148 (bg), :1183 + :5026 (scene scripts) |
implemented (generic) |
verbosegiveitem (S.S. TICKET, METAL COAT, RARE CANDY) |
src/script/gen2/Vm.lua:490-522 |
implemented |
checkitem S_S_TICKET boarding gate |
src/script/gen2/Vm.lua:523 |
implemented |
loadtrainer / startbattle (Stanly, Lt. Surge) |
src/script/gen2/Vm.lua:806, :918 (winlosstext) |
implemented |
OBJECTTYPE_TRAINER sight lines (ship + gym trainers) |
src/world/gen2/Trainers.lua:98 Trainers.sees |
implemented |
TRAINERTYPE_MOVES parties (Lt. Surge) and TRAINERTYPE_ITEM (Colin) |
src/import/RomExtractorGen2.lua:3900-3968 |
implemented |
setmapscene / sdefer scene plumbing (ports, ship, B1F) |
src/script/gen2/Vm.lua:92, :279 |
implemented |
moveobject + appear sailor-shuffle on B1F |
src/script/gen2/Vm.lua:337-350 (the comment calls out exactly this pattern) |
implemented |
showemote (grandpa's !) and earthquake (boarding) |
src/script/gen2/Vm.lua:961, :1799 |
implemented |
blackoutmod (cabin / Vermilion respawn) |
src/script/gen2/Vm.lua:1136 |
implemented |
special HealParty (bed, post-Stanly), FadeOutToWhite/Black, ReloadSpritesNoPalettes, RestartMapMusic |
src/script/gen2/Specials.lua:450, :998, :1025, :1059 |
implemented |
specialphonecall SPECIALCALL_SSTICKET |
src/script/gen2/Vm.lua:1364; roster entry src/core/gen2/Phone.lua:395 ([5] = SPECIALCALL_SSTICKET, condition anywhere) |
implemented |
CUT on the Vermilion tree (TILESET_KANTO $35 -> $4c, anim 0) |
src/world/gen2/FieldMoves.lua:191-208, :242 |
implemented |
Hidden items (PROTEIN, IRON, FULL_HEAL) |
src/world/gen2/HiddenItems.lua:64, :112 |
implemented |
ENGINE_FLYPOINT_VERMILION from the map callback |
src/world/gen2/FieldMoves.lua:361 (LANDMARK_VERMILION_CITY -> SPAWN_VERMILION, flag 57) |
implemented |
readvar VAR_BADGES (Vermilion badge guy) |
src/world/gen2/World.lua:117, :1240 |
implemented |
special SnorlaxAwake |
src/script/gen2/Specials.lua:1562 |
implemented |
Water encounters / FISHGROUP_OCEAN at the ports |
src/battle/gen2/Encounter.lua |
not verified in this pass - no port-specific check was run |
| A driver that exercises the crossing end to end | tests/drivers/gold_*.lua |
missing - no gold_fastship_*, gold_vermilion_* or gold_surge_* driver exists |
| Any hand-ported script for these 14 maps | - | missing by design; all behaviour comes from the extracted ROM script bytes |
Note: the many Vermilion* hits under src/world/OverworldController.lua and
src/world/FieldDefaults.lua are the Gen 1 (pokered) Vermilion Gym trash-can
puzzle. That puzzle does not exist in Gold, and none of that code is on the Gen 2
path.
6. Unresolved / verify by hand
- "cut down the tree blocking the gym" is wrong.
maps/VermilionCity.blkhas exactly one cuttable block,$35at block(6,9), whoseCUT_TREEquadrant is cell(13,18). The gym door is theDOORquadrant of block$12at(5,9)= cell(10,19), and the tiles south of it ((10,20),(11,20),(12,20)) are allFLOOR. Walking a straight path from the port entrance to the gym door never touches the tree. Cutting it only opens cell(13,18), which is beside the hiddenFULL_HEALat(12,19). Verified againstdata/tilesets/kanto_collision.asmrows$12,$35,$4c,$31. - "Meal Coat" in the walkthrough's item list is a typo for
METAL_COAT(SSAquaMetalCoatAndDocking). NoMEAL_*item exists. - Lt. Surge's party order in the walkthrough (Raichu, Magneton, Electabuzz,
Electrode, Electrode) does not match
data/trainers/parties.asm:289-296(Raichu, Electrode, Magneton, Electrode, Electabuzz). - Juggler Fritz's party order: asm is Mr. Mime / Magmar / Machoke; the walkthrough says Mr. Mime / Machoke / Magmar.
- "Lt. Surge has a Full Restore" - the party entry is
TRAINERTYPE_MOVES, which carries no held item. Gym-leader item use is AI behaviour (data/trainers/attributes.asm/ the trainer-class AI item list), which was not opened in this pass. Verify before relying on it. - Prize money figures ("You get: 1056G", "4600G", "???G" for Colin) are not stored anywhere in the asm as literals - Gen 2 computes them from base money x level. Not reproduced here.
- EXP values quoted per Pokemon are party- and level-dependent runtime calculations, not table data. Not reproduced here.
EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT_BUT_BAG_WAS_FULLis read byPokemonFanClubChairmanScriptbut is neversetevent'd anywhere inmaps/PokemonFanClub.asm. Either it is set elsewhere (nothing found by grep) or it is dead in this revision; a full-bag player appears to have to sit through the Rapidash speech again.- "Note the new Pokemon music for Kanto": the Vermilion maps use
MUSIC_VERMILION_CITY(data/maps/maps.asm:296). Whether that is the "Kanto remix" the walkthrough means was not checked against the audio engine. - The walkthrough's cabin-by-cabin narration ("two cabins to the right", "the
cabin next to yours") was reconciled against the 1F warp
xpositions (north rowx= 27/23/19/15, south rowx= 15/19/23/27) and is consistent, but the prose ordering of trainers withinFAST_SHIP_B1F("head left, then down") was not re-walked tile by tile.