mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-14 23:31:27 +02:00
1094 lines
67 KiB
Markdown
1094 lines
67 KiB
Markdown
# 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:441` `map_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`, sym `60:427b` for `ElmGiveTicketScript`).
|
|
First two opcodes after `faceplayer`/`opentext` are the ticket gate:
|
|
`checkevent EVENT_GOT_SS_TICKET_FROM_ELM` / `iftrue ElmCheckMasterBall`, then
|
|
`checkevent 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 **no** `iffalse` bag-full guard on this `verbosegiveitem`, unlike
|
|
every other Elm gift in the same file - the flag is set unconditionally.
|
|
- `engine/phone/scripts/elm.asm:69` `ElmPhoneCallerScript` routes
|
|
`SPECIALCALL_SSTICKET` to `.gift`, which prints `ElmPhoneGiftText` and clears
|
|
the pending call with `specialphonecall 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 with `VermilionPortPassage`; there is no
|
|
`OlivinePortPassage.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:314` `map_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:307` `map_const OLIVINE_PORT, 10, 18` (20 x 36 cells)
|
|
- Attributes: `data/maps/attributes.asm:586` `map_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)`): turns `SAILOR3`
|
|
right, bails via `.skip` if either `EVENT_TEMPORARY_UNTIL_MAP_RELOAD_1` or
|
|
`_2` is set, else asks `OlivinePortAskBoardText` with `yesorno`.
|
|
If `EVENT_FAST_SHIP_FIRST_TIME` is **clear** it jumps straight past the
|
|
weekday gate (`.FirstTime`) - the maiden voyage sails any day.
|
|
Otherwise `readvar VAR_WEEKDAY`: `SUNDAY`/`SATURDAY` -> `.NextShipMonday`,
|
|
`TUESDAY`/`WEDNESDAY`/`THURSDAY` -> `.NextShipFriday`. So from Olivine the ship
|
|
sails **Monday and Friday**.
|
|
Then `checkitem S_S_TICKET`; `iffalse .NoTicket`. On success it sets
|
|
`EVENT_TEMPORARY_UNTIL_MAP_RELOAD_2`, walks the player 7 steps down
|
|
(`OlivinePortApproachFastShipFirstTimeMovement`) and `sjump`s into
|
|
`OlivinePortSailorAtGangwayScript`.
|
|
- `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 does `clearevent EVENT_FAST_SHIP_PASSENGERS_EASTBOUND`,
|
|
`setevent EVENT_FAST_SHIP_PASSENGERS_WESTBOUND` and clears the eight
|
|
eastbound `EVENT_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` (scene `SCENE_OLIVINEPORT_LEAVE_SHIP`, 1): the
|
|
arrival cutscene for the return trip - one step up, `appear` the 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:309` `map_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` (sym `5b:48ad`, scene 1, run via `sdefer`): 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`. Then
|
|
`checkevent EVENT_FAST_SHIP_FIRST_TIME` / `iftrue .SkipGrandpa`: on the first
|
|
crossing it sets `SCENE_FASTSHIP1F_MEET_GRANDPA`, otherwise
|
|
`SCENE_FASTSHIP1F_NOOP`.
|
|
- `WorriedGrandpaSceneLeft`: `appear FASTSHIP1F_GENTLEMAN`, four `big_step RIGHT`,
|
|
`playsound SFX_TACKLE`, knocks the player one step right,
|
|
`writetext FastShip1FGrandpaText` ("My granddaughter is missing!"), then the
|
|
gentleman runs off, `disappear`s and the scene is reset to
|
|
`SCENE_FASTSHIP1F_NOOP`. Purely informational - it sets no quest flag.
|
|
- `FastShip1FSailor1Script` (the door guard at `(25,2)`): if
|
|
`EVENT_FAST_SHIP_HAS_ARRIVED` is clear it just says "en route", branching on
|
|
`EVENT_FAST_SHIP_DESTINATION_OLIVINE` for the destination name. Once arrived it
|
|
runs `.LetThePlayerOut` (`readvar VAR_FACING`, two step-up variants), then
|
|
`setevent EVENT_VERMILION_PORT_SAILOR_AT_GANGWAY` (note: **set** hides that
|
|
object), `setmapscene VERMILION_PORT, SCENE_VERMILIONPORT_LEAVE_SHIP` and
|
|
`warp 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:310` `map_const FAST_SHIP_CABINS_NNW_NNE_NE, 4, 16` (8 x 32 cells)
|
|
- Layout: three stacked sub-rooms, `y` 0-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` (sym `5b:4d68`): not a `trainer` object, 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`.
|
|
Note `special HealParty` fires 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:311` `map_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 if `EVENT_FAST_SHIP_HAS_ARRIVED`; otherwise
|
|
`checkevent EVENT_FAST_SHIP_FOUND_GIRL` **or**
|
|
`checkevent EVENT_FAST_SHIP_FIRST_TIME` -> `.CanArrive`, which plays
|
|
`SFX_ELEVATOR_END`, prints the arrival text and
|
|
`setevent EVENT_FAST_SHIP_HAS_ARRIVED`.
|
|
**Bot-relevant**: on the maiden voyage, sleeping in the bed does *not* dock the
|
|
ship, because both `EVENT_FAST_SHIP_FOUND_GIRL` and `EVENT_FAST_SHIP_FIRST_TIME`
|
|
are 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:312` `map_const FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN, 5, 17` (10 x 34 cells)
|
|
- Layout: sub-room 1 `y` 0-11 (Colin + Twins), sub-room 2 `y` 12-23 (grandpa),
|
|
sub-room 3 `y` 24-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 `..._GENTLEMAN` at `(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 plus
|
|
`setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_NOOP`.
|
|
- `SSAquaGranddaughterBefore` (talk to `..._TWIN2` at `(2,25)` in the captain's
|
|
cabin) - the payoff scene: `FadeOutToBlack`, `disappear` TWIN2, teleport the
|
|
player with `SSAquaCaptainsCabinWarpsToGrandpasCabinMovement`
|
|
(`big_step RIGHT` + six `big_step UP`), `moveobject TWIN1, 3, 19` + `appear`,
|
|
`showemote EMOTE_SHOCK` on the gentleman, dialogue, then
|
|
`setevent EVENT_VERMILION_PORT_SAILOR_AT_GANGWAY`,
|
|
`setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_NOOP`,
|
|
`sjump SSAquaMetalCoatAndDocking`.
|
|
- `SSAquaMetalCoatAndDocking` (sym `5b:5633`): `verbosegiveitem METAL_COAT`,
|
|
`iffalse .NoRoom`, `setevent EVENT_GOT_METAL_COAT_FROM_GRANDPA_ON_SS_AQUA`,
|
|
then `playsound 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:313` `map_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` (sym `5b: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;
|
|
if `EVENT_FAST_SHIP_FOUND_GIRL` is still clear he also prints
|
|
`FastShipB1FOnDutySailorSawLittleGirlText` (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_SAILOR` and
|
|
`clearevent 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. Once `FastShipLazySailorScript` runs
|
|
`setmapscene 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:308` `map_const VERMILION_PORT, 10, 18` (20 x 36 cells)
|
|
- Attributes: `data/maps/attributes.asm:587` `map_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` (sym `5b:450e`, scene 1, `sdefer`): the arrival
|
|
cutscene. One `step 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 sets
|
|
`EVENT_FAST_SHIP_PASSENGERS_EASTBOUND`, clears `..._WESTBOUND`, clears the ten
|
|
westbound `EVENT_BEAT_*` flags, sets
|
|
`EVENT_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:315` `map_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:273` `map_const VERMILION_CITY, 20, 18` (40 x 36 cells)
|
|
- Attributes: `data/maps/attributes.asm:342` `map_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**
|
|
|
|
- `VermilionGymBadgeGuy` at `(31,12)`: `readvar VAR_BADGES`,
|
|
`ifequal NUM_BADGES, .AllBadges` (16 badges -> `verbosegiveitem HP_UP`,
|
|
`EVENT_GOT_HP_UP_FROM_VERMILION_GUY`), `ifgreater 13`, `ifgreater 9` for the
|
|
intermediate lines. Not reachable this section.
|
|
- `VermilionSnorlax` at `(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 to `DIGLETTS_CAVE`; out of scope
|
|
here but it is the reason the east side is closed.
|
|
- The **cut tree**: `maps/VermilionCity.blk` block index `(6,9)` holds
|
|
`TILESET_KANTO` block `$35`, whose collision quad is
|
|
`tilecoll FLOOR, CUT_TREE, WALL, FLOOR` (`data/tilesets/kanto_collision.asm`
|
|
row `$35`). That puts the cuttable tile at cell **`(13,18)`**, replacement
|
|
block `$4c`, animation `0` (`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 the
|
|
`WALL` quadrant 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:277` `map_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). Otherwise
|
|
`yesorno` on `...DidYouVisitToHearAboutMyMonText`; **answering No** goes to
|
|
`.NotListening` and gives nothing. Yes -> the Rapidash speech ->
|
|
`verbosegiveitem RARE_CANDY`, `iffalse .BagFull`,
|
|
`setevent EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT`.
|
|
(Nothing in this file ever *sets*
|
|
`EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT_BUT_BAG_WAS_FULL`; it is only read.)
|
|
- `PokemonFanClubClefairyGuyScript` handles the `LOST_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:281` `map_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`; else `LtSurgeIntroText`, `winlosstext LtSurgeWinLossText, 0`,
|
|
`loadtrainer LT_SURGE, LT_SURGE1`, `startbattle`, `reloadmapafterbattle`,
|
|
then `setevent EVENT_BEAT_LTSURGE` **and**
|
|
`setevent 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. Then
|
|
`ReceivedThunderBadgeText`, `playsound SFX_GET_BADGE`, `waitsfx`,
|
|
`setflag ENGINE_THUNDERBADGE`, `LtSurgeThunderBadgeText`.
|
|
There is no TM award in this gym script.
|
|
- `VermilionGymGuideScript` branches on `EVENT_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
|
|
|
|
1. `NEW_BARK_TOWN` -> walk to `(6,3)`, warp 1, enter `ELMS_LAB`.
|
|
Pre: `EVENT_BEAT_ELITE_FOUR` set. (An `SPECIALCALL_SSTICKET` phone call may
|
|
fire on the way; answering it is optional.)
|
|
2. `ELMS_LAB` -> walk to `(5,3)` and face up to talk to `ELMSLAB_ELM` at `(5,2)`.
|
|
Intent: talk. Pre: `EVENT_BEAT_ELITE_FOUR`, `!EVENT_GOT_SS_TICKET_FROM_ELM`.
|
|
Post: `EVENT_GOT_SS_TICKET_FROM_ELM`, bag holds `S_S_TICKET`.
|
|
3. Fly to `OLIVINE_CITY`; walk to warp 10 `(19,27)` -> `OLIVINE_PORT_PASSAGE`.
|
|
4. `OLIVINE_PORT_PASSAGE`: warp 3 `(15,4)` -> lands at warp 4 `(3,2)`; then walk
|
|
to warp 5 `(3,14)` -> `OLIVINE_PORT` warp 1 at `(11,7)`.
|
|
5. `OLIVINE_PORT`: walk onto `(7,15)`. Intent: walk (coord event).
|
|
Post: yes/no prompt -> answer **Yes**; `checkitem S_S_TICKET` passes; the
|
|
script auto-walks you 7 south and warps you to `FAST_SHIP_1F (25,1)`.
|
|
Post-flags: `EVENT_TEMPORARY_UNTIL_MAP_RELOAD_2`,
|
|
`!EVENT_FAST_SHIP_DESTINATION_OLIVINE`, scene `FAST_SHIP_1F` = 1.
|
|
(Alternative: talk to `OLIVINEPORT_SAILOR3` at `(6,15)` for the same flow.)
|
|
6. `FAST_SHIP_1F`: the boarding cutscene runs on entry (scene 1). Then walk south
|
|
to `(24,6)` or `(25,6)`. Intent: walk (coord event `WorriedGrandpaSceneLeft`).
|
|
Post: scene -> `SCENE_FASTSHIP1F_NOOP`; nothing else changes.
|
|
7. `FAST_SHIP_1F` warp 3 at `(23,8)` -> `FAST_SHIP_CABINS_NNW_NNE_NE (2,12)`.
|
|
Battle `TrainerHikerNoland` at `(4,17)` (sight 3, faces up).
|
|
Post: `EVENT_BEAT_HIKER_NOLAND`.
|
|
8. 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.
|
|
9. 1F warp 6 at `(15,15)` -> `..._SW_SSW_NW (2,19)`. Battle
|
|
`TrainerFirebreatherLyle` at `(1,15)`. Post: `EVENT_BEAT_FIREBREATHER_LYLE`.
|
|
10. 1F warp 8 at `(23,15)` -> `..._SE_SSE (2,7)`. Battle `TrainerPokefanmColin`
|
|
at `(5,6)` and the twins at `(2,4)`/`(3,4)`.
|
|
Post: `EVENT_BEAT_POKEFANM_COLIN`, `EVENT_BEAT_TWINS_MEG_AND_PEG`.
|
|
11. 1F warp 9 at `(27,15)` -> `..._SE_SSE (2,19)`. Talk to `SSAquaGrandpa` at
|
|
`(2,17)`. Post: `setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_NOOP` (flavour
|
|
only; the errand is not flagged here).
|
|
12. 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_SAILOR` set,
|
|
`EVENT_FAST_SHIP_CABINS_NNW_NNE_NE_SAILOR` cleared.
|
|
13. Back to 1F; warp 4 at `(19,8)` -> `..._NNW_NNE_NE (2,24)`. Talk to the sailor
|
|
at `(4,26)`. Intent: talk -> forced battle `SAILOR STANLY`.
|
|
Post: `EVENT_BEAT_SAILOR_STANLY`, `EVENT_FAST_SHIP_LAZY_SAILOR`,
|
|
`FAST_SHIP_B1F` scene -> `SCENE_FASTSHIPB1F_NOOP`, party healed.
|
|
14. `FAST_SHIP_B1F` again (1F warp 12 -> `(31,13)`): the corridor is now passable.
|
|
Battle `TrainerJugglerFritz` at `(26,9)`, `TrainerSailorJeff` at `(9,11)`,
|
|
`TrainerPicnickerDebra` at `(6,4)`.
|
|
15. `FAST_SHIP_B1F` warp 1 at `(5,11)` -> `FAST_SHIP_1F (6,12)`; then 1F warp 10
|
|
at `(3,13)` -> `..._SE_SSE (2,33)`, the captain's cabin.
|
|
16. 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)`.
|
|
17. `FAST_SHIP_1F`: walk to `(25,3)` and talk to `FASTSHIP1F_SAILOR1` at `(25,2)`.
|
|
Pre: `EVENT_FAST_SHIP_HAS_ARRIVED`.
|
|
Post: `warp VERMILION_PORT, 7, 17`, `VERMILION_PORT` scene ->
|
|
`SCENE_VERMILIONPORT_LEAVE_SHIP`.
|
|
18. `VERMILION_PORT`: the arrival scene runs (one step up). Post-flags include
|
|
`EVENT_FAST_SHIP_FIRST_TIME`, `EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP`,
|
|
`blackoutmod VERMILION_CITY`, `ENGINE_FLYPOINT_VERMILION` (map callback).
|
|
Optional: face `(16,13)` for the hidden `IRON`.
|
|
19. 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)`.
|
|
20. `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 holds `RARE_CANDY`.
|
|
21. Optional: `VERMILION_POKECENTER_1F` via warp 2 `(9,5)` to heal.
|
|
22. Optional: face cell `(13,18)` and use CUT (needs `ENGINE_HIVEBADGE`), then
|
|
face `(12,19)` for the hidden `FULL_HEAL`.
|
|
23. `VERMILION_CITY` warp 7 at `(10,19)` -> `VERMILION_GYM (4,17)`.
|
|
24. Gym: `TrainerGuitaristVincent` at `(4,7)` (sight 3, faces down),
|
|
`TrainerJugglerHorton` at `(0,10)` (sight 4, faces right),
|
|
`TrainerGentlemanGregory` at `(8,8)` (sight 4, faces left).
|
|
All three are optional - Surge's win script sets their flags.
|
|
25. Walk to `(5,3)` and talk to `VERMILIONGYM_SURGE` at `(5,2)`.
|
|
Pre: `!ENGINE_THUNDERBADGE`. Intent: talk -> battle `LT_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.blk` has
|
|
exactly one cuttable block, `$35` at block `(6,9)`, whose `CUT_TREE` quadrant is
|
|
cell `(13,18)`. The gym door is the `DOOR` quadrant of block `$12` at
|
|
`(5,9)` = cell `(10,19)`, and the tiles south of it (`(10,20)`, `(11,20)`,
|
|
`(12,20)`) are all `FLOOR`. 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 hidden `FULL_HEAL` at `(12,19)`. Verified against
|
|
`data/tilesets/kanto_collision.asm` rows `$12`, `$35`, `$4c`, `$31`.
|
|
- **"Meal Coat"** in the walkthrough's item list is a typo for `METAL_COAT`
|
|
(`SSAquaMetalCoatAndDocking`). No `MEAL_*` 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_FULL`** is read by
|
|
`PokemonFanClubChairmanScript` but is never `setevent`'d anywhere in
|
|
`maps/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 `x` positions
|
|
(north row `x` = 27/23/19/15, south row `x` = 15/19/23/27) and is consistent,
|
|
but the prose ordering of trainers within `FAST_SHIP_B1F` ("head left, then
|
|
down") was not re-walked tile by tile.
|