mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
1264 lines
74 KiB
Lua
1264 lines
74 KiB
Lua
-- Gold route: New Bark Town through the Olivine Gym (asm-walk sections 00-09).
|
|
--
|
|
-- Hand-authored from docs/gold-walkthrough/asm-walk/section-NN-*.md. Every row
|
|
-- carries the section and checklist step it came from in `id`, so a stall names
|
|
-- a paragraph a human can go read.
|
|
--
|
|
-- Why this is not generated from the markdown. The plan was a converter over
|
|
-- each section's "## 4. Bot checklist" table, on the botconv principle that the
|
|
-- docs stay the source of truth. Seven of these ten sections write that
|
|
-- checklist as free prose ("walk west along y=11..13", "grind to the
|
|
-- walkthrough's level 8", "avoid the three trainers") rather than the template's
|
|
-- six-column table, and the Intent column has no controlled vocabulary anywhere
|
|
-- -- so a parser would have been a prose-guesser wearing a converter's clothes,
|
|
-- and normalising 300 rows of prose into tables by hand is strictly more work
|
|
-- than writing the Lua those tables would have produced. The anti-drift job the
|
|
-- converter was for is done better by tests/gold_route_validate_test.lua, which
|
|
-- checks every coordinate below against the extracted cache: a warp that is not
|
|
-- at (6,3), an object that moved, a map that does not exist and an EVENT_* that
|
|
-- is not a real flag name all fail in seconds, which is more than a markdown
|
|
-- parser could ever have caught.
|
|
--
|
|
-- Scope: the REQUIRED spine only. Optional pickups, phone numbers, the Ruins of
|
|
-- Alph, the Bug Contest and the day-of-week NPCs are left out of this first
|
|
-- pass; each one is a place the bot can stall for no progression benefit. Rows
|
|
-- marked `optional = true` may fail without failing the run.
|
|
--
|
|
-- Ops:
|
|
-- travel be on this map, however the map graph gets there
|
|
-- walk stand on this cell (trip-wires and coord events)
|
|
-- warp walk onto this warp cell, expect to arrive on `to`
|
|
-- edge cross this map connection, expect to arrive on `to`
|
|
-- talk stand adjacent, face it, press A, answer `answers` in order
|
|
-- battle as `talk`/`walk`, then fight whatever starts
|
|
-- grind fight wilds here until the party's lowest level reaches `level`
|
|
-- heal talk to this map's Pokecenter nurse
|
|
-- teach teach a move from an HM to an eligible party mon
|
|
-- field use a field move against this cell
|
|
-- catch hunt this map's wild encounters until one of `species` is caught
|
|
-- manual not implemented; log it, record it, carry on
|
|
|
|
return {
|
|
|
|
-- =========================================================================
|
|
-- Section 00 : the bedroom through the starter
|
|
-- =========================================================================
|
|
-- NEW GAME, InitClock and NamePlayer have no rows here on purpose. A
|
|
-- POKEPORT_DRIVER run without POKEPORT_BOOT_CINEMA boots straight into the
|
|
-- world (src/core/Game2.lua:load), so the bot starts already stood
|
|
-- in the bedroom with none of the three ever on screen. With the cinema on
|
|
-- they are driven instead by tests/drivers/gold_boot_smoke.lua.
|
|
|
|
{ id = "00.5", map = "PLAYERS_HOUSE_2F", op = "warp", x = 7, y = 0,
|
|
to = "PLAYERS_HOUSE_1F" },
|
|
|
|
-- MeetMomScript fires on the scene-0 load and runs ~1300 frames of text with
|
|
-- a yes/no pair inside it. The section's step 6a is explicit that answering
|
|
-- the DST question is not enough: the confirm loops back to .SetDayOfWeek on
|
|
-- "no", so both answers have to be yes.
|
|
{ id = "00.6", map = "PLAYERS_HOUSE_1F", op = "settle",
|
|
answers = { "yes", "yes" }, budget = 4000 },
|
|
|
|
{ id = "00.7", map = "PLAYERS_HOUSE_1F", op = "warp", x = 6, y = 7,
|
|
to = "NEW_BARK_TOWN" },
|
|
{ id = "00.9", map = "NEW_BARK_TOWN", op = "warp", x = 6, y = 3,
|
|
to = "ELMS_LAB" },
|
|
|
|
-- Scene 0 auto-walks the player to (4,2) and talks; nothing to drive but the
|
|
-- text.
|
|
{ id = "00.10", map = "ELMS_LAB", op = "settle", budget = 3000 },
|
|
|
|
-- Starter. Cyndaquil at (6,3): section 09's own battle notes say to bring a
|
|
-- Fire or Fighting lead for Jasmine, and Fire also answers Bugsy's Scyther in
|
|
-- section 04. Answers are yes (take it) then no (skip the nickname screen --
|
|
-- the naming keyboard has no cancel, only END, so it is far cheaper never to
|
|
-- open it: src/ui/gen2/NamingScreen.lua:236).
|
|
{ id = "00.11", map = "ELMS_LAB", op = "talk", x = 6, y = 3,
|
|
answers = { "yes", "no" }, expect = "EVENT_GOT_A_POKEMON_FROM_ELM" },
|
|
|
|
{ id = "00.12", map = "ELMS_LAB", op = "walk", x = 4, y = 8 },
|
|
{ id = "00.14", map = "ELMS_LAB", op = "warp", x = 4, y = 11,
|
|
to = "NEW_BARK_TOWN" },
|
|
{ id = "00.15", map = "NEW_BARK_TOWN", op = "edge", dir = "west",
|
|
to = "ROUTE_29" },
|
|
|
|
-- =========================================================================
|
|
-- Section 01 : Cherrygrove, Mr Pokemon, the egg, and north to Violet
|
|
-- =========================================================================
|
|
|
|
-- The starter is level 5 and Falkner is four maps away. The walkthrough
|
|
-- grinds Route 29 to 8 before Cherrygrove; do the same, because every later
|
|
-- gate in this section is a scripted battle we cannot decline.
|
|
{ id = "01.5", map = "ROUTE_29", op = "grind", level = 8 },
|
|
{ id = "01.6", map = "ROUTE_29", op = "edge", dir = "west",
|
|
to = "CHERRYGROVE_CITY" },
|
|
|
|
-- The guide gent's tour is a long follow/stopfollow cutscene. It is not a
|
|
-- progression gate, but he walks up and starts it unprompted, so it is
|
|
-- cheaper to run it deliberately than to be ambushed mid-path later.
|
|
{ id = "01.7", map = "CHERRYGROVE_CITY", op = "talk", x = 32, y = 6,
|
|
answers = { "yes" }, optional = true, budget = 6000 },
|
|
{ id = "01.8", map = "CHERRYGROVE_CITY", op = "heal", optional = true },
|
|
|
|
{ id = "01.9", map = "CHERRYGROVE_CITY", op = "edge", dir = "up",
|
|
to = "ROUTE_30" },
|
|
{ id = "01.12", map = "ROUTE_30", op = "warp", x = 17, y = 5,
|
|
to = "MR_POKEMONS_HOUSE" },
|
|
|
|
-- The scene fires on load: egg, Pokedex, the blackout point moves to
|
|
-- Cherrygrove, and SPECIALCALL_ROBBED is armed.
|
|
{ id = "01.13", map = "MR_POKEMONS_HOUSE", op = "settle", budget = 5000,
|
|
expect = "EVENT_GOT_MYSTERY_EGG_FROM_MR_POKEMON" },
|
|
{ id = "01.14", map = "MR_POKEMONS_HOUSE", op = "warp", x = 2, y = 7,
|
|
to = "ROUTE_30" },
|
|
|
|
-- Elm's call lands a few overworld steps after leaving; `settle` after the
|
|
-- travel below picks it up wherever it fires.
|
|
{ id = "01.15", map = "CHERRYGROVE_CITY", op = "travel" },
|
|
{ id = "01.15b", map = "CHERRYGROVE_CITY", op = "settle", budget = 2000,
|
|
optional = true },
|
|
{ id = "01.16", map = "CHERRYGROVE_CITY", op = "battle", x = 33, y = 6,
|
|
note = "rival scene trip-wire on row 6/7 at x=33" },
|
|
|
|
{ id = "01.18", map = "ELMS_LAB", op = "travel" },
|
|
{ id = "01.18b", map = "ELMS_LAB", op = "walk", x = 4, y = 5,
|
|
note = "SCENE_ELMSLAB_MEET_OFFICER trip-wire; CopScript names the rival" },
|
|
{ id = "01.18c", map = "ELMS_LAB", op = "settle", budget = 4000 },
|
|
{ id = "01.19", map = "ELMS_LAB", op = "talk", x = 5, y = 2,
|
|
answers = { "yes" }, expect = "EVENT_GAVE_MYSTERY_EGG_TO_ELM" },
|
|
{ id = "01.20", map = "ELMS_LAB", op = "walk", x = 4, y = 8,
|
|
note = "aide's five POKE BALLs" },
|
|
|
|
-- Route 30's north blockers come down with the egg handed over, so the run
|
|
-- north to Violet is only now possible. The trainers on the way (Joey,
|
|
-- Mikey, Don, Wade) are walked into rather than sought: the route is
|
|
-- geography and the sight lines do the rest.
|
|
{ id = "01.25", map = "ROUTE_30", op = "travel" },
|
|
{ id = "01.26", map = "ROUTE_31", op = "travel" },
|
|
{ id = "01.30", map = "VIOLET_CITY", op = "travel" },
|
|
|
|
-- =========================================================================
|
|
-- Section 02 : Sprout Tower and Falkner
|
|
-- =========================================================================
|
|
-- Sprout Tower is optional for the badge but is where HM05 FLASH lives, and
|
|
-- the rival fight on 3F is a scene trip-wire that will otherwise ambush a
|
|
-- later pass through. Kept, but the sages are left to their sight lines.
|
|
|
|
{ id = "02.1", map = "SPROUT_TOWER_1F", op = "travel", optional = true },
|
|
{ id = "02.15", map = "SPROUT_TOWER_3F", op = "travel", optional = true },
|
|
{ id = "02.15b", map = "SPROUT_TOWER_3F", op = "walk", x = 11, y = 9,
|
|
optional = true, note = "rival encounter coord event, scene 0" },
|
|
{ id = "02.16", map = "SPROUT_TOWER_3F", op = "talk", x = 10, y = 2,
|
|
optional = true, expect = "EVENT_GOT_HM05_FLASH" },
|
|
|
|
-- Grind before each gym. The route used to carry exactly one grind row (the
|
|
-- opening Route 29 one) and fought every leader at whatever level the walking
|
|
-- happened to produce -- which is why runs stalled with a level-10 lead and
|
|
-- two badges. The badges are load bearing far beyond the badge count: FOG
|
|
-- gates SURF and PLAIN gates STRENGTH, so losing Morty or Whitney means the
|
|
-- HMs never work and Cianwood is never reached.
|
|
{ id = "02.g", map = "ROUTE_31", op = "grind", level = 14, lead = true },
|
|
{ id = "02.19", map = "VIOLET_CITY", op = "travel" },
|
|
{ id = "02.20", map = "VIOLET_CITY", op = "heal" },
|
|
{ id = "02.22", map = "VIOLET_GYM", op = "travel" },
|
|
|
|
-- Falkner at (5,1). Abe and Rod are in the way of the walk up and engage on
|
|
-- their own; the badge script force-sets their flags either way.
|
|
{ id = "02.26", map = "VIOLET_GYM", op = "battle", x = 5, y = 1, talk = true,
|
|
expect = "ENGINE_ZEPHYRBADGE",
|
|
retryFrom = "02.20", retryLimit = 4 },
|
|
|
|
-- The Togepi Egg, and it is not a side quest: it is what OPENS ROUTE 32.
|
|
--
|
|
-- Route 32's only road south runs through (18,8), which carries a coord
|
|
-- event at scene 0 -- the Miracle Seed man, who follows you, walks you two
|
|
-- cells back north and hands you nothing you need (maps/Route32.asm
|
|
-- Route32CooltrainerMStopsYouScene). Nothing in that script changes the
|
|
-- scene. The one thing in the game that does is Elm's aide, three maps
|
|
-- away: giving you the egg runs `setmapscene ROUTE_32,
|
|
-- SCENE_ROUTE32_OFFER_SLOWPOKETAIL` (maps/VioletPokecenter1F.asm), and only
|
|
-- then does the road open. The map is a soft gate and the egg is the key.
|
|
--
|
|
-- Without these three rows the bot walked into that scene, was pushed back,
|
|
-- re-planned the identical path and was pushed back again -- so Azalea, Ilex
|
|
-- Forest, Goldenrod and everything past them were reachable only by
|
|
-- teleport, which is most of what the run's shortcut count was.
|
|
--
|
|
-- The aide only appears once Elm has phoned: Falkner's badge script arms
|
|
-- `specialphonecall SPECIALCALL_ASSISTANT` (maps/VioletGym.asm), the call
|
|
-- lands outdoors after a few steps, and its script clears
|
|
-- EVENT_ELMS_AIDE_IN_VIOLET_POKEMON_CENTER, which is what un-hides him.
|
|
--
|
|
-- The wander row waits on a flag being CLEARED rather than set, which is why
|
|
-- it carries `expectClear` instead of `expect`: an object_event's event flag
|
|
-- HIDES the object when set (CheckObjectFlag), so the aide appears the moment
|
|
-- the call clears his.
|
|
{ id = "02.26b", map = "VIOLET_CITY", op = "wander", budget = 40,
|
|
expectClear = "EVENT_ELMS_AIDE_IN_VIOLET_POKEMON_CENTER", optional = true,
|
|
note = "walk outdoors until Elm's SPECIALCALL_ASSISTANT lands" },
|
|
{ id = "02.26c", map = "VIOLET_POKECENTER_1F", op = "travel" },
|
|
{ id = "02.26d", map = "VIOLET_POKECENTER_1F", op = "talk", x = 4, y = 3,
|
|
answers = { "yes" }, budget = 6000,
|
|
expect = "EVENT_GOT_TOGEPI_EGG_FROM_ELMS_AIDE" },
|
|
|
|
-- =========================================================================
|
|
-- Section 03 : Route 32, Union Cave, Route 33
|
|
-- =========================================================================
|
|
-- The Ruins of Alph detour (steps 4-14) is skipped: the Unown puzzle needs
|
|
-- `special UnownPuzzle` driven through a sliding-tile UI, and nothing past it
|
|
-- gates progress to Azalea.
|
|
|
|
{ id = "03.16", map = "ROUTE_32", op = "travel" },
|
|
{ id = "03.28", map = "ROUTE_32_POKECENTER_1F", op = "travel",
|
|
optional = true },
|
|
{ id = "03.28b", map = "ROUTE_32_POKECENTER_1F", op = "heal",
|
|
optional = true },
|
|
{ id = "03.29", map = "UNION_CAVE_1F", op = "travel" },
|
|
{ id = "03.36", map = "ROUTE_33", op = "travel" },
|
|
{ id = "03.39", map = "AZALEA_TOWN", op = "travel" },
|
|
|
|
-- =========================================================================
|
|
-- Section 04 : Slowpoke Well and Bugsy
|
|
-- =========================================================================
|
|
-- Slowpoke Well is a hard gate, not a side quest: clearing it is what sets
|
|
-- AZALEA_TOWN's scene to SCENE_AZALEATOWN_RIVAL_BATTLE, and Ilex Forest --
|
|
-- the only way west -- is behind that scene's coord event.
|
|
|
|
{ id = "04.3", map = "KURTS_HOUSE", op = "travel" },
|
|
{ id = "04.3b", map = "KURTS_HOUSE", op = "talk", x = 3, y = 2,
|
|
expect = "EVENT_AZALEA_TOWN_SLOWPOKETAIL_ROCKET" },
|
|
{ id = "04.5", map = "AZALEA_POKECENTER_1F", op = "travel", optional = true },
|
|
{ id = "04.5b", map = "AZALEA_POKECENTER_1F", op = "heal", optional = true },
|
|
|
|
-- Balls before the well. Elm's aide gives five in the whole game, and the
|
|
-- SLOWPOKE below is not optional: it is the only SURF user available before
|
|
-- FOGBADGE opens water hunting, so five failed throws cost Cianwood, the
|
|
-- Storm Badge and everything after it. A run that came this far has
|
|
-- thousands of yen and nothing else to spend it on. Count is sized for this
|
|
-- catch plus the later POLIWAG and bird hunts (07.g0 / 07.30).
|
|
{ id = "04.5c", map = "AZALEA_MART", op = "buy", item = "POKE_BALL",
|
|
count = 40 },
|
|
-- Potions, for the same reason the balls are bought: the bot has thousands
|
|
-- of yen and nothing else to spend it on, and until now it walked into every
|
|
-- gym leader with no way to answer damage except more levels. Bot:fightBattle
|
|
-- drinks the strongest thing in the bag when the lead drops below a third.
|
|
{ id = "04.5d", map = "AZALEA_MART", op = "buy", item = "SUPER_POTION",
|
|
count = 10, optional = true },
|
|
|
|
{ id = "04.6", map = "SLOWPOKE_WELL_B1F", op = "travel" },
|
|
|
|
-- Catch a SLOWPOKE while we are down here. Not in the walkthrough, and the
|
|
-- run cannot finish without it: SURF is required to reach Cianwood in section
|
|
-- 08, and the Cyndaquil line cannot learn it (its tmhm list has CUT,
|
|
-- STRENGTH and ROCK_SMASH but no SURF or FLY). SLOWPOKE is in this map's own
|
|
-- grass table and learns SURF *and* STRENGTH -- but NOT WHIRLPOOL or
|
|
-- WATERFALL, which is why 07.30 catches a POLIWAG once the pond opens.
|
|
{ id = "04.6b", map = "SLOWPOKE_WELL_B1F", op = "catch",
|
|
species = { "SLOWPOKE" }, ball = "POKE_BALL" },
|
|
-- The three grunts are sight-line fights on the way north and west; the last
|
|
-- one at (5,2) runs the whole clear-out cutscene with no endifjustbattled,
|
|
-- ending in HealParty and a warp to Kurt's house.
|
|
{ id = "04.8", map = "SLOWPOKE_WELL_B1F", op = "battle", x = 15, y = 8 },
|
|
{ id = "04.9", map = "SLOWPOKE_WELL_B1F", op = "battle", x = 13, y = 3 },
|
|
{ id = "04.11", map = "SLOWPOKE_WELL_B1F", op = "battle", x = 6, y = 6 },
|
|
{ id = "04.13", map = "SLOWPOKE_WELL_B1F", op = "battle", x = 5, y = 3,
|
|
budget = 8000, expect = "EVENT_CLEARED_SLOWPOKE_WELL" },
|
|
|
|
{ id = "04.14", map = "KURTS_HOUSE", op = "talk", x = 3, y = 2,
|
|
answers = { "no" }, optional = true,
|
|
note = "LURE_BALL, then decline the apricorn prompt" },
|
|
|
|
{ id = "04.g", map = "UNION_CAVE_1F", op = "grind", level = 19, lead = true },
|
|
{ id = "04.17", map = "AZALEA_GYM", op = "travel" },
|
|
{ id = "04.22", map = "AZALEA_GYM", op = "battle", x = 5, y = 7, talk = true,
|
|
expect = "ENGINE_HIVEBADGE",
|
|
retryFrom = "04.17", retryLimit = 4 },
|
|
|
|
-- =========================================================================
|
|
-- Section 05 : Ilex Forest, CUT, and Whitney
|
|
-- =========================================================================
|
|
|
|
{ id = "05.1", map = "AZALEA_TOWN", op = "travel" },
|
|
{ id = "05.1b", map = "AZALEA_TOWN", op = "battle", x = 5, y = 10,
|
|
note = "SCENE_AZALEATOWN_RIVAL_BATTLE trip-wire" },
|
|
-- Enter the forest from AZALEA, not from Route 34.
|
|
--
|
|
-- Ilex Forest is two regions with no walk between them until the tree at
|
|
-- (8,25) is cut, and the whole of section 05 -- the Farfetch'd herd, the
|
|
-- man who hands over HM01, the tree itself -- is in the southern one. A
|
|
-- plain `travel ILEX_FOREST` is satisfied by either, and the planner
|
|
-- naturally picked the northern gate: the bot arrived in the forest, on the
|
|
-- correct map, with every remaining objective behind a tree it needed CUT to
|
|
-- remove and CUT behind the tree. Naming the gate is what pins the side.
|
|
{ id = "05.2b", map = "ILEX_FOREST_AZALEA_GATE", op = "travel" },
|
|
{ id = "05.3", map = "ILEX_FOREST", op = "travel" },
|
|
|
|
-- The Farfetch'd herd. Nine talks, each moving the bird to the next spot.
|
|
--
|
|
-- Every FarfetchdPositionN script (bar the first) scalls
|
|
-- FarfetchdCryAndCheckFacing, so the direction the PLAYER is facing decides
|
|
-- whether the bird goes onwards or doubles back round the loop. `facings`
|
|
-- lists the directions that advance it, taken straight from the section-05
|
|
-- branch table; approaching from whichever side happens to be nearest herds
|
|
-- in circles forever.
|
|
--
|
|
-- Pos2 -> Pos3, except DOWN -> Pos8
|
|
-- Pos3 -> Pos4, except LEFT -> Pos2
|
|
-- Pos4 -> Pos5, except UP -> Pos3
|
|
-- Pos5 -> Pos6, except LEFT -> Pos7, UP/RIGHT -> Pos4
|
|
-- Pos6 -> Pos7, except RIGHT -> Pos5
|
|
-- Pos7 -> Pos8, except LEFT -> Pos6, DOWN -> Pos5
|
|
-- Pos8 -> Pos9, except RIGHT -> Pos7, UP/LEFT -> Pos2
|
|
-- Pos9 -> Pos10 (terminal), except RIGHT/DOWN -> Pos8
|
|
{ id = "05.5", map = "ILEX_FOREST", op = "talk", x = 14, y = 31,
|
|
note = "Pos1: no facing check, always advances" },
|
|
{ id = "05.6b", map = "ILEX_FOREST", op = "talk", x = 15, y = 25,
|
|
facings = { "up", "left", "right" } },
|
|
{ id = "05.6c", map = "ILEX_FOREST", op = "talk", x = 20, y = 24,
|
|
facings = { "up", "down", "right" } },
|
|
{ id = "05.6d", map = "ILEX_FOREST", op = "talk", x = 29, y = 22,
|
|
facings = { "down", "left", "right" } },
|
|
{ id = "05.6e", map = "ILEX_FOREST", op = "talk", x = 28, y = 31,
|
|
facings = { "down" } },
|
|
{ id = "05.6f", map = "ILEX_FOREST", op = "talk", x = 24, y = 35,
|
|
facings = { "up", "down", "left" } },
|
|
{ id = "05.6g", map = "ILEX_FOREST", op = "talk", x = 22, y = 31,
|
|
facings = { "up", "right" } },
|
|
{ id = "05.6h", map = "ILEX_FOREST", op = "talk", x = 15, y = 29,
|
|
facings = { "down" } },
|
|
{ id = "05.6i", map = "ILEX_FOREST", op = "talk", x = 10, y = 35,
|
|
facings = { "up", "left" }, expect = "EVENT_HERDED_FARFETCHD" },
|
|
|
|
{ id = "05.8", map = "ILEX_FOREST", op = "talk", x = 5, y = 28,
|
|
expect = "EVENT_GOT_HM01_CUT" },
|
|
{ id = "05.9", map = "ILEX_FOREST", op = "teach", move = "CUT" },
|
|
-- The tree itself is at (8,25); section 05 step 10 writes (8,24), which is
|
|
-- the cell you STAND on to face it (verified against the cache: (8,24) is
|
|
-- plain floor, (8,25) is COLL_CUT_TREE $12). A field move targets the tile,
|
|
-- so the route names the tree.
|
|
{ id = "05.10", map = "ILEX_FOREST", op = "field", move = "CUT", x = 8, y = 25,
|
|
note = "opens the path north; block (4,12) becomes $17" },
|
|
|
|
{ id = "05.13", map = "ROUTE_34", op = "travel" },
|
|
{ id = "05.24", map = "GOLDENROD_CITY", op = "travel" },
|
|
{ id = "05.25", map = "GOLDENROD_CITY", op = "heal" },
|
|
-- Two grinds before Whitney, and both are load bearing.
|
|
--
|
|
-- The lead one is obvious: MILTANK is the wall of the first half of the game
|
|
-- and the bot fights with no items and a "hit it with the strongest move"
|
|
-- policy, so it needs the levels the walkthrough's player would have.
|
|
--
|
|
-- The party one is what was missing. The bot fought every gym with one
|
|
-- Pokemon and a level-7 SLOWPOKE behind it, so the moment the lead fainted
|
|
-- the run was over -- and the SLOWPOKE is not a spare, it is the only mon
|
|
-- that can learn SURF before water hunting opens, so it has to survive as
|
|
-- far as Cianwood either way. `lead = false` grinds the party MINIMUM,
|
|
-- which is what drags it up.
|
|
{ id = "05.g", map = "ROUTE_34", op = "grind", level = 20, lead = false,
|
|
wipeBudget = 6 },
|
|
{ id = "05.g2", map = "ROUTE_34", op = "grind", level = 30, lead = true },
|
|
-- Re-enter Goldenrod from ROUTE_34 specifically. Its north edge is a direct
|
|
-- connection and the flood fill confirms reachable border cells (x=8..11);
|
|
-- the alternative the planner keeps finding -- Violet -> Route 36 -> Route 35
|
|
-- -- ends at Route 35's SOUTH gate, whose warp is not reachable from the
|
|
-- north border you arrive on, so the bot ping-pongs instead of arriving.
|
|
{ id = "05.24b", map = "ROUTE_34", op = "travel" },
|
|
-- Heal between the grind and the leader. Whitney's MILTANK is the wall of
|
|
-- the first half of the game and the grind that precedes her ends with the
|
|
-- party wherever the wild encounters left it; a run that walks in at half HP
|
|
-- wins the fight and then blacks out on the way to the badge talk, which
|
|
-- costs PLAINBADGE -- and PLAINBADGE gates STRENGTH, the Squirtbottle,
|
|
-- Sudowoodo and ROCK SMASH behind it.
|
|
{ id = "05.38", map = "GOLDENROD_CITY", op = "heal" },
|
|
{ id = "05.39", map = "GOLDENROD_GYM", op = "travel" },
|
|
{ id = "05.44", map = "GOLDENROD_GYM", op = "battle", x = 8, y = 3, talk = true,
|
|
expect = "EVENT_BEAT_WHITNEY" },
|
|
-- Whitney cries afterwards and blocks the door until the trip-wire at (8,5)
|
|
-- runs WhitneyCriesScript; only then does a second talk hand over the badge.
|
|
{ id = "05.45", map = "GOLDENROD_GYM", op = "walk", x = 8, y = 5 },
|
|
{ id = "05.46", map = "GOLDENROD_GYM", op = "talk", x = 8, y = 3,
|
|
expect = "ENGINE_PLAINBADGE",
|
|
retryFrom = "05.38", retryLimit = 4 },
|
|
|
|
{ id = "05.46b", map = "ROUTE_34", op = "travel", optional = true },
|
|
{ id = "05.47", map = "GOLDENROD_FLOWER_SHOP", op = "travel" },
|
|
{ id = "05.47b", map = "GOLDENROD_FLOWER_SHOP", op = "talk", x = 2, y = 4,
|
|
expect = "EVENT_GOT_SQUIRTBOTTLE" },
|
|
|
|
-- =========================================================================
|
|
-- Section 06 : Sudowoodo and ROCK SMASH
|
|
-- =========================================================================
|
|
-- Sudowoodo is a hard gate: it stands on the Route 36 tile that leads east to
|
|
-- Violet and north to Ecruteak, and TM08 ROCK SMASH (needed for the Burned
|
|
-- Tower in section 07) is behind having fought it.
|
|
|
|
{ id = "06.15", map = "ROUTE_36", op = "travel" },
|
|
{ id = "06.20", map = "ROUTE_36", op = "battle", x = 35, y = 9, talk = true,
|
|
answers = { "yes" }, expect = "EVENT_FOUGHT_SUDOWOODO" },
|
|
{ id = "06.21", map = "ROUTE_36", op = "talk", x = 44, y = 9,
|
|
expect = "EVENT_GOT_TM08_ROCK_SMASH" },
|
|
-- ROCK SMASH is a TM, not an HM, so nothing teaches it as a side effect of
|
|
-- picking it up -- and the Burned Tower's north half is behind a rock. The
|
|
-- route had the TM and no `teach` row, so `07.20 field ROCK_SMASH` skipped
|
|
-- with "no party mon knows ROCK_SMASH", the beasts were never released and
|
|
-- Morty was fought without them.
|
|
{ id = "06.21b", map = "ROUTE_36", op = "teach", move = "ROCK_SMASH" },
|
|
|
|
-- =========================================================================
|
|
-- Section 07 : Ecruteak, SURF, the beasts, and Morty
|
|
-- =========================================================================
|
|
|
|
{ id = "07.6", map = "ECRUTEAK_CITY", op = "travel" },
|
|
{ id = "07.7", map = "ECRUTEAK_POKECENTER_1F", op = "travel" },
|
|
{ id = "07.7b", map = "ECRUTEAK_POKECENTER_1F", op = "settle", budget = 5000,
|
|
note = "Bill / Time Capsule scene fires on load" },
|
|
{ id = "07.7c", map = "ECRUTEAK_POKECENTER_1F", op = "heal" },
|
|
|
|
-- The five Kimono Girls all have sight 0 and will not start a fight
|
|
-- themselves, so each is an explicit talk.
|
|
{ id = "07.12", map = "DANCE_THEATER", op = "travel" },
|
|
{ id = "07.13a", map = "DANCE_THEATER", op = "battle", x = 0, y = 2, talk = true },
|
|
{ id = "07.13b", map = "DANCE_THEATER", op = "battle", x = 2, y = 1, talk = true },
|
|
{ id = "07.13c", map = "DANCE_THEATER", op = "battle", x = 6, y = 2, talk = true },
|
|
{ id = "07.13d", map = "DANCE_THEATER", op = "battle", x = 9, y = 1, talk = true },
|
|
{ id = "07.13e", map = "DANCE_THEATER", op = "battle", x = 11, y = 2, talk = true },
|
|
{ id = "07.14", map = "DANCE_THEATER", op = "talk", x = 7, y = 10,
|
|
expect = "EVENT_GOT_HM03_SURF" },
|
|
{ id = "07.14b", map = "DANCE_THEATER", op = "teach", move = "SURF" },
|
|
-- ops.teach walks the party for the first mon whose tmhm list contains the
|
|
-- move, so the SLOWPOKE caught in section 04 is what picks this up.
|
|
|
|
-- Grind and heal BEFORE the tower, not after it.
|
|
--
|
|
-- The Burned Tower is a pit maze whose lower floor has six regions, four of
|
|
-- them one-way pockets, and the bot can and does get stuck in one. With the
|
|
-- grind and the heal sitting on the far side of it, a tower that went wrong
|
|
-- took Morty with it -- the badge fight was reached at whatever level and
|
|
-- whatever HP the tower left behind, and FOGBADGE gates SURF and everything
|
|
-- after. Nothing in the tower gates the gym, so it is now a detour that may
|
|
-- fail on its own.
|
|
-- Morty is the hardest fight in Johto for this party. His GASTLY line is
|
|
-- Ghost/Poison: the starter's Normal moves cannot touch it at all and its
|
|
-- Fire is resisted, so the whole gym is carried by the SLOWPOKE's SURF --
|
|
-- which means the SLOWPOKE has to be a real Pokemon by now, not the level-20
|
|
-- HM caddy it is when it arrives. Both grinds, and the higher lead target,
|
|
-- are what the fight costs.
|
|
-- A FLY user before the party grind. Cyndaquil/SLOWPOKE/TOGEPI none of
|
|
-- them learn FLY (TOGETIC would, but the egg never sees a Shiny Stone on
|
|
-- this route). ROUTE_37's grass is PIDGEY / HOOTHOOT / PIDGEOTTO; catching
|
|
-- here costs no detour and the party-minimum grind that follows levels it.
|
|
{ id = "07.g0", map = "ROUTE_37", op = "catch",
|
|
species = { "PIDGEY", "PIDGEOTTO", "HOOTHOOT", "NOCTOWL" },
|
|
ball = "POKE_BALL" },
|
|
{ id = "07.g", map = "ROUTE_37", op = "grind", level = 28, lead = false,
|
|
wipeBudget = 6 },
|
|
{ id = "07.g2", map = "ROUTE_37", op = "grind", level = 36, lead = true },
|
|
|
|
{ id = "07.18", map = "BURNED_TOWER_1F", op = "travel", optional = true },
|
|
-- The rival scene fires on entry, before anything can be driven.
|
|
{ id = "07.19", map = "BURNED_TOWER_1F", op = "settle", budget = 8000,
|
|
optional = true },
|
|
-- A smashable rock is an OBJECT, not a tile. `BURNEDTOWER1F_ROCK1` at (4,3)
|
|
-- is a SPRITEMOVEDATA_SMASHABLE_ROCK whose script is `jumpstd
|
|
-- SmashRockScript` -> `AskRockSmashScript`, so it is TALKED to and answered
|
|
-- YES; World:useFieldMove reads the faced TILE and quite correctly refuses
|
|
-- ("Can't use that here"), which is what the `field` row used to fail with.
|
|
-- No badge is required for ROCK SMASH, only a party mon that knows it.
|
|
{ id = "07.20", map = "BURNED_TOWER_1F", op = "talk", x = 4, y = 3,
|
|
answers = { "yes" }, budget = 4000, optional = true,
|
|
note = "opens the north half" },
|
|
{ id = "07.21", map = "BURNED_TOWER_1F", op = "battle", x = 8, y = 1,
|
|
optional = true },
|
|
-- Fall through the CENTRE pit (1F warp 9 -> B1F warp 3, landing (10,8)).
|
|
-- The beasts' plateau is its own region and only that landing is on it; a
|
|
-- plain travel used to take the nearest pit, land at (3,3), and leave (9,5)
|
|
-- unreachable. Getting OUT afterwards is the hop-down ledges to the ladder
|
|
-- at (7,15), which the planner walks now that ledge hops exist.
|
|
{ id = "07.22", map = "BURNED_TOWER_1F", op = "warp", x = 10, y = 7,
|
|
to = "BURNED_TOWER_B1F", optional = true },
|
|
{ id = "07.23", map = "BURNED_TOWER_B1F", op = "walk", x = 9, y = 5,
|
|
expect = "EVENT_RELEASED_THE_BEASTS", budget = 8000, optional = true },
|
|
|
|
-- Walk into the gym healed. Morty's GASTLY line is immune to the starter's
|
|
-- Normal moves and resists its Fire, so the fight is carried by the SLOWPOKE
|
|
-- and its SURF -- and a SLOWPOKE that arrives at half HP loses to the gym
|
|
-- trainers before the leader is reached.
|
|
{ id = "07.26", map = "ECRUTEAK_MART", op = "buy", item = "HYPER_POTION",
|
|
count = 10, optional = true },
|
|
{ id = "07.27", map = "ECRUTEAK_CITY", op = "heal" },
|
|
{ id = "07.28", map = "ECRUTEAK_GYM", op = "travel" },
|
|
{ id = "07.29", map = "ECRUTEAK_GYM", op = "battle", x = 5, y = 1, talk = true,
|
|
expect = "ENGINE_FOGBADGE",
|
|
retryFrom = "07.27", retryLimit = 4 },
|
|
|
|
-- WHIRLPOOL / WATERFALL mule. SLOWPOKE can learn SURF and STRENGTH but its
|
|
-- tmhm list has neither WHIRLPOOL nor WATERFALL -- that is why 11.34b and
|
|
-- 13.10b used to report "no party mon can learn …". ECRUTEAK_CITY's water
|
|
-- table is POLIWAG / POLIWHIRL only (no grass table at all), FOGBADGE just
|
|
-- opened the pond, and SURF is already taught, so this is a zero-detour
|
|
-- water hunt. POLIWHIRL also picks up STRENGTH on evolution.
|
|
{ id = "07.30", map = "ECRUTEAK_CITY", op = "catch",
|
|
species = { "POLIWAG", "POLIWHIRL" }, ball = "POKE_BALL", water = true },
|
|
|
|
-- =========================================================================
|
|
-- Section 08 : Olivine, STRENGTH, the lighthouse, Cianwood, Chuck
|
|
-- =========================================================================
|
|
|
|
{ id = "08.17", map = "OLIVINE_CITY", op = "travel" },
|
|
{ id = "08.18", map = "OLIVINE_CITY", op = "walk", x = 13, y = 12,
|
|
note = "rival scene trip-wire, scene 0" },
|
|
{ id = "08.20", map = "OLIVINE_CITY", op = "heal" },
|
|
{ id = "08.21", map = "OLIVINE_CAFE", op = "travel" },
|
|
{ id = "08.21b", map = "OLIVINE_CAFE", op = "talk", x = 4, y = 3,
|
|
expect = "EVENT_GOT_HM04_STRENGTH" },
|
|
{ id = "08.22", map = "OLIVINE_CAFE", op = "teach", move = "STRENGTH" },
|
|
|
|
-- Up the lighthouse to Jasmine. Her explanation is what unlocks the Cianwood
|
|
-- pharmacy, so this visit is required even though nothing here is a fight.
|
|
{ id = "08.43", map = "OLIVINE_LIGHTHOUSE_6F", op = "travel" },
|
|
{ id = "08.43b", map = "OLIVINE_LIGHTHOUSE_6F", op = "talk", x = 8, y = 8,
|
|
expect = "EVENT_JASMINE_EXPLAINED_AMPHYS_SICKNESS" },
|
|
|
|
{ id = "08.50", map = "ROUTE_40", op = "travel" },
|
|
-- Start surfing. The SLOWPOKE caught in section 04 is the SURF user (the
|
|
-- Cyndaquil line cannot learn it). (8,8) is water with walkable land at
|
|
-- (8,7), so approachAndFace stands on the beach facing the sea and
|
|
-- World:useFieldMove does the rest.
|
|
{ id = "08.51", map = "ROUTE_40", op = "field", move = "SURF", x = 8, y = 8 },
|
|
{ id = "08.57", map = "CIANWOOD_CITY", op = "travel" },
|
|
{ id = "08.60", map = "CIANWOOD_PHARMACY", op = "travel" },
|
|
{ id = "08.60b", map = "CIANWOOD_PHARMACY", op = "talk", x = 2, y = 3,
|
|
expect = "EVENT_GOT_SECRETPOTION_FROM_PHARMACY" },
|
|
|
|
-- Chuck's POLIWRATH and PRIMEAPE are the second wall of Johto, and the bot
|
|
-- reaches him having fought four Blackbelts and shoved three boulders on the
|
|
-- way in. With the lane finally open (rows 08.65a-c) the fight itself became
|
|
-- the blocker, so it gets the same treatment Morty did: bring the whole party
|
|
-- up, then top the lead off, then walk in healed.
|
|
{ id = "08.g", map = "ROUTE_41", op = "grind", level = 32, lead = false,
|
|
wipeBudget = 6 },
|
|
{ id = "08.g2", map = "ROUTE_41", op = "grind", level = 40, lead = true },
|
|
{ id = "08.61", map = "CIANWOOD_CITY", op = "heal" },
|
|
{ id = "08.62", map = "CIANWOOD_GYM", op = "travel" },
|
|
{ id = "08.63a", map = "CIANWOOD_GYM", op = "battle", x = 2, y = 12 },
|
|
{ id = "08.63b", map = "CIANWOOD_GYM", op = "battle", x = 7, y = 12 },
|
|
{ id = "08.64", map = "CIANWOOD_GYM", op = "battle", x = 3, y = 9 },
|
|
-- The boulder lane is the only way to the back of the gym.
|
|
-- The boulder row at y=7 (BOULDER2/3/4 at x=3/4/5) is the only way to the
|
|
-- back of the gym, and it is what STRENGTH is for -- the walkthrough's "use
|
|
-- Strength to push your way to the last trainer before the gym leader".
|
|
-- Shoving the middle one north opens the lane behind it. This was a
|
|
-- `manual` row that logged and moved on, which meant Chuck was fought from
|
|
-- the wrong side of a rock and STORMBADGE was never earned.
|
|
-- The boulder puzzle, solved sideways.
|
|
--
|
|
-- Row 7 (boulders at x=3/4/5) is the only link between the gym's halves:
|
|
-- rows 6-7 are x=3..5, row 5 narrows to (4,5) and (5,5), Blackbelt Lung
|
|
-- stands on (5,5) and does not leave it, and (4,3) is solid wall. So
|
|
-- shoving the middle boulder NORTH can never work -- it stays in the one
|
|
-- column the player needs, and its furthest cell (4,4) blocks the last step
|
|
-- into row 4. Every count from 2 to 6 was tried and every end state is
|
|
-- blocked.
|
|
--
|
|
-- The way through is to empty the row instead of climbing it: push the two
|
|
-- OUTER boulders north (each frees its own cell in row 7 and parks itself in
|
|
-- a dead-end pocket of row 6), then stand where the right-hand one was and
|
|
-- push the middle boulder WEST into the gap the left-hand one left. Row 7's
|
|
-- middle cell is then clear and the column above it is untouched.
|
|
--
|
|
-- A push does not move the player -- the cart treats a strength boulder like
|
|
-- a solid NPC -- so each of these costs a pair of presses: one to shove the
|
|
-- rock, one to step into the cell it left. `ops.push` waits for the rock to
|
|
-- stop sliding between presses, because World:tryPushBoulder refuses while
|
|
-- `npc.moving`.
|
|
{ id = "08.65a", map = "CIANWOOD_GYM", op = "push", x = 3, y = 7,
|
|
dir = "up", count = 2, note = "left boulder to (3,6); frees (3,7)" },
|
|
{ id = "08.65b", map = "CIANWOOD_GYM", op = "push", x = 5, y = 7,
|
|
dir = "up", count = 2, note = "right boulder to (5,6); frees (5,7)" },
|
|
{ id = "08.65c", map = "CIANWOOD_GYM", op = "push", x = 4, y = 7,
|
|
dir = "left", count = 2,
|
|
note = "middle boulder west into (3,7); the lane north is now open" },
|
|
{ id = "08.66", map = "CIANWOOD_GYM", op = "battle", x = 5, y = 5,
|
|
talk = true, budget = 8000 },
|
|
{ id = "08.68", map = "CIANWOOD_GYM", op = "battle", x = 4, y = 1, talk = true,
|
|
expect = "ENGINE_STORMBADGE",
|
|
retryFrom = "08.61", retryLimit = 4,
|
|
-- Rewind OUTSIDE the gym, not to 08.66 one row up.
|
|
--
|
|
-- Chuck sits behind a STRENGTH boulder puzzle, and a puzzle left in a bad
|
|
-- state cannot be retried in place: run 25 pushed the boulders into a
|
|
-- arrangement that sealed the north half, and both 08.66 and 08.68 then answered
|
|
-- "approach: nowhere to stand" instantly -- burning all four laps in a
|
|
-- single frame without ever moving. World:setMap calls restoreBlocks,
|
|
-- which refills the map from ROM, so LEAVING and re-entering is what puts
|
|
-- the boulders back. 08.61 is the Cianwood heal, one map outside the door.
|
|
},
|
|
-- FLY is an optimisation, never a gate: section 09 opens by flying back to
|
|
-- Olivine and travelTo can simply swim the way it came. Optional so a miss
|
|
-- here cannot cost the badge chain behind it. The bird from 07.g0 is who
|
|
-- learns it.
|
|
{ id = "08.70", map = "CIANWOOD_CITY", op = "talk", x = 10, y = 46,
|
|
optional = true, expect = "EVENT_GOT_HM02_FLY" },
|
|
{ id = "08.70b", map = "CIANWOOD_CITY", op = "teach", move = "FLY",
|
|
optional = true },
|
|
|
|
-- =========================================================================
|
|
-- Section 09 : back to Olivine, cure Amphy, and Jasmine
|
|
-- =========================================================================
|
|
-- The section opens by flying, which the bot does not need: travelTo can swim
|
|
-- back the way it came. Flying is strictly an optimisation here.
|
|
|
|
{ id = "09.14", map = "OLIVINE_LIGHTHOUSE_6F", op = "travel" },
|
|
{ id = "09.15", map = "OLIVINE_LIGHTHOUSE_6F", op = "talk", x = 8, y = 8,
|
|
answers = { "yes" }, budget = 6000,
|
|
expect = "EVENT_JASMINE_RETURNED_TO_GYM" },
|
|
|
|
{ id = "09.17", map = "OLIVINE_CITY", op = "travel" },
|
|
{ id = "09.17b", map = "OLIVINE_CITY", op = "heal" },
|
|
{ id = "09.g", map = "ROUTE_39", op = "grind", level = 38, lead = true },
|
|
{ id = "09.18", map = "OLIVINE_GYM", op = "travel" },
|
|
{ id = "09.20", map = "OLIVINE_GYM", op = "battle", x = 5, y = 3, talk = true,
|
|
budget = 12000, expect = "EVENT_BEAT_JASMINE" },
|
|
{ id = "09.21", map = "OLIVINE_GYM", op = "check", expect = "ENGINE_MINERALBADGE" },
|
|
|
|
-- =========================================================================
|
|
-- Section 10 : Route 42, Mahogany, Route 43, the Lake of Rage
|
|
-- =========================================================================
|
|
-- No badge here. What the section is FOR is EVENT_DECIDED_TO_HELP_LANCE,
|
|
-- which arms SCENE_MAHOGANYMART1F_LANCE_UNCOVERS_STAIRS and is the only way
|
|
-- into the Rocket base -- and therefore the only way to HM06 WHIRLPOOL.
|
|
|
|
{ id = "10.1", map = "ECRUTEAK_CITY", op = "travel" },
|
|
{ id = "10.3", map = "ROUTE_42", op = "travel" },
|
|
-- Route 42's two lakes sit across the road east. The bot surfs on its own
|
|
-- now (Bot:stepDir starts the field move when a planned step enters water),
|
|
-- so this is a plain travel row.
|
|
{ id = "10.13", map = "MAHOGANY_TOWN", op = "travel" },
|
|
{ id = "10.14", map = "MAHOGANY_TOWN", op = "heal" },
|
|
{ id = "10.18", map = "ROUTE_43", op = "travel" },
|
|
{ id = "10.26", map = "LAKE_OF_RAGE", op = "travel" },
|
|
{ id = "10.g", map = "ROUTE_43", op = "grind", level = 40, lead = true },
|
|
|
|
-- The Red Gyarados. Its script is `loadwildmon GYARADOS, 30` with
|
|
-- BATTLETYPE_FORCESHINY, so this is a wild fight the bot may simply win; the
|
|
-- RED_SCALE and Lance's appearance are set on a KO as well as a catch.
|
|
{ id = "10.33", map = "LAKE_OF_RAGE", op = "battle", x = 18, y = 22,
|
|
talk = true, budget = 12000,
|
|
expect = "EVENT_LAKE_OF_RAGE_RED_GYARADOS" },
|
|
{ id = "10.34", map = "LAKE_OF_RAGE", op = "talk", x = 21, y = 28,
|
|
answers = { "yes" }, budget = 8000,
|
|
expect = "EVENT_DECIDED_TO_HELP_LANCE" },
|
|
|
|
-- =========================================================================
|
|
-- Section 11 : the Rocket hideout and Pryce
|
|
-- =========================================================================
|
|
|
|
{ id = "11.2", map = "MAHOGANY_MART_1F", op = "travel" },
|
|
{ id = "11.2b", map = "MAHOGANY_MART_1F", op = "settle", budget = 8000,
|
|
expect = "EVENT_UNCOVERED_STAIRCASE_IN_MAHOGANY_MART",
|
|
note = "LanceUncoversStaircaseScript runs unattended on arrival" },
|
|
|
|
{ id = "11.3", map = "TEAM_ROCKET_BASE_B1F", op = "travel" },
|
|
-- The security cameras are sight-line scripts on the way west; each is the
|
|
-- same pair of grunts and the bot fights them where it meets them. The
|
|
-- switch that ends them is a bg event read from (19,12) facing UP.
|
|
{ id = "11.10", map = "TEAM_ROCKET_BASE_B1F", op = "talk", x = 19, y = 11,
|
|
facings = { "up" }, budget = 6000,
|
|
expect = "EVENT_TURNED_OFF_SECURITY_CAMERAS" },
|
|
|
|
{ id = "11.12", map = "TEAM_ROCKET_BASE_B2F", op = "travel" },
|
|
{ id = "11.13", map = "TEAM_ROCKET_BASE_B2F", op = "walk", x = 5, y = 14,
|
|
note = "Lance heals the party here; scene 0 -> 1" },
|
|
{ id = "11.15", map = "TEAM_ROCKET_BASE_B3F", op = "travel" },
|
|
{ id = "11.15b", map = "TEAM_ROCKET_BASE_B3F", op = "settle", budget = 6000,
|
|
expect = "EVENT_TEAM_ROCKET_BASE_B3F_LANCE_PASSWORDS" },
|
|
-- Both passwords are learned by talking: the sight-0 grunt at (21,7) has to
|
|
-- be spoken to TWICE (the first talk is the battle), and the spinning grunt
|
|
-- at (5,15) the same.
|
|
-- Both battle rows carry the trainer's own beat flag: the fight fires on a
|
|
-- sight line DURING the approach, the trainer then stands wherever it
|
|
-- happened, and the approach's own opinion of reaching the (now moved)
|
|
-- object is worthless -- run 3 recorded a FAIL on a fight it had won.
|
|
{ id = "11.18", map = "TEAM_ROCKET_BASE_B3F", op = "battle", x = 21, y = 7,
|
|
talk = true, budget = 8000, expect = "EVENT_BEAT_ROCKET_GRUNTF_5" },
|
|
{ id = "11.18b", map = "TEAM_ROCKET_BASE_B3F", op = "talk", x = 21, y = 7,
|
|
expect = "EVENT_LEARNED_SLOWPOKETAIL" },
|
|
{ id = "11.20", map = "TEAM_ROCKET_BASE_B3F", op = "battle", x = 5, y = 15,
|
|
talk = true, budget = 8000, expect = "EVENT_BEAT_ROCKET_GRUNTM_28" },
|
|
{ id = "11.20b", map = "TEAM_ROCKET_BASE_B3F", op = "talk", x = 5, y = 15,
|
|
expect = "EVENT_LEARNED_RATICATE_TAIL" },
|
|
-- Region 1, and only NOW: the two passwords above are learned from grunts at
|
|
-- (21,7) and (5,15), which are in region 3. Pinning region 1 before them put
|
|
-- the bot on the wrong side of a floor it could not cross and both password
|
|
-- rows failed instantly.
|
|
--
|
|
-- Region 1, not "anywhere on B3F".
|
|
--
|
|
-- The floor is three regions that never touch: region 3 (214 cells, the way
|
|
-- in from B1F, warps 2 and 4 on the right), region 1 (57 cells, warps 1 and 3
|
|
-- on the LEFT), and region 2 (46 cells, the boss chamber, sealed until
|
|
-- Giovanni's door opens). Every beat this section needs -- the rival at
|
|
-- (8,10), the locked door at (10,9), Executive 4, HAIL GIOVANNI -- is in
|
|
-- region 1. Arriving anywhere on B3F satisfied a plain `travel`, so the bot
|
|
-- stood in region 3 while row after row reported "no path" to cells on the
|
|
-- same floor. The honest route is a loop: B1F -> B2F r4 -> B3F r3 -> back up
|
|
-- via B3F warp 2 -> B2F r1 -> down B2F warp 2 -> B3F r1.
|
|
--
|
|
-- Region indices come from `tools/goldwalk/mapgraph.lua map <MAP>`; they are
|
|
-- the order in tests/drivers/gold/map_regions.lua and change if the extractor
|
|
-- output changes, so re-check them when regenerating that file.
|
|
-- Heal BEFORE the region-1 loop, then noHeal all the way through HAIL
|
|
-- GIOVANNI. The rival, Giovanni's door, Executive 4 and the Murkrow are
|
|
-- all in region 1 and the loop into it (11.15r) is a five-hop crossing
|
|
-- through both floors; a between-rows auto-heal after the Executive fight
|
|
-- (which arrives with the party beaten in a continuous run) left the base,
|
|
-- healed at Mahogany, and re-entered in region 3 -- from which (7,2) has no
|
|
-- path. A wipe on 11.27 still recovers: the whiteout heals, and retryFrom
|
|
-- 11.15r re-runs the loop.
|
|
{ id = "11.20h", map = "MAHOGANY_TOWN", op = "heal" },
|
|
{ id = "11.15r", map = "TEAM_ROCKET_BASE_B3F", op = "travel", region = 1,
|
|
noHeal = true },
|
|
{ id = "11.25", map = "TEAM_ROCKET_BASE_B3F", op = "walk", x = 8, y = 10,
|
|
noHeal = true, note = "rival cutscene, no battle; scene 1 -> 2" },
|
|
{ id = "11.26", map = "TEAM_ROCKET_BASE_B3F", op = "talk", x = 10, y = 9,
|
|
facings = { "up" }, budget = 6000, noHeal = true,
|
|
expect = "EVENT_OPENED_DOOR_TO_GIOVANNIS_OFFICE" },
|
|
{ id = "11.27", map = "TEAM_ROCKET_BASE_B3F", op = "battle", x = 10, y = 8,
|
|
budget = 12000, noHeal = true, expect = "EVENT_BEAT_ROCKET_EXECUTIVEM_4",
|
|
-- Losable, so it laps. The rewind goes back to the region-1 travel rather
|
|
-- than one row up, because a wipe puts the player in a Pokecenter and the
|
|
-- way back into this half of B3F is the loop through both floors.
|
|
retryFrom = "11.20h", retryLimit = 5 },
|
|
{ id = "11.28", map = "TEAM_ROCKET_BASE_B3F", op = "talk", x = 7, y = 2,
|
|
noHeal = true, expect = "EVENT_LEARNED_HAIL_GIOVANNI" },
|
|
|
|
-- Back to the B1F side of B2F. Coming out of B3F region 1 lands in B2F
|
|
-- region 1 (top-left, 66 cells); the transmitter door at (14,12) is in region
|
|
-- 4, the half the stairs from B1F open into, and the two do not touch. Same
|
|
-- shape as 11.15r, one floor up.
|
|
-- Via B1F, deliberately, rather than by naming a region index.
|
|
--
|
|
-- The transmitter door's standing cell (14,13) is in the 103-cell half that
|
|
-- the B1F stairs open into, and coming out of B3F region 1 lands in the
|
|
-- 66-cell half instead -- which has no B1F exit at all, only the two back up
|
|
-- to B3F. Going to B1F therefore forces the whole loop, and the plain travel
|
|
-- that follows can only arrive on the right side. A `region =` hint was tried
|
|
-- first and was not reliable here: Bot:currentRegions matches a LIVE flood
|
|
-- fill against the generated seeds, and on this floor it claimed the far
|
|
-- region while standing in the near one, so the travel reported success
|
|
-- without moving.
|
|
-- Heal BEFORE the transmitter room. Once the Electrode scene arms, the
|
|
-- room cannot be LEFT: Lance's coord events at (12,3)/(12,10)/(12,11) and
|
|
-- the (14/15,12) pair walk the player straight back in (cart behaviour --
|
|
-- RocketBaseLancesSideScript / RocketBaseCantLeaveScript), so a mid-block
|
|
-- auto-heal just bounced off them until the walk gave up and 11.33b/c ran
|
|
-- in whatever state that left. noHeal through HM06.
|
|
{ id = "11.30h", map = "MAHOGANY_TOWN", op = "heal" },
|
|
{ id = "11.30q", map = "TEAM_ROCKET_BASE_B1F", op = "travel" },
|
|
{ id = "11.30r", map = "TEAM_ROCKET_BASE_B2F", op = "travel", noHeal = true },
|
|
{ id = "11.31", map = "TEAM_ROCKET_BASE_B2F", op = "talk", x = 14, y = 12,
|
|
facings = { "up" }, budget = 6000, noHeal = true,
|
|
expect = "EVENT_OPENED_DOOR_TO_ROCKET_HIDEOUT_TRANSMITTER" },
|
|
{ id = "11.32", map = "TEAM_ROCKET_BASE_B2F", op = "battle", x = 14, y = 11,
|
|
budget = 12000, noHeal = true, expect = "EVENT_BEAT_ROCKET_EXECUTIVEF_2",
|
|
retryFrom = "11.30h", retryLimit = 5 },
|
|
-- The three Electrodes are wild L23 battles that may Selfdestruct; the third
|
|
-- one ends the base and hands over HM06.
|
|
{ id = "11.33a", map = "TEAM_ROCKET_BASE_B2F", op = "battle", x = 7, y = 5,
|
|
talk = true, budget = 8000, noHeal = true },
|
|
{ id = "11.33b", map = "TEAM_ROCKET_BASE_B2F", op = "battle", x = 7, y = 7,
|
|
talk = true, budget = 8000, noHeal = true },
|
|
{ id = "11.33c", map = "TEAM_ROCKET_BASE_B2F", op = "battle", x = 7, y = 9,
|
|
talk = true, budget = 12000, noHeal = true },
|
|
{ id = "11.34", map = "TEAM_ROCKET_BASE_B2F", op = "check", noHeal = true,
|
|
expect = "EVENT_GOT_HM06_WHIRLPOOL",
|
|
-- The whole tail re-runs from the heal when the third Electrode's
|
|
-- handout was missed (a Selfdestruct wipe mid-trio leaves the scene
|
|
-- armed and the room sealed).
|
|
retryFrom = "11.30h", retryLimit = 4 },
|
|
-- WHIRLPOOL and WATERFALL are both water-route gates rather than optional
|
|
-- extras: Route 27 has a whirlpool block on the way to Route 26, and Tohjo
|
|
-- Falls needs the climb. Taught to the POLIWAG/POLIWHIRL from 07.30 --
|
|
-- SLOWPOKE cannot learn either, despite carrying SURF.
|
|
{ id = "11.34b", map = "TEAM_ROCKET_BASE_B2F", op = "teach",
|
|
move = "WHIRLPOOL" },
|
|
|
|
{ id = "11.36", map = "MAHOGANY_TOWN", op = "travel" },
|
|
{ id = "11.36b", map = "MAHOGANY_TOWN", op = "heal" },
|
|
{ id = "11.g", map = "ROUTE_43", op = "grind", level = 43, lead = true },
|
|
{ id = "11.36c", map = "MAHOGANY_GYM", op = "travel" },
|
|
|
|
-- Mahogany's floor is ice: a press slides until something stops it, so no
|
|
-- cell here can be aimed at and the asm-walk writes the whole gym as a list
|
|
-- of directions. These two are transcribed from its slide table -- the
|
|
-- first reaches (2,14) beside the pillar, the second the cell below Pryce.
|
|
{ id = "11.42", map = "MAHOGANY_GYM", op = "press",
|
|
dirs = { "up", "left", "left", "up", "up" },
|
|
note = "entrance (4,17) -> (2,14); the last three cells are plain floor" },
|
|
{ id = "11.43", map = "MAHOGANY_GYM", op = "press",
|
|
dirs = { "up", "up", "right", "down", "left", "up", "right" },
|
|
note = "(2,14) -> (5,4), directly below Pryce at (5,3)" },
|
|
{ id = "11.44", map = "MAHOGANY_GYM", op = "battle", x = 5, y = 3, talk = true,
|
|
budget = 14000, expect = "ENGINE_GLACIERBADGE",
|
|
retryFrom = "11.36c", retryLimit = 4 },
|
|
|
|
-- =========================================================================
|
|
-- Section 12 : the Radio Tower and the Goldenrod underground
|
|
-- =========================================================================
|
|
-- Seven badges arm ENGINE_ROCKETS_IN_RADIO_TOWER, which is the precondition
|
|
-- for the whole section. Two passes at the tower with the underground in
|
|
-- between: the Basement Key comes off Executive 3 on 5F, the Card Key from
|
|
-- the Director in the underground warehouse, and only the Card Key opens the
|
|
-- way to the boss.
|
|
|
|
-- Mahogany -> Goldenrod the WEST way, surfing across Route 42, not the
|
|
-- eastern loop through the Route 45/46/Dark Cave junction the foot-only graph
|
|
-- prefers (where the live edge-crosser oscillates and teleports). Route 42
|
|
-- is water-split like Route 27: the Mahogany side and the Ecruteak-gate warp
|
|
-- (0,8) connect only by surf, so name the gate and warp to it -- planPath
|
|
-- surfs the crossing. From Ecruteak the run to Goldenrod is clean
|
|
-- (Route 37/36/National Park/35). Same waypoint-the-water-crossing lesson as
|
|
-- TOHJO_FALLS in section 16.
|
|
{ id = "12.0a", map = "ROUTE_42", op = "travel" },
|
|
{ id = "12.0b", map = "ROUTE_42", op = "warp", x = 0, y = 8,
|
|
to = "ROUTE_42_ECRUTEAK_GATE" },
|
|
{ id = "12.0c", map = "ECRUTEAK_CITY", op = "travel" },
|
|
{ id = "12.1", map = "RADIO_TOWER_1F", op = "travel" },
|
|
-- Heal at Goldenrod BEFORE the boss, and lap from here. Executive 3's four
|
|
-- self-destructing mons can wipe the party, and the whiteout goes to
|
|
-- blackoutMap -- which, walking in from Mahogany, was MAHOGANY_TOWN. The
|
|
-- recovery travel Mahogany -> Goldenrod then has to cross the Route 45/46/
|
|
-- Dark Cave junction, where the live edge-crosser oscillates and teleports.
|
|
-- Healing at Goldenrod's Pokecenter first sets the spawn HERE (World:
|
|
-- updateWhiteoutSpawn fires on the outdoor->Pokecenter warp), so a wipe lands
|
|
-- next door to the tower and the lap is a two-hop walk, not a cross-Johto
|
|
-- one. It also enters the fight at full HP, which is half the point.
|
|
{ id = "12.8h", map = "GOLDENROD_CITY", op = "heal" },
|
|
{ id = "12.9", map = "RADIO_TOWER_5F", op = "travel" },
|
|
{ id = "12.9b", map = "RADIO_TOWER_5F", op = "walk", x = 0, y = 3,
|
|
budget = 14000, expect = "EVENT_BEAT_ROCKET_EXECUTIVEM_3",
|
|
note = "FakeDirectorScript coord event; six mons, four of them explode",
|
|
retryFrom = "12.8h", retryLimit = 6 },
|
|
|
|
{ id = "12.11", map = "GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES",
|
|
op = "travel" },
|
|
-- Region 1 of the underground (157 cells, warps 1/2/3): the salon side that
|
|
-- holds the Basement Key door at (18,6). The basement side (region 5) is the
|
|
-- OTHER half of the same-map warp pair, and a plain travel can land there
|
|
-- via switch-room warp 1 -- after which (18,6) has nowhere to stand.
|
|
{ id = "12.14", map = "GOLDENROD_UNDERGROUND", op = "travel", region = 1 },
|
|
{ id = "12.14b", map = "GOLDENROD_UNDERGROUND", op = "talk", x = 18, y = 6,
|
|
expect = "EVENT_USED_BASEMENT_KEY" },
|
|
-- Region 1 of the switch room (91 cells, warp 1 only): the north corridor
|
|
-- with the rival trigger and Switch1/2/3. Ten regions on this map; city
|
|
-- warps land in 9/10 and underground warp 1 lands in 10, none of which can
|
|
-- reach (16,1). Only underground warp 6 (basement side) opens into region 1.
|
|
{ id = "12.16", map = "GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES",
|
|
op = "walk", x = 19, y = 4, budget = 14000, region = 1,
|
|
expect = "EVENT_RIVAL_GOLDENROD_UNDERGROUND" },
|
|
|
|
-- Heal BEFORE the puzzle. noHeal from 12.18a through the Card Key:
|
|
-- MAPCALLBACK_NEWMAP on the underground / warehouse zeroes
|
|
-- wUndergroundSwitchPositions, so a heal between Switch3 and Switch2 undoes
|
|
-- the puzzle. The warehouse grunts are also losable, so arrive full.
|
|
{ id = "12.15h", map = "GOLDENROD_CITY", op = "heal" },
|
|
|
|
-- Pin region 1 before the switches. 12.16 can be `already satisfied` (the
|
|
-- rival flag survives a wipe / resume), which skips tryReach and leaves the
|
|
-- bot in whichever half of the map a plain hop preferred -- then every
|
|
-- switch reports "nowhere to stand". Same shape as 11.15r.
|
|
{ id = "12.17r", map = "GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES",
|
|
op = "travel", region = 1, noHeal = true },
|
|
|
|
-- The switch puzzle. Each switch is a bg event read with A; the shared byte
|
|
-- is a plain sum, and intermediate positions leave some doors untouched, so
|
|
-- order matters. 1-then-2-then-3 opens door 8 (Eddie) but NOT door 5.
|
|
-- 3-then-2-then-1 from the reset state opens doors 3,5,6,8,9,11 -- door 5
|
|
-- at (10,10) is the one that reaches the warehouse warps at (22,10)/(23,10).
|
|
-- See asm-walk section 12, "Consequences a bot needs".
|
|
{ id = "12.18a", map = "GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES",
|
|
op = "talk", x = 2, y = 1, budget = 4000, region = 1, noHeal = true,
|
|
note = "Switch3 ON (byte 0->3)" },
|
|
{ id = "12.18b", map = "GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES",
|
|
op = "talk", x = 10, y = 1, budget = 4000, region = 1, noHeal = true,
|
|
note = "Switch2 ON (byte 3->5); leaves door 5 open" },
|
|
{ id = "12.18c", map = "GOLDENROD_UNDERGROUND_SWITCH_ROOM_ENTRANCES",
|
|
op = "talk", x = 16, y = 1, budget = 4000, region = 1, noHeal = true,
|
|
note = "Switch1 ON (byte 5->6); warehouse path open" },
|
|
{ id = "12.24", map = "GOLDENROD_UNDERGROUND_WAREHOUSE", op = "travel",
|
|
noHeal = true },
|
|
{ id = "12.26", map = "GOLDENROD_UNDERGROUND_WAREHOUSE", op = "talk",
|
|
x = 12, y = 8, budget = 12000, noHeal = true,
|
|
expect = "EVENT_RECEIVED_CARD_KEY",
|
|
-- A wipe blacks out to the city and the switch callback has already
|
|
-- zeroed the puzzle, so the rewind re-enters from the heal + region pin.
|
|
retryFrom = "12.15h", retryLimit = 5 },
|
|
|
|
-- Out of the warehouse the intended (and only) road is THROUGH the dept
|
|
-- store basement: EVENT_RECEIVED_CARD_KEY's MAPCALLBACK_TILES clears the
|
|
-- box pile at B1F block (8,2) (GoldenrodDeptStoreB1F.asm), joining the
|
|
-- warehouse-stairs pocket to the elevator. That changeblock is invisible to
|
|
-- the static region graph -- its B1F region 2 lists only the way back -- so
|
|
-- travel alone loops the switch-room pocket and falls back to TELEPORT.
|
|
-- Ride the elevator to 1F and leave by the front door.
|
|
{ id = "12.27", map = "GOLDENROD_DEPT_STORE_B1F", op = "travel",
|
|
noHeal = true },
|
|
{ id = "12.27b", map = "GOLDENROD_DEPT_STORE_ELEVATOR", op = "travel",
|
|
noHeal = true },
|
|
{ id = "12.27c", map = "GOLDENROD_DEPT_STORE_ELEVATOR", op = "elevator",
|
|
x = 3, y = 0, floor = "1F", doorX = 1, doorY = 3,
|
|
to = "GOLDENROD_DEPT_STORE_1F" },
|
|
{ id = "12.28", map = "RADIO_TOWER_3F", op = "travel" },
|
|
{ id = "12.29", map = "RADIO_TOWER_3F", op = "talk", x = 14, y = 2,
|
|
facings = { "up" }, budget = 6000,
|
|
expect = "EVENT_USED_THE_CARD_KEY_IN_THE_RADIO_TOWER" },
|
|
{ id = "12.g", map = "ROUTE_35", op = "grind", level = 45, lead = true },
|
|
-- 5F is two regions that never touch: region 1 (35 cells, warp 1 from the
|
|
-- west stairs) and region 2 (44 cells, warp 2 from 4F's east stairs). The
|
|
-- boss coord at (16,5) is in region 2, and the only way onto that half is
|
|
-- 3F warp 3 (behind the Card Key shutter) -> 4F region 2 -> 5F warp 2.
|
|
-- A plain travel lands at 5F (0,0) in region 1, where (16,5) has no path.
|
|
{ id = "12.32", map = "RADIO_TOWER_5F", op = "travel", region = 2 },
|
|
{ id = "12.33", map = "RADIO_TOWER_5F", op = "walk", x = 16, y = 5,
|
|
budget = 20000, region = 2, expect = "EVENT_CLEARED_RADIO_TOWER",
|
|
note = "the script walks the player two cells left, then EXECUTIVEM_1",
|
|
retryFrom = "12.32", retryLimit = 5 },
|
|
|
|
-- =========================================================================
|
|
-- Section 13 : the Ice Path, Clair and the Rising Badge
|
|
-- =========================================================================
|
|
|
|
{ id = "13.1", map = "MAHOGANY_TOWN", op = "travel" },
|
|
{ id = "13.1b", map = "MAHOGANY_TOWN", op = "heal" },
|
|
{ id = "13.9", map = "ICE_PATH_1F", op = "travel" },
|
|
{ id = "13.10", map = "ICE_PATH_1F", op = "talk", x = 31, y = 7,
|
|
expect = "EVENT_GOT_HM07_WATERFALL" },
|
|
-- Same mule as 11.34b: the POLIWAG/POLIWHIRL from 07.30.
|
|
{ id = "13.10b", map = "ICE_PATH_1F", op = "teach", move = "WATERFALL" },
|
|
{ id = "13.11", map = "ICE_PATH_B1F", op = "travel" },
|
|
|
|
-- Four boulders onto four holes (stonetable warp N+2). Each straight shove
|
|
-- of N cells uses count = 2*N - 1: the player does not move with the rock, so
|
|
-- every other press is the step into the cell it vacated (same pairing
|
|
-- Cianwood's 08.65* rows use). A hole-ending segment stops on the falling
|
|
-- push so the bot does not walk into the pit afterward.
|
|
--
|
|
-- Order matters: the spawn boulders seal each other's stand cells, and the
|
|
-- old single-row "push up 5 from spawn" rows could not even stand south of
|
|
-- boulder 1. Solved against the extracted collision + player reachability.
|
|
|
|
-- B3 (8,9) -> hole (5,12) = EVENT_BOULDER_IN_ICE_PATH_3
|
|
{ id = "13.12a", map = "ICE_PATH_B1F", op = "push", x = 8, y = 9, dir = "right",
|
|
count = 1 },
|
|
{ id = "13.12b", map = "ICE_PATH_B1F", op = "push", x = 9, y = 9, dir = "down",
|
|
count = 11 },
|
|
{ id = "13.12c", map = "ICE_PATH_B1F", op = "push", x = 9, y = 15, dir = "left",
|
|
count = 5 },
|
|
{ id = "13.12d", map = "ICE_PATH_B1F", op = "push", x = 6, y = 15, dir = "up",
|
|
count = 1 },
|
|
{ id = "13.12e", map = "ICE_PATH_B1F", op = "push", x = 6, y = 14, dir = "left",
|
|
count = 1 },
|
|
{ id = "13.12", map = "ICE_PATH_B1F", op = "push", x = 5, y = 14, dir = "up",
|
|
count = 3, expect = "EVENT_BOULDER_IN_ICE_PATH_3" },
|
|
|
|
-- B4 (17,7) -> hole (12,13) = EVENT_BOULDER_IN_ICE_PATH_4
|
|
{ id = "13.13a", map = "ICE_PATH_B1F", op = "push", x = 17, y = 7, dir = "left",
|
|
count = 1 },
|
|
{ id = "13.13b", map = "ICE_PATH_B1F", op = "push", x = 16, y = 7, dir = "down",
|
|
count = 7 },
|
|
{ id = "13.13c", map = "ICE_PATH_B1F", op = "push", x = 16, y = 11, dir = "right",
|
|
count = 1 },
|
|
{ id = "13.13d", map = "ICE_PATH_B1F", op = "push", x = 17, y = 11, dir = "down",
|
|
count = 3 },
|
|
{ id = "13.13", map = "ICE_PATH_B1F", op = "push", x = 17, y = 13, dir = "left",
|
|
count = 9, expect = "EVENT_BOULDER_IN_ICE_PATH_4" },
|
|
|
|
-- B1 (11,7) -> hole (11,2) = EVENT_BOULDER_IN_ICE_PATH_1
|
|
-- Approaches the hole from the west: (11,4) is wall, so the last shove is
|
|
-- right from (10,2) (see tests/drivers/gold_icepath_boulder.lua).
|
|
{ id = "13.14a", map = "ICE_PATH_B1F", op = "push", x = 11, y = 7, dir = "up",
|
|
count = 3 },
|
|
{ id = "13.14b", map = "ICE_PATH_B1F", op = "push", x = 11, y = 5, dir = "left",
|
|
count = 1 },
|
|
{ id = "13.14c", map = "ICE_PATH_B1F", op = "push", x = 10, y = 5, dir = "up",
|
|
count = 5 },
|
|
{ id = "13.14", map = "ICE_PATH_B1F", op = "push", x = 10, y = 2, dir = "right",
|
|
count = 1, expect = "EVENT_BOULDER_IN_ICE_PATH_1" },
|
|
|
|
-- B2 (7,8) -> hole (4,7) = EVENT_BOULDER_IN_ICE_PATH_2
|
|
{ id = "13.15a", map = "ICE_PATH_B1F", op = "push", x = 7, y = 8, dir = "left",
|
|
count = 1 },
|
|
{ id = "13.15b", map = "ICE_PATH_B1F", op = "push", x = 6, y = 8, dir = "up",
|
|
count = 9 },
|
|
{ id = "13.15c", map = "ICE_PATH_B1F", op = "push", x = 6, y = 3, dir = "left",
|
|
count = 1 },
|
|
{ id = "13.15d", map = "ICE_PATH_B1F", op = "push", x = 5, y = 3, dir = "down",
|
|
count = 7 },
|
|
{ id = "13.15", map = "ICE_PATH_B1F", op = "push", x = 5, y = 7, dir = "left",
|
|
count = 1, expect = "EVENT_BOULDER_IN_ICE_PATH_2" },
|
|
|
|
{ id = "13.26", map = "BLACKTHORN_CITY", op = "travel" },
|
|
{ id = "13.27", map = "BLACKTHORN_CITY", op = "heal" },
|
|
-- Two FULL RESTOREs for Clair. Her lead DRAGONAIR opens with THUNDER WAVE,
|
|
-- and a paralyzed Fire lead loses the KINGDRA war (half speed, quarter of
|
|
-- its turns skipped, super-effective SURF, plus Clair's own HYPER POTION).
|
|
-- FULL RESTORE is the only status cure the port implements as a battle item,
|
|
-- and A.statusCure spends one to un-paralyse -- after which a level-58
|
|
-- TYPHLOSION outspeeds and wins. Bought at Blackthorn's mart; the Elite
|
|
-- Four buys its own later, so this does not raid that budget.
|
|
{ id = "13.26b", map = "BLACKTHORN_MART", op = "buy", item = "FULL_RESTORE",
|
|
count = 2, optional = true },
|
|
-- 52 lead: the fighter usually arrives higher from the switch grinds, and
|
|
-- 13.g re-checks as satisfied then. The Clair retry loop cannot grow the
|
|
-- party (same reason), so the real lever is the paralysis cure above.
|
|
{ id = "13.g", map = "ROUTE_45", op = "grind", level = 52, lead = true },
|
|
{ id = "13.28", map = "BLACKTHORN_GYM_1F", op = "travel" },
|
|
-- Clair's island is its own region on 1F. EVENT_BOULDER_IN_BLACKTHORN_GYM_1
|
|
-- and _3 (with _2 for the full intended bridge) are painted by the 1F
|
|
-- MAPCALLBACK_TILES when the matching 2F boulders fall; without them the
|
|
-- right-stairs landing never reaches (5,3).
|
|
{ id = "13.28b", map = "BLACKTHORN_GYM_2F", op = "travel" },
|
|
|
|
-- Cody and Fran FIRST, then heal, then run the boulders in one unbroken
|
|
-- visit. The full run wiped the lead on their sight lines mid-sequence,
|
|
-- the between-rows auto-heal left the gym, and the map reload respawned
|
|
-- every unfallen boulder under the remaining rows -- 13.29c/13.29a2 then
|
|
-- had no stand cell. Beaten trainers stay beaten, so the fights are safe
|
|
-- to take early; noHeal below keeps the sequence unbroken.
|
|
{ id = "13.28c", map = "BLACKTHORN_GYM_2F", op = "battle", x = 4, y = 1,
|
|
talk = true, budget = 10000, optional = true,
|
|
expect = "EVENT_BEAT_COOLTRAINERM_CODY" },
|
|
{ id = "13.28d", map = "BLACKTHORN_GYM_2F", op = "battle", x = 4, y = 11,
|
|
talk = true, budget = 10000, optional = true,
|
|
expect = "EVENT_BEAT_COOLTRAINERF_FRAN" },
|
|
{ id = "13.28h", map = "BLACKTHORN_CITY", op = "heal" },
|
|
{ id = "13.28r", map = "BLACKTHORN_GYM_2F", op = "travel" },
|
|
|
|
-- Cody at (4,1) seals the top row, so the stand cell south of B2 (2,2) is
|
|
-- unreachable until B4 is parked north out of the (3,2)/(3,3) corridor.
|
|
{ id = "13.29a0", map = "BLACKTHORN_GYM_2F", op = "push", x = 3, y = 3, dir = "up",
|
|
count = 3, optional = true, noHeal = true,
|
|
note = "B4 to (3,1); opens the path to (2,2)" },
|
|
-- B2 (2,3) -> (2,4), then into hole (2,5) after B1 (order from the solver)
|
|
{ id = "13.29a", map = "BLACKTHORN_GYM_2F", op = "push", x = 2, y = 3, dir = "down",
|
|
count = 1, optional = true, noHeal = true },
|
|
-- B5 (6,1) park. optional so a Clair retry can soft-miss.
|
|
{ id = "13.29b", map = "BLACKTHORN_GYM_2F", op = "push", x = 6, y = 1, dir = "right",
|
|
count = 5, optional = true, noHeal = true },
|
|
-- B6 (8,14) clears the south corridor for B3.
|
|
{ id = "13.29d", map = "BLACKTHORN_GYM_2F", op = "push", x = 8, y = 14, dir = "down",
|
|
count = 5, optional = true, noHeal = true },
|
|
-- B3 (6,16) up to (6,7), then one right to (7,7) while B1/B2 finish.
|
|
{ id = "13.29e", map = "BLACKTHORN_GYM_2F", op = "push", x = 6, y = 16, dir = "up",
|
|
count = 17, optional = true, noHeal = true },
|
|
{ id = "13.29e2", map = "BLACKTHORN_GYM_2F", op = "push", x = 6, y = 7, dir = "right",
|
|
count = 1, optional = true, noHeal = true },
|
|
-- B1 (8,2) -> hole (8,3)
|
|
{ id = "13.29c", map = "BLACKTHORN_GYM_2F", op = "push", x = 8, y = 2, dir = "down",
|
|
count = 1, noHeal = true, expect = "EVENT_BOULDER_IN_BLACKTHORN_GYM_1" },
|
|
-- B2 (2,4) -> hole (2,5)
|
|
{ id = "13.29a2", map = "BLACKTHORN_GYM_2F", op = "push", x = 2, y = 4, dir = "down",
|
|
count = 1, noHeal = true, expect = "EVENT_BOULDER_IN_BLACKTHORN_GYM_2" },
|
|
-- B3 (7,7) -> hole (8,7)
|
|
{ id = "13.29f", map = "BLACKTHORN_GYM_2F", op = "push", x = 7, y = 7, dir = "right",
|
|
count = 1, noHeal = true, expect = "EVENT_BOULDER_IN_BLACKTHORN_GYM_3" },
|
|
|
|
-- Come down the RIGHT stairs so we land in the bridged region. The door
|
|
-- from the city is the OTHER region and cannot reach Clair even with every
|
|
-- bridge painted -- only warp 2 / hole landings 6 and 7 can.
|
|
{ id = "13.29g", map = "BLACKTHORN_GYM_2F", op = "warp", x = 7, y = 9,
|
|
to = "BLACKTHORN_GYM_1F", noHeal = true },
|
|
-- Clair is the hardest single fight in the Johto half for a mono-Fire lead:
|
|
-- a bulky Water/Dragon KINGDRA that resists Fire and SURFs super-effectively,
|
|
-- THUNDER WAVE paralysis off her DRAGONAIRs, and her own HYPER POTION. A
|
|
-- level-58 TYPHLOSION wins it about one lap in five, so the lever is laps.
|
|
-- retryFrom the FULL RESTORE buy so a paralysis cure is restocked while
|
|
-- there is money (a lost lap halves it -- Gen 2 -- so the cure mostly lands
|
|
-- on the first attempt); verified beaten within budget from RESUME=13.
|
|
-- retryLimit 26, not 12: each lost lap KEEPS the EXP from beating her three
|
|
-- DRAGONAIRs before KINGDRA (resolveFaints awards it before the loss check),
|
|
-- so the lead climbs ~1 level every ~3 laps -- but her level-37 mons give a
|
|
-- level-58 TYPHLOSION so little that 12 laps only bought +3 (to 61), short of
|
|
-- what out-races KINGDRA + her HYPER POTION under paralysis. ~26 laps buys
|
|
-- ~+8, which wins reliably; most runs land it in well under a dozen and stop
|
|
-- early. (This is the same lose-to-grind loop the Elite Four rides, only
|
|
-- against much weaker mons, hence the higher count.)
|
|
{ id = "13.30", map = "BLACKTHORN_GYM_1F", op = "battle", x = 5, y = 3,
|
|
talk = true, budget = 16000, expect = "EVENT_BEAT_CLAIR",
|
|
retryFrom = "13.26b", retryLimit = 26 },
|
|
|
|
-- The badge is not Clair's to give until the Dragon's Den test: the Dragon
|
|
-- Fang at the shrine is what sets RISINGBADGE.
|
|
{ id = "13.32", map = "DRAGONS_DEN_B1F", op = "travel" },
|
|
{ id = "13.33", map = "DRAGONS_DEN_B1F", op = "talk", x = 35, y = 16,
|
|
budget = 12000, expect = "EVENT_DRAGONS_DEN_B1F_DRAGON_FANG" },
|
|
{ id = "13.33b", map = "DRAGONS_DEN_B1F", op = "check",
|
|
expect = "ENGINE_RISINGBADGE" },
|
|
|
|
-- =========================================================================
|
|
-- Section 16 : east to Kanto's door
|
|
-- =========================================================================
|
|
-- Eight badges, SURF, WATERFALL and WHIRLPOOL are all in hand by here, which
|
|
-- is what makes Route 27 and Tohjo Falls crossable at all.
|
|
|
|
-- Waypointed through Route 46 so the Route 45 descent is two short legs, not
|
|
-- one Blackthorn -> New Bark plan that flip-flopped at the seam. The
|
|
-- crossing itself needed the edgeTarget fix: coming onto Route 45's top strip
|
|
-- (region 3), the west border cells nearest the landing are region 1/2 and
|
|
-- unreachable, and the old nearest-16 reachability cap never scanned down to
|
|
-- region 3's own Route 46 cells (Bot:edgeTarget).
|
|
{ id = "16.22a", map = "ROUTE_46", op = "travel" },
|
|
{ id = "16.22b", map = "ROUTE_29", op = "travel" },
|
|
{ id = "16.23", map = "NEW_BARK_TOWN", op = "travel" },
|
|
{ id = "16.24", map = "ELMS_LAB", op = "travel", optional = true },
|
|
{ id = "16.24b", map = "ELMS_LAB", op = "talk", x = 5, y = 2, optional = true,
|
|
expect = "EVENT_GOT_MASTER_BALL_FROM_ELM" },
|
|
{ id = "16.27", map = "ROUTE_27", op = "travel" },
|
|
{ id = "16.28", map = "ROUTE_27", op = "settle", budget = 8000,
|
|
note = "FirstStepIntoKantoScene is unskippable" },
|
|
-- Route 27 is split by water and by TOHJO FALLS: the west half (where the
|
|
-- New Bark crossing lands, itself over water -- asm-walk map row 4, "the
|
|
-- crossing itself is water, so SURF") does not touch the east edge that
|
|
-- connects to Route 26. The intended path is through the falls -- surf to
|
|
-- warp 2, climb inside with WATERFALL, exit warp 3 onto the east half -- and
|
|
-- the static region graph is foot-only, so `travel ROUTE_26` from the west
|
|
-- tries the unreachable east edge and oscillates into a teleport. Naming
|
|
-- TOHJO_FALLS forces the surf-and-climb; the east half then reaches Route 26.
|
|
{ id = "16.42", map = "TOHJO_FALLS", op = "travel" },
|
|
-- Leave by the EAST warp (25,15 -> Route 27 warp 3), not the west one we came
|
|
-- in through. Reaching it means climbing the falls inside -- warp 1's pool
|
|
-- (region 6) and warp 2's ledge (region 7) touch only up the WATERFALL -- so
|
|
-- this exercises the HM07 climb. A plain `travel ROUTE_27` picked the nearest
|
|
-- warp, which was the west one straight back into the pocket.
|
|
{ id = "16.42b", map = "TOHJO_FALLS", op = "warp", x = 25, y = 15,
|
|
to = "ROUTE_27" },
|
|
{ id = "16.43", map = "ROUTE_26", op = "travel" },
|
|
{ id = "16.54", map = "VICTORY_ROAD_GATE", op = "travel" },
|
|
{ id = "16.55", map = "VICTORY_ROAD_GATE", op = "walk", x = 10, y = 11,
|
|
budget = 6000, note = "the badge check; eight badges walks straight through" },
|
|
|
|
-- =========================================================================
|
|
-- Section 17 : Victory Road
|
|
-- =========================================================================
|
|
|
|
{ id = "17.2", map = "VICTORY_ROAD", op = "travel" },
|
|
{ id = "17.11", map = "VICTORY_ROAD", op = "walk", x = 13, y = 8,
|
|
budget = 16000, expect = "EVENT_RIVAL_VICTORY_ROAD",
|
|
note = "the rival ambush; there is no way past it" },
|
|
{ id = "17.15", map = "ROUTE_23", op = "travel" },
|
|
|
|
-- =========================================================================
|
|
-- Section 18 : the Pokemon League
|
|
-- =========================================================================
|
|
-- One-way. Every room seals behind you and the Pokecenter's own
|
|
-- MAPCALLBACK_NEWMAP wipes every EVENT_BEAT_ELITE_4_*, so a heal after Will
|
|
-- restarts the gauntlet -- which is why the only heal row is before the door.
|
|
|
|
{ id = "18.4", map = "INDIGO_PLATEAU_POKECENTER_1F", op = "travel" },
|
|
-- The gauntlet is five fights with no heal between them (the Pokecenter's
|
|
-- MAPCALLBACK_NEWMAP wipes every EVENT_BEAT_ELITE_4_*), so everything the
|
|
-- party will ever have has to be bought and earned before the door. Run 13
|
|
-- earned all eight badges and then lost Koga and Bruno on level and
|
|
-- attrition alone.
|
|
-- Grind on VICTORY_ROAD, not Route 26, and only the lead.
|
|
--
|
|
-- Johto's wilds cap around level 30, so a target of 78 on Route 26's
|
|
-- low-twenties encounters is a number the bot can never reach -- it spent
|
|
-- 160k frames gaining nothing and then failed on its wipe budget. Victory
|
|
-- Road is the highest-level ground actually reachable before the door.
|
|
-- The party-minimum grind is dropped here on purpose: it rotates the WEAKEST
|
|
-- mon to the front, and at this point in the game that mon is wiped by the
|
|
-- wilds faster than it can earn anything.
|
|
{ id = "18.g", map = "VICTORY_ROAD", op = "grind", level = 62, lead = true,
|
|
wipeBudget = 8 },
|
|
-- Cheap heals FIRST, and only then the expensive one.
|
|
--
|
|
-- This bought FULL_RESTORE first at Y3000 each, which with a lap's ~Y9000
|
|
-- meant a bag of exactly three items and nothing left for HYPER_POTIONs. The
|
|
-- bot then spent all three topping up in Will's, Koga's and Bruno's rooms and
|
|
-- walked into LANCE with an empty bag -- it was killing five of his six and
|
|
-- losing to the last DRAGONITE with no answer. Five HYPER_POTIONs (Y6000) and
|
|
-- one FULL_RESTORE (Y3000) is the same money for twice the heals, and it is
|
|
-- the shape A.bestHeal's rationing wants: something cheap to spend between
|
|
-- 0.35 and 0.6, and one good thing held back for below it.
|
|
{ id = "18.g3", map = "INDIGO_PLATEAU_POKECENTER_1F", op = "buy",
|
|
item = "HYPER_POTION", count = 4, optional = true },
|
|
{ id = "18.g4", map = "INDIGO_PLATEAU_POKECENTER_1F", op = "buy",
|
|
item = "FULL_RESTORE", count = 4, optional = true },
|
|
{ id = "18.g5", map = "INDIGO_PLATEAU_POKECENTER_1F", op = "buy",
|
|
item = "REVIVE", count = 10, optional = true },
|
|
{ id = "18.4b", map = "INDIGO_PLATEAU_POKECENTER_1F", op = "travel" },
|
|
{ id = "18.4c", map = "INDIGO_PLATEAU_POKECENTER_1F", op = "heal" },
|
|
|
|
-- Every fight from here to the Champion carries `retryFrom = "18.g3"`.
|
|
--
|
|
-- Losing costs half the money and nothing else -- the experience earned on
|
|
-- the way to the wipe is kept -- so a lost gauntlet is not a dead end, it is
|
|
-- a grind that pays better than any grass in the game. Will's mons are in
|
|
-- the forties; a lap that dies to Bruno still banks Xatu, Jynx, Exeggutor,
|
|
-- Slowbro, Ariados, Venomoth, Muk, Forretress and Hitmontop.
|
|
--
|
|
-- The rewind lands on 18.g3 (the shop) rather than on Will's door because
|
|
-- IndigoPlateauPokecenter1F's MAPCALLBACK_NEWMAP clears all five BEAT flags
|
|
-- AND all ten room ENTRANCE/EXIT flags, so after a wipe the gauntlet really
|
|
-- does start over at Will -- and the restock and heal have to happen again
|
|
-- with it. See maps/IndigoPlateauPokecenter1F.asm.
|
|
{ id = "18.7", map = "WILLS_ROOM", op = "travel" },
|
|
{ id = "18.8", map = "WILLS_ROOM", op = "settle", budget = 6000,
|
|
expect = "EVENT_WILLS_ROOM_ENTRANCE_CLOSED", retryFrom = "18.g3" },
|
|
{ id = "18.9", map = "WILLS_ROOM", op = "battle", x = 5, y = 7, talk = true,
|
|
budget = 20000, expect = "EVENT_BEAT_ELITE_4_WILL", retryFrom = "18.g3" },
|
|
|
|
{ id = "18.11", map = "KOGAS_ROOM", op = "travel" },
|
|
{ id = "18.11b", map = "KOGAS_ROOM", op = "settle", budget = 6000 },
|
|
{ id = "18.11c", map = "KOGAS_ROOM", op = "battle", x = 5, y = 7, talk = true,
|
|
budget = 20000, expect = "EVENT_BEAT_ELITE_4_KOGA", retryFrom = "18.g3" },
|
|
|
|
{ id = "18.13", map = "BRUNOS_ROOM", op = "travel" },
|
|
{ id = "18.13b", map = "BRUNOS_ROOM", op = "settle", budget = 6000 },
|
|
-- 18 laps, not the default 12: Bruno is the wall when the party arrives
|
|
-- light, and a lost gauntlet lap is the best-paying grind in the game --
|
|
-- the extra laps cost frames, running out of them costs the run.
|
|
{ id = "18.13c", map = "BRUNOS_ROOM", op = "battle", x = 5, y = 7, talk = true,
|
|
budget = 20000, expect = "EVENT_BEAT_ELITE_4_BRUNO", retryFrom = "18.g3",
|
|
retryLimit = 18 },
|
|
|
|
{ id = "18.15", map = "KARENS_ROOM", op = "travel" },
|
|
{ id = "18.15b", map = "KARENS_ROOM", op = "settle", budget = 6000 },
|
|
{ id = "18.15c", map = "KARENS_ROOM", op = "battle", x = 5, y = 7, talk = true,
|
|
budget = 20000, expect = "EVENT_BEAT_ELITE_4_KAREN", retryFrom = "18.g3" },
|
|
|
|
{ id = "18.17", map = "LANCES_ROOM", op = "travel" },
|
|
{ id = "18.17b", map = "LANCES_ROOM", op = "settle", budget = 8000,
|
|
expect = "EVENT_LANCES_ROOM_ENTRANCE_CLOSED", retryFrom = "18.g3" },
|
|
-- The coord event at (4,5) is the Champion fight; the script walks the
|
|
-- player in, so this is a walk row rather than a talk.
|
|
-- No `expect` on the walk itself, and this is not laziness.
|
|
--
|
|
-- LancesRoom.asm sets EVENT_BEAT_CHAMPION_LANCE, prints two more pages of
|
|
-- text, opens the door with `changeblock` and only then lets the player
|
|
-- north. The bot walks through that door the moment it opens, so the `walk`
|
|
-- op ends with "left LANCES_ROOM for HALL_OF_FAME" -- and a postcondition
|
|
-- checked at that instant raced the script. Run 20 beat Lance ("CHAMPION
|
|
-- LANCE was defeated!", ¥5000 prize) NINE times and the row failed all nine,
|
|
-- each time rewinding the bot back out of the Hall of Fame to refight the
|
|
-- whole gauntlet. The win was real every time; the oracle was wrong.
|
|
--
|
|
-- So the walk just triggers the fight, and the finish line is measured where
|
|
-- it actually happens: standing in the HALL OF FAME with the flag its own
|
|
-- script sets.
|
|
{ id = "18.18", map = "LANCES_ROOM", op = "walk", x = 4, y = 5,
|
|
budget = 30000, expect = "EVENT_BEAT_CHAMPION_LANCE",
|
|
retryFrom = "18.g3" },
|
|
-- No row here with `map = "HALL_OF_FAME"` that is allowed to fail softly.
|
|
-- One was tried and it manufactured a false win: the runner reaches a row's
|
|
-- map before running it, could not walk to the Hall of Fame from the
|
|
-- Pokecenter it had just whited out to, and fell back to the harness
|
|
-- TELEPORT shortcut -- so a run that LOST to Lance still finished with
|
|
-- "final map: HALL_OF_FAME", and 18.20 then read `already satisfied` off an
|
|
-- EVENT_BEAT_ELITE_FOUR left over in the checkpoint. 18.18 is the gate.
|
|
{ id = "18.20", map = "HALL_OF_FAME", op = "settle", budget = 20000,
|
|
expect = "EVENT_BEAT_ELITE_FOUR",
|
|
note = "Lance's speech, the roster, the credits: the finish line" },
|
|
}
|