From 43ac578a0c595d897d0b528c6c0039bcc9c51d02 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 00:27:01 -0700 Subject: [PATCH 01/16] FRLG: watch for wild battles only on steps where one can start Each route step says whether it crosses tall grass or water. The walker watches for a wild battle's flash only there; elsewhere it watches for messages alone. On console B the walk east to the bedroom's wall stopped on a false battle: the screen darkened at the edge of the small room like a battle's flash, and fleeing failed five times. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../Overworld/PokemonFRLG_OverworldRoute.cpp | 45 +++++++++++++++++++ .../Overworld/PokemonFRLG_OverworldRoute.h | 4 ++ .../Overworld/PokemonFRLG_OverworldWalk.cpp | 30 +++++++------ .../Overworld/PokemonFRLG_OverworldWalk.h | 18 ++++++-- 4 files changed, 79 insertions(+), 18 deletions(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp index 1bbe90ab9b..9619ba7beb 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp @@ -307,6 +307,17 @@ RouteStep to_route_step(const std::vector& maps, const Pokemon::Leg maps = overworld_maps(); + std::vector route; + UnitTestResult result = check_route( + maps, point_on(maps, "PalletTown_PlayersHouse_2F", "start"), + {point_on(maps, "PalletTown", "oaks_lab_front"), Direction::NORTH}, route + ); + if (result.result != UnitTestResult::PASSED){ + return result; + } + for (const RouteStep& step : route){ + if (step.wild){ + return "Expected no wild step from the bedroom to Oak's Lab, got " + to_string(step) + ":" + describe(route); + } + } + route.clear(); + result = check_route( + maps, point_on(maps, "ViridianCity_Mart", "clerk_front"), + {point_on(maps, "PewterCity", "gym_front"), Direction::NORTH}, route + ); + if (result.result != UnitTestResult::PASSED){ + return result; + } + for (const RouteStep& step : route){ + if (step.wild && step.end.map == "ViridianForest"){ + return true; + } + } + return "Expected a wild step in Viridian Forest:" + describe(route); +} + const char* const TEST_ROOM_JSON = R"({ "name": "Room", "width": 5, "height": 4, "tiles": ["#####", "#...#", "#...#", "##v##"], @@ -697,6 +741,7 @@ void add_tests_OverworldRoute(UnitTestDatabase& database){ database.add("maps to Brock", test_story_maps); database.add("bedroom to Oak's Lab", test_bedroom_to_oaks_lab); database.add("Viridian Mart to Pewter Gym", test_viridian_mart_to_pewter_gym); + database.add("wild steps", test_wild_steps); database.add("step rules", test_step_rules); database.add("maps", test_maps); database.add("Cerulean Cave entrance to Mewtwo", test_entrance_to_mewtwo); diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.h index 35afa7a1e4..112d402e35 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.h +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.h @@ -52,6 +52,10 @@ struct RouteStep{ // WALK: a wall stops the player at the end, so the leg can be held for // longer than it takes and still ends on its tile. bool to_wall = false; + // WALK, SURF: a wild Pokemon can appear on the way: the step crosses + // tall grass or water. Elsewhere (indoors, streets) no wild battle can + // start, so the walker doesn't watch for one. + bool wild = false; // Which way the player faces after the step. Arriving at a door or a // cave mouth, the game walks the player a tile out, facing south. Direction facing_after = Direction::NORTH; diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp index 202b5e076f..de4ffbb73c 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp @@ -211,11 +211,12 @@ void start_surf(ConsoleHandle& console, ProControllerContext& context, Direction -OverworldInterrupts overworld_interrupts_with_repel(int max_repel_slot){ - OverworldInterrupts ret; - ret.emplace_back(std::make_unique()); - ret.emplace_back(std::make_unique()); - ret.emplace_back(std::make_unique(max_repel_slot)); +OverworldInterruptSet overworld_interrupts_with_repel(int max_repel_slot){ + OverworldInterruptSet ret; + ret.wild.emplace_back(std::make_unique()); + ret.wild.emplace_back(std::make_unique()); + ret.wild.emplace_back(std::make_unique(max_repel_slot)); + ret.other.emplace_back(std::make_unique(max_repel_slot)); return ret; } @@ -245,13 +246,14 @@ void use_max_repel_from_bag(ConsoleHandle& console, ProControllerContext& contex context.wait_for_all_requests(); } -const OverworldInterrupts& default_overworld_interrupts(){ +const OverworldInterruptSet& default_overworld_interrupts(){ // Battles first: their screens are checked before the message box's. - static const OverworldInterrupts interrupts = []{ - OverworldInterrupts ret; - ret.emplace_back(std::make_unique()); - ret.emplace_back(std::make_unique()); - ret.emplace_back(std::make_unique()); + static const OverworldInterruptSet interrupts = []{ + OverworldInterruptSet ret; + ret.wild.emplace_back(std::make_unique()); + ret.wild.emplace_back(std::make_unique()); + ret.wild.emplace_back(std::make_unique()); + ret.other.emplace_back(std::make_unique()); return ret; }(); return interrupts; @@ -262,7 +264,7 @@ void walk_overworld_route( ConsoleHandle& console, ProControllerContext& context, const std::vector& route, std::optional facing, - const OverworldInterrupts& interrupts + const OverworldInterruptSet& interrupts ){ // Each leg starts with a turn tap unless it goes the way the player faces. // A tap while already facing that way takes a step, so a facing not @@ -286,7 +288,7 @@ void walk_overworld_route( if (facing != step.direction){ pbf_press_dpad(context, dpad(step.direction), TURN_TAP, TURN_SETTLE); } - Pokemon::walk_leg(console, context, mover, interrupts, leg_spec(step), MAX_INTERRUPTIONS_PER_LEG); + Pokemon::walk_leg(console, context, mover, step.wild ? interrupts.wild : interrupts.other, leg_spec(step), MAX_INTERRUPTIONS_PER_LEG); if (step.warps){ wait_out_warp(console, context, step); pbf_wait(context, AFTER_WARP); @@ -300,7 +302,7 @@ void walk_overworld_route( break; } if (step.action != RouteAction::FACE){ - Pokemon::clear_late_interrupts(console, context, interrupts, AFTER_LEG_WATCH, MAX_INTERRUPTIONS_PER_LEG); + Pokemon::clear_late_interrupts(console, context, step.wild ? interrupts.wild : interrupts.other, AFTER_LEG_WATCH, MAX_INTERRUPTIONS_PER_LEG); } facing = step.facing_after; } diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h index 402826fd7a..2df795b774 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h @@ -35,14 +35,24 @@ namespace PokemonFRLG{ using OverworldInterrupt = Pokemon::LegInterrupt; using OverworldInterrupts = Pokemon::LegInterrupts; +// What to watch for on a route's steps: `wild` on steps where a wild +// Pokemon can appear (RouteStep::wild), `other` on the rest. Watching for a +// battle where none can start only risks a false one: walking to the edge +// of a small room, the screen darkens like a battle's flash (console B, +// 2026-11-01, the bedroom's east wall). +struct OverworldInterruptSet{ + OverworldInterrupts wild; + OverworldInterrupts other; +}; + // A wild battle, run from, and a message (e.g. "REPEL's effect wore off..."), -// closed with B. -const OverworldInterrupts& default_overworld_interrupts(); +// closed with B. See OverworldInterruptSet. +const OverworldInterruptSet& default_overworld_interrupts(); // The same, except that after a message another Max Repel is used, from // slot `max_repel_slot` (from 0) of the Items pocket. Any message on the // overworld is taken to be the one saying the last Repel wore off. -OverworldInterrupts overworld_interrupts_with_repel(int max_repel_slot); +OverworldInterruptSet overworld_interrupts_with_repel(int max_repel_slot); // From the overworld, uses the Max Repel in `slot` (from 0) of the Items // pocket and returns to the overworld. @@ -58,7 +68,7 @@ void walk_overworld_route( ConsoleHandle& console, ProControllerContext& context, const std::vector& route, std::optional facing = std::nullopt, - const OverworldInterrupts& interrupts = default_overworld_interrupts() + const OverworldInterruptSet& interrupts = default_overworld_interrupts() ); From f11a566721a9b919373502a9fc4d5e716b022ad7 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 00:31:51 -0700 Subject: [PATCH 02/16] FRLG: never plan a hold into a sign moving north or south FireRed shows a sign's message to a player who walks into it moving north or south (TrySetUpWalkIntoSignpostScript() in pokefirered). The maps now mark signs ('S': signposts with a sign event, Center, Mart and Indigo Plateau signs), and the planner no longer counts on one to stop a leg. On console B, the walk north to the bedroom's wall read the poster above it, and walking to the wall again read it again. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../Overworld/PokemonFRLG_OverworldMap.cpp | 3 +- .../Overworld/PokemonFRLG_OverworldMap.h | 4 ++ .../Overworld/PokemonFRLG_OverworldRoute.cpp | 41 +++++++++++++++++++ devtools/maps/frlg_maps.py | 17 ++++++-- 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMap.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMap.cpp index 8ad357066c..d838d5cb7b 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMap.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMap.cpp @@ -21,6 +21,7 @@ std::optional tile_from_char(char c){ case '"': return Tile::TALL_GRASS; case '~': return Tile::WATER; case 'D': return Tile::DOOR; + case 'S': return Tile::SIGN; case 'C': return Tile::CAVE_ENTRANCE; case 'L': return Tile::LADDER; case '^': return Tile::MAT_NORTH; @@ -48,7 +49,7 @@ uint8_t elevation_at(const MapData& map, const TilePos& point){ bool is_wall(const MapData& map, const TilePos& point){ const Tile tile = tile_at(map, point); - return tile == Tile::WALL || tile == Tile::DOOR || tile == Tile::LEDGE; + return tile == Tile::WALL || tile == Tile::DOOR || tile == Tile::SIGN || tile == Tile::LEDGE; } bool is_ledge(const MapData& map, const TilePos& point){ return tile_at(map, point) == Tile::LEDGE; diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMap.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMap.h index 83ea60b342..804b838a2f 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMap.h +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMap.h @@ -88,6 +88,10 @@ enum class Tile : uint8_t{ TALL_GRASS, // '"' floor with wild encounters WATER, // '~' entered only by starting to Surf DOOR, // 'D' a wall that warps the player who walks north into it + SIGN, // 'S' a wall that shows its message to the player who + // walks into it moving north or south (signposts, + // Center and Mart signs; pokefirered + // TrySetUpWalkIntoSignpostScript()) CAVE_ENTRANCE, // 'C' floor that warps the player who steps onto it LADDER, // 'L' ladder or escalator: floor that warps the player // who steps onto it diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp index 9619ba7beb..25c1d40b1e 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp @@ -219,6 +219,12 @@ bool stops_at(const std::vector& maps, const Located& player, Direction } const MapData& map = maps[player.map]; const TilePos ahead = player.state.position.next(direction); + // Held into a sign moving north or south, the game shows the sign's + // message: the player stops, but the walk is interrupted (console B, + // 2026-11-01, the poster on the bedroom's wall). + if (tile_at(map, ahead) == Tile::SIGN && (direction == Direction::NORTH || direction == Direction::SOUTH)){ + return false; + } if (in_bounds(map, ahead)){ return object_at(map, ahead) == nullptr; } @@ -663,6 +669,40 @@ UnitTestResult test_viridian_mart_to_pewter_gym(){ return true; } +// A room with a sign on its north wall, above the third column. +const char* const TEST_SIGN_ROOM_JSON = R"({ + "name": "SignRoom", "width": 5, "height": 5, + "tiles": ["##S##", "#...#", "#...#", "#...#", "#####"], + "elevation": ["33333", "33333", "33333", "33333", "33333"], + "warps": [], "objects": [], + "connections": [], "points": [], "flag_sets": [] +})"; + +// Walking north under a sign stops by counting tiles, never by holding into +// the sign; under the wall beside it, the wall stops the player. +UnitTestResult test_no_hold_into_sign(){ + const std::vector maps{parse_map(TEST_SIGN_ROOM_JSON, "SignRoom")}; + std::vector route; + UnitTestResult result = check_route(maps, {"SignRoom", {2, 3}}, {{"SignRoom", {2, 1}}, std::nullopt}, route); + if (result.result != UnitTestResult::PASSED){ + return result; + } + for (const RouteStep& step : route){ + if (step.to_wall && step.end.point == TilePos{2, 1}){ + return "Expected no hold into the sign:" + describe(route); + } + } + route.clear(); + result = check_route(maps, {"SignRoom", {1, 3}}, {{"SignRoom", {1, 1}}, std::nullopt}, route); + if (result.result != UnitTestResult::PASSED){ + return result; + } + if (route.empty() || !route.back().to_wall){ + return "Expected the wall to stop the player beside the sign:" + describe(route); + } + return true; +} + // Two small maps that don't need the map files: a room left by the exit mat // at its bottom, onto the door of a yard, out of which the game walks the // player. @@ -742,6 +782,7 @@ void add_tests_OverworldRoute(UnitTestDatabase& database){ database.add("bedroom to Oak's Lab", test_bedroom_to_oaks_lab); database.add("Viridian Mart to Pewter Gym", test_viridian_mart_to_pewter_gym); database.add("wild steps", test_wild_steps); + database.add("no hold into a sign", test_no_hold_into_sign); database.add("step rules", test_step_rules); database.add("maps", test_maps); database.add("Cerulean Cave entrance to Mewtwo", test_entrance_to_mewtwo); diff --git a/devtools/maps/frlg_maps.py b/devtools/maps/frlg_maps.py index 07fe744d0f..9cd2111b61 100644 --- a/devtools/maps/frlg_maps.py +++ b/devtools/maps/frlg_maps.py @@ -101,7 +101,15 @@ def tileset_attributes(decomp, symbol, kind): return [struct.unpack_from('> 10) & 3, value >> 12 attributes = primary[metatile] if metatile < 640 else secondary[metatile - 640] behavior = names.get(attributes & 0x1ff, hex(attributes & 0x1ff)) - row += tile_character(behavior, collision, unhandled) + row += tile_character(behavior, collision, unhandled, (x, y) in signs) levels += '%x' % level tiles.append(row) elevation.append(levels) @@ -148,7 +156,8 @@ def wander(obj): def map_json(decomp, name, layouts, names, loaded, unhandled): source = json.loads(decomp.read(f'data/maps/{name}/map.json')) - width, height, tiles, elevation = grid(decomp, layouts[source['layout']], names, unhandled) + signs = frozenset((e['x'], e['y']) for e in source.get('bg_events', []) if e.get('type') == 'sign') + width, height, tiles, elevation = grid(decomp, layouts[source['layout']], names, unhandled, signs) objects = [] for obj in source.get('object_events', []): flag = obj.get('flag') or '' From e60819ae48cfe71228c4f252c0278cfa3df08f4c Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 09:31:07 -0800 Subject: [PATCH 03/16] FRLG: run the overworld route tests on maps compiled into the program CI has no map files in Packages, so the route tests on real maps were skipped there. PokemonFRLG_OverworldMapsTestData.cpp holds the 25 maps of Resources/PokemonFRLG/Maps as frlg_maps.py --cpp writes them, the same text as the Packages files, and test_overworld_maps() reads them as overworld_maps() reads the files. The route tests use it and no longer skip on a missing file. `frlg_maps.py --cpp --check` checks the file against a fresh generation. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../PokemonFRLG_OverworldMapsTestData.cpp | 3628 +++++++++++++++++ .../PokemonFRLG_OverworldMapsTestData.h | 38 + .../Overworld/PokemonFRLG_OverworldRoute.cpp | 18 +- SerialPrograms/cmake/SourceFiles.cmake | 2 + 4 files changed, 3676 insertions(+), 10 deletions(-) create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.cpp create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.h diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.cpp new file mode 100644 index 0000000000..1e2fc58818 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.cpp @@ -0,0 +1,3628 @@ +/* Overworld Maps Test Data + * + * From: https://github.com/PokemonAutomation/ + * + * Generated by devtools/maps/frlg_maps.py; do not edit. Regenerate with + * python3 devtools/maps/frlg_maps.py --cpp + * and check it with + * python3 devtools/maps/frlg_maps.py --cpp --check + * + */ + +#include "Common/Cpp/Exceptions.h" +#include "PokemonFRLG_OverworldMapsTestData.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + + +const std::vector>& overworld_map_json(){ + static const std::vector> MAPS{ + {"PalletTown", R"json({ + "name": "PalletTown", + "width": 24, + "height": 20, + "tiles": [ + "############..##########", + "############..##########", + "##....................##", + "##....................##", + "##...#####....#####...##", + "##...#####....#####...##", + "##...#####....#####...##", + "##..S#D###...S#D###...##", + "##....................##", + "##....................##", + "##...........#######..##", + "##...####S...#######..##", + "##...........#######..##", + "##...........###D###..##", + "##...S................##", + "##....................##", + "##...........###S##...##", + "##.....~~~~...........##", + "##.....~~~~...........##", + "##.....~~~~...........##" + ], + "elevation": [ + "000000000000330000000000", + "000000000000330000000000", + "003333333333333333333300", + "003333333333333333333300", + "003330000033330000033300", + "003330000033330000033300", + "003330000033330000033300", + "003300000033300000033300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333300000003300", + "003330000033300000003300", + "003333333333300000003300", + "003333333333300000003300", + "003330333333333333333300", + "003333333333333333333300", + "003333333333300000033300", + "003333311113333333333300", + "003333311113333333333300", + "003333311113333333333300" + ], + "warps": [ + { + "x": 6, + "y": 7, + "dest_map": "PalletTown_PlayersHouse_1F", + "dest_warp": 1 + }, + { + "x": 15, + "y": 7, + "dest_map": "PalletTown_RivalsHouse", + "dest_warp": 0 + }, + { + "x": 16, + "y": 13, + "dest_map": "PalletTown_ProfessorOaksLab", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 3, + "y": 10, + "kind": "woman_1", + "flag": "", + "wander_x": 1, + "wander_y": 4 + }, + { + "x": 13, + "y": 17, + "kind": "fat_man", + "flag": "", + "wander_x": 6, + "wander_y": 2 + }, + { + "x": 10, + "y": 8, + "kind": "prof_oak", + "flag": "FLAG_HIDE_OAK_IN_PALLET_TOWN", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "north", + "offset": 0, + "map": "Route1" + } + ], + "points": [ + { + "name": "oaks_lab_front", + "x": 16, + "y": 14 + } + ], + "flag_sets": [] +} +)json"}, + {"PalletTown_PlayersHouse_1F", R"json({ + "name": "PalletTown_PlayersHouse_1F", + "width": 13, + "height": 10, + "tiles": [ + "#############", + "#############", + "#.........>##", + "#............", + "#.....##.....", + "#.....##.....", + "#............", + "##..........#", + "#...v........", + "#############" + ], + "elevation": [ + "0000000000000", + "0000000000000", + "0333333333300", + "0333333333333", + "0333330033333", + "0333330033333", + "0333333333333", + "0033333333330", + "0333333333333", + "0000000000000" + ], + "warps": [ + { + "x": 5, + "y": 8, + "dest_map": "PalletTown", + "dest_warp": 0 + }, + { + "x": 4, + "y": 8, + "dest_map": "PalletTown", + "dest_warp": 0 + }, + { + "x": 10, + "y": 2, + "dest_map": "PalletTown_PlayersHouse_2F", + "dest_warp": 0 + }, + { + "x": 3, + "y": 9, + "dest_map": "PalletTown", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 8, + "y": 4, + "kind": "mom", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} +)json"}, + {"PalletTown_PlayersHouse_2F", R"json({ + "name": "PalletTown_PlayersHouse_2F", + "width": 12, + "height": 9, + "tiles": [ + "############", + "###########S", + "#.......##<.", + "#.......##..", + "#.s...#.....", + "#.n...#.....", + "#.#.........", + "#...........", + "#..........." + ], + "elevation": [ + "000000000000", + "000000000000", + "033333330033", + "033333330033", + "033333033333", + "003033033333", + "040403333333", + "003033333333", + "033333333333" + ], + "warps": [ + { + "x": 10, + "y": 2, + "dest_map": "PalletTown_PlayersHouse_1F", + "dest_warp": 2 + } + ], + "objects": [], + "connections": [], + "points": [ + { + "name": "start", + "x": 6, + "y": 6 + } + ], + "flag_sets": [] +} +)json"}, + {"PalletTown_RivalsHouse", R"json({ + "name": "PalletTown_RivalsHouse", + "width": 13, + "height": 10, + "tiles": [ + "#############", + "#############", + ".............", + ".............", + "......##.....", + "......##.....", + ".............", + ".............", + "#...v.......#", + "#############" + ], + "elevation": [ + "0000000000000", + "0000000000000", + "3333333333333", + "3333333333333", + "3333330033333", + "3333330033333", + "3333333333333", + "3333333333333", + "0333333333330", + "3330003333333" + ], + "warps": [ + { + "x": 4, + "y": 8, + "dest_map": "PalletTown", + "dest_warp": 1 + }, + { + "x": 5, + "y": 8, + "dest_map": "PalletTown", + "dest_warp": 1 + }, + { + "x": 3, + "y": 8, + "dest_map": "PalletTown", + "dest_warp": 1 + } + ], + "objects": [ + { + "x": 10, + "y": 6, + "kind": "daisy", + "flag": "", + "wander_x": 1, + "wander_y": 3 + }, + { + "x": 6, + "y": 4, + "kind": "town_map", + "flag": "FLAG_HIDE_TOWN_MAP", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} +)json"}, + {"PalletTown_ProfessorOaksLab", R"json({ + "name": "PalletTown_ProfessorOaksLab", + "width": 13, + "height": 14, + "tiles": [ + "#############", + "######SS#####", + ".............", + "#............", + "###.....###..", + ".##..........", + ".............", + ".............", + "#####...#####", + ".............", + ".............", + ".............", + "#.....v.....#", + "#############" + ], + "elevation": [ + "0000000000000", + "0000000000000", + "3333333333333", + "0333333333333", + "0003333300033", + "3003333333333", + "3333333333333", + "3333333333333", + "0000033300000", + "3333333333333", + "3333333333333", + "3333333333333", + "0333333333330", + "0000000000000" + ], + "warps": [ + { + "x": 6, + "y": 12, + "dest_map": "PalletTown", + "dest_warp": 2 + }, + { + "x": 7, + "y": 12, + "dest_map": "PalletTown", + "dest_warp": 2 + }, + { + "x": 5, + "y": 12, + "dest_map": "PalletTown", + "dest_warp": 2 + } + ], + "objects": [ + { + "x": 3, + "y": 11, + "kind": "scientist", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 10, + "kind": "worker_f", + "flag": "", + "wander_x": 0, + "wander_y": 4 + }, + { + "x": 11, + "y": 10, + "kind": "scientist", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 6, + "y": 3, + "kind": "prof_oak", + "flag": "FLAG_HIDE_OAK_IN_HIS_LAB", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 8, + "y": 4, + "kind": "item_ball", + "flag": "FLAG_HIDE_BULBASAUR_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 9, + "y": 4, + "kind": "item_ball", + "flag": "FLAG_HIDE_SQUIRTLE_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 4, + "kind": "item_ball", + "flag": "FLAG_HIDE_CHARMANDER_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 4, + "kind": "blue", + "flag": "FLAG_HIDE_RIVAL_IN_LAB", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 1, + "kind": "pokedex", + "flag": "FLAG_HIDE_POKEDEX", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 1, + "kind": "pokedex", + "flag": "FLAG_HIDE_POKEDEX", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} +)json"}, + {"Route1", R"json({ + "name": "Route1", + "width": 24, + "height": 40, + "tiles": [ + "##########....##########", + "##########....##########", + "##....................##", + "##....................##", + "##......##............##", + "##JJJJJJ##JJJJJJ......##", + "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", + "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", + "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", + "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", + "##JJJJJJ##\"\"\"\"\"\"\"\"\"\"\"\"##", + "##......##............##", + "##....................##", + "##..............\"\"\"\"\"\"##", + "##..............\"\"\"\"\"\"##", + "####JJJJJJ######\"\"\"\"\"\"##", + "####......######\"\"\"\"\"\"##", + "##..............\"\"\"\"\"\"##", + "##....................##", + "##....................##", + "##JJ.JJJJ..JJJJJJJJJJJ##", + "##....................##", + "##....................##", + "##....................##", + "##..........\"\"\"\"\"\"....##", + "############\"\"\"\"\"\"....##", + "############\"\"\"\"\"\"JJJJ##", + "##..........\"\"\"\"\"\"....##", + "##..........\"\"\"\"\"\"....##", + "##....................##", + "##....................##", + "##JJJJ...SJJJJJJJJJJJJ##", + "##..\"\"\"\"\"\"\"......\"\"\"\"\"##", + "##..\"\"\"\"\"\"\"......\"\"\"\"\"##", + "##\"\"\"\"\"\"\"......\"\"\"\"\"..##", + "##\"\"\"\"\"\"\"...\"\".\"\"\"\"\"..##", + "############\"\"##########", + "##.........#\"\"#.......##", + "############\"\"##########", + "############\"\"##########" + ], + "elevation": [ + "000000000033330000000000", + "000000000033330000000000", + "003333333333333333333300", + "003333333333333333333300", + "003333330033333333333300", + "000000000000000033333300", + "003333330033333333333300", + "003333330033333333333300", + "003333330033333333333300", + "003333330033333333333300", + "000000000033333333333300", + "003333330033333333333300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "000000000000000033333300", + "000033333300000033333300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "000030000330000000000000", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "000000000000333333333300", + "000000000000333333000000", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "000000333000000000000000", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "000000000000330000000000", + "003333333330330333333300", + "000000000000330000000000", + "000000000000330000000000" + ], + "warps": [], + "objects": [ + { + "x": 6, + "y": 28, + "kind": "clerk", + "flag": "", + "wander_x": 0, + "wander_y": 1 + }, + { + "x": 19, + "y": 16, + "kind": "boy", + "flag": "", + "wander_x": 1, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "north", + "offset": -12, + "map": "ViridianCity" + }, + { + "direction": "south", + "offset": 0, + "map": "PalletTown" + } + ], + "points": [], + "flag_sets": [] +} +)json"}, + {"ViridianCity", R"json({ + "name": "ViridianCity", + "width": 48, + "height": 40, + "tiles": [ + "###################.....########################", + "###################....S########################", + "###################.....########################", + "###################.....########################", + "###################.....####..............######", + "########..................................######", + "########.##########.......................######", + "########.###########.............######...######", + "########.##########..............######...######", + "########.###########...######....######...######", + "########.##########.....#####...S..#D#....######", + "########.###########...##D###.............######", + "########.##########........##JJJJJJJJJJJJJ######", + "########.###########......................######", + "########.##########.......................######", + "######...###########.........###################", + ".........##########.S..######.............######", + "........................#####.....####....######", + ".......................##D###.....####....######", + "..................................SSD#....######", + "#######...................................######", + "#######...................................######", + "#######...................................######", + "###########.............#####.............######", + "###########.##..........#####.............######", + "#######.....##..........#####.............######", + "#######....~~~~~~.......SSD##.............######", + "#######....~~~~~~.........................######", + "#######....~~~~~~.........................######", + "#######....~~~~~~.........................######", + "#######JJJJ~~~~~~JJJ...JJJJJJJJJJJJJJJJJJJ######", + "#######.............S.....................######", + "#######...................................######", + "#######...................................######", + "##############............................######", + "##############............................######", + "######################....######################", + "######################....######################", + "######################....######################", + "######################....######################" + ], + "elevation": [ + "000000000000000000033333000000000000000000000000", + "000000000000000000033330000000000000000000000000", + "000000000000000000033333000000000000000000000000", + "000000000000000000033333000000000000000000000000", + "000000000000000000033333000033333333333333000000", + "000000003333333333333333333333333333333333000000", + "000000003000000000033333333333333333333333000000", + "000000003000000000003333333333333000000333000000", + "000000003000000000033333333333333000000333000000", + "000000003000000000003330000003333000000333000000", + "000000003000000000033333000003330330003333000000", + "000000003000000000003330000003333333333333000000", + "000000003000000000033333333000000000000000000000", + "000000003000000000003333333333333333333333000000", + "000000003000000000033333333333333333333333000000", + "000000333000000000003333333330000000000000000000", + "333333333000000000030330000003333333333333000000", + "333333333333333333333333000003333300003333000000", + "333333333333333333333330000003333300003333000000", + "333333333333333333333333333333333300003333000000", + "000000033333333333333333333333333333333333000000", + "000000033333333333333333333333333333333333000000", + "000000033333333333333333333333333333333333000000", + "000000000003333333333333000003333333333333000000", + "000000000003003333333333000003333333333333000000", + "000000033333003333333333000003333333333333000000", + "000000033331111113333333000003333333333333000000", + "000000033331111113333333333333333333333333000000", + "000000033331111113333333333333333333333333000000", + "000000033331111113333333333333333333333333000000", + "000000000001111110003330000000000000000000000000", + "000000033333333333330333333333333333333333000000", + "000000033333333333333333333333333333333333000000", + "000000033333333333333333333333333333333333000000", + "000000000000003333333333333333333333333333000000", + "000000000000003333333333333333333333333333000000", + "000000000000000000000033330000000000000000000000", + "000000000000000000000033330000000000000000000000", + "000000000000000000000033330000000000000000000000", + "000000000000000000000033330000000000000000000000" + ], + "warps": [ + { + "x": 26, + "y": 26, + "dest_map": "ViridianCity_PokemonCenter_1F", + "dest_warp": 1 + }, + { + "x": 25, + "y": 11, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 36, + "y": 10, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 25, + "y": 18, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 36, + "y": 19, + "dest_map": "ViridianCity_Mart", + "dest_warp": 1 + } + ], + "objects": [ + { + "x": 8, + "y": 26, + "kind": "fat_man", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 11, + "y": 24, + "kind": "cut_tree", + "flag": "FLAG_TEMP_11", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 34, + "y": 11, + "kind": "old_man_1", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 21, + "y": 6, + "kind": "var_0", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 20, + "y": 12, + "kind": "woman_3", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 26, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 2 + }, + { + "x": 16, + "y": 22, + "kind": "boy", + "flag": "", + "wander_x": 1, + "wander_y": 2 + }, + { + "x": 18, + "y": 5, + "kind": "cut_tree", + "flag": "FLAG_TEMP_12", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 17, + "y": 5, + "kind": "item_ball", + "flag": "FLAG_HIDE_VIRIDIAN_CITY_POTION", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "north", + "offset": 12, + "map": "Route2" + }, + { + "direction": "south", + "offset": 12, + "map": "Route1" + }, + { + "direction": "west", + "offset": 10, + "map": "Route22" + } + ], + "points": [], + "flag_sets": [] +} +)json"}, + {"ViridianCity_Mart", R"json({ + "name": "ViridianCity_Mart", + "width": 11, + "height": 9, + "tiles": [ + "###########", + "###########", + "##.#......#", + "...#.......", + "####...##.#", + ".......##.#", + ".##....##.#", + "....v......", + "###########" + ], + "elevation": [ + "00000000000", + "00000000000", + "00303333330", + "33003333333", + "00003330030", + "33333330030", + "30033330030", + "33333333333", + "00000000000" + ], + "warps": [ + { + "x": 3, + "y": 7, + "dest_map": "ViridianCity", + "dest_warp": 4 + }, + { + "x": 4, + "y": 7, + "dest_map": "ViridianCity", + "dest_warp": 4 + }, + { + "x": 5, + "y": 7, + "dest_map": "ViridianCity", + "dest_warp": 4 + } + ], + "objects": [ + { + "x": 2, + "y": 3, + "kind": "clerk", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 6, + "y": 2, + "kind": "youngster", + "flag": "", + "wander_x": 1, + "wander_y": 1 + }, + { + "x": 9, + "y": 5, + "kind": "woman_1", + "flag": "", + "wander_x": 0, + "wander_y": 1 + } + ], + "connections": [], + "points": [ + { + "name": "clerk_front", + "x": 4, + "y": 3 + } + ], + "flag_sets": [] +} +)json"}, + {"ViridianCity_PokemonCenter_1F", R"json({ + "name": "ViridianCity_PokemonCenter_1F", + "width": 15, + "height": 10, + "tiles": [ + "#.#############", + "###############", + "....###..##....", + "....#######....", + "...............", + "...............", + "#L.........##..", + "...........##..", + ".......v.......", + "###############" + ], + "elevation": [ + "030000000000000", + "000000000000000", + "333300033003333", + "333300000003333", + "333333333333333", + "330333333333333", + "044033333330033", + "330333333330033", + "333333333333333", + "000000000000000" + ], + "warps": [ + { + "x": 6, + "y": 8, + "dest_map": "ViridianCity", + "dest_warp": 0 + }, + { + "x": 7, + "y": 8, + "dest_map": "ViridianCity", + "dest_warp": 0 + }, + { + "x": 8, + "y": 8, + "dest_map": "ViridianCity", + "dest_warp": 0 + }, + { + "x": 1, + "y": 6, + "dest_map": "", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 7, + "y": 2, + "kind": "nurse", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 5, + "kind": "gentleman", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 7, + "kind": "boy", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 3, + "kind": "youngster", + "flag": "", + "wander_x": 1, + "wander_y": 1 + } + ], + "connections": [], + "points": [ + { + "name": "nurse_front", + "x": 7, + "y": 4 + } + ], + "flag_sets": [] +} +)json"}, + {"Route22", R"json({ + "name": "Route22", + "width": 48, + "height": 24, + "tiles": [ + "#############################################...", + "###########################################.#...", + "##################################........#.###.", + "##################################JJJJ.JJJ#...##", + "######################....................#.....", + "########D######...........................######", + "#####.......###.........................##......", + "###...........#.............######......##......", + "###...........#JJJJJJJ~~~~~~######JJ..JJ##......", + "###JJJJJJJ..JJ#\"\"\"\"\"\"\"~~~~~~######\"\"\"\"\"\"##......", + "###...........#\"\"\"\"\"\"\"~~~~~~######\"\"\"\"\"\"##....##", + "###...........#\"\"\"\"\"\"\"~~~~~~######\"\"\"\"\"\"##....##", + "####...S#######\"\"\"\"\"\"\"......######\"\"\"\"\"\"##....##", + "####...........\"\"\"\"\"\"\"......######\"\"\"\"\"\"##....##", + "####........................######............##", + "####JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ..JJJJJ##", + "####..........................................##", + "####..........................................##", + "####..........................................##", + "################################################", + "################################################", + "################################################", + "################################################", + "################################################" + ], + "elevation": [ + "000000000000000000000000000000000000000000000333", + "000000000000000000000000000000000000000000030333", + "000000000000000000000000000000000033333333030003", + "000000000000000000000000000000000000003000033300", + "000000000000000000000033333333333333333333033333", + "000000000000000333333333333333333333333333000000", + "000003333333000333333333333333333333333300333333", + "000333333333330333333333333300000033333300333333", + "000333333333330000000011111100000000330000333333", + "000000000033000333333311111100000033333300333333", + "000333333333330333333311111100000033333300333300", + "000333333333330333333311111100000033333300333300", + "000033300000000333333333333300000033333300333300", + "000033333333333333333333333300000033333300333300", + "000033333333333333333333333300000033333333333300", + "000000000000000000000000000000000000000330000000", + "000033333333333333333333333333333333333333333300", + "000033333333333333333333333333333333333333333300", + "000033333333333333333333333333333333333333333300", + "000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000" + ], + "warps": [ + { + "x": 8, + "y": 5, + "dest_map": "", + "dest_warp": 2 + }, + { + "x": 9, + "y": 5, + "dest_map": "", + "dest_warp": 2 + } + ], + "objects": [ + { + "x": 25, + "y": 4, + "kind": "blue", + "flag": "FLAG_HIDE_ROUTE_22_RIVAL", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "east", + "offset": -10, + "map": "ViridianCity" + } + ], + "points": [], + "flag_sets": [] +} +)json"}, + {"Route2", R"json({ + "name": "Route2", + "width": 24, + "height": 80, + "tiles": [ + "########....############", + "########....############", + "##\"\"\"\"\"\"\"...############", + "##\"\"\"\"\"\"\"...#.........##", + "##\"\"\"\"\"\"\"...#.........##", + "##\"\"\"\"\"\"\"...#.........##", + "##\"\"\"\"\"\"\"...#########.##", + "##\"\"\"\"\"\"\"...#########.##", + "##\"\"\"\"\"\"\"...#########.##", + "##..........#########.##", + "##..........#########.##", + "##..........#####C###.##", + "##..........#.S.......##", + "####.vv.###.#.........##", + "###########...........##", + "##########............##", + "##############........##", + "##############........##", + "##############........##", + "##############........##", + "##############........##", + "###################...##", + "#################D#...##", + "##############........##", + "################......##", + "################......##", + "##################.#####", + "################......##", + "################......##", + "################......##", + "################......##", + "################......##", + "################JJJ.JJ##", + "################......##", + "################......##", + "################......##", + "################......##", + "################JJJ.JJ##", + "################......##", + "################......##", + "################......##", + "#################.vv.###", + "########################", + "########################", + "########################", + "##........##############", + "##################CC####", + "#################....###", + "################......##", + "################......##", + "###.####.#######......##", + "#####CC#########JJJ.JJ##", + "####....########......##", + "##............##......##", + "##............##......##", + "##JJJJJJJJJ...##......##", + "##....\"\"\"\"\"\"\".##......##", + "##....\"\"\"\"\"\"\".##JJ.JJJ##", + "##....\"\"\"\"\"\"\".##......##", + "##....\"\"\"\"\"\"\".##......##", + "##....\"\"\"\"\"\"\".##......##", + "##............##......##", + "##....................##", + "##....##########......##", + "##....##########......##", + "##....##########......##", + "##....##########......##", + "##............##......##", + "##............##......##", + "##....................##", + "##JJJJJJJ..JJJ..JJ.JJJ##", + "##............##......##", + "####..........##......##", + "####...S......##......##", + "####..........##......##", + "####..........##......##", + "####..........##......##", + "####..........##......##", + "#######.......##########", + "#######.....############" + ], + "elevation": [ + "000000003333000000000000", + "000000003333000000000000", + "003333333333000000000000", + "003333333333033333333300", + "003333333333033333333300", + "003333333333033333333300", + "003333333333000000000300", + "003333333333000000000300", + "003333333333000000000300", + "003333333333000000000300", + "003333333333000000000300", + "003333333333000003000300", + "003333333333030333333300", + "000033330003033333333300", + "000000000003333333333300", + "000000000033333333333300", + "000000000000003333333300", + "000000000000003333333300", + "000000000000003333333300", + "000000000000003333333300", + "000000000000003333333300", + "000000000000000000033300", + "000000000000000000033300", + "000000000000003333333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000000300000", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000000030000", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000000030000", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000003333000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "003333333300000000000000", + "000000000000000000330000", + "000000000000000003333000", + "000000000000000033333300", + "000000000000000033333300", + "000300003000000033333300", + "000003300000000000030000", + "000033330000000033333300", + "003333333333330033333300", + "003333333333330033333300", + "000000000003330033333300", + "003333333333330033333300", + "003333333333330000300000", + "003333333333330033333300", + "003333333333330033333300", + "003333333333330033333300", + "003333333333330033333300", + "003333333333333333333300", + "003333000000000033333300", + "003333000000000033333300", + "003333000000000033333300", + "003333000000000033333300", + "003333333333330033333300", + "003333333333330033333300", + "003333333333333333333300", + "000000000330003300300000", + "003333333333330033333300", + "000033333333330033333300", + "000033303333330033333300", + "000033333333330033333300", + "000033333333330033333300", + "000033333333330033333300", + "000033333333330033333300", + "000000033333330000000000", + "000000033333000000000000" + ], + "warps": [ + { + "x": 5, + "y": 13, + "dest_map": "Route2_ViridianForest_NorthEntrance", + "dest_warp": 3 + }, + { + "x": 6, + "y": 13, + "dest_map": "Route2_ViridianForest_NorthEntrance", + "dest_warp": 3 + }, + { + "x": 5, + "y": 51, + "dest_map": "Route2_ViridianForest_SouthEntrance", + "dest_warp": 1 + }, + { + "x": 17, + "y": 11, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 17, + "y": 22, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 18, + "y": 46, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 18, + "y": 41, + "dest_map": "", + "dest_warp": 3 + }, + { + "x": 19, + "y": 41, + "dest_map": "", + "dest_warp": 3 + }, + { + "x": 19, + "y": 46, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 6, + "y": 51, + "dest_map": "Route2_ViridianForest_SouthEntrance", + "dest_warp": 1 + } + ], + "objects": [ + { + "x": 16, + "y": 62, + "kind": "cut_tree", + "flag": "FLAG_TEMP_14", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 15, + "y": 69, + "kind": "cut_tree", + "flag": "FLAG_TEMP_13", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 11, + "y": 13, + "kind": "cut_tree", + "flag": "FLAG_TEMP_15", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 18, + "y": 26, + "kind": "cut_tree", + "flag": "FLAG_TEMP_16", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 17, + "y": 54, + "kind": "item_ball", + "flag": "FLAG_HIDE_ROUTE2_ETHER", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 17, + "y": 64, + "kind": "item_ball", + "flag": "FLAG_HIDE_ROUTE2_PARALYZE_HEAL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 6, + "y": 85, + "kind": "cut_tree", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "north", + "offset": -12, + "map": "PewterCity" + }, + { + "direction": "south", + "offset": -12, + "map": "ViridianCity" + } + ], + "points": [], + "flag_sets": [] +} +)json"}, + {"Route2_ViridianForest_SouthEntrance", R"json({ + "name": "Route2_ViridianForest_SouthEntrance", + "width": 15, + "height": 12, + "tiles": [ + "###############", + "#######C#######", + "##...#...#...##", + "#.............#", + "#..........##.#", + "###........##.#", + "#.............#", + "#..........##.#", + "###........##.#", + "#.............#", + "#......v......#", + "###############" + ], + "elevation": [ + "000000000000000", + "000000030000000", + "003330333033300", + "033333333333330", + "033333333330030", + "000333333330030", + "033333333333330", + "033333333330030", + "000333333330030", + "033333333333330", + "033333333333330", + "000000000000000" + ], + "warps": [ + { + "x": 6, + "y": 10, + "dest_map": "Route2", + "dest_warp": 2 + }, + { + "x": 7, + "y": 10, + "dest_map": "Route2", + "dest_warp": 2 + }, + { + "x": 8, + "y": 10, + "dest_map": "Route2", + "dest_warp": 2 + }, + { + "x": 7, + "y": 1, + "dest_map": "ViridianForest", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 10, + "y": 6, + "kind": "woman_2", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 7, + "kind": "woman_1", + "flag": "", + "wander_x": 1, + "wander_y": 1 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} +)json"}, + {"ViridianForest", R"json({ + "name": "ViridianForest", + "width": 54, + "height": 69, + "tiles": [ + "######################################################", + "######################################################", + "######################################################", + "######################################################", + "######################################################", + "###########.............###........................###", + "###########.............###........................###", + "###########.............###........................###", + "#..#####..#.............###.....###############....###", + "####CCC####.............###.....###############....###", + "####...####.............###.....###############....###", + "####...####.....###.....###.....###############....###", + "####..S####\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###############....###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###############....###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###############....###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".............###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".............###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".............###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".......#########", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"........#########", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"######......#########", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###...\"\"\"######......#########", + "###\"\"\"\"\"###\"\"\"\"\"###.....###......######......#########", + "###\"\"\"\"\"###\"\"\"\"\"###..............######......#########", + "###\"\"\"\"\"###\"\"\"\"\"#####............######......#########", + "###\"\"\"\"\"###\"\"\"\"\"#####............######............###", + "###\"\"\"\"\"###\"\"\"\"\"\"\"#####################....S.......###", + "###\"\"\"\"\"...\"\"\"\"\"\"\"#####################............###", + "###...............#####################............###", + "###......S........#####################\"\"\"\"........###", + "###...............#####################\"\"\"\"\"###....###", + "###.....................###############\"\"\"\"\"###....###", + "###.....................###############\"\"\"\"\"###....###", + "###.....................###############\"\"\"\"\"###....###", + "##################......###############\"\"\"\"\"###....###", + "##################......###############\"\"\"\"\"###....###", + "#######################################\"\"\"\"\"###....###", + "#######################################\"\"\"\"\"###....###", + "#######################################\"\"\"\"\"###....###", + "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", + "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", + "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", + "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", + "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"######\"\"\"\"........###", + "############\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"S..\"\"######\"\"\".........###", + "############\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"...\"\"######\"\"\".........###", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "###\"\"\"\"\"\"\"\"\"..\"\"\"\"\"\"\"\"\"\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"\"..\"\"\"\"\"\"\"\"\"\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"\"\"\"\"\"\".###.\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"\"....\"\"\"\"\"\"\"\"\"\".......\"\"\"\"\"\"\"....\"\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"............................S....\"\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"....................S...........\"\"\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"................................\"\"\"\"\"\"\"\"###", + "###########################.vvv..#####################", + "######################################################", + "######################################################", + "######################################################", + "######################################################", + "######################################################", + "######################################################" + ], + "elevation": [ + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000003333333333333000333333333333333333333333000", + "000000000003333333333333000333333333333333333333333000", + "000000000003333333333333000333333333333333333333333000", + "033000003303333333333333000333330000000000000003333000", + "000033300003333333333333000333330000000000000003333000", + "000033300003333333333333000333330000000000000003333000", + "000033300003333300033333000333330000000000000003333000", + "000033000003333300033333000333330000000000000003333000", + "000333330003333300033333000333330000000000000003333000", + "000333330003333300033333000333330000000000000003333000", + "000333330003333300033333000333333333333333333333333000", + "000333330003333300033333000333333333333333333333333000", + "000333330003333300033333000333333333333333333333333000", + "000333330003333300033333000333333333333333333000000000", + "000333330003333300033333000333333333333333333000000000", + "000333330003333300033333000333333000000333333000000000", + "000333330003333300033333000333333000000333333000000000", + "000333330003333300033333000333333000000333333000000000", + "000333330003333300033333333333333000000333333000000000", + "000333330003333300000333333333333000000333333000000000", + "000333330003333300000333333333333000000333333333333000", + "000333330003333333000000000000000000000333303333333000", + "000333333333333333000000000000000000000333333333333000", + "000333333333333333000000000000000000000333333333333000", + "000333333033333333000000000000000000000333333333333000", + "000333333333333333000000000000000000000333330003333000", + "000333333333333333333333000000000000000333330003333000", + "000333333333333333333333000000000000000333330003333000", + "000333333333333333333333000000000000000333330003333000", + "000000000000000000333333000000000000000333330003333000", + "000000000000000000333333000000000000000333330003333000", + "000000000000000000000000000000000000000333330003333000", + "000000000000000000000000000000000000000333330003333000", + "000000000000000000000000000000000000000333330003333000", + "000333333333333333000000000000000000000333330003333000", + "000333333333333333000000000000000000000333330003333000", + "000333333333333333000000000000000000000333330003333000", + "000333333333333333000000000000000000000333330003333000", + "000333333333333333333333333333333000000333333333333000", + "000000000000333333333333333303333000000333333333333000", + "000000000000333333333333333333333000000333333333333000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000333333333333333333333333300033333333333333333333000", + "000333333333333333333333333300033333333333333333333000", + "000333333333333333333333333300033333333333333333333000", + "000333333333333333333333333333333333333333333333333000", + "000333333333333333333333333333333333333033333333333000", + "000333333333333333333333333333303333333333333333333000", + "000333333333333333333333333333333333333333333333333000", + "000000000000000000000000000333333000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000" + ], + "warps": [ + { + "x": 29, + "y": 62, + "dest_map": "Route2_ViridianForest_SouthEntrance", + "dest_warp": 3 + }, + { + "x": 28, + "y": 62, + "dest_map": "Route2_ViridianForest_SouthEntrance", + "dest_warp": 3 + }, + { + "x": 5, + "y": 9, + "dest_map": "Route2_ViridianForest_NorthEntrance", + "dest_warp": 1 + }, + { + "x": 6, + "y": 9, + "dest_map": "Route2_ViridianForest_NorthEntrance", + "dest_warp": 1 + }, + { + "x": 30, + "y": 62, + "dest_map": "Route2_ViridianForest_SouthEntrance", + "dest_warp": 3 + }, + { + "x": 4, + "y": 9, + "dest_map": "Route2_ViridianForest_NorthEntrance", + "dest_warp": 1 + } + ], + "objects": [ + { + "x": 29, + "y": 58, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 45, + "y": 58, + "kind": "boy", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 47, + "y": 45, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 47, + "y": 29, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 7, + "y": 22, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 41, + "kind": "item_ball", + "flag": "FLAG_HIDE_VIRIDIAN_FOREST_POKE_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 40, + "y": 21, + "kind": "item_ball", + "flag": "FLAG_HIDE_VIRIDIAN_FOREST_ANTIDOTE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 21, + "y": 34, + "kind": "item_ball", + "flag": "FLAG_HIDE_VIRIDIAN_FOREST_POTION", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 43, + "y": 6, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 16, + "y": 5, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 49, + "y": 60, + "kind": "item_ball", + "flag": "FLAG_HIDE_VIRIDIAN_FOREST_POTION_2", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} +)json"}, + {"Route2_ViridianForest_NorthEntrance", R"json({ + "name": "Route2_ViridianForest_NorthEntrance", + "width": 15, + "height": 12, + "tiles": [ + "###############", + "#######C#######", + "##...#...#...##", + "#.............#", + "#..........##.#", + "###........##.#", + "#.............#", + "#..........##.#", + "###........##.#", + "#.............#", + "#......v......#", + "###############" + ], + "elevation": [ + "000000000000000", + "000000030000000", + "003330333033300", + "033333333333330", + "033333333330030", + "000333333330030", + "033333333333330", + "033333333330030", + "000333333330030", + "033333333333330", + "033333333333330", + "000000000000000" + ], + "warps": [ + { + "x": 6, + "y": 10, + "dest_map": "ViridianForest", + "dest_warp": 2 + }, + { + "x": 7, + "y": 10, + "dest_map": "ViridianForest", + "dest_warp": 2 + }, + { + "x": 8, + "y": 10, + "dest_map": "ViridianForest", + "dest_warp": 2 + }, + { + "x": 7, + "y": 1, + "dest_map": "Route2", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 5, + "y": 4, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 7, + "kind": "old_man_1", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 5, + "kind": "cooltrainer_f", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} +)json"}, + {"PewterCity", R"json({ + "name": "PewterCity", + "width": 48, + "height": 40, + "tiles": [ + "################################################", + "#######################....#####################", + "####........#################.........##########", + "####........#################.........##########", + "####........#############D######......##########", + "####........###########...............##########", + "#######.....#####C#####..#######........########", + "####JJJ..JJJJJJJ...SJJJJJJJJJJJJJJJJJ...########", + "####....................................########", + "####............................#####...########", + "######..........................#####...########", + "######..........................#D###...########", + "######..................................########", + "######...##.#######.##..................########", + "######...#############..................########", + "######...##.#######.##..................########", + "######...##S..#D#...##....####..........########", + "######...............#....######........########", + "######...............#....SSD###........########", + "######...............#.................S########", + "######################..........................", + "######..........................................", + "######.......#########..........................", + "######.......#########....##########............", + "######.......#########....##########....########", + "######.......##SSD####....#####S#####...########", + "######....................#.........#...########", + "######....................#.........#...########", + "######..#####.............#.........#...########", + "######..#####.............#.........#...########", + "######..#D###.......S.....#JJJJ.JJJJ#...########", + "######..................................########", + "######..................................########", + "######..................................########", + "######..................................########", + "######..................................########", + "####################....########################", + "####################....########################", + "####################....########################", + "####################....########################" + ], + "elevation": [ + "000000000000000000000000000000000000000000000000", + "000000000000000000000003333000000000000000000000", + "000033333333000000000000000003333333330000000000", + "000033333333000000000000000003333333330000000000", + "000033333333000000000000000000003333330000000000", + "000033333333000000000003333333333333330000000000", + "000000033333000003000003300000003333333300000000", + "000000033000000033300000000000000000033300000000", + "000033333333333333333333333333333333333300000000", + "000033333333333333333333333333330000033300000000", + "000000333333333333333333333333330000033300000000", + "000000333333333333333333333333330000033300000000", + "000000333333333333333333333333333333333300000000", + "000000333003000000030033333333333333333300000000", + "000000333000000000000033333333333333333300000000", + "000000333003000000030033333333333333333300000000", + "000000333000330003330033330000333333333300000000", + "000000333333333333333033330000003333333300000000", + "000000333333333333333033330000003333333300000000", + "000000333333333333333033333333333333333000000000", + "000000000000000000000033333333333333333333333333", + "000000333333333333333333333333333333333333333333", + "000000333333300000000033333333333333333333333333", + "000000333333300000000033330000000000333333333333", + "000000333333300000000033330000000000333300000000", + "000000333333300000000033330000000000033300000000", + "000000333333333333333333330333333333033300000000", + "000000333333333333333333330333333333033300000000", + "000000330000033333333333330333333333033300000000", + "000000330000033333333333330333333333033300000000", + "000000330000033333330333330000030000033300000000", + "000000333333333333333333333333333333333300000000", + "000000333333333333333333333333333333333300000000", + "000000333333333333333333333333333333333300000000", + "000000333333333333333333333333333333333300000000", + "000000333333333333333333333333333333333300000000", + "000000000000000000003333000000000000000000000000", + "000000000000000000003333000000000000000000000000", + "000000000000000000003333000000000000000000000000", + "000000000000000000003333000000000000000000000000" + ], + "warps": [ + { + "x": 17, + "y": 6, + "dest_map": "PewterCity_Museum_1F", + "dest_warp": 1 + }, + { + "x": 25, + "y": 4, + "dest_map": "PewterCity_Museum_1F", + "dest_warp": 3 + }, + { + "x": 15, + "y": 16, + "dest_map": "PewterCity_Gym", + "dest_warp": 1 + }, + { + "x": 28, + "y": 18, + "dest_map": "PewterCity_Mart", + "dest_warp": 1 + }, + { + "x": 33, + "y": 11, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 17, + "y": 25, + "dest_map": "PewterCity_PokemonCenter_1F", + "dest_warp": 1 + }, + { + "x": 9, + "y": 30, + "dest_map": "", + "dest_warp": 1 + } + ], + "objects": [ + { + "x": 6, + "y": 15, + "kind": "lass", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 17, + "kind": "man", + "flag": "FLAG_HIDE_PEWTER_MUSEUM_GUIDE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 21, + "y": 28, + "kind": "fat_man", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 27, + "kind": "bug_catcher", + "flag": "", + "wander_x": 2, + "wander_y": 0 + }, + { + "x": 42, + "y": 20, + "kind": "boy", + "flag": "FLAG_HIDE_PEWTER_CITY_GYM_GUIDE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 30, + "y": 5, + "kind": "cut_tree", + "flag": "FLAG_TEMP_12", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 46, + "y": 20, + "kind": "scientist", + "flag": "FLAG_HIDE_PEWTER_CITY_RUNNING_SHOES_GUY", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "south", + "offset": 12, + "map": "Route2" + } + ], + "points": [ + { + "name": "gym_front", + "x": 15, + "y": 17 + } + ], + "flag_sets": [] +} +)json"}, + {"PewterCity_PokemonCenter_1F", R"json({ + "name": "PewterCity_PokemonCenter_1F", + "width": 15, + "height": 10, + "tiles": [ + "#.#############", + "###############", + "....###..##....", + "....#######....", + "...............", + "...............", + "#L.........##..", + "...........##..", + ".......v.......", + "###############" + ], + "elevation": [ + "030000000000000", + "000000000000000", + "333300033003333", + "333300000003333", + "333333333333333", + "330333333333333", + "044033333330033", + "330333333330033", + "333333333333333", + "000000000000000" + ], + "warps": [ + { + "x": 6, + "y": 8, + "dest_map": "PewterCity", + "dest_warp": 5 + }, + { + "x": 7, + "y": 8, + "dest_map": "PewterCity", + "dest_warp": 5 + }, + { + "x": 8, + "y": 8, + "dest_map": "PewterCity", + "dest_warp": 5 + }, + { + "x": 1, + "y": 6, + "dest_map": "", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 2, + "y": 2, + "kind": "jigglypuff", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 8, + "kind": "gentleman", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 7, + "y": 2, + "kind": "nurse", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 1, + "y": 2, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 13, + "y": 2, + "kind": "woman_1", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 7, + "kind": "gba_kid", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 14, + "y": 6, + "kind": "gba_kid", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [ + { + "name": "nurse_front", + "x": 7, + "y": 4 + } + ], + "flag_sets": [] +} +)json"}, + {"PewterCity_Mart", R"json({ + "name": "PewterCity_Mart", + "width": 11, + "height": 9, + "tiles": [ + "###########", + "###########", + "##.#......#", + "...#.......", + "####...##.#", + ".......##.#", + ".##....##.#", + "....v......", + "###########" + ], + "elevation": [ + "00000000000", + "00000000000", + "00303333330", + "33003333333", + "00003330030", + "33333330030", + "30033330030", + "33333333333", + "00000000000" + ], + "warps": [ + { + "x": 3, + "y": 7, + "dest_map": "PewterCity", + "dest_warp": 3 + }, + { + "x": 4, + "y": 7, + "dest_map": "PewterCity", + "dest_warp": 3 + }, + { + "x": 5, + "y": 7, + "dest_map": "PewterCity", + "dest_warp": 3 + } + ], + "objects": [ + { + "x": 8, + "y": 2, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 6, + "y": 4, + "kind": "boy", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 3, + "kind": "clerk", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} +)json"}, + {"PewterCity_Museum_1F", R"json({ + "name": "PewterCity_Museum_1F", + "width": 28, + "height": 11, + "tiles": [ + "############################", + "############################", + "...............#............", + "...............#......#....#", + "...####........#...........#", + "...............#............", + "...........#...#...........#", + "...####..###...###.........#", + "........>###.....#..........", + "#........###..v.##...v..##..", + "############################" + ], + "elevation": [ + "0000000000000000000000000000", + "0000000000000000000000000000", + "3333333333333330333333333333", + "3333333333333330333333033330", + "3330000333333330333333333330", + "3333333333333330333333333333", + "3333333333303330333333333330", + "3330000330003330003333333330", + "3333333330003333303333333333", + "0333333330003333003333330033", + "0000000000000000000000000000" + ], + "warps": [ + { + "x": 13, + "y": 9, + "dest_map": "PewterCity", + "dest_warp": 0 + }, + { + "x": 14, + "y": 9, + "dest_map": "PewterCity", + "dest_warp": 0 + }, + { + "x": 15, + "y": 9, + "dest_map": "PewterCity", + "dest_warp": 0 + }, + { + "x": 21, + "y": 9, + "dest_map": "PewterCity", + "dest_warp": 1 + }, + { + "x": 22, + "y": 9, + "dest_map": "PewterCity", + "dest_warp": 1 + }, + { + "x": 8, + "y": 8, + "dest_map": "", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 16, + "y": 5, + "kind": "worker_m", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 4, + "kind": "old_man_1", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 21, + "y": 3, + "kind": "scientist", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 22, + "y": 3, + "kind": "old_amber", + "flag": "FLAG_HIDE_OLD_AMBER", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 26, + "y": 4, + "kind": "scientist", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 26, + "y": 7, + "kind": "scientist", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} +)json"}, + {"PewterCity_Gym", R"json({ + "name": "PewterCity_Gym", + "width": 13, + "height": 16, + "tiles": [ + "#############", + "####.....####", + "#############", + "#....#.#....#", + "#...........#", + "#...#...#...#", + "#...........#", + "#..#.#.#.#..#", + "##.........##", + "#...#...#...#", + "##.........##", + "#...........#", + "#...S...S...#", + "#...........#", + "#.....v.....#", + "#############" + ], + "elevation": [ + "0000000000000", + "0000333330000", + "0000000000000", + "0333303033330", + "0333333333330", + "0333033303330", + "0333333333330", + "0330303030330", + "0033333333300", + "0333033303330", + "0033333333300", + "0333333333330", + "0333033303330", + "0333333333330", + "0333333333330", + "0000000000000" + ], + "warps": [ + { + "x": 5, + "y": 14, + "dest_map": "PewterCity", + "dest_warp": 2 + }, + { + "x": 6, + "y": 14, + "dest_map": "PewterCity", + "dest_warp": 2 + }, + { + "x": 7, + "y": 14, + "dest_map": "PewterCity", + "dest_warp": 2 + } + ], + "objects": [ + { + "x": 6, + "y": 5, + "kind": "brock", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 3, + "y": 8, + "kind": "camper", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 7, + "y": 12, + "kind": "gym_guy", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [ + { + "name": "brock_front", + "x": 6, + "y": 6 + } + ], + "flag_sets": [] +} +)json"}, + {"CeruleanCity_PokemonCenter_1F", R"json({ + "name": "CeruleanCity_PokemonCenter_1F", + "width": 15, + "height": 10, + "tiles": [ + "#.#############", + "###############", + "....###..##....", + "....#######....", + "...............", + "...............", + "#L.........##..", + "...........##..", + ".......v.......", + "###############" + ], + "elevation": [ + "030000000000000", + "000000000000000", + "333300033003333", + "333300000003333", + "333333333333333", + "330333333333333", + "044033333330033", + "330333333330033", + "333333333333333", + "000000000000000" + ], + "warps": [ + { + "x": 6, + "y": 8, + "dest_map": "CeruleanCity", + "dest_warp": 3 + }, + { + "x": 7, + "y": 8, + "dest_map": "CeruleanCity", + "dest_warp": 3 + }, + { + "x": 8, + "y": 8, + "dest_map": "CeruleanCity", + "dest_warp": 3 + }, + { + "x": 1, + "y": 6, + "dest_map": "", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 7, + "y": 2, + "kind": "nurse", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 5, + "kind": "gentleman", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 4, + "kind": "rocker", + "flag": "", + "wander_x": 1, + "wander_y": 0 + }, + { + "x": 4, + "y": 8, + "kind": "youngster", + "flag": "", + "wander_x": 1, + "wander_y": 0 + }, + { + "x": 3, + "y": 3, + "kind": "lass", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 1, + "kind": "0", + "flag": "FLAG_HIDE_POSTGAME_GOSSIPERS", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 3, + "y": 1, + "kind": "0", + "flag": "FLAG_HIDE_POSTGAME_GOSSIPERS", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [ + { + "name": "pc", + "x": 11, + "y": 2 + }, + { + "name": "nurse_front", + "x": 7, + "y": 4 + } + ], + "flag_sets": [] +} +)json"}, + {"CeruleanCity", R"json({ + "name": "CeruleanCity", + "width": 48, + "height": 40, + "tiles": [ + "################~~~~~#...#...#~~~~~~~~~~~~~~~~~~", + "################~~~~~#...#JJJ#~~~~~~~~~~~~~~~~~~", + "####~~~~~~~~~~~~~~~~~#...#...#~~~~~~~~~~~~~~~~~~", + "####~~~~~~~~~~~~~~~~~#...#...#~~~~~~~~~~~~~~~~~~", + "####~~~~~~~~~~~~~~~~~#...#...###################", + "####~~~###############...#...#.........#########", + "####~~~#.............#...#...#.........#########", + "####~~~#.............#...#...#.........#########", + "####~~~##.v.##########.......#.v.##...##########", + "####~~~###############......#######...##########", + "####~~~###############......#######...##########", + "####~~~###D######D####......##D####......#######", + "#C##~~~#..........................#......#######", + "....~~~#..........................#......#######", + "....~~~#..........................#......#######", + "....~~~#.....#######..............#......#######", + "~~~~~~~#...JJ############.........#......#......", + "~~~~~~~#.....##D#########.........#......#######", + "~~~~~~~#............#####JJJ#######.............", + "########............SSD##...#######.............", + "............................#######JJJ#..#######", + "...........................S..#D#.....#..#......", + "......................................#..#######", + "#######...............................#..#######", + "#######.....####......................#..#######", + "#######....#####....S.................#..#######", + "#######....#####.....###############..#..#######", + "#######....#####.....###############..#..#######", + "#######....S#CC#.....##D###SSD######..#..#######", + "#######...............................#..#######", + "#######...............................#..#######", + "#######...............................#..#######", + "###################S######.############..#######", + "#######..................................#######", + "#######..................................#######", + "###############....#........#....###############", + "###############....#JJJJJJJJ#....###############", + "###############....#........#....###############", + "###############....#........#....###############", + "###############....#........#....###############" + ], + "elevation": [ + "000000000000000011111033303330100000000000000000", + "000000000000000011111033300000100000000000000000", + "000011111111111111111033303330100000000000000000", + "000011111111111111111033303330111111111111111111", + "000011111111111111111033303330000000000000000000", + "000011100000000000000033303330333333333000000000", + "000011103333333333333033303330333333333000000000", + "000011103333333333333033303330333333333000000000", + "000011100333000000000033333330333003330000000000", + "000011100000000000000033333300000003330000000000", + "000011100000000000000033333300000003330000000000", + "000011100000000000000033333300000003333330000000", + "030011103333333333333333333333333303333330000000", + "333311103333333333333333333333333303333330000000", + "333311103333333333333333333333333303333330000000", + "333311103333300000003333333333333303333330000000", + "111111103330000000000000033333333303333330333333", + "111111103333300000000000033333333303333330000000", + "111111103333333333330000000000000003333333333333", + "000000003333333333330000033300000003333333333333", + "333333333333333333333333333300000000000330000000", + "333333333333333333333333333033000333330330333333", + "333333333333333333333333333333333333330330000000", + "000000033333333333333333333333333333330330000000", + "000000033333000033333333333333333333330330000000", + "000000033330000033330333333333333333330330000000", + "000000033330000033333000000000000000330330000000", + "000000033330000033333000000000000000330330000000", + "000000033330033033333000000000000000330330000000", + "000000033333333333333333333333333333330330000000", + "000000033333333333333333333333333333330330000000", + "000000033333333333333333333333333333330330000000", + "000000000000000000000000003000000000000330000000", + "000000033333333333333333333333333333333330000000", + "000000033333333333333333333333333333333330000000", + "000000000000000333303333333303333000000000000000", + "000000000000000333300000000003333000000000000000", + "000000000000000333303333333303333000000000000000", + "000000000000000333303333333303333000000000000000", + "000000000000000333303333333303333000000000000000" + ], + "warps": [ + { + "x": 10, + "y": 11, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 30, + "y": 11, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 15, + "y": 17, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 22, + "y": 19, + "dest_map": "CeruleanCity_PokemonCenter_1F", + "dest_warp": 1 + }, + { + "x": 31, + "y": 21, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 13, + "y": 28, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 29, + "y": 28, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 1, + "y": 12, + "dest_map": "CeruleanCave_1F", + "dest_warp": 0 + }, + { + "x": 10, + "y": 8, + "dest_map": "", + "dest_warp": 3 + }, + { + "x": 31, + "y": 8, + "dest_map": "", + "dest_warp": 3 + }, + { + "x": 31, + "y": 9, + "dest_map": "", + "dest_warp": 3 + }, + { + "x": 14, + "y": 28, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 23, + "y": 28, + "dest_map": "", + "dest_warp": 0 + }, + { + "x": 17, + "y": 11, + "dest_map": "", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 31, + "y": 12, + "kind": "policeman", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 6, + "kind": "rocket_m", + "flag": "FLAG_HIDE_CERULEAN_ROCKET", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 16, + "y": 21, + "kind": "little_boy", + "flag": "", + "wander_x": 0, + "wander_y": 3 + }, + { + "x": 9, + "y": 23, + "kind": "balding_man", + "flag": "", + "wander_x": 1, + "wander_y": 1 + }, + { + "x": 32, + "y": 29, + "kind": "slowbro", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 29, + "kind": "lass", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 34, + "y": 22, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 22, + "y": 0, + "kind": "blue", + "flag": "FLAG_HIDE_CERULEAN_RIVAL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 26, + "y": 32, + "kind": "cut_tree", + "flag": "FLAG_TEMP_13", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 50, + "y": 18, + "kind": "cut_tree", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 30, + "kind": "woman_1", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 1, + "y": 13, + "kind": "cooltrainer_m", + "flag": "FLAG_HIDE_CERULEAN_CAVE_GUARD", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "north", + "offset": 12, + "map": "Route24" + } + ], + "points": [], + "flag_sets": [ + { + "name": "after_hall_of_fame", + "flags": [ + "FLAG_HIDE_CERULEAN_CAVE_GUARD", + "FLAG_HIDE_CERULEAN_RIVAL", + "FLAG_HIDE_CERULEAN_ROCKET" + ] + } + ] +} +)json"}, + {"Route24", R"json({ + "name": "Route24", + "width": 24, + "height": 40, + "tiles": [ + "########################", + "########################", + "########################", + "####.........J...J......", + "####.........J...J......", + "####.........J...J......", + "###JJJJ..JJJJ#...#JJJJJJ", + "###.....................", + "###.....................", + "###.....................", + "###..........###########", + "###..........#..........", + "###..........#...#######", + "###..........#...#######", + "###..........#...#######", + "###..........#...#######", + "###...~~~#...#...#######", + "###...~~~#...#...#######", + "###...~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#~~~~~~", + "###\"\"\"~~~#...#...#~~~~~~", + "###\"\"\"~~~#...#...#~~~~~~", + "###\"\"\"~~~#...#...#~~~~~~", + "###\"\"\"~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~" + ], + "elevation": [ + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000033333333303330333333", + "000033333333303330333333", + "000033333333303330333333", + "000000033000003330000000", + "000333333333333333333333", + "000333333333333333333333", + "000333333333333333333333", + "000333333333300000000000", + "000333333333303333333333", + "000333333333303330000000", + "000333333333303330000000", + "000333333333303330000000", + "000333333333303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330111111", + "000333111033303330100000", + "000333111033303330100000", + "000333111033303330100000", + "000333111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000" + ], + "warps": [], + "objects": [ + { + "x": 12, + "y": 15, + "kind": "man", + "flag": "FLAG_HIDE_NUGGET_BRIDGE_ROCKET", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 19, + "kind": "camper", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 22, + "kind": "lass", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 25, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 28, + "kind": "lass", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 31, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 21, + "kind": "camper", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 11, + "y": 4, + "kind": "item_ball", + "flag": "FLAG_HIDE_ROUTE24_TM45", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "south", + "offset": -12, + "map": "CeruleanCity" + } + ], + "points": [], + "flag_sets": [] +} +)json"}, + {"CeruleanCave_1F", R"json({ + "name": "CeruleanCave_1F", + "width": 40, + "height": 23, + "tiles": [ + "########################################", + "#######...##.#########~~~~~~~~~#..##..##", + "#######...L..#########~~~~~~~~~#..L...##", + "#######..##..#~~~~~~~~~~~~~~~~~#......##", + "##L####..##..#~~~~~~~~~~#...#~~##.######", + "##.#.........#~~~~~~~~~~#...#~~~~~~~~~~#", + "#..#....##...#~~~#..........#~~~~~~~~~~#", + "#L.#....##...#~~~#..........#~~~~~~~~~~#", + "#..#....##...#~~~#.................#~~~#", + "####....##.###~~~#...######...#....#~~~#", + "##.#....#~~~##~~~#...##.####..L....#~~~#", + "##......#~~~##~~~##.###.L.##.......#~~~#", + "##......#~~~~~~~~#....#...##...#####~~~#", + "##......#~~~~~~~~#..#.##.###...###.....#", + "##..##..#~~~~~~~~#.........#...#.......#", + "##..#L..#~~~#....##......###...#.....###", + "##......#...#....####...####...#...#####", + "##......#...#..................#...#####", + "#####.###...##.#...............#...#####", + "#####..........#...............#...#####", + "#####..........#...............#...#####", + "#####..........#################.v.#####", + "########################################" + ], + "elevation": [ + "0000000000000000000000000000000000000000", + "0000000333003000000000111111111033003300", + "0000000333333000000000111111111033333300", + "0000000330033011111111111111111033333300", + "0030000330033011111111110444011003000000", + "0030333333333011111111110444011111111110", + "0330333300333011104444444444011111111110", + "0330333300333011104444444444011111111110", + "0330333300333011104444444444444444401110", + "0000333300300011104440000004440444401110", + "0030333301110011104440030000444444401110", + "0033333301110011100000033300444444401110", + "0033333301111111103333033300444000001110", + "0033333301111111103303003000444000333330", + "0033003301111111103333333330444033333330", + "0033033301110444400333333000444033333000", + "0033333303330444400003330000444033300000", + "0033333303330444444444444444444033300000", + "0000030003330000444444444444444033300000", + "0000033333333330444444444444444033300000", + "0000033333333330444444444444444033300000", + "0000033333333330000000000000000033300000", + "0000000000000000000000000000000000000000" + ], + "warps": [ + { + "x": 33, + "y": 21, + "dest_map": "CeruleanCity", + "dest_warp": 7 + }, + { + "x": 34, + "y": 2, + "dest_map": "CeruleanCave_2F", + "dest_warp": 0 + }, + { + "x": 1, + "y": 7, + "dest_map": "CeruleanCave_B1F", + "dest_warp": 0 + }, + { + "x": 10, + "y": 2, + "dest_map": "CeruleanCave_2F", + "dest_warp": 1 + }, + { + "x": 5, + "y": 15, + "dest_map": "CeruleanCave_2F", + "dest_warp": 2 + }, + { + "x": 30, + "y": 10, + "dest_map": "CeruleanCave_2F", + "dest_warp": 3 + }, + { + "x": 24, + "y": 11, + "dest_map": "CeruleanCave_2F", + "dest_warp": 4 + }, + { + "x": 2, + "y": 4, + "dest_map": "CeruleanCave_2F", + "dest_warp": 5 + } + ], + "objects": [ + { + "x": 7, + "y": 3, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_1F_NUGGET", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 11, + "y": 16, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_1F_FULL_RESTORE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 25, + "y": 5, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_1F_MAX_ELIXIR", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 7, + "y": 21, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_12", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 13, + "y": 21, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_13", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 20, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_14", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 14, + "y": 20, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_15", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 11, + "y": 21, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_16", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 9, + "y": 18, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_17", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [ + { + "name": "entrance", + "x": 33, + "y": 21 + } + ], + "flag_sets": [] +} +)json"}, + {"CeruleanCave_2F", R"json({ + "name": "CeruleanCave_2F", + "width": 40, + "height": 23, + "tiles": [ + "########################################", + "########################################", + "########################################", + "####....####..##.....#............######", + "#######......L#..###.#.#########.L######", + "####..####.####.##.#.#.........#########", + "####.L...#.........###########....######", + "#######.############.........####.######", + "####.#...............#######....#.######", + "####.#################..#.L###.##.######", + "####.#....#............L#...#...#.######", + "####.#.##.#.#####.#######.#####.#.######", + "####.#..#.#.....#.......#.....#.#.######", + "####.#..#.#####.#######.#####.#.########", + "####.#.L#.#.....#.....#.....#.#.#.######", + "####.####.#.#####.###.#.#.#.#.#.#.######", + "####.#....#.........#.#.#.#.#.#.#.######", + "####.#.####.#########.#.#.#.###.#.######", + "####.#....#.....#.....#.#.#.....#.######", + "####.############.#####.#.#######.######", + "####..............#.....#.........######", + "########################################", + "########################################" + ], + "elevation": [ + "0000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000", + "0000333300003300333330333333333333000000", + "0000000333333303300030300000000033000000", + "0000330000300003003030333333333000000000", + "0000333330333333333000000000003333000000", + "0000000300000000000033333333300003000000", + "0000303333333333333330000000333303000000", + "0000300000000000000000330330003003000000", + "0000303333033333333333330333033303000000", + "0000303003030000030000000300000303000000", + "0000303303033333033333330333330303000000", + "0000303303000003000000030000030300000000", + "0000303303033333033333033333030303000000", + "0000300003030000030003030303030303000000", + "0000303333033333333303030303030303000000", + "0000303000030000000003030303000303000000", + "0000303333033333033333030303333303000000", + "0000300000000000030000030300000003000000", + "0000333333333333330333330333333333000000", + "0000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000" + ], + "warps": [ + { + "x": 33, + "y": 4, + "dest_map": "CeruleanCave_1F", + "dest_warp": 1 + }, + { + "x": 13, + "y": 4, + "dest_map": "CeruleanCave_1F", + "dest_warp": 3 + }, + { + "x": 7, + "y": 14, + "dest_map": "CeruleanCave_1F", + "dest_warp": 4 + }, + { + "x": 26, + "y": 9, + "dest_map": "CeruleanCave_1F", + "dest_warp": 5 + }, + { + "x": 23, + "y": 10, + "dest_map": "CeruleanCave_1F", + "dest_warp": 6 + }, + { + "x": 5, + "y": 6, + "dest_map": "CeruleanCave_1F", + "dest_warp": 7 + } + ], + "objects": [ + { + "x": 9, + "y": 18, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_2F_PP_UP", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 29, + "y": 16, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_2F_ULTRA_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 12, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_2F_FULL_RESTORE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 10, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_12", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 9, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_13", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 25, + "y": 11, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_14", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 28, + "y": 20, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_15", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 30, + "y": 20, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_16", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 9, + "y": 13, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_17", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 23, + "y": 16, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_18", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 13, + "y": 6, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_19", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 12, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_1A", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 20, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_1B", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} +)json"}, + {"CeruleanCave_B1F", R"json({ + "name": "CeruleanCave_B1F", + "width": 40, + "height": 23, + "tiles": [ + "########################################", + "##..............##.....############....#", + "##..............#........#######.......#", + "##..............#..####.....#######....#", + "##......#####.###..####.....#######....#", + "##......#..........########.#######.#..#", + "##..##..##........#########............#", + "##..#L..###......##########............#", + "##......#~~~~~##................#...####", + "#########~~~~~##................#...####", + "#~~~############................#...####", + "#~~~##############.########.###.#...####", + "#~~~#.#.#.########........#.###.#...####", + "#~~~#.....########........#.....#...####", + "#~~~#.....########........#.....#...####", + "#~~~###.###~~~~#......#...#.###.#...####", + "#~~~~~~~~~~~~~~#......#...#.###.#...####", + "#~~~~~~~~~~~~~~#......#...#.....#...####", + "#~~~~~~~~~~~~~~#......#...#.....#...####", + "######~~~~~~~~~##.##.##...###.###...####", + "######~~~~~~~~~~~~#.......###.......####", + "######~~~~~~~~~~~~##.....####.......####", + "########################################" + ], + "elevation": [ + "0000000000000000000000000000000000000000", + "0033333333333333003333300000000000033330", + "0033333333333333033333333000000033333330", + "0033333333333333033000033333000000033330", + "0033333300000300033000033333000000033330", + "0033333303333333333000000003000000030330", + "0033003300333333330000000003333333333330", + "0033033300033333300000000003333333333330", + "0033333301111100444444444444444403330000", + "0000000001111100444444444444444403330000", + "0111000000000000444444444444444403330000", + "0111000000000000000000000004000403330000", + "0111030303000000003333333304000403330000", + "0111033333000000003333333304444403330000", + "0111033333000000003333333304444403330000", + "0111000300011110444444033304000403330000", + "0111111111111110444444033304000403330000", + "0111111111111110444444033304444403330000", + "0111111111111110404444033304444403330000", + "0000001111111110030000033300000003330000", + "0000001111111111110333333300033333330000", + "0000001111111111110033333000033333330000", + "0000000000000000000000000000000000000000" + ], + "warps": [ + { + "x": 5, + "y": 7, + "dest_map": "CeruleanCave_1F", + "dest_warp": 2 + } + ], + "objects": [ + { + "x": 31, + "y": 9, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_B1F_ULTRA_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 32, + "y": 2, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_B1F_MAX_REVIVE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 7, + "y": 12, + "kind": "mewtwo", + "flag": "FLAG_HIDE_MEWTWO", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 37, + "y": 1, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_12", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 38, + "y": 2, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_13", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 35, + "y": 1, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_14", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 37, + "y": 4, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_15", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 35, + "y": 5, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_16", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 2, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_17", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 1, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_18", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 6, + "y": 1, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_19", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 3, + "y": 4, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_1A", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [ + { + "name": "mewtwo", + "x": 7, + "y": 12 + } + ], + "flag_sets": [] +} +)json"}, + }; + return MAPS; +} + +std::vector test_overworld_maps(const std::set& set_flags){ + static const std::vector ALL = []{ + std::vector maps; + for (const auto& item : overworld_map_json()){ + maps.push_back(parse_map(item.second, item.first + " (test data)")); + if (maps.back().name != item.first){ + throw ParseException(item.first + " (test data): name is \"" + maps.back().name + "\"."); + } + } + return maps; + }(); + std::vector maps = ALL; + for (MapData& map : maps){ + hide_objects(map, set_flags); + } + return maps; +} + + + +} +} +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.h new file mode 100644 index 0000000000..e392c38a8b --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.h @@ -0,0 +1,38 @@ +/* Overworld Maps Test Data + * + * From: https://github.com/PokemonAutomation/ + * + * The FRLG maps compiled into the program, for tests: CI runs without the + * map files in Packages. PokemonFRLG_OverworldMapsTestData.cpp holds the + * same JSON as the files in Resources/PokemonFRLG/Maps, written by + * devtools/maps/frlg_maps.py --cpp, which also checks it (--check). + * + */ + +#ifndef PokemonAutomation_PokemonFRLG_OverworldMapsTestData_H +#define PokemonAutomation_PokemonFRLG_OverworldMapsTestData_H + +#include +#include +#include +#include +#include "PokemonFRLG_OverworldMaps.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + + +// Every map's name and JSON text, as in its file in Packages. +const std::vector>& overworld_map_json(); + +// overworld_maps(), read from overworld_map_json() rather than from the +// files. Throws ParseException as parse_map(). +std::vector test_overworld_maps(const std::set& set_flags = {}); + + + +} +} +} +#endif diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp index 25c1d40b1e..461c5b83b2 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp @@ -11,6 +11,7 @@ #include "Common/Cpp/TestRunners/UnitTest.h" #include "Pokemon/Navigation/Pokemon_LegPlanner.h" #include "PokemonFRLG_OverworldMaps.h" +#include "PokemonFRLG_OverworldMapsTestData.h" #include "PokemonFRLG_OverworldRoute.h" namespace PokemonAutomation{ @@ -421,9 +422,6 @@ class Test_OverworldRoute : public UnitTest{ virtual UnitTestResult run(Logger&, CancellableScope&) const override{ try{ return m_body(); - }catch (FileException& e){ - // CI runs with upstream Packages, which may not have the maps yet. - return UnitTestResult(UnitTestResult::SKIPPED, "Map files not found: " + e.message()); }catch (Exception& e){ return std::string(e.name()) + ": " + e.message(); } @@ -481,7 +479,7 @@ UnitTestResult test_step_rules(){ // The maps after the Hall of Fame, which clears the way to Cerulean Cave. std::vector post_game_maps(){ - return overworld_maps(map_flag_set(overworld_maps(), "after_hall_of_fame")); + return test_overworld_maps(map_flag_set(test_overworld_maps(), "after_hall_of_fame")); } MapPosition point_on(const std::vector& maps, const std::string& map, const std::string& point){ @@ -511,7 +509,7 @@ UnitTestResult test_maps(){ if (object_at(*city, {1, 13}) != nullptr){ return "The cave guard is still there after the Hall of Fame."; } - if (object_at(*map_named(overworld_maps(), "CeruleanCity"), {1, 13}) == nullptr){ + if (object_at(*map_named(test_overworld_maps(), "CeruleanCity"), {1, 13}) == nullptr){ return "The cave guard is missing before the Hall of Fame."; } return true; @@ -591,7 +589,7 @@ UnitTestResult test_pokemon_center_to_mewtwo(){ UnitTestResult test_cave_guard_blocks(){ // Before the Hall of Fame the guard stands in the cave entrance. - const std::vector maps = overworld_maps(); + const std::vector maps = test_overworld_maps(); if (plan_overworld_route(maps, point_on(maps, "CeruleanCity_PokemonCenter_1F", "pc"), facing_mewtwo(maps))){ return "Planned past the cave guard."; } @@ -612,7 +610,7 @@ UnitTestResult test_mewtwo_tile_unreachable(){ } UnitTestResult test_story_maps(){ - const std::vector maps = overworld_maps(); + const std::vector maps = test_overworld_maps(); for (const char* name : { "PalletTown_PlayersHouse_2F", "PalletTown_ProfessorOaksLab", "Route1", "ViridianCity_Mart", "Route22", "Route2", "ViridianForest", "PewterCity", "PewterCity_Museum_1F", "PewterCity_Gym", @@ -636,7 +634,7 @@ std::vector maps_warped_into(const std::vector& route){ } UnitTestResult test_bedroom_to_oaks_lab(){ - const std::vector maps = overworld_maps(); + const std::vector maps = test_overworld_maps(); std::vector route; UnitTestResult result = check_route( maps, point_on(maps, "PalletTown_PlayersHouse_2F", "start"), @@ -653,7 +651,7 @@ UnitTestResult test_bedroom_to_oaks_lab(){ } UnitTestResult test_viridian_mart_to_pewter_gym(){ - const std::vector maps = overworld_maps(); + const std::vector maps = test_overworld_maps(); std::vector route; UnitTestResult result = check_route( maps, point_on(maps, "ViridianCity_Mart", "clerk_front"), @@ -709,7 +707,7 @@ UnitTestResult test_no_hold_into_sign(){ // No wild battle can start between the bedroom and Oak's Lab: Pallet Town's // streets have no tall grass. Route 2 and Viridian Forest do. UnitTestResult test_wild_steps(){ - const std::vector maps = overworld_maps(); + const std::vector maps = test_overworld_maps(); std::vector route; UnitTestResult result = check_route( maps, point_on(maps, "PalletTown_PlayersHouse_2F", "start"), diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 00cc9806ae..33270be43d 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1766,6 +1766,8 @@ file(GLOB LIBRARY_SOURCES Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMap.h Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.h + Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.cpp + Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.h Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps_Tests.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.h From b3c74141ded512037504cfa40168614c7ccc914c Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 09:34:42 -0800 Subject: [PATCH 04/16] FRLG: count a leg's grass on every map it crosses A leg's wild flag was worked out from the tiles on its start map only, so "north 22" from Pallet Town, through Route 1's grass beyond the map's edge, was walked without watching for battles (console B, 2026-11-01). It now comes from the planner's per-step wild flag (#114), set on tall grass and water. The wild-steps route test checks that leg. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../Overworld/PokemonFRLG_OverworldRoute.cpp | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp index 461c5b83b2..bd61217a89 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp @@ -272,6 +272,10 @@ class StepModel{ } if (is_tall_grass(m_maps[step.next.map], step.next.state.position)){ step.extra_cost += route_cost(m_costs, RouteCost::GRASS_TILE); + step.wild = true; + } + if (step.next.state.surfing){ + step.wild = true; } return step; } @@ -315,15 +319,10 @@ RouteStep to_route_step(const std::vector& maps, const Pokemon::Leg 14 && !step.wild){ + return "Expected the leg from Pallet Town onto Route 1 to be wild, got " + to_string(step) + ":" + describe(route); } } - return "Expected a wild step in Viridian Forest:" + describe(route); + return true; } const char* const TEST_ROOM_JSON = R"({ From bf5618e4d280d1d2df9ccc7e67828174e9f25263 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 09:35:24 -0800 Subject: [PATCH 05/16] FRLG: never plan a hold into a ledge A leg to a wall is held two tiles longer than it takes, so a ledge the plan took for a wall was hopped: in Viridian City "south 2 (to wall)" from the Pokemon Center ended on (26, 31), below the ledge, not on (26, 29), and every later leg was off (console B, 2026-11-01). The maps don't record which way a ledge faces, so a leg now never ends held into any ledge; it counts its tiles instead. Tested on a small yard and on Viridian City. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../Overworld/PokemonFRLG_OverworldRoute.cpp | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp index bd61217a89..1f6ee6600d 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp @@ -208,8 +208,8 @@ std::optional press(const std::vector& maps, const Located& return transition; } -// Whether holding `direction` stops the player where they are: a wall, a -// ledge, or water they'd need to Surf onto. A leg that ends there can be +// Whether holding `direction` stops the player where they are: a wall, or +// water they'd need to Surf onto. A leg that ends there can be // held for longer than it takes, and walked again after an interruption. A // person in the way doesn't count, since they may have wandered off, and // neither does an edge to a map that isn't loaded. @@ -226,6 +226,13 @@ bool stops_at(const std::vector& maps, const Located& player, Direction if (tile_at(map, ahead) == Tile::SIGN && (direction == Direction::NORTH || direction == Direction::SOUTH)){ return false; } + // Held into a ledge the way it faces, the player hops down it (console + // B, 2026-11-01, Viridian City: "south 2 (to wall)" from the Pokemon + // Center hopped the ledge two rows down). The maps don't keep which way + // a ledge faces, so none is held into. + if (is_ledge(map, ahead)){ + return false; + } if (in_bounds(map, ahead)){ return object_at(map, ahead) == nullptr; } @@ -700,6 +707,44 @@ UnitTestResult test_no_hold_into_sign(){ return true; } +// A yard with a row of ledges across it. +const char* const TEST_LEDGE_YARD_JSON = R"({ + "name": "LedgeYard", "width": 5, "height": 6, + "tiles": ["#####", "#...#", "#...#", "#JJJ#", "#...#", "#####"], + "elevation": ["33333", "33333", "33333", "33333", "33333", "33333"], + "warps": [], "objects": [], + "connections": [], "points": [], "flag_sets": [] +})"; + +// A ledge isn't a wall to hold into: moving the way it faces the player +// would hop it, and the maps don't say which way that is. Viridian City, +// from the Pokemon Center's door south to the row above the ledge. +UnitTestResult test_no_hold_into_ledge(){ + const std::vector maps{parse_map(TEST_LEDGE_YARD_JSON, "LedgeYard")}; + std::vector route; + UnitTestResult result = check_route(maps, {"LedgeYard", {2, 1}}, {{"LedgeYard", {2, 2}}, std::nullopt}, route); + if (result.result != UnitTestResult::PASSED){ + return result; + } + for (const RouteStep& step : route){ + if (step.to_wall){ + return "Expected no hold into the ledge:" + describe(route); + } + } + route.clear(); + const std::vector world = test_overworld_maps(); + result = check_route(world, {"ViridianCity", {26, 27}}, {{"ViridianCity", {26, 29}}, std::nullopt}, route); + if (result.result != UnitTestResult::PASSED){ + return result; + } + for (const RouteStep& step : route){ + if (step.to_wall && step.end.point == TilePos{26, 29}){ + return "Expected no hold into the ledge below the Pokemon Center:" + describe(route); + } + } + return true; +} + // Two small maps that don't need the map files: a room left by the exit mat // at its bottom, onto the door of a yard, out of which the game walks the // player. @@ -797,6 +842,7 @@ void add_tests_OverworldRoute(UnitTestDatabase& database){ database.add("Viridian Mart to Pewter Gym", test_viridian_mart_to_pewter_gym); database.add("wild steps", test_wild_steps); database.add("no hold into a sign", test_no_hold_into_sign); + database.add("no hold into a ledge", test_no_hold_into_ledge); database.add("step rules", test_step_rules); database.add("maps", test_maps); database.add("Cerulean Cave entrance to Mewtwo", test_entrance_to_mewtwo); From b8db75455a13efb64a66c7de223998fd6cae66e8 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 09:35:43 -0800 Subject: [PATCH 06/16] FRLG: wait out a late-seen battle after each leg through grass Run 7 on console B (2026-11-01, Route 1) lost a whole leg twice. A battle on a leg's last grass step had its flashes missed; its "Wild ... appeared!" showed 3.7s after that press, by which time the next leg, off the grass and so not watched for battles, had been walked into the battle without moving the player. After a leg through grass the walker now watches 3.5s, not 0.5s, for a battle before the next leg, and a battle seen only by its dialog is placed 3.7s back, as measured, not 2s. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../Overworld/PokemonFRLG_OverworldWalk.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp index 8bd824eb9e..36a9599048 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp @@ -45,6 +45,12 @@ constexpr Milliseconds AFTER_WARP = 1500ms; // A message set off by a leg's last step shows after the hold ends. Caught // here, before the next leg's turn tap, which the message would swallow. constexpr Milliseconds AFTER_LEG_WATCH = 500ms; +// The same after a leg through grass. A battle whose flashes are missed is +// seen only by its "Wild appeared!", 3.7s after its step's press +// (twice on Route 1, console B, 2026-11-01, run 7). Unless the walker waits +// that long, the next leg is walked into the battle and lost: there, "east +// 4" and "west 4". +constexpr Milliseconds AFTER_WILD_LEG_WATCH = 3500ms; // After a message closes: a trainer who saw the player speaks first, then // the battle starts, with " would like to battle!" seconds later. constexpr Milliseconds TRAINER_BATTLE_WATCH = 6000ms; @@ -80,9 +86,11 @@ class LateWildBattleInterrupt : public WildBattleInterrupt{ virtual std::unique_ptr make_watcher() const override{ return std::make_unique(COLOR_RED); } - // The flashes, the wipe and the opening animation. Not calibrated yet. + // The flashes, the wipe and the opening animation: 3.7s after the step's + // press, twice on Route 1 (console B, 2026-11-01). Other maps open + // battles with other wipes, so elsewhere this is a guess. virtual Milliseconds detection_delay() const override{ - return 2000ms; + return 3700ms; } }; @@ -350,7 +358,10 @@ void walk_overworld_route( break; } if (step.action != RouteAction::FACE){ - Pokemon::clear_late_interrupts(console, context, step.wild ? interrupts.wild : interrupts.other, AFTER_LEG_WATCH, MAX_INTERRUPTIONS_PER_LEG); + Pokemon::clear_late_interrupts( + console, context, step.wild ? interrupts.wild : interrupts.other, + step.wild ? AFTER_WILD_LEG_WATCH : AFTER_LEG_WATCH, MAX_INTERRUPTIONS_PER_LEG + ); } facing = step.facing_after; } From 1797366090dfb6fc4979d5987f5655826bc91f5c Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 09:36:21 -0800 Subject: [PATCH 07/16] FRLG: tell a warp's fade from a wild battle's, by its battle screen In run 7 (console B, 2026-11-01) the player had drifted onto Route 1's grass, and the step meant for Oak's Lab's door set off a wild battle. Its flashes and wipe passed for the warp's fade, and the route went on as if inside. After a warp's fade the walker now watches 5s for a battle screen; if one shows, it flees and fails with "a wild battle, not the warp to ...: the player is off the route", for the caller to re-plan. A battle screen is BattleScreenDetector: the battle menu, or the battle text box together with an HP box. The text box alone also reads on the black below a small indoor map (Oak's Lab's mat, Viridian Forest's north gate), where the walker tried to flee battles that weren't there. The late-battle and trainer-battle watches use it too. The detector is moved here unchanged from #120 (ac1873bb7), where it was added for the story's battles. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../PokemonFRLG_BattleScreenDetector.cpp | 36 +++++++++++++ .../PokemonFRLG_BattleScreenDetector.h | 54 +++++++++++++++++++ .../Overworld/PokemonFRLG_OverworldWalk.cpp | 30 +++++++++-- SerialPrograms/cmake/SourceFiles.cmake | 2 + 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleScreenDetector.cpp create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleScreenDetector.h diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleScreenDetector.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleScreenDetector.cpp new file mode 100644 index 0000000000..a3ac1c9106 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleScreenDetector.cpp @@ -0,0 +1,36 @@ +/* Battle Screen Detector + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "PokemonFRLG_BattleScreenDetector.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + + +BattleScreenDetector::BattleScreenDetector(Color color) + : m_dialog(color) + , m_menu(color) + , m_opponent(color) + , m_player(color) +{} +void BattleScreenDetector::make_overlays(VideoOverlaySet& items) const{ + m_dialog.make_overlays(items); + m_opponent.make_overlays(items); + m_player.make_overlays(items); +} +bool BattleScreenDetector::detect(const ImageViewRGB32& screen){ + if (m_menu.detect(screen)){ + return true; + } + return m_dialog.detect(screen) && (m_opponent.detect(screen) || m_player.detect(screen)); +} + + + +} +} +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleScreenDetector.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleScreenDetector.h new file mode 100644 index 0000000000..ac4257c707 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleScreenDetector.h @@ -0,0 +1,54 @@ +/* Battle Screen Detector + * + * From: https://github.com/PokemonAutomation/ + * + * A battle on screen: the battle text box, and with it the opponent's HP + * box, the player's or the battle menu. The text box alone also reads on + * the black below a small indoor map (console B, 2026-11-01: Oak's Lab's + * mat, Viridian Forest's north gate). + * + */ + +#ifndef PokemonAutomation_PokemonFRLG_BattleScreenDetector_H +#define PokemonAutomation_PokemonFRLG_BattleScreenDetector_H + +#include +#include "Common/Cpp/Color.h" +#include "CommonFramework/ImageTypes/ImageViewRGB32.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "CommonTools/VisualDetector.h" +#include "VideoGames/PokemonFRLG/Inference/Dialogs/PokemonFRLG_BattleDialogs.h" +#include "VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattlePokemonDetector.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + + +class BattleScreenDetector : public StaticScreenDetector{ +public: + BattleScreenDetector(Color color = COLOR_RED); + + virtual void make_overlays(VideoOverlaySet& items) const override; + virtual bool detect(const ImageViewRGB32& screen) override; + +private: + BattleDialogDetector m_dialog; + BattleMenuDetector m_menu; + BattleOpponentDetector m_opponent; + BattlePokemonDetector m_player; +}; + +class BattleScreenWatcher : public DetectorToFinder{ +public: + BattleScreenWatcher(Color color = COLOR_RED) + : DetectorToFinder("BattleScreenWatcher", std::chrono::milliseconds(250), color) + {} +}; + + + +} +} +} +#endif diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp index 36a9599048..1ad6f1bed7 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp @@ -14,6 +14,7 @@ #include "VideoGames/PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h" #include "VideoGames/PokemonFRLG/Inference/Menus/PokemonFRLG_StartMenuDetector.h" #include "VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleFlashWatcher.h" +#include "VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleScreenDetector.h" #include "VideoGames/PokemonFRLG/PokemonFRLG_Navigation.h" #include "PokemonFRLG_PlayerFacingReader.h" #include "PokemonFRLG_OverworldWalk.h" @@ -42,6 +43,9 @@ constexpr Milliseconds SURF_ANIMATION = 3000ms; // on its own, and a leg started before that ends loses tiles (on the console a // 600ms wait cost 2 tiles). constexpr Milliseconds AFTER_WARP = 1500ms; +// After a warp's fade, which a wild battle's flashes and wipe can pass for: +// a battle's HP box shows within this long (console B, 2026-11-01). +constexpr Milliseconds AFTER_WARP_BATTLE_WATCH = 5000ms; // A message set off by a leg's last step shows after the hold ends. Caught // here, before the next leg's turn tap, which the message would swallow. constexpr Milliseconds AFTER_LEG_WATCH = 500ms; @@ -84,7 +88,7 @@ class LateWildBattleInterrupt : public WildBattleInterrupt{ return "a wild battle (seen late)"; } virtual std::unique_ptr make_watcher() const override{ - return std::make_unique(COLOR_RED); + return std::make_unique(COLOR_RED); } // The flashes, the wipe and the opening animation: 3.7s after the step's // press, twice on Route 1 (console B, 2026-11-01). Other maps open @@ -133,7 +137,7 @@ class MessageInterrupt : public OverworldInterrupt{ // A trainer's battle can't be fled, and the walker must not try (console // B, 2026-11-01, Viridian Forest): it stops here for the caller. static void check_no_trainer_battle(ConsoleHandle& console, ProControllerContext& context){ - BattleDialogWatcher battle(COLOR_RED); + BattleScreenWatcher battle(COLOR_RED); context.wait_for_all_requests(); if (wait_until(console, context, TRAINER_BATTLE_WATCH, {battle}) >= 0){ OperationFailedExceptionWithScreenshot::fire( @@ -232,6 +236,25 @@ void check_overworld(ConsoleHandle& console, ProControllerContext& context, cons } } +// After a warp's fade: fails, once the battle is fled, if it was a wild +// battle's. In run 7 (console B, 2026-11-01) the player had drifted onto +// Route 1's grass, and the step meant for Oak's Lab's door set off a +// battle; its flashes and wipe passed for the warp's fade, the route went +// on as if inside, and the next screen was the battle's FIGHT menu. +void check_warp_was_no_battle(ConsoleHandle& console, ProControllerContext& context, const RouteStep& step){ + BattleScreenWatcher battle(COLOR_RED); + context.wait_for_all_requests(); + if (wait_until(console, context, AFTER_WARP_BATTLE_WATCH, {battle}) < 0){ + return; + } + flee_battle(console, context); + OperationFailedExceptionWithScreenshot::fire( + ErrorReportMode::SEND_ERROR_REPORT, + "walk_overworld_route(): a wild battle, not the warp to " + step.end.map + ": the player is off the route.", + console + ); +} + void start_surf(ConsoleHandle& console, ProControllerContext& context, Direction direction, bool facing_water){ // "The water is a deep blue... Would you like to SURF?", with YES selected. // An A pressed while the player is still turning is lost. @@ -347,7 +370,8 @@ void walk_overworld_route( Pokemon::walk_leg(console, context, mover, step.wild ? interrupts.wild : interrupts.other, leg_spec(step), MAX_INTERRUPTIONS_PER_LEG); if (step.warps){ wait_out_warp(console, context, step); - pbf_wait(context, AFTER_WARP); + static_assert(AFTER_WARP_BATTLE_WATCH >= AFTER_WARP); + check_warp_was_no_battle(console, context, step); } break; case RouteAction::SURF: diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 33270be43d..0c8a8ba32d 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1734,6 +1734,8 @@ file(GLOB LIBRARY_SOURCES Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleFlashWatcher.h Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattlePokemonDetector.cpp Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattlePokemonDetector.h + Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleScreenDetector.cpp + Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleScreenDetector.h Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleSelectionArrowDetector.cpp Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleSelectionArrowDetector.h Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_DaycareManDetector.cpp From 910c460df9390e4d571ea7cbbad7a7c449395343 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 09:41:23 -0800 Subject: [PATCH 08/16] FRLG: the overworld maps as .json files in the repo, built into the program Overworld/Maps holds the 25 maps as frlg_maps.py writes them, the same files as Resources/PokemonFRLG/Maps in Packages (check them with `frlg_maps.py --out --check`). CMake builds their text into the program (pa_embed_text_files()), as overworld_map_json(), so tests can plan on them without Packages. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- SerialPrograms/CMakeLists.txt | 2 + .../Overworld/Maps/CeruleanCave_1F.json | 188 +++++++++++ .../Overworld/Maps/CeruleanCave_2F.json | 202 ++++++++++++ .../Overworld/Maps/CeruleanCave_B1F.json | 170 ++++++++++ .../Overworld/Maps/CeruleanCity.json | 291 +++++++++++++++++ .../Maps/CeruleanCity_PokemonCenter_1F.json | 127 ++++++++ .../Overworld/Maps/PalletTown.json | 110 +++++++ .../Maps/PalletTown_PlayersHouse_1F.json | 68 ++++ .../Maps/PalletTown_PlayersHouse_2F.json | 45 +++ .../Maps/PalletTown_ProfessorOaksLab.json | 142 ++++++++ .../Maps/PalletTown_RivalsHouse.json | 70 ++++ .../Overworld/Maps/PewterCity.json | 206 ++++++++++++ .../Overworld/Maps/PewterCity_Gym.json | 96 ++++++ .../Overworld/Maps/PewterCity_Mart.json | 76 +++++ .../Overworld/Maps/PewterCity_Museum_1F.json | 122 +++++++ .../Maps/PewterCity_PokemonCenter_1F.json | 122 +++++++ .../PokemonFRLG/Overworld/Maps/Route1.json | 122 +++++++ .../PokemonFRLG/Overworld/Maps/Route2.json | 303 ++++++++++++++++++ .../PokemonFRLG/Overworld/Maps/Route22.json | 90 ++++++ .../PokemonFRLG/Overworld/Maps/Route24.json | 165 ++++++++++ .../Route2_ViridianForest_NorthEntrance.json | 88 +++++ .../Route2_ViridianForest_SouthEntrance.json | 80 +++++ .../Overworld/Maps/ViridianCity.json | 214 +++++++++++++ .../Overworld/Maps/ViridianCity_Mart.json | 82 +++++ .../Maps/ViridianCity_PokemonCenter_1F.json | 98 ++++++ .../Overworld/Maps/ViridianForest.json | 278 ++++++++++++++++ .../Overworld/PokemonFRLG_OverworldTestMaps.h | 35 ++ SerialPrograms/cmake/SourceFiles.cmake | 1 + 28 files changed, 3593 insertions(+) create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_1F.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_2F.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_B1F.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCity.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCity_PokemonCenter_1F.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_1F.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_2F.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_ProfessorOaksLab.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_RivalsHouse.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Gym.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Mart.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Museum_1F.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_PokemonCenter_1F.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route1.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route22.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route24.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_NorthEntrance.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_SouthEntrance.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity_Mart.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity_PokemonCenter_1F.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianForest.json create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index d0966df32f..f9a9b0db5c 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -197,6 +197,8 @@ add_library(SerialProgramsLib STATIC ${CORE_LIBRARY_SOURCES} ${LIBRARY_SOURCES}) include(cmake/EmbedTextFiles.cmake) pa_embed_text_files(SerialProgramsLib Source/Pokemon/Navigation/TestMaps Pokemon/Navigation/Pokemon_Navigation_Tests.h PokemonAutomation::Pokemon navigation_test_map_json) +pa_embed_text_files(SerialProgramsLib Source/VideoGames/PokemonFRLG/Overworld/Maps + VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h PokemonAutomation::NintendoSwitch::PokemonFRLG overworld_map_json) # Create binary target diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_1F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_1F.json new file mode 100644 index 0000000000..71d6f98963 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_1F.json @@ -0,0 +1,188 @@ +{ + "name": "CeruleanCave_1F", + "width": 40, + "height": 23, + "tiles": [ + "########################################", + "#######...##.#########~~~~~~~~~#..##..##", + "#######...L..#########~~~~~~~~~#..L...##", + "#######..##..#~~~~~~~~~~~~~~~~~#......##", + "##L####..##..#~~~~~~~~~~#...#~~##.######", + "##.#.........#~~~~~~~~~~#...#~~~~~~~~~~#", + "#..#....##...#~~~#..........#~~~~~~~~~~#", + "#L.#....##...#~~~#..........#~~~~~~~~~~#", + "#..#....##...#~~~#.................#~~~#", + "####....##.###~~~#...######...#....#~~~#", + "##.#....#~~~##~~~#...##.####..L....#~~~#", + "##......#~~~##~~~##.###.L.##.......#~~~#", + "##......#~~~~~~~~#....#...##...#####~~~#", + "##......#~~~~~~~~#..#.##.###...###.....#", + "##..##..#~~~~~~~~#.........#...#.......#", + "##..#L..#~~~#....##......###...#.....###", + "##......#...#....####...####...#...#####", + "##......#...#..................#...#####", + "#####.###...##.#...............#...#####", + "#####..........#...............#...#####", + "#####..........#...............#...#####", + "#####..........#################.v.#####", + "########################################" + ], + "elevation": [ + "0000000000000000000000000000000000000000", + "0000000333003000000000111111111033003300", + "0000000333333000000000111111111033333300", + "0000000330033011111111111111111033333300", + "0030000330033011111111110444011003000000", + "0030333333333011111111110444011111111110", + "0330333300333011104444444444011111111110", + "0330333300333011104444444444011111111110", + "0330333300333011104444444444444444401110", + "0000333300300011104440000004440444401110", + "0030333301110011104440030000444444401110", + "0033333301110011100000033300444444401110", + "0033333301111111103333033300444000001110", + "0033333301111111103303003000444000333330", + "0033003301111111103333333330444033333330", + "0033033301110444400333333000444033333000", + "0033333303330444400003330000444033300000", + "0033333303330444444444444444444033300000", + "0000030003330000444444444444444033300000", + "0000033333333330444444444444444033300000", + "0000033333333330444444444444444033300000", + "0000033333333330000000000000000033300000", + "0000000000000000000000000000000000000000" + ], + "warps": [ + { + "x": 33, + "y": 21, + "dest_map": "CeruleanCity", + "dest_warp": 7 + }, + { + "x": 34, + "y": 2, + "dest_map": "CeruleanCave_2F", + "dest_warp": 0 + }, + { + "x": 1, + "y": 7, + "dest_map": "CeruleanCave_B1F", + "dest_warp": 0 + }, + { + "x": 10, + "y": 2, + "dest_map": "CeruleanCave_2F", + "dest_warp": 1 + }, + { + "x": 5, + "y": 15, + "dest_map": "CeruleanCave_2F", + "dest_warp": 2 + }, + { + "x": 30, + "y": 10, + "dest_map": "CeruleanCave_2F", + "dest_warp": 3 + }, + { + "x": 24, + "y": 11, + "dest_map": "CeruleanCave_2F", + "dest_warp": 4 + }, + { + "x": 2, + "y": 4, + "dest_map": "CeruleanCave_2F", + "dest_warp": 5 + } + ], + "objects": [ + { + "x": 7, + "y": 3, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_1F_NUGGET", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 11, + "y": 16, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_1F_FULL_RESTORE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 25, + "y": 5, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_1F_MAX_ELIXIR", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 7, + "y": 21, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_12", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 13, + "y": 21, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_13", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 20, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_14", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 14, + "y": 20, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_15", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 11, + "y": 21, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_16", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 9, + "y": 18, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_17", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [ + { + "name": "entrance", + "x": 33, + "y": 21 + } + ], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_2F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_2F.json new file mode 100644 index 0000000000..12acb62d1f --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_2F.json @@ -0,0 +1,202 @@ +{ + "name": "CeruleanCave_2F", + "width": 40, + "height": 23, + "tiles": [ + "########################################", + "########################################", + "########################################", + "####....####..##.....#............######", + "#######......L#..###.#.#########.L######", + "####..####.####.##.#.#.........#########", + "####.L...#.........###########....######", + "#######.############.........####.######", + "####.#...............#######....#.######", + "####.#################..#.L###.##.######", + "####.#....#............L#...#...#.######", + "####.#.##.#.#####.#######.#####.#.######", + "####.#..#.#.....#.......#.....#.#.######", + "####.#..#.#####.#######.#####.#.########", + "####.#.L#.#.....#.....#.....#.#.#.######", + "####.####.#.#####.###.#.#.#.#.#.#.######", + "####.#....#.........#.#.#.#.#.#.#.######", + "####.#.####.#########.#.#.#.###.#.######", + "####.#....#.....#.....#.#.#.....#.######", + "####.############.#####.#.#######.######", + "####..............#.....#.........######", + "########################################", + "########################################" + ], + "elevation": [ + "0000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000", + "0000333300003300333330333333333333000000", + "0000000333333303300030300000000033000000", + "0000330000300003003030333333333000000000", + "0000333330333333333000000000003333000000", + "0000000300000000000033333333300003000000", + "0000303333333333333330000000333303000000", + "0000300000000000000000330330003003000000", + "0000303333033333333333330333033303000000", + "0000303003030000030000000300000303000000", + "0000303303033333033333330333330303000000", + "0000303303000003000000030000030300000000", + "0000303303033333033333033333030303000000", + "0000300003030000030003030303030303000000", + "0000303333033333333303030303030303000000", + "0000303000030000000003030303000303000000", + "0000303333033333033333030303333303000000", + "0000300000000000030000030300000003000000", + "0000333333333333330333330333333333000000", + "0000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000" + ], + "warps": [ + { + "x": 33, + "y": 4, + "dest_map": "CeruleanCave_1F", + "dest_warp": 1 + }, + { + "x": 13, + "y": 4, + "dest_map": "CeruleanCave_1F", + "dest_warp": 3 + }, + { + "x": 7, + "y": 14, + "dest_map": "CeruleanCave_1F", + "dest_warp": 4 + }, + { + "x": 26, + "y": 9, + "dest_map": "CeruleanCave_1F", + "dest_warp": 5 + }, + { + "x": 23, + "y": 10, + "dest_map": "CeruleanCave_1F", + "dest_warp": 6 + }, + { + "x": 5, + "y": 6, + "dest_map": "CeruleanCave_1F", + "dest_warp": 7 + } + ], + "objects": [ + { + "x": 9, + "y": 18, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_2F_PP_UP", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 29, + "y": 16, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_2F_ULTRA_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 12, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_2F_FULL_RESTORE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 10, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_12", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 9, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_13", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 25, + "y": 11, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_14", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 28, + "y": 20, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_15", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 30, + "y": 20, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_16", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 9, + "y": 13, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_17", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 23, + "y": 16, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_18", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 13, + "y": 6, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_19", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 12, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_1A", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 20, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_1B", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_B1F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_B1F.json new file mode 100644 index 0000000000..58f72c3415 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_B1F.json @@ -0,0 +1,170 @@ +{ + "name": "CeruleanCave_B1F", + "width": 40, + "height": 23, + "tiles": [ + "########################################", + "##..............##.....############....#", + "##..............#........#######.......#", + "##..............#..####.....#######....#", + "##......#####.###..####.....#######....#", + "##......#..........########.#######.#..#", + "##..##..##........#########............#", + "##..#L..###......##########............#", + "##......#~~~~~##................#...####", + "#########~~~~~##................#...####", + "#~~~############................#...####", + "#~~~##############.########.###.#...####", + "#~~~#.#.#.########........#.###.#...####", + "#~~~#.....########........#.....#...####", + "#~~~#.....########........#.....#...####", + "#~~~###.###~~~~#......#...#.###.#...####", + "#~~~~~~~~~~~~~~#......#...#.###.#...####", + "#~~~~~~~~~~~~~~#......#...#.....#...####", + "#~~~~~~~~~~~~~~#......#...#.....#...####", + "######~~~~~~~~~##.##.##...###.###...####", + "######~~~~~~~~~~~~#.......###.......####", + "######~~~~~~~~~~~~##.....####.......####", + "########################################" + ], + "elevation": [ + "0000000000000000000000000000000000000000", + "0033333333333333003333300000000000033330", + "0033333333333333033333333000000033333330", + "0033333333333333033000033333000000033330", + "0033333300000300033000033333000000033330", + "0033333303333333333000000003000000030330", + "0033003300333333330000000003333333333330", + "0033033300033333300000000003333333333330", + "0033333301111100444444444444444403330000", + "0000000001111100444444444444444403330000", + "0111000000000000444444444444444403330000", + "0111000000000000000000000004000403330000", + "0111030303000000003333333304000403330000", + "0111033333000000003333333304444403330000", + "0111033333000000003333333304444403330000", + "0111000300011110444444033304000403330000", + "0111111111111110444444033304000403330000", + "0111111111111110444444033304444403330000", + "0111111111111110404444033304444403330000", + "0000001111111110030000033300000003330000", + "0000001111111111110333333300033333330000", + "0000001111111111110033333000033333330000", + "0000000000000000000000000000000000000000" + ], + "warps": [ + { + "x": 5, + "y": 7, + "dest_map": "CeruleanCave_1F", + "dest_warp": 2 + } + ], + "objects": [ + { + "x": 31, + "y": 9, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_B1F_ULTRA_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 32, + "y": 2, + "kind": "item_ball", + "flag": "FLAG_HIDE_CERULEAN_CAVE_B1F_MAX_REVIVE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 7, + "y": 12, + "kind": "mewtwo", + "flag": "FLAG_HIDE_MEWTWO", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 37, + "y": 1, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_12", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 38, + "y": 2, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_13", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 35, + "y": 1, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_14", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 37, + "y": 4, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_15", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 35, + "y": 5, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_16", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 2, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_17", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 1, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_18", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 6, + "y": 1, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_19", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 3, + "y": 4, + "kind": "rock_smash_rock", + "flag": "FLAG_TEMP_1A", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [ + { + "name": "mewtwo", + "x": 7, + "y": 12 + } + ], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCity.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCity.json new file mode 100644 index 0000000000..af06b3db98 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCity.json @@ -0,0 +1,291 @@ +{ + "name": "CeruleanCity", + "width": 48, + "height": 40, + "tiles": [ + "################~~~~~#...#...#~~~~~~~~~~~~~~~~~~", + "################~~~~~#...#JJJ#~~~~~~~~~~~~~~~~~~", + "####~~~~~~~~~~~~~~~~~#...#...#~~~~~~~~~~~~~~~~~~", + "####~~~~~~~~~~~~~~~~~#...#...#~~~~~~~~~~~~~~~~~~", + "####~~~~~~~~~~~~~~~~~#...#...###################", + "####~~~###############...#...#.........#########", + "####~~~#.............#...#...#.........#########", + "####~~~#.............#...#...#.........#########", + "####~~~##.v.##########.......#.v.##...##########", + "####~~~###############......#######...##########", + "####~~~###############......#######...##########", + "####~~~###D######D####......##D####......#######", + "#C##~~~#..........................#......#######", + "....~~~#..........................#......#######", + "....~~~#..........................#......#######", + "....~~~#.....#######..............#......#######", + "~~~~~~~#...JJ############.........#......#......", + "~~~~~~~#.....##D#########.........#......#######", + "~~~~~~~#............#####JJJ#######.............", + "########............SSD##...#######.............", + "............................#######JJJ#..#######", + "...........................S..#D#.....#..#......", + "......................................#..#######", + "#######...............................#..#######", + "#######.....####......................#..#######", + "#######....#####....S.................#..#######", + "#######....#####.....###############..#..#######", + "#######....#####.....###############..#..#######", + "#######....S#CC#.....##D###SSD######..#..#######", + "#######...............................#..#######", + "#######...............................#..#######", + "#######...............................#..#######", + "###################S######.############..#######", + "#######..................................#######", + "#######..................................#######", + "###############....#........#....###############", + "###############....#JJJJJJJJ#....###############", + "###############....#........#....###############", + "###############....#........#....###############", + "###############....#........#....###############" + ], + "elevation": [ + "000000000000000011111033303330100000000000000000", + "000000000000000011111033300000100000000000000000", + "000011111111111111111033303330100000000000000000", + "000011111111111111111033303330111111111111111111", + "000011111111111111111033303330000000000000000000", + "000011100000000000000033303330333333333000000000", + "000011103333333333333033303330333333333000000000", + "000011103333333333333033303330333333333000000000", + "000011100333000000000033333330333003330000000000", + "000011100000000000000033333300000003330000000000", + "000011100000000000000033333300000003330000000000", + "000011100000000000000033333300000003333330000000", + "030011103333333333333333333333333303333330000000", + "333311103333333333333333333333333303333330000000", + "333311103333333333333333333333333303333330000000", + "333311103333300000003333333333333303333330000000", + "111111103330000000000000033333333303333330333333", + "111111103333300000000000033333333303333330000000", + "111111103333333333330000000000000003333333333333", + "000000003333333333330000033300000003333333333333", + "333333333333333333333333333300000000000330000000", + "333333333333333333333333333033000333330330333333", + "333333333333333333333333333333333333330330000000", + "000000033333333333333333333333333333330330000000", + "000000033333000033333333333333333333330330000000", + "000000033330000033330333333333333333330330000000", + "000000033330000033333000000000000000330330000000", + "000000033330000033333000000000000000330330000000", + "000000033330033033333000000000000000330330000000", + "000000033333333333333333333333333333330330000000", + "000000033333333333333333333333333333330330000000", + "000000033333333333333333333333333333330330000000", + "000000000000000000000000003000000000000330000000", + "000000033333333333333333333333333333333330000000", + "000000033333333333333333333333333333333330000000", + "000000000000000333303333333303333000000000000000", + "000000000000000333300000000003333000000000000000", + "000000000000000333303333333303333000000000000000", + "000000000000000333303333333303333000000000000000", + "000000000000000333303333333303333000000000000000" + ], + "warps": [ + { + "x": 10, + "y": 11, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 30, + "y": 11, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 15, + "y": 17, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 22, + "y": 19, + "dest_map": "CeruleanCity_PokemonCenter_1F", + "dest_warp": 1 + }, + { + "x": 31, + "y": 21, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 13, + "y": 28, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 29, + "y": 28, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 1, + "y": 12, + "dest_map": "CeruleanCave_1F", + "dest_warp": 0 + }, + { + "x": 10, + "y": 8, + "dest_map": "", + "dest_warp": 3 + }, + { + "x": 31, + "y": 8, + "dest_map": "", + "dest_warp": 3 + }, + { + "x": 31, + "y": 9, + "dest_map": "", + "dest_warp": 3 + }, + { + "x": 14, + "y": 28, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 23, + "y": 28, + "dest_map": "", + "dest_warp": 0 + }, + { + "x": 17, + "y": 11, + "dest_map": "", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 31, + "y": 12, + "kind": "policeman", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 6, + "kind": "rocket_m", + "flag": "FLAG_HIDE_CERULEAN_ROCKET", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 16, + "y": 21, + "kind": "little_boy", + "flag": "", + "wander_x": 0, + "wander_y": 3 + }, + { + "x": 9, + "y": 23, + "kind": "balding_man", + "flag": "", + "wander_x": 1, + "wander_y": 1 + }, + { + "x": 32, + "y": 29, + "kind": "slowbro", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 29, + "kind": "lass", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 34, + "y": 22, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 22, + "y": 0, + "kind": "blue", + "flag": "FLAG_HIDE_CERULEAN_RIVAL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 26, + "y": 32, + "kind": "cut_tree", + "flag": "FLAG_TEMP_13", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 50, + "y": 18, + "kind": "cut_tree", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 30, + "kind": "woman_1", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 1, + "y": 13, + "kind": "cooltrainer_m", + "flag": "FLAG_HIDE_CERULEAN_CAVE_GUARD", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "north", + "offset": 12, + "map": "Route24" + } + ], + "points": [], + "flag_sets": [ + { + "name": "after_hall_of_fame", + "flags": [ + "FLAG_HIDE_CERULEAN_CAVE_GUARD", + "FLAG_HIDE_CERULEAN_RIVAL", + "FLAG_HIDE_CERULEAN_ROCKET" + ] + } + ] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCity_PokemonCenter_1F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCity_PokemonCenter_1F.json new file mode 100644 index 0000000000..22d90bfb20 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCity_PokemonCenter_1F.json @@ -0,0 +1,127 @@ +{ + "name": "CeruleanCity_PokemonCenter_1F", + "width": 15, + "height": 10, + "tiles": [ + "#.#############", + "###############", + "....###..##....", + "....#######....", + "...............", + "...............", + "#L.........##..", + "...........##..", + ".......v.......", + "###############" + ], + "elevation": [ + "030000000000000", + "000000000000000", + "333300033003333", + "333300000003333", + "333333333333333", + "330333333333333", + "044033333330033", + "330333333330033", + "333333333333333", + "000000000000000" + ], + "warps": [ + { + "x": 6, + "y": 8, + "dest_map": "CeruleanCity", + "dest_warp": 3 + }, + { + "x": 7, + "y": 8, + "dest_map": "CeruleanCity", + "dest_warp": 3 + }, + { + "x": 8, + "y": 8, + "dest_map": "CeruleanCity", + "dest_warp": 3 + }, + { + "x": 1, + "y": 6, + "dest_map": "", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 7, + "y": 2, + "kind": "nurse", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 5, + "kind": "gentleman", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 4, + "kind": "rocker", + "flag": "", + "wander_x": 1, + "wander_y": 0 + }, + { + "x": 4, + "y": 8, + "kind": "youngster", + "flag": "", + "wander_x": 1, + "wander_y": 0 + }, + { + "x": 3, + "y": 3, + "kind": "lass", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 1, + "kind": "0", + "flag": "FLAG_HIDE_POSTGAME_GOSSIPERS", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 3, + "y": 1, + "kind": "0", + "flag": "FLAG_HIDE_POSTGAME_GOSSIPERS", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [ + { + "name": "pc", + "x": 11, + "y": 2 + }, + { + "name": "nurse_front", + "x": 7, + "y": 4 + } + ], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown.json new file mode 100644 index 0000000000..2794c4b8d7 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown.json @@ -0,0 +1,110 @@ +{ + "name": "PalletTown", + "width": 24, + "height": 20, + "tiles": [ + "############..##########", + "############..##########", + "##....................##", + "##....................##", + "##...#####....#####...##", + "##...#####....#####...##", + "##...#####....#####...##", + "##..S#D###...S#D###...##", + "##....................##", + "##....................##", + "##...........#######..##", + "##...####S...#######..##", + "##...........#######..##", + "##...........###D###..##", + "##...S................##", + "##....................##", + "##...........###S##...##", + "##.....~~~~...........##", + "##.....~~~~...........##", + "##.....~~~~...........##" + ], + "elevation": [ + "000000000000330000000000", + "000000000000330000000000", + "003333333333333333333300", + "003333333333333333333300", + "003330000033330000033300", + "003330000033330000033300", + "003330000033330000033300", + "003300000033300000033300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333300000003300", + "003330000033300000003300", + "003333333333300000003300", + "003333333333300000003300", + "003330333333333333333300", + "003333333333333333333300", + "003333333333300000033300", + "003333311113333333333300", + "003333311113333333333300", + "003333311113333333333300" + ], + "warps": [ + { + "x": 6, + "y": 7, + "dest_map": "PalletTown_PlayersHouse_1F", + "dest_warp": 1 + }, + { + "x": 15, + "y": 7, + "dest_map": "PalletTown_RivalsHouse", + "dest_warp": 0 + }, + { + "x": 16, + "y": 13, + "dest_map": "PalletTown_ProfessorOaksLab", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 3, + "y": 10, + "kind": "woman_1", + "flag": "", + "wander_x": 1, + "wander_y": 4 + }, + { + "x": 13, + "y": 17, + "kind": "fat_man", + "flag": "", + "wander_x": 6, + "wander_y": 2 + }, + { + "x": 10, + "y": 8, + "kind": "prof_oak", + "flag": "FLAG_HIDE_OAK_IN_PALLET_TOWN", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "north", + "offset": 0, + "map": "Route1" + } + ], + "points": [ + { + "name": "oaks_lab_front", + "x": 16, + "y": 14 + } + ], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_1F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_1F.json new file mode 100644 index 0000000000..72843f10c5 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_1F.json @@ -0,0 +1,68 @@ +{ + "name": "PalletTown_PlayersHouse_1F", + "width": 13, + "height": 10, + "tiles": [ + "#############", + "#############", + "#.........>##", + "#............", + "#.....##.....", + "#.....##.....", + "#............", + "##..........#", + "#...v........", + "#############" + ], + "elevation": [ + "0000000000000", + "0000000000000", + "0333333333300", + "0333333333333", + "0333330033333", + "0333330033333", + "0333333333333", + "0033333333330", + "0333333333333", + "0000000000000" + ], + "warps": [ + { + "x": 5, + "y": 8, + "dest_map": "PalletTown", + "dest_warp": 0 + }, + { + "x": 4, + "y": 8, + "dest_map": "PalletTown", + "dest_warp": 0 + }, + { + "x": 10, + "y": 2, + "dest_map": "PalletTown_PlayersHouse_2F", + "dest_warp": 0 + }, + { + "x": 3, + "y": 9, + "dest_map": "PalletTown", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 8, + "y": 4, + "kind": "mom", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_2F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_2F.json new file mode 100644 index 0000000000..c69bd6be3d --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_2F.json @@ -0,0 +1,45 @@ +{ + "name": "PalletTown_PlayersHouse_2F", + "width": 12, + "height": 9, + "tiles": [ + "############", + "###########S", + "#.......##<.", + "#.......##..", + "#.s...#.....", + "#.n...#.....", + "#.#.........", + "#...........", + "#..........." + ], + "elevation": [ + "000000000000", + "000000000000", + "033333330033", + "033333330033", + "033333033333", + "003033033333", + "040403333333", + "003033333333", + "033333333333" + ], + "warps": [ + { + "x": 10, + "y": 2, + "dest_map": "PalletTown_PlayersHouse_1F", + "dest_warp": 2 + } + ], + "objects": [], + "connections": [], + "points": [ + { + "name": "start", + "x": 6, + "y": 6 + } + ], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_ProfessorOaksLab.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_ProfessorOaksLab.json new file mode 100644 index 0000000000..223450196d --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_ProfessorOaksLab.json @@ -0,0 +1,142 @@ +{ + "name": "PalletTown_ProfessorOaksLab", + "width": 13, + "height": 14, + "tiles": [ + "#############", + "######SS#####", + ".............", + "#............", + "###.....###..", + ".##..........", + ".............", + ".............", + "#####...#####", + ".............", + ".............", + ".............", + "#.....v.....#", + "#############" + ], + "elevation": [ + "0000000000000", + "0000000000000", + "3333333333333", + "0333333333333", + "0003333300033", + "3003333333333", + "3333333333333", + "3333333333333", + "0000033300000", + "3333333333333", + "3333333333333", + "3333333333333", + "0333333333330", + "0000000000000" + ], + "warps": [ + { + "x": 6, + "y": 12, + "dest_map": "PalletTown", + "dest_warp": 2 + }, + { + "x": 7, + "y": 12, + "dest_map": "PalletTown", + "dest_warp": 2 + }, + { + "x": 5, + "y": 12, + "dest_map": "PalletTown", + "dest_warp": 2 + } + ], + "objects": [ + { + "x": 3, + "y": 11, + "kind": "scientist", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 10, + "kind": "worker_f", + "flag": "", + "wander_x": 0, + "wander_y": 4 + }, + { + "x": 11, + "y": 10, + "kind": "scientist", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 6, + "y": 3, + "kind": "prof_oak", + "flag": "FLAG_HIDE_OAK_IN_HIS_LAB", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 8, + "y": 4, + "kind": "item_ball", + "flag": "FLAG_HIDE_BULBASAUR_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 9, + "y": 4, + "kind": "item_ball", + "flag": "FLAG_HIDE_SQUIRTLE_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 4, + "kind": "item_ball", + "flag": "FLAG_HIDE_CHARMANDER_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 4, + "kind": "blue", + "flag": "FLAG_HIDE_RIVAL_IN_LAB", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 1, + "kind": "pokedex", + "flag": "FLAG_HIDE_POKEDEX", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 1, + "kind": "pokedex", + "flag": "FLAG_HIDE_POKEDEX", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_RivalsHouse.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_RivalsHouse.json new file mode 100644 index 0000000000..ce5634bf46 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_RivalsHouse.json @@ -0,0 +1,70 @@ +{ + "name": "PalletTown_RivalsHouse", + "width": 13, + "height": 10, + "tiles": [ + "#############", + "#############", + ".............", + ".............", + "......##.....", + "......##.....", + ".............", + ".............", + "#...v.......#", + "#############" + ], + "elevation": [ + "0000000000000", + "0000000000000", + "3333333333333", + "3333333333333", + "3333330033333", + "3333330033333", + "3333333333333", + "3333333333333", + "0333333333330", + "3330003333333" + ], + "warps": [ + { + "x": 4, + "y": 8, + "dest_map": "PalletTown", + "dest_warp": 1 + }, + { + "x": 5, + "y": 8, + "dest_map": "PalletTown", + "dest_warp": 1 + }, + { + "x": 3, + "y": 8, + "dest_map": "PalletTown", + "dest_warp": 1 + } + ], + "objects": [ + { + "x": 10, + "y": 6, + "kind": "daisy", + "flag": "", + "wander_x": 1, + "wander_y": 3 + }, + { + "x": 6, + "y": 4, + "kind": "town_map", + "flag": "FLAG_HIDE_TOWN_MAP", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity.json new file mode 100644 index 0000000000..c01026d4f7 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity.json @@ -0,0 +1,206 @@ +{ + "name": "PewterCity", + "width": 48, + "height": 40, + "tiles": [ + "################################################", + "#######################....#####################", + "####........#################.........##########", + "####........#################.........##########", + "####........#############D######......##########", + "####........###########...............##########", + "#######.....#####C#####..#######........########", + "####JJJ..JJJJJJJ...SJJJJJJJJJJJJJJJJJ...########", + "####....................................########", + "####............................#####...########", + "######..........................#####...########", + "######..........................#D###...########", + "######..................................########", + "######...##.#######.##..................########", + "######...#############..................########", + "######...##.#######.##..................########", + "######...##S..#D#...##....####..........########", + "######...............#....######........########", + "######...............#....SSD###........########", + "######...............#.................S########", + "######################..........................", + "######..........................................", + "######.......#########..........................", + "######.......#########....##########............", + "######.......#########....##########....########", + "######.......##SSD####....#####S#####...########", + "######....................#.........#...########", + "######....................#.........#...########", + "######..#####.............#.........#...########", + "######..#####.............#.........#...########", + "######..#D###.......S.....#JJJJ.JJJJ#...########", + "######..................................########", + "######..................................########", + "######..................................########", + "######..................................########", + "######..................................########", + "####################....########################", + "####################....########################", + "####################....########################", + "####################....########################" + ], + "elevation": [ + "000000000000000000000000000000000000000000000000", + "000000000000000000000003333000000000000000000000", + "000033333333000000000000000003333333330000000000", + "000033333333000000000000000003333333330000000000", + "000033333333000000000000000000003333330000000000", + "000033333333000000000003333333333333330000000000", + "000000033333000003000003300000003333333300000000", + "000000033000000033300000000000000000033300000000", + "000033333333333333333333333333333333333300000000", + "000033333333333333333333333333330000033300000000", + "000000333333333333333333333333330000033300000000", + "000000333333333333333333333333330000033300000000", + "000000333333333333333333333333333333333300000000", + "000000333003000000030033333333333333333300000000", + "000000333000000000000033333333333333333300000000", + "000000333003000000030033333333333333333300000000", + "000000333000330003330033330000333333333300000000", + "000000333333333333333033330000003333333300000000", + "000000333333333333333033330000003333333300000000", + "000000333333333333333033333333333333333000000000", + "000000000000000000000033333333333333333333333333", + "000000333333333333333333333333333333333333333333", + "000000333333300000000033333333333333333333333333", + "000000333333300000000033330000000000333333333333", + "000000333333300000000033330000000000333300000000", + "000000333333300000000033330000000000033300000000", + "000000333333333333333333330333333333033300000000", + "000000333333333333333333330333333333033300000000", + "000000330000033333333333330333333333033300000000", + "000000330000033333333333330333333333033300000000", + "000000330000033333330333330000030000033300000000", + "000000333333333333333333333333333333333300000000", + "000000333333333333333333333333333333333300000000", + "000000333333333333333333333333333333333300000000", + "000000333333333333333333333333333333333300000000", + "000000333333333333333333333333333333333300000000", + "000000000000000000003333000000000000000000000000", + "000000000000000000003333000000000000000000000000", + "000000000000000000003333000000000000000000000000", + "000000000000000000003333000000000000000000000000" + ], + "warps": [ + { + "x": 17, + "y": 6, + "dest_map": "PewterCity_Museum_1F", + "dest_warp": 1 + }, + { + "x": 25, + "y": 4, + "dest_map": "PewterCity_Museum_1F", + "dest_warp": 3 + }, + { + "x": 15, + "y": 16, + "dest_map": "PewterCity_Gym", + "dest_warp": 1 + }, + { + "x": 28, + "y": 18, + "dest_map": "PewterCity_Mart", + "dest_warp": 1 + }, + { + "x": 33, + "y": 11, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 17, + "y": 25, + "dest_map": "PewterCity_PokemonCenter_1F", + "dest_warp": 1 + }, + { + "x": 9, + "y": 30, + "dest_map": "", + "dest_warp": 1 + } + ], + "objects": [ + { + "x": 6, + "y": 15, + "kind": "lass", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 17, + "kind": "man", + "flag": "FLAG_HIDE_PEWTER_MUSEUM_GUIDE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 21, + "y": 28, + "kind": "fat_man", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 27, + "kind": "bug_catcher", + "flag": "", + "wander_x": 2, + "wander_y": 0 + }, + { + "x": 42, + "y": 20, + "kind": "boy", + "flag": "FLAG_HIDE_PEWTER_CITY_GYM_GUIDE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 30, + "y": 5, + "kind": "cut_tree", + "flag": "FLAG_TEMP_12", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 46, + "y": 20, + "kind": "scientist", + "flag": "FLAG_HIDE_PEWTER_CITY_RUNNING_SHOES_GUY", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "south", + "offset": 12, + "map": "Route2" + } + ], + "points": [ + { + "name": "gym_front", + "x": 15, + "y": 17 + } + ], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Gym.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Gym.json new file mode 100644 index 0000000000..cbc7068f74 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Gym.json @@ -0,0 +1,96 @@ +{ + "name": "PewterCity_Gym", + "width": 13, + "height": 16, + "tiles": [ + "#############", + "####.....####", + "#############", + "#....#.#....#", + "#...........#", + "#...#...#...#", + "#...........#", + "#..#.#.#.#..#", + "##.........##", + "#...#...#...#", + "##.........##", + "#...........#", + "#...S...S...#", + "#...........#", + "#.....v.....#", + "#############" + ], + "elevation": [ + "0000000000000", + "0000333330000", + "0000000000000", + "0333303033330", + "0333333333330", + "0333033303330", + "0333333333330", + "0330303030330", + "0033333333300", + "0333033303330", + "0033333333300", + "0333333333330", + "0333033303330", + "0333333333330", + "0333333333330", + "0000000000000" + ], + "warps": [ + { + "x": 5, + "y": 14, + "dest_map": "PewterCity", + "dest_warp": 2 + }, + { + "x": 6, + "y": 14, + "dest_map": "PewterCity", + "dest_warp": 2 + }, + { + "x": 7, + "y": 14, + "dest_map": "PewterCity", + "dest_warp": 2 + } + ], + "objects": [ + { + "x": 6, + "y": 5, + "kind": "brock", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 3, + "y": 8, + "kind": "camper", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 7, + "y": 12, + "kind": "gym_guy", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [ + { + "name": "brock_front", + "x": 6, + "y": 6 + } + ], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Mart.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Mart.json new file mode 100644 index 0000000000..1cdef57978 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Mart.json @@ -0,0 +1,76 @@ +{ + "name": "PewterCity_Mart", + "width": 11, + "height": 9, + "tiles": [ + "###########", + "###########", + "##.#......#", + "...#.......", + "####...##.#", + ".......##.#", + ".##....##.#", + "....v......", + "###########" + ], + "elevation": [ + "00000000000", + "00000000000", + "00303333330", + "33003333333", + "00003330030", + "33333330030", + "30033330030", + "33333333333", + "00000000000" + ], + "warps": [ + { + "x": 3, + "y": 7, + "dest_map": "PewterCity", + "dest_warp": 3 + }, + { + "x": 4, + "y": 7, + "dest_map": "PewterCity", + "dest_warp": 3 + }, + { + "x": 5, + "y": 7, + "dest_map": "PewterCity", + "dest_warp": 3 + } + ], + "objects": [ + { + "x": 8, + "y": 2, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 6, + "y": 4, + "kind": "boy", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 3, + "kind": "clerk", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Museum_1F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Museum_1F.json new file mode 100644 index 0000000000..1bb4797613 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Museum_1F.json @@ -0,0 +1,122 @@ +{ + "name": "PewterCity_Museum_1F", + "width": 28, + "height": 11, + "tiles": [ + "############################", + "############################", + "...............#............", + "...............#......#....#", + "...####........#...........#", + "...............#............", + "...........#...#...........#", + "...####..###...###.........#", + "........>###.....#..........", + "#........###..v.##...v..##..", + "############################" + ], + "elevation": [ + "0000000000000000000000000000", + "0000000000000000000000000000", + "3333333333333330333333333333", + "3333333333333330333333033330", + "3330000333333330333333333330", + "3333333333333330333333333333", + "3333333333303330333333333330", + "3330000330003330003333333330", + "3333333330003333303333333333", + "0333333330003333003333330033", + "0000000000000000000000000000" + ], + "warps": [ + { + "x": 13, + "y": 9, + "dest_map": "PewterCity", + "dest_warp": 0 + }, + { + "x": 14, + "y": 9, + "dest_map": "PewterCity", + "dest_warp": 0 + }, + { + "x": 15, + "y": 9, + "dest_map": "PewterCity", + "dest_warp": 0 + }, + { + "x": 21, + "y": 9, + "dest_map": "PewterCity", + "dest_warp": 1 + }, + { + "x": 22, + "y": 9, + "dest_map": "PewterCity", + "dest_warp": 1 + }, + { + "x": 8, + "y": 8, + "dest_map": "", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 16, + "y": 5, + "kind": "worker_m", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 4, + "kind": "old_man_1", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 21, + "y": 3, + "kind": "scientist", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 22, + "y": 3, + "kind": "old_amber", + "flag": "FLAG_HIDE_OLD_AMBER", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 26, + "y": 4, + "kind": "scientist", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 26, + "y": 7, + "kind": "scientist", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_PokemonCenter_1F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_PokemonCenter_1F.json new file mode 100644 index 0000000000..e6c20a0d10 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_PokemonCenter_1F.json @@ -0,0 +1,122 @@ +{ + "name": "PewterCity_PokemonCenter_1F", + "width": 15, + "height": 10, + "tiles": [ + "#.#############", + "###############", + "....###..##....", + "....#######....", + "...............", + "...............", + "#L.........##..", + "...........##..", + ".......v.......", + "###############" + ], + "elevation": [ + "030000000000000", + "000000000000000", + "333300033003333", + "333300000003333", + "333333333333333", + "330333333333333", + "044033333330033", + "330333333330033", + "333333333333333", + "000000000000000" + ], + "warps": [ + { + "x": 6, + "y": 8, + "dest_map": "PewterCity", + "dest_warp": 5 + }, + { + "x": 7, + "y": 8, + "dest_map": "PewterCity", + "dest_warp": 5 + }, + { + "x": 8, + "y": 8, + "dest_map": "PewterCity", + "dest_warp": 5 + }, + { + "x": 1, + "y": 6, + "dest_map": "", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 2, + "y": 2, + "kind": "jigglypuff", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 8, + "kind": "gentleman", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 7, + "y": 2, + "kind": "nurse", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 1, + "y": 2, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 13, + "y": 2, + "kind": "woman_1", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 7, + "kind": "gba_kid", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 14, + "y": 6, + "kind": "gba_kid", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [ + { + "name": "nurse_front", + "x": 7, + "y": 4 + } + ], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route1.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route1.json new file mode 100644 index 0000000000..735f2320d5 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route1.json @@ -0,0 +1,122 @@ +{ + "name": "Route1", + "width": 24, + "height": 40, + "tiles": [ + "##########....##########", + "##########....##########", + "##....................##", + "##....................##", + "##......##............##", + "##JJJJJJ##JJJJJJ......##", + "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", + "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", + "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", + "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", + "##JJJJJJ##\"\"\"\"\"\"\"\"\"\"\"\"##", + "##......##............##", + "##....................##", + "##..............\"\"\"\"\"\"##", + "##..............\"\"\"\"\"\"##", + "####JJJJJJ######\"\"\"\"\"\"##", + "####......######\"\"\"\"\"\"##", + "##..............\"\"\"\"\"\"##", + "##....................##", + "##....................##", + "##JJ.JJJJ..JJJJJJJJJJJ##", + "##....................##", + "##....................##", + "##....................##", + "##..........\"\"\"\"\"\"....##", + "############\"\"\"\"\"\"....##", + "############\"\"\"\"\"\"JJJJ##", + "##..........\"\"\"\"\"\"....##", + "##..........\"\"\"\"\"\"....##", + "##....................##", + "##....................##", + "##JJJJ...SJJJJJJJJJJJJ##", + "##..\"\"\"\"\"\"\"......\"\"\"\"\"##", + "##..\"\"\"\"\"\"\"......\"\"\"\"\"##", + "##\"\"\"\"\"\"\"......\"\"\"\"\"..##", + "##\"\"\"\"\"\"\"...\"\".\"\"\"\"\"..##", + "############\"\"##########", + "##.........#\"\"#.......##", + "############\"\"##########", + "############\"\"##########" + ], + "elevation": [ + "000000000033330000000000", + "000000000033330000000000", + "003333333333333333333300", + "003333333333333333333300", + "003333330033333333333300", + "000000000000000033333300", + "003333330033333333333300", + "003333330033333333333300", + "003333330033333333333300", + "003333330033333333333300", + "000000000033333333333300", + "003333330033333333333300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "000000000000000033333300", + "000033333300000033333300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "000030000330000000000000", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "000000000000333333333300", + "000000000000333333000000", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "000000333000000000000000", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "003333333333333333333300", + "000000000000330000000000", + "003333333330330333333300", + "000000000000330000000000", + "000000000000330000000000" + ], + "warps": [], + "objects": [ + { + "x": 6, + "y": 28, + "kind": "clerk", + "flag": "", + "wander_x": 0, + "wander_y": 1 + }, + { + "x": 19, + "y": 16, + "kind": "boy", + "flag": "", + "wander_x": 1, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "north", + "offset": -12, + "map": "ViridianCity" + }, + { + "direction": "south", + "offset": 0, + "map": "PalletTown" + } + ], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2.json new file mode 100644 index 0000000000..b0beb72f22 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2.json @@ -0,0 +1,303 @@ +{ + "name": "Route2", + "width": 24, + "height": 80, + "tiles": [ + "########....############", + "########....############", + "##\"\"\"\"\"\"\"...############", + "##\"\"\"\"\"\"\"...#.........##", + "##\"\"\"\"\"\"\"...#.........##", + "##\"\"\"\"\"\"\"...#.........##", + "##\"\"\"\"\"\"\"...#########.##", + "##\"\"\"\"\"\"\"...#########.##", + "##\"\"\"\"\"\"\"...#########.##", + "##..........#########.##", + "##..........#########.##", + "##..........#####C###.##", + "##..........#.S.......##", + "####.vv.###.#.........##", + "###########...........##", + "##########............##", + "##############........##", + "##############........##", + "##############........##", + "##############........##", + "##############........##", + "###################...##", + "#################D#...##", + "##############........##", + "################......##", + "################......##", + "##################.#####", + "################......##", + "################......##", + "################......##", + "################......##", + "################......##", + "################JJJ.JJ##", + "################......##", + "################......##", + "################......##", + "################......##", + "################JJJ.JJ##", + "################......##", + "################......##", + "################......##", + "#################.vv.###", + "########################", + "########################", + "########################", + "##........##############", + "##################CC####", + "#################....###", + "################......##", + "################......##", + "###.####.#######......##", + "#####CC#########JJJ.JJ##", + "####....########......##", + "##............##......##", + "##............##......##", + "##JJJJJJJJJ...##......##", + "##....\"\"\"\"\"\"\".##......##", + "##....\"\"\"\"\"\"\".##JJ.JJJ##", + "##....\"\"\"\"\"\"\".##......##", + "##....\"\"\"\"\"\"\".##......##", + "##....\"\"\"\"\"\"\".##......##", + "##............##......##", + "##....................##", + "##....##########......##", + "##....##########......##", + "##....##########......##", + "##....##########......##", + "##............##......##", + "##............##......##", + "##....................##", + "##JJJJJJJ..JJJ..JJ.JJJ##", + "##............##......##", + "####..........##......##", + "####...S......##......##", + "####..........##......##", + "####..........##......##", + "####..........##......##", + "####..........##......##", + "#######.......##########", + "#######.....############" + ], + "elevation": [ + "000000003333000000000000", + "000000003333000000000000", + "003333333333000000000000", + "003333333333033333333300", + "003333333333033333333300", + "003333333333033333333300", + "003333333333000000000300", + "003333333333000000000300", + "003333333333000000000300", + "003333333333000000000300", + "003333333333000000000300", + "003333333333000003000300", + "003333333333030333333300", + "000033330003033333333300", + "000000000003333333333300", + "000000000033333333333300", + "000000000000003333333300", + "000000000000003333333300", + "000000000000003333333300", + "000000000000003333333300", + "000000000000003333333300", + "000000000000000000033300", + "000000000000000000033300", + "000000000000003333333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000000300000", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000000030000", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000000030000", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000033333300", + "000000000000000003333000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "003333333300000000000000", + "000000000000000000330000", + "000000000000000003333000", + "000000000000000033333300", + "000000000000000033333300", + "000300003000000033333300", + "000003300000000000030000", + "000033330000000033333300", + "003333333333330033333300", + "003333333333330033333300", + "000000000003330033333300", + "003333333333330033333300", + "003333333333330000300000", + "003333333333330033333300", + "003333333333330033333300", + "003333333333330033333300", + "003333333333330033333300", + "003333333333333333333300", + "003333000000000033333300", + "003333000000000033333300", + "003333000000000033333300", + "003333000000000033333300", + "003333333333330033333300", + "003333333333330033333300", + "003333333333333333333300", + "000000000330003300300000", + "003333333333330033333300", + "000033333333330033333300", + "000033303333330033333300", + "000033333333330033333300", + "000033333333330033333300", + "000033333333330033333300", + "000033333333330033333300", + "000000033333330000000000", + "000000033333000000000000" + ], + "warps": [ + { + "x": 5, + "y": 13, + "dest_map": "Route2_ViridianForest_NorthEntrance", + "dest_warp": 3 + }, + { + "x": 6, + "y": 13, + "dest_map": "Route2_ViridianForest_NorthEntrance", + "dest_warp": 3 + }, + { + "x": 5, + "y": 51, + "dest_map": "Route2_ViridianForest_SouthEntrance", + "dest_warp": 1 + }, + { + "x": 17, + "y": 11, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 17, + "y": 22, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 18, + "y": 46, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 18, + "y": 41, + "dest_map": "", + "dest_warp": 3 + }, + { + "x": 19, + "y": 41, + "dest_map": "", + "dest_warp": 3 + }, + { + "x": 19, + "y": 46, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 6, + "y": 51, + "dest_map": "Route2_ViridianForest_SouthEntrance", + "dest_warp": 1 + } + ], + "objects": [ + { + "x": 16, + "y": 62, + "kind": "cut_tree", + "flag": "FLAG_TEMP_14", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 15, + "y": 69, + "kind": "cut_tree", + "flag": "FLAG_TEMP_13", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 11, + "y": 13, + "kind": "cut_tree", + "flag": "FLAG_TEMP_15", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 18, + "y": 26, + "kind": "cut_tree", + "flag": "FLAG_TEMP_16", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 17, + "y": 54, + "kind": "item_ball", + "flag": "FLAG_HIDE_ROUTE2_ETHER", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 17, + "y": 64, + "kind": "item_ball", + "flag": "FLAG_HIDE_ROUTE2_PARALYZE_HEAL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 6, + "y": 85, + "kind": "cut_tree", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "north", + "offset": -12, + "map": "PewterCity" + }, + { + "direction": "south", + "offset": -12, + "map": "ViridianCity" + } + ], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route22.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route22.json new file mode 100644 index 0000000000..ef4a2a11fb --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route22.json @@ -0,0 +1,90 @@ +{ + "name": "Route22", + "width": 48, + "height": 24, + "tiles": [ + "#############################################...", + "###########################################.#...", + "##################################........#.###.", + "##################################JJJJ.JJJ#...##", + "######################....................#.....", + "########D######...........................######", + "#####.......###.........................##......", + "###...........#.............######......##......", + "###...........#JJJJJJJ~~~~~~######JJ..JJ##......", + "###JJJJJJJ..JJ#\"\"\"\"\"\"\"~~~~~~######\"\"\"\"\"\"##......", + "###...........#\"\"\"\"\"\"\"~~~~~~######\"\"\"\"\"\"##....##", + "###...........#\"\"\"\"\"\"\"~~~~~~######\"\"\"\"\"\"##....##", + "####...S#######\"\"\"\"\"\"\"......######\"\"\"\"\"\"##....##", + "####...........\"\"\"\"\"\"\"......######\"\"\"\"\"\"##....##", + "####........................######............##", + "####JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ..JJJJJ##", + "####..........................................##", + "####..........................................##", + "####..........................................##", + "################################################", + "################################################", + "################################################", + "################################################", + "################################################" + ], + "elevation": [ + "000000000000000000000000000000000000000000000333", + "000000000000000000000000000000000000000000030333", + "000000000000000000000000000000000033333333030003", + "000000000000000000000000000000000000003000033300", + "000000000000000000000033333333333333333333033333", + "000000000000000333333333333333333333333333000000", + "000003333333000333333333333333333333333300333333", + "000333333333330333333333333300000033333300333333", + "000333333333330000000011111100000000330000333333", + "000000000033000333333311111100000033333300333333", + "000333333333330333333311111100000033333300333300", + "000333333333330333333311111100000033333300333300", + "000033300000000333333333333300000033333300333300", + "000033333333333333333333333300000033333300333300", + "000033333333333333333333333300000033333333333300", + "000000000000000000000000000000000000000330000000", + "000033333333333333333333333333333333333333333300", + "000033333333333333333333333333333333333333333300", + "000033333333333333333333333333333333333333333300", + "000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000" + ], + "warps": [ + { + "x": 8, + "y": 5, + "dest_map": "", + "dest_warp": 2 + }, + { + "x": 9, + "y": 5, + "dest_map": "", + "dest_warp": 2 + } + ], + "objects": [ + { + "x": 25, + "y": 4, + "kind": "blue", + "flag": "FLAG_HIDE_ROUTE_22_RIVAL", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "east", + "offset": -10, + "map": "ViridianCity" + } + ], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route24.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route24.json new file mode 100644 index 0000000000..ecac345dff --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route24.json @@ -0,0 +1,165 @@ +{ + "name": "Route24", + "width": 24, + "height": 40, + "tiles": [ + "########################", + "########################", + "########################", + "####.........J...J......", + "####.........J...J......", + "####.........J...J......", + "###JJJJ..JJJJ#...#JJJJJJ", + "###.....................", + "###.....................", + "###.....................", + "###..........###########", + "###..........#..........", + "###..........#...#######", + "###..........#...#######", + "###..........#...#######", + "###..........#...#######", + "###...~~~#...#...#######", + "###...~~~#...#...#######", + "###...~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#######", + "###\"\"\"~~~#...#...#~~~~~~", + "###\"\"\"~~~#...#...#~~~~~~", + "###\"\"\"~~~#...#...#~~~~~~", + "###\"\"\"~~~#...#...#~~~~~~", + "###\"\"\"~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~", + "####~~~~~#...#...#~~~~~~" + ], + "elevation": [ + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000033333333303330333333", + "000033333333303330333333", + "000033333333303330333333", + "000000033000003330000000", + "000333333333333333333333", + "000333333333333333333333", + "000333333333333333333333", + "000333333333300000000000", + "000333333333303333333333", + "000333333333303330000000", + "000333333333303330000000", + "000333333333303330000000", + "000333333333303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330000000", + "000333111033303330111111", + "000333111033303330100000", + "000333111033303330100000", + "000333111033303330100000", + "000333111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000", + "000011111033303330100000" + ], + "warps": [], + "objects": [ + { + "x": 12, + "y": 15, + "kind": "man", + "flag": "FLAG_HIDE_NUGGET_BRIDGE_ROCKET", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 19, + "kind": "camper", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 22, + "kind": "lass", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 25, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 28, + "kind": "lass", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 31, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 21, + "kind": "camper", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 11, + "y": 4, + "kind": "item_ball", + "flag": "FLAG_HIDE_ROUTE24_TM45", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "south", + "offset": -12, + "map": "CeruleanCity" + } + ], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_NorthEntrance.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_NorthEntrance.json new file mode 100644 index 0000000000..5058f58189 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_NorthEntrance.json @@ -0,0 +1,88 @@ +{ + "name": "Route2_ViridianForest_NorthEntrance", + "width": 15, + "height": 12, + "tiles": [ + "###############", + "#######C#######", + "##...#...#...##", + "#.............#", + "#..........##.#", + "###........##.#", + "#.............#", + "#..........##.#", + "###........##.#", + "#.............#", + "#......v......#", + "###############" + ], + "elevation": [ + "000000000000000", + "000000030000000", + "003330333033300", + "033333333333330", + "033333333330030", + "000333333330030", + "033333333333330", + "033333333330030", + "000333333330030", + "033333333333330", + "033333333333330", + "000000000000000" + ], + "warps": [ + { + "x": 6, + "y": 10, + "dest_map": "ViridianForest", + "dest_warp": 2 + }, + { + "x": 7, + "y": 10, + "dest_map": "ViridianForest", + "dest_warp": 2 + }, + { + "x": 8, + "y": 10, + "dest_map": "ViridianForest", + "dest_warp": 2 + }, + { + "x": 7, + "y": 1, + "dest_map": "Route2", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 5, + "y": 4, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 7, + "kind": "old_man_1", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 10, + "y": 5, + "kind": "cooltrainer_f", + "flag": "", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_SouthEntrance.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_SouthEntrance.json new file mode 100644 index 0000000000..ea9cb605aa --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_SouthEntrance.json @@ -0,0 +1,80 @@ +{ + "name": "Route2_ViridianForest_SouthEntrance", + "width": 15, + "height": 12, + "tiles": [ + "###############", + "#######C#######", + "##...#...#...##", + "#.............#", + "#..........##.#", + "###........##.#", + "#.............#", + "#..........##.#", + "###........##.#", + "#.............#", + "#......v......#", + "###############" + ], + "elevation": [ + "000000000000000", + "000000030000000", + "003330333033300", + "033333333333330", + "033333333330030", + "000333333330030", + "033333333333330", + "033333333330030", + "000333333330030", + "033333333333330", + "033333333333330", + "000000000000000" + ], + "warps": [ + { + "x": 6, + "y": 10, + "dest_map": "Route2", + "dest_warp": 2 + }, + { + "x": 7, + "y": 10, + "dest_map": "Route2", + "dest_warp": 2 + }, + { + "x": 8, + "y": 10, + "dest_map": "Route2", + "dest_warp": 2 + }, + { + "x": 7, + "y": 1, + "dest_map": "ViridianForest", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 10, + "y": 6, + "kind": "woman_2", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 7, + "kind": "woman_1", + "flag": "", + "wander_x": 1, + "wander_y": 1 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity.json new file mode 100644 index 0000000000..fb3714c07b --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity.json @@ -0,0 +1,214 @@ +{ + "name": "ViridianCity", + "width": 48, + "height": 40, + "tiles": [ + "###################.....########################", + "###################....S########################", + "###################.....########################", + "###################.....########################", + "###################.....####..............######", + "########..................................######", + "########.##########.......................######", + "########.###########.............######...######", + "########.##########..............######...######", + "########.###########...######....######...######", + "########.##########.....#####...S..#D#....######", + "########.###########...##D###.............######", + "########.##########........##JJJJJJJJJJJJJ######", + "########.###########......................######", + "########.##########.......................######", + "######...###########.........###################", + ".........##########.S..######.............######", + "........................#####.....####....######", + ".......................##D###.....####....######", + "..................................SSD#....######", + "#######...................................######", + "#######...................................######", + "#######...................................######", + "###########.............#####.............######", + "###########.##..........#####.............######", + "#######.....##..........#####.............######", + "#######....~~~~~~.......SSD##.............######", + "#######....~~~~~~.........................######", + "#######....~~~~~~.........................######", + "#######....~~~~~~.........................######", + "#######JJJJ~~~~~~JJJ...JJJJJJJJJJJJJJJJJJJ######", + "#######.............S.....................######", + "#######...................................######", + "#######...................................######", + "##############............................######", + "##############............................######", + "######################....######################", + "######################....######################", + "######################....######################", + "######################....######################" + ], + "elevation": [ + "000000000000000000033333000000000000000000000000", + "000000000000000000033330000000000000000000000000", + "000000000000000000033333000000000000000000000000", + "000000000000000000033333000000000000000000000000", + "000000000000000000033333000033333333333333000000", + "000000003333333333333333333333333333333333000000", + "000000003000000000033333333333333333333333000000", + "000000003000000000003333333333333000000333000000", + "000000003000000000033333333333333000000333000000", + "000000003000000000003330000003333000000333000000", + "000000003000000000033333000003330330003333000000", + "000000003000000000003330000003333333333333000000", + "000000003000000000033333333000000000000000000000", + "000000003000000000003333333333333333333333000000", + "000000003000000000033333333333333333333333000000", + "000000333000000000003333333330000000000000000000", + "333333333000000000030330000003333333333333000000", + "333333333333333333333333000003333300003333000000", + "333333333333333333333330000003333300003333000000", + "333333333333333333333333333333333300003333000000", + "000000033333333333333333333333333333333333000000", + "000000033333333333333333333333333333333333000000", + "000000033333333333333333333333333333333333000000", + "000000000003333333333333000003333333333333000000", + "000000000003003333333333000003333333333333000000", + "000000033333003333333333000003333333333333000000", + "000000033331111113333333000003333333333333000000", + "000000033331111113333333333333333333333333000000", + "000000033331111113333333333333333333333333000000", + "000000033331111113333333333333333333333333000000", + "000000000001111110003330000000000000000000000000", + "000000033333333333330333333333333333333333000000", + "000000033333333333333333333333333333333333000000", + "000000033333333333333333333333333333333333000000", + "000000000000003333333333333333333333333333000000", + "000000000000003333333333333333333333333333000000", + "000000000000000000000033330000000000000000000000", + "000000000000000000000033330000000000000000000000", + "000000000000000000000033330000000000000000000000", + "000000000000000000000033330000000000000000000000" + ], + "warps": [ + { + "x": 26, + "y": 26, + "dest_map": "ViridianCity_PokemonCenter_1F", + "dest_warp": 1 + }, + { + "x": 25, + "y": 11, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 36, + "y": 10, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 25, + "y": 18, + "dest_map": "", + "dest_warp": 1 + }, + { + "x": 36, + "y": 19, + "dest_map": "ViridianCity_Mart", + "dest_warp": 1 + } + ], + "objects": [ + { + "x": 8, + "y": 26, + "kind": "fat_man", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 11, + "y": 24, + "kind": "cut_tree", + "flag": "FLAG_TEMP_11", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 34, + "y": 11, + "kind": "old_man_1", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 21, + "y": 6, + "kind": "var_0", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 20, + "y": 12, + "kind": "woman_3", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 33, + "y": 26, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 2 + }, + { + "x": 16, + "y": 22, + "kind": "boy", + "flag": "", + "wander_x": 1, + "wander_y": 2 + }, + { + "x": 18, + "y": 5, + "kind": "cut_tree", + "flag": "FLAG_TEMP_12", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 17, + "y": 5, + "kind": "item_ball", + "flag": "FLAG_HIDE_VIRIDIAN_CITY_POTION", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [ + { + "direction": "north", + "offset": 12, + "map": "Route2" + }, + { + "direction": "south", + "offset": 12, + "map": "Route1" + }, + { + "direction": "west", + "offset": 10, + "map": "Route22" + } + ], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity_Mart.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity_Mart.json new file mode 100644 index 0000000000..f4b1fa32fc --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity_Mart.json @@ -0,0 +1,82 @@ +{ + "name": "ViridianCity_Mart", + "width": 11, + "height": 9, + "tiles": [ + "###########", + "###########", + "##.#......#", + "...#.......", + "####...##.#", + ".......##.#", + ".##....##.#", + "....v......", + "###########" + ], + "elevation": [ + "00000000000", + "00000000000", + "00303333330", + "33003333333", + "00003330030", + "33333330030", + "30033330030", + "33333333333", + "00000000000" + ], + "warps": [ + { + "x": 3, + "y": 7, + "dest_map": "ViridianCity", + "dest_warp": 4 + }, + { + "x": 4, + "y": 7, + "dest_map": "ViridianCity", + "dest_warp": 4 + }, + { + "x": 5, + "y": 7, + "dest_map": "ViridianCity", + "dest_warp": 4 + } + ], + "objects": [ + { + "x": 2, + "y": 3, + "kind": "clerk", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 6, + "y": 2, + "kind": "youngster", + "flag": "", + "wander_x": 1, + "wander_y": 1 + }, + { + "x": 9, + "y": 5, + "kind": "woman_1", + "flag": "", + "wander_x": 0, + "wander_y": 1 + } + ], + "connections": [], + "points": [ + { + "name": "clerk_front", + "x": 4, + "y": 3 + } + ], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity_PokemonCenter_1F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity_PokemonCenter_1F.json new file mode 100644 index 0000000000..7bb1c5369c --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianCity_PokemonCenter_1F.json @@ -0,0 +1,98 @@ +{ + "name": "ViridianCity_PokemonCenter_1F", + "width": 15, + "height": 10, + "tiles": [ + "#.#############", + "###############", + "....###..##....", + "....#######....", + "...............", + "...............", + "#L.........##..", + "...........##..", + ".......v.......", + "###############" + ], + "elevation": [ + "030000000000000", + "000000000000000", + "333300033003333", + "333300000003333", + "333333333333333", + "330333333333333", + "044033333330033", + "330333333330033", + "333333333333333", + "000000000000000" + ], + "warps": [ + { + "x": 6, + "y": 8, + "dest_map": "ViridianCity", + "dest_warp": 0 + }, + { + "x": 7, + "y": 8, + "dest_map": "ViridianCity", + "dest_warp": 0 + }, + { + "x": 8, + "y": 8, + "dest_map": "ViridianCity", + "dest_warp": 0 + }, + { + "x": 1, + "y": 6, + "dest_map": "", + "dest_warp": 0 + } + ], + "objects": [ + { + "x": 7, + "y": 2, + "kind": "nurse", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 12, + "y": 5, + "kind": "gentleman", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 4, + "y": 7, + "kind": "boy", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 2, + "y": 3, + "kind": "youngster", + "flag": "", + "wander_x": 1, + "wander_y": 1 + } + ], + "connections": [], + "points": [ + { + "name": "nurse_front", + "x": 7, + "y": 4 + } + ], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianForest.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianForest.json new file mode 100644 index 0000000000..ae6808cb11 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianForest.json @@ -0,0 +1,278 @@ +{ + "name": "ViridianForest", + "width": 54, + "height": 69, + "tiles": [ + "######################################################", + "######################################################", + "######################################################", + "######################################################", + "######################################################", + "###########.............###........................###", + "###########.............###........................###", + "###########.............###........................###", + "#..#####..#.............###.....###############....###", + "####CCC####.............###.....###############....###", + "####...####.............###.....###############....###", + "####...####.....###.....###.....###############....###", + "####..S####\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###############....###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###############....###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###############....###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".............###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".............###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".............###", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".......#########", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"........#########", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"######......#########", + "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###...\"\"\"######......#########", + "###\"\"\"\"\"###\"\"\"\"\"###.....###......######......#########", + "###\"\"\"\"\"###\"\"\"\"\"###..............######......#########", + "###\"\"\"\"\"###\"\"\"\"\"#####............######......#########", + "###\"\"\"\"\"###\"\"\"\"\"#####............######............###", + "###\"\"\"\"\"###\"\"\"\"\"\"\"#####################....S.......###", + "###\"\"\"\"\"...\"\"\"\"\"\"\"#####################............###", + "###...............#####################............###", + "###......S........#####################\"\"\"\"........###", + "###...............#####################\"\"\"\"\"###....###", + "###.....................###############\"\"\"\"\"###....###", + "###.....................###############\"\"\"\"\"###....###", + "###.....................###############\"\"\"\"\"###....###", + "##################......###############\"\"\"\"\"###....###", + "##################......###############\"\"\"\"\"###....###", + "#######################################\"\"\"\"\"###....###", + "#######################################\"\"\"\"\"###....###", + "#######################################\"\"\"\"\"###....###", + "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", + "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", + "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", + "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", + "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"######\"\"\"\"........###", + "############\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"S..\"\"######\"\"\".........###", + "############\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"...\"\"######\"\"\".........###", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", + "###\"\"\"\"\"\"\"\"\"..\"\"\"\"\"\"\"\"\"\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"\"..\"\"\"\"\"\"\"\"\"\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"\"\"\"\"\"\".###.\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"\"....\"\"\"\"\"\"\"\"\"\".......\"\"\"\"\"\"\"....\"\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"............................S....\"\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"....................S...........\"\"\"\"\"\"\"\"###", + "###\"\"\"\"\"\"\"\"................................\"\"\"\"\"\"\"\"###", + "###########################.vvv..#####################", + "######################################################", + "######################################################", + "######################################################", + "######################################################", + "######################################################", + "######################################################" + ], + "elevation": [ + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000003333333333333000333333333333333333333333000", + "000000000003333333333333000333333333333333333333333000", + "000000000003333333333333000333333333333333333333333000", + "033000003303333333333333000333330000000000000003333000", + "000033300003333333333333000333330000000000000003333000", + "000033300003333333333333000333330000000000000003333000", + "000033300003333300033333000333330000000000000003333000", + "000033000003333300033333000333330000000000000003333000", + "000333330003333300033333000333330000000000000003333000", + "000333330003333300033333000333330000000000000003333000", + "000333330003333300033333000333333333333333333333333000", + "000333330003333300033333000333333333333333333333333000", + "000333330003333300033333000333333333333333333333333000", + "000333330003333300033333000333333333333333333000000000", + "000333330003333300033333000333333333333333333000000000", + "000333330003333300033333000333333000000333333000000000", + "000333330003333300033333000333333000000333333000000000", + "000333330003333300033333000333333000000333333000000000", + "000333330003333300033333333333333000000333333000000000", + "000333330003333300000333333333333000000333333000000000", + "000333330003333300000333333333333000000333333333333000", + "000333330003333333000000000000000000000333303333333000", + "000333333333333333000000000000000000000333333333333000", + "000333333333333333000000000000000000000333333333333000", + "000333333033333333000000000000000000000333333333333000", + "000333333333333333000000000000000000000333330003333000", + "000333333333333333333333000000000000000333330003333000", + "000333333333333333333333000000000000000333330003333000", + "000333333333333333333333000000000000000333330003333000", + "000000000000000000333333000000000000000333330003333000", + "000000000000000000333333000000000000000333330003333000", + "000000000000000000000000000000000000000333330003333000", + "000000000000000000000000000000000000000333330003333000", + "000000000000000000000000000000000000000333330003333000", + "000333333333333333000000000000000000000333330003333000", + "000333333333333333000000000000000000000333330003333000", + "000333333333333333000000000000000000000333330003333000", + "000333333333333333000000000000000000000333330003333000", + "000333333333333333333333333333333000000333333333333000", + "000000000000333333333333333303333000000333333333333000", + "000000000000333333333333333333333000000333333333333000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000000000000333330000000003333333000000333333000000000", + "000333333333333333333333333300033333333333333333333000", + "000333333333333333333333333300033333333333333333333000", + "000333333333333333333333333300033333333333333333333000", + "000333333333333333333333333333333333333333333333333000", + "000333333333333333333333333333333333333033333333333000", + "000333333333333333333333333333303333333333333333333000", + "000333333333333333333333333333333333333333333333333000", + "000000000000000000000000000333333000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000" + ], + "warps": [ + { + "x": 29, + "y": 62, + "dest_map": "Route2_ViridianForest_SouthEntrance", + "dest_warp": 3 + }, + { + "x": 28, + "y": 62, + "dest_map": "Route2_ViridianForest_SouthEntrance", + "dest_warp": 3 + }, + { + "x": 5, + "y": 9, + "dest_map": "Route2_ViridianForest_NorthEntrance", + "dest_warp": 1 + }, + { + "x": 6, + "y": 9, + "dest_map": "Route2_ViridianForest_NorthEntrance", + "dest_warp": 1 + }, + { + "x": 30, + "y": 62, + "dest_map": "Route2_ViridianForest_SouthEntrance", + "dest_warp": 3 + }, + { + "x": 4, + "y": 9, + "dest_map": "Route2_ViridianForest_NorthEntrance", + "dest_warp": 1 + } + ], + "objects": [ + { + "x": 29, + "y": 58, + "kind": "youngster", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 45, + "y": 58, + "kind": "boy", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 47, + "y": 45, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 47, + "y": 29, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 7, + "y": 22, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 5, + "y": 41, + "kind": "item_ball", + "flag": "FLAG_HIDE_VIRIDIAN_FOREST_POKE_BALL", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 40, + "y": 21, + "kind": "item_ball", + "flag": "FLAG_HIDE_VIRIDIAN_FOREST_ANTIDOTE", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 21, + "y": 34, + "kind": "item_ball", + "flag": "FLAG_HIDE_VIRIDIAN_FOREST_POTION", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 43, + "y": 6, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 16, + "y": 5, + "kind": "bug_catcher", + "flag": "", + "wander_x": 0, + "wander_y": 0 + }, + { + "x": 49, + "y": 60, + "kind": "item_ball", + "flag": "FLAG_HIDE_VIRIDIAN_FOREST_POTION_2", + "wander_x": 0, + "wander_y": 0 + } + ], + "connections": [], + "points": [], + "flag_sets": [] +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h new file mode 100644 index 0000000000..61486c59a6 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h @@ -0,0 +1,35 @@ +/* Overworld Test Maps + * + * From: https://github.com/PokemonAutomation/ + * + * The FRLG maps built into the program, for tests: CI has none of the map + * files in Packages. The .json files in Maps/ next to this file are what + * devtools/maps/frlg_maps.py writes, the same as Resources/PokemonFRLG/Maps + * in Packages; `frlg_maps.py --out --check` checks them. + * CMake builds their text in (pa_embed_text_files() in + * cmake/EmbedTextFiles.cmake). + * + */ + +#ifndef PokemonAutomation_PokemonFRLG_OverworldTestMaps_H +#define PokemonAutomation_PokemonFRLG_OverworldTestMaps_H + +#include +#include +#include + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + + +// (name, JSON text) of each file in Maps/, sorted by name. Generated at +// build time. +const std::vector>& overworld_map_json(); + + + +} +} +} +#endif diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 0c8a8ba32d..a077350236 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1773,6 +1773,7 @@ file(GLOB LIBRARY_SOURCES Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps_Tests.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.h + Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_PlayerFacingReader.cpp From 6fb5b39e8c758007e2bfe1cdef1141f3a5e26117 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 09:41:44 -0800 Subject: [PATCH 09/16] FRLG: route tests read the built-in .json maps; drop the generated C++ copy test_overworld_maps() now parses overworld_map_json(), the Maps/*.json files CMake builds in, so PokemonFRLG_OverworldMapsTestData.{h,cpp}, the copy frlg_maps.py --cpp wrote, goes. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../PokemonFRLG_OverworldMapsTestData.cpp | 3628 ----------------- .../PokemonFRLG_OverworldMapsTestData.h | 38 - .../Overworld/PokemonFRLG_OverworldRoute.cpp | 2 +- .../PokemonFRLG_OverworldTestMaps.cpp | 39 + .../Overworld/PokemonFRLG_OverworldTestMaps.h | 6 + SerialPrograms/cmake/SourceFiles.cmake | 3 +- 6 files changed, 47 insertions(+), 3669 deletions(-) delete mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.cpp delete mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.h create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.cpp diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.cpp deleted file mode 100644 index 1e2fc58818..0000000000 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.cpp +++ /dev/null @@ -1,3628 +0,0 @@ -/* Overworld Maps Test Data - * - * From: https://github.com/PokemonAutomation/ - * - * Generated by devtools/maps/frlg_maps.py; do not edit. Regenerate with - * python3 devtools/maps/frlg_maps.py --cpp - * and check it with - * python3 devtools/maps/frlg_maps.py --cpp --check - * - */ - -#include "Common/Cpp/Exceptions.h" -#include "PokemonFRLG_OverworldMapsTestData.h" - -namespace PokemonAutomation{ -namespace NintendoSwitch{ -namespace PokemonFRLG{ - - -const std::vector>& overworld_map_json(){ - static const std::vector> MAPS{ - {"PalletTown", R"json({ - "name": "PalletTown", - "width": 24, - "height": 20, - "tiles": [ - "############..##########", - "############..##########", - "##....................##", - "##....................##", - "##...#####....#####...##", - "##...#####....#####...##", - "##...#####....#####...##", - "##..S#D###...S#D###...##", - "##....................##", - "##....................##", - "##...........#######..##", - "##...####S...#######..##", - "##...........#######..##", - "##...........###D###..##", - "##...S................##", - "##....................##", - "##...........###S##...##", - "##.....~~~~...........##", - "##.....~~~~...........##", - "##.....~~~~...........##" - ], - "elevation": [ - "000000000000330000000000", - "000000000000330000000000", - "003333333333333333333300", - "003333333333333333333300", - "003330000033330000033300", - "003330000033330000033300", - "003330000033330000033300", - "003300000033300000033300", - "003333333333333333333300", - "003333333333333333333300", - "003333333333300000003300", - "003330000033300000003300", - "003333333333300000003300", - "003333333333300000003300", - "003330333333333333333300", - "003333333333333333333300", - "003333333333300000033300", - "003333311113333333333300", - "003333311113333333333300", - "003333311113333333333300" - ], - "warps": [ - { - "x": 6, - "y": 7, - "dest_map": "PalletTown_PlayersHouse_1F", - "dest_warp": 1 - }, - { - "x": 15, - "y": 7, - "dest_map": "PalletTown_RivalsHouse", - "dest_warp": 0 - }, - { - "x": 16, - "y": 13, - "dest_map": "PalletTown_ProfessorOaksLab", - "dest_warp": 0 - } - ], - "objects": [ - { - "x": 3, - "y": 10, - "kind": "woman_1", - "flag": "", - "wander_x": 1, - "wander_y": 4 - }, - { - "x": 13, - "y": 17, - "kind": "fat_man", - "flag": "", - "wander_x": 6, - "wander_y": 2 - }, - { - "x": 10, - "y": 8, - "kind": "prof_oak", - "flag": "FLAG_HIDE_OAK_IN_PALLET_TOWN", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [ - { - "direction": "north", - "offset": 0, - "map": "Route1" - } - ], - "points": [ - { - "name": "oaks_lab_front", - "x": 16, - "y": 14 - } - ], - "flag_sets": [] -} -)json"}, - {"PalletTown_PlayersHouse_1F", R"json({ - "name": "PalletTown_PlayersHouse_1F", - "width": 13, - "height": 10, - "tiles": [ - "#############", - "#############", - "#.........>##", - "#............", - "#.....##.....", - "#.....##.....", - "#............", - "##..........#", - "#...v........", - "#############" - ], - "elevation": [ - "0000000000000", - "0000000000000", - "0333333333300", - "0333333333333", - "0333330033333", - "0333330033333", - "0333333333333", - "0033333333330", - "0333333333333", - "0000000000000" - ], - "warps": [ - { - "x": 5, - "y": 8, - "dest_map": "PalletTown", - "dest_warp": 0 - }, - { - "x": 4, - "y": 8, - "dest_map": "PalletTown", - "dest_warp": 0 - }, - { - "x": 10, - "y": 2, - "dest_map": "PalletTown_PlayersHouse_2F", - "dest_warp": 0 - }, - { - "x": 3, - "y": 9, - "dest_map": "PalletTown", - "dest_warp": 0 - } - ], - "objects": [ - { - "x": 8, - "y": 4, - "kind": "mom", - "flag": "", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [], - "flag_sets": [] -} -)json"}, - {"PalletTown_PlayersHouse_2F", R"json({ - "name": "PalletTown_PlayersHouse_2F", - "width": 12, - "height": 9, - "tiles": [ - "############", - "###########S", - "#.......##<.", - "#.......##..", - "#.s...#.....", - "#.n...#.....", - "#.#.........", - "#...........", - "#..........." - ], - "elevation": [ - "000000000000", - "000000000000", - "033333330033", - "033333330033", - "033333033333", - "003033033333", - "040403333333", - "003033333333", - "033333333333" - ], - "warps": [ - { - "x": 10, - "y": 2, - "dest_map": "PalletTown_PlayersHouse_1F", - "dest_warp": 2 - } - ], - "objects": [], - "connections": [], - "points": [ - { - "name": "start", - "x": 6, - "y": 6 - } - ], - "flag_sets": [] -} -)json"}, - {"PalletTown_RivalsHouse", R"json({ - "name": "PalletTown_RivalsHouse", - "width": 13, - "height": 10, - "tiles": [ - "#############", - "#############", - ".............", - ".............", - "......##.....", - "......##.....", - ".............", - ".............", - "#...v.......#", - "#############" - ], - "elevation": [ - "0000000000000", - "0000000000000", - "3333333333333", - "3333333333333", - "3333330033333", - "3333330033333", - "3333333333333", - "3333333333333", - "0333333333330", - "3330003333333" - ], - "warps": [ - { - "x": 4, - "y": 8, - "dest_map": "PalletTown", - "dest_warp": 1 - }, - { - "x": 5, - "y": 8, - "dest_map": "PalletTown", - "dest_warp": 1 - }, - { - "x": 3, - "y": 8, - "dest_map": "PalletTown", - "dest_warp": 1 - } - ], - "objects": [ - { - "x": 10, - "y": 6, - "kind": "daisy", - "flag": "", - "wander_x": 1, - "wander_y": 3 - }, - { - "x": 6, - "y": 4, - "kind": "town_map", - "flag": "FLAG_HIDE_TOWN_MAP", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [], - "flag_sets": [] -} -)json"}, - {"PalletTown_ProfessorOaksLab", R"json({ - "name": "PalletTown_ProfessorOaksLab", - "width": 13, - "height": 14, - "tiles": [ - "#############", - "######SS#####", - ".............", - "#............", - "###.....###..", - ".##..........", - ".............", - ".............", - "#####...#####", - ".............", - ".............", - ".............", - "#.....v.....#", - "#############" - ], - "elevation": [ - "0000000000000", - "0000000000000", - "3333333333333", - "0333333333333", - "0003333300033", - "3003333333333", - "3333333333333", - "3333333333333", - "0000033300000", - "3333333333333", - "3333333333333", - "3333333333333", - "0333333333330", - "0000000000000" - ], - "warps": [ - { - "x": 6, - "y": 12, - "dest_map": "PalletTown", - "dest_warp": 2 - }, - { - "x": 7, - "y": 12, - "dest_map": "PalletTown", - "dest_warp": 2 - }, - { - "x": 5, - "y": 12, - "dest_map": "PalletTown", - "dest_warp": 2 - } - ], - "objects": [ - { - "x": 3, - "y": 11, - "kind": "scientist", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 2, - "y": 10, - "kind": "worker_f", - "flag": "", - "wander_x": 0, - "wander_y": 4 - }, - { - "x": 11, - "y": 10, - "kind": "scientist", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 6, - "y": 3, - "kind": "prof_oak", - "flag": "FLAG_HIDE_OAK_IN_HIS_LAB", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 8, - "y": 4, - "kind": "item_ball", - "flag": "FLAG_HIDE_BULBASAUR_BALL", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 9, - "y": 4, - "kind": "item_ball", - "flag": "FLAG_HIDE_SQUIRTLE_BALL", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 10, - "y": 4, - "kind": "item_ball", - "flag": "FLAG_HIDE_CHARMANDER_BALL", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 5, - "y": 4, - "kind": "blue", - "flag": "FLAG_HIDE_RIVAL_IN_LAB", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 4, - "y": 1, - "kind": "pokedex", - "flag": "FLAG_HIDE_POKEDEX", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 5, - "y": 1, - "kind": "pokedex", - "flag": "FLAG_HIDE_POKEDEX", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [], - "flag_sets": [] -} -)json"}, - {"Route1", R"json({ - "name": "Route1", - "width": 24, - "height": 40, - "tiles": [ - "##########....##########", - "##########....##########", - "##....................##", - "##....................##", - "##......##............##", - "##JJJJJJ##JJJJJJ......##", - "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", - "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", - "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", - "##......##\"\"\"\"\"\"\"\"\"\"\"\"##", - "##JJJJJJ##\"\"\"\"\"\"\"\"\"\"\"\"##", - "##......##............##", - "##....................##", - "##..............\"\"\"\"\"\"##", - "##..............\"\"\"\"\"\"##", - "####JJJJJJ######\"\"\"\"\"\"##", - "####......######\"\"\"\"\"\"##", - "##..............\"\"\"\"\"\"##", - "##....................##", - "##....................##", - "##JJ.JJJJ..JJJJJJJJJJJ##", - "##....................##", - "##....................##", - "##....................##", - "##..........\"\"\"\"\"\"....##", - "############\"\"\"\"\"\"....##", - "############\"\"\"\"\"\"JJJJ##", - "##..........\"\"\"\"\"\"....##", - "##..........\"\"\"\"\"\"....##", - "##....................##", - "##....................##", - "##JJJJ...SJJJJJJJJJJJJ##", - "##..\"\"\"\"\"\"\"......\"\"\"\"\"##", - "##..\"\"\"\"\"\"\"......\"\"\"\"\"##", - "##\"\"\"\"\"\"\"......\"\"\"\"\"..##", - "##\"\"\"\"\"\"\"...\"\".\"\"\"\"\"..##", - "############\"\"##########", - "##.........#\"\"#.......##", - "############\"\"##########", - "############\"\"##########" - ], - "elevation": [ - "000000000033330000000000", - "000000000033330000000000", - "003333333333333333333300", - "003333333333333333333300", - "003333330033333333333300", - "000000000000000033333300", - "003333330033333333333300", - "003333330033333333333300", - "003333330033333333333300", - "003333330033333333333300", - "000000000033333333333300", - "003333330033333333333300", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "000000000000000033333300", - "000033333300000033333300", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "000030000330000000000000", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "000000000000333333333300", - "000000000000333333000000", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "000000333000000000000000", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "000000000000330000000000", - "003333333330330333333300", - "000000000000330000000000", - "000000000000330000000000" - ], - "warps": [], - "objects": [ - { - "x": 6, - "y": 28, - "kind": "clerk", - "flag": "", - "wander_x": 0, - "wander_y": 1 - }, - { - "x": 19, - "y": 16, - "kind": "boy", - "flag": "", - "wander_x": 1, - "wander_y": 0 - } - ], - "connections": [ - { - "direction": "north", - "offset": -12, - "map": "ViridianCity" - }, - { - "direction": "south", - "offset": 0, - "map": "PalletTown" - } - ], - "points": [], - "flag_sets": [] -} -)json"}, - {"ViridianCity", R"json({ - "name": "ViridianCity", - "width": 48, - "height": 40, - "tiles": [ - "###################.....########################", - "###################....S########################", - "###################.....########################", - "###################.....########################", - "###################.....####..............######", - "########..................................######", - "########.##########.......................######", - "########.###########.............######...######", - "########.##########..............######...######", - "########.###########...######....######...######", - "########.##########.....#####...S..#D#....######", - "########.###########...##D###.............######", - "########.##########........##JJJJJJJJJJJJJ######", - "########.###########......................######", - "########.##########.......................######", - "######...###########.........###################", - ".........##########.S..######.............######", - "........................#####.....####....######", - ".......................##D###.....####....######", - "..................................SSD#....######", - "#######...................................######", - "#######...................................######", - "#######...................................######", - "###########.............#####.............######", - "###########.##..........#####.............######", - "#######.....##..........#####.............######", - "#######....~~~~~~.......SSD##.............######", - "#######....~~~~~~.........................######", - "#######....~~~~~~.........................######", - "#######....~~~~~~.........................######", - "#######JJJJ~~~~~~JJJ...JJJJJJJJJJJJJJJJJJJ######", - "#######.............S.....................######", - "#######...................................######", - "#######...................................######", - "##############............................######", - "##############............................######", - "######################....######################", - "######################....######################", - "######################....######################", - "######################....######################" - ], - "elevation": [ - "000000000000000000033333000000000000000000000000", - "000000000000000000033330000000000000000000000000", - "000000000000000000033333000000000000000000000000", - "000000000000000000033333000000000000000000000000", - "000000000000000000033333000033333333333333000000", - "000000003333333333333333333333333333333333000000", - "000000003000000000033333333333333333333333000000", - "000000003000000000003333333333333000000333000000", - "000000003000000000033333333333333000000333000000", - "000000003000000000003330000003333000000333000000", - "000000003000000000033333000003330330003333000000", - "000000003000000000003330000003333333333333000000", - "000000003000000000033333333000000000000000000000", - "000000003000000000003333333333333333333333000000", - "000000003000000000033333333333333333333333000000", - "000000333000000000003333333330000000000000000000", - "333333333000000000030330000003333333333333000000", - "333333333333333333333333000003333300003333000000", - "333333333333333333333330000003333300003333000000", - "333333333333333333333333333333333300003333000000", - "000000033333333333333333333333333333333333000000", - "000000033333333333333333333333333333333333000000", - "000000033333333333333333333333333333333333000000", - "000000000003333333333333000003333333333333000000", - "000000000003003333333333000003333333333333000000", - "000000033333003333333333000003333333333333000000", - "000000033331111113333333000003333333333333000000", - "000000033331111113333333333333333333333333000000", - "000000033331111113333333333333333333333333000000", - "000000033331111113333333333333333333333333000000", - "000000000001111110003330000000000000000000000000", - "000000033333333333330333333333333333333333000000", - "000000033333333333333333333333333333333333000000", - "000000033333333333333333333333333333333333000000", - "000000000000003333333333333333333333333333000000", - "000000000000003333333333333333333333333333000000", - "000000000000000000000033330000000000000000000000", - "000000000000000000000033330000000000000000000000", - "000000000000000000000033330000000000000000000000", - "000000000000000000000033330000000000000000000000" - ], - "warps": [ - { - "x": 26, - "y": 26, - "dest_map": "ViridianCity_PokemonCenter_1F", - "dest_warp": 1 - }, - { - "x": 25, - "y": 11, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 36, - "y": 10, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 25, - "y": 18, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 36, - "y": 19, - "dest_map": "ViridianCity_Mart", - "dest_warp": 1 - } - ], - "objects": [ - { - "x": 8, - "y": 26, - "kind": "fat_man", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 11, - "y": 24, - "kind": "cut_tree", - "flag": "FLAG_TEMP_11", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 34, - "y": 11, - "kind": "old_man_1", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 21, - "y": 6, - "kind": "var_0", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 20, - "y": 12, - "kind": "woman_3", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 33, - "y": 26, - "kind": "youngster", - "flag": "", - "wander_x": 0, - "wander_y": 2 - }, - { - "x": 16, - "y": 22, - "kind": "boy", - "flag": "", - "wander_x": 1, - "wander_y": 2 - }, - { - "x": 18, - "y": 5, - "kind": "cut_tree", - "flag": "FLAG_TEMP_12", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 17, - "y": 5, - "kind": "item_ball", - "flag": "FLAG_HIDE_VIRIDIAN_CITY_POTION", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [ - { - "direction": "north", - "offset": 12, - "map": "Route2" - }, - { - "direction": "south", - "offset": 12, - "map": "Route1" - }, - { - "direction": "west", - "offset": 10, - "map": "Route22" - } - ], - "points": [], - "flag_sets": [] -} -)json"}, - {"ViridianCity_Mart", R"json({ - "name": "ViridianCity_Mart", - "width": 11, - "height": 9, - "tiles": [ - "###########", - "###########", - "##.#......#", - "...#.......", - "####...##.#", - ".......##.#", - ".##....##.#", - "....v......", - "###########" - ], - "elevation": [ - "00000000000", - "00000000000", - "00303333330", - "33003333333", - "00003330030", - "33333330030", - "30033330030", - "33333333333", - "00000000000" - ], - "warps": [ - { - "x": 3, - "y": 7, - "dest_map": "ViridianCity", - "dest_warp": 4 - }, - { - "x": 4, - "y": 7, - "dest_map": "ViridianCity", - "dest_warp": 4 - }, - { - "x": 5, - "y": 7, - "dest_map": "ViridianCity", - "dest_warp": 4 - } - ], - "objects": [ - { - "x": 2, - "y": 3, - "kind": "clerk", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 6, - "y": 2, - "kind": "youngster", - "flag": "", - "wander_x": 1, - "wander_y": 1 - }, - { - "x": 9, - "y": 5, - "kind": "woman_1", - "flag": "", - "wander_x": 0, - "wander_y": 1 - } - ], - "connections": [], - "points": [ - { - "name": "clerk_front", - "x": 4, - "y": 3 - } - ], - "flag_sets": [] -} -)json"}, - {"ViridianCity_PokemonCenter_1F", R"json({ - "name": "ViridianCity_PokemonCenter_1F", - "width": 15, - "height": 10, - "tiles": [ - "#.#############", - "###############", - "....###..##....", - "....#######....", - "...............", - "...............", - "#L.........##..", - "...........##..", - ".......v.......", - "###############" - ], - "elevation": [ - "030000000000000", - "000000000000000", - "333300033003333", - "333300000003333", - "333333333333333", - "330333333333333", - "044033333330033", - "330333333330033", - "333333333333333", - "000000000000000" - ], - "warps": [ - { - "x": 6, - "y": 8, - "dest_map": "ViridianCity", - "dest_warp": 0 - }, - { - "x": 7, - "y": 8, - "dest_map": "ViridianCity", - "dest_warp": 0 - }, - { - "x": 8, - "y": 8, - "dest_map": "ViridianCity", - "dest_warp": 0 - }, - { - "x": 1, - "y": 6, - "dest_map": "", - "dest_warp": 0 - } - ], - "objects": [ - { - "x": 7, - "y": 2, - "kind": "nurse", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 12, - "y": 5, - "kind": "gentleman", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 4, - "y": 7, - "kind": "boy", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 2, - "y": 3, - "kind": "youngster", - "flag": "", - "wander_x": 1, - "wander_y": 1 - } - ], - "connections": [], - "points": [ - { - "name": "nurse_front", - "x": 7, - "y": 4 - } - ], - "flag_sets": [] -} -)json"}, - {"Route22", R"json({ - "name": "Route22", - "width": 48, - "height": 24, - "tiles": [ - "#############################################...", - "###########################################.#...", - "##################################........#.###.", - "##################################JJJJ.JJJ#...##", - "######################....................#.....", - "########D######...........................######", - "#####.......###.........................##......", - "###...........#.............######......##......", - "###...........#JJJJJJJ~~~~~~######JJ..JJ##......", - "###JJJJJJJ..JJ#\"\"\"\"\"\"\"~~~~~~######\"\"\"\"\"\"##......", - "###...........#\"\"\"\"\"\"\"~~~~~~######\"\"\"\"\"\"##....##", - "###...........#\"\"\"\"\"\"\"~~~~~~######\"\"\"\"\"\"##....##", - "####...S#######\"\"\"\"\"\"\"......######\"\"\"\"\"\"##....##", - "####...........\"\"\"\"\"\"\"......######\"\"\"\"\"\"##....##", - "####........................######............##", - "####JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ..JJJJJ##", - "####..........................................##", - "####..........................................##", - "####..........................................##", - "################################################", - "################################################", - "################################################", - "################################################", - "################################################" - ], - "elevation": [ - "000000000000000000000000000000000000000000000333", - "000000000000000000000000000000000000000000030333", - "000000000000000000000000000000000033333333030003", - "000000000000000000000000000000000000003000033300", - "000000000000000000000033333333333333333333033333", - "000000000000000333333333333333333333333333000000", - "000003333333000333333333333333333333333300333333", - "000333333333330333333333333300000033333300333333", - "000333333333330000000011111100000000330000333333", - "000000000033000333333311111100000033333300333333", - "000333333333330333333311111100000033333300333300", - "000333333333330333333311111100000033333300333300", - "000033300000000333333333333300000033333300333300", - "000033333333333333333333333300000033333300333300", - "000033333333333333333333333300000033333333333300", - "000000000000000000000000000000000000000330000000", - "000033333333333333333333333333333333333333333300", - "000033333333333333333333333333333333333333333300", - "000033333333333333333333333333333333333333333300", - "000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000" - ], - "warps": [ - { - "x": 8, - "y": 5, - "dest_map": "", - "dest_warp": 2 - }, - { - "x": 9, - "y": 5, - "dest_map": "", - "dest_warp": 2 - } - ], - "objects": [ - { - "x": 25, - "y": 4, - "kind": "blue", - "flag": "FLAG_HIDE_ROUTE_22_RIVAL", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [ - { - "direction": "east", - "offset": -10, - "map": "ViridianCity" - } - ], - "points": [], - "flag_sets": [] -} -)json"}, - {"Route2", R"json({ - "name": "Route2", - "width": 24, - "height": 80, - "tiles": [ - "########....############", - "########....############", - "##\"\"\"\"\"\"\"...############", - "##\"\"\"\"\"\"\"...#.........##", - "##\"\"\"\"\"\"\"...#.........##", - "##\"\"\"\"\"\"\"...#.........##", - "##\"\"\"\"\"\"\"...#########.##", - "##\"\"\"\"\"\"\"...#########.##", - "##\"\"\"\"\"\"\"...#########.##", - "##..........#########.##", - "##..........#########.##", - "##..........#####C###.##", - "##..........#.S.......##", - "####.vv.###.#.........##", - "###########...........##", - "##########............##", - "##############........##", - "##############........##", - "##############........##", - "##############........##", - "##############........##", - "###################...##", - "#################D#...##", - "##############........##", - "################......##", - "################......##", - "##################.#####", - "################......##", - "################......##", - "################......##", - "################......##", - "################......##", - "################JJJ.JJ##", - "################......##", - "################......##", - "################......##", - "################......##", - "################JJJ.JJ##", - "################......##", - "################......##", - "################......##", - "#################.vv.###", - "########################", - "########################", - "########################", - "##........##############", - "##################CC####", - "#################....###", - "################......##", - "################......##", - "###.####.#######......##", - "#####CC#########JJJ.JJ##", - "####....########......##", - "##............##......##", - "##............##......##", - "##JJJJJJJJJ...##......##", - "##....\"\"\"\"\"\"\".##......##", - "##....\"\"\"\"\"\"\".##JJ.JJJ##", - "##....\"\"\"\"\"\"\".##......##", - "##....\"\"\"\"\"\"\".##......##", - "##....\"\"\"\"\"\"\".##......##", - "##............##......##", - "##....................##", - "##....##########......##", - "##....##########......##", - "##....##########......##", - "##....##########......##", - "##............##......##", - "##............##......##", - "##....................##", - "##JJJJJJJ..JJJ..JJ.JJJ##", - "##............##......##", - "####..........##......##", - "####...S......##......##", - "####..........##......##", - "####..........##......##", - "####..........##......##", - "####..........##......##", - "#######.......##########", - "#######.....############" - ], - "elevation": [ - "000000003333000000000000", - "000000003333000000000000", - "003333333333000000000000", - "003333333333033333333300", - "003333333333033333333300", - "003333333333033333333300", - "003333333333000000000300", - "003333333333000000000300", - "003333333333000000000300", - "003333333333000000000300", - "003333333333000000000300", - "003333333333000003000300", - "003333333333030333333300", - "000033330003033333333300", - "000000000003333333333300", - "000000000033333333333300", - "000000000000003333333300", - "000000000000003333333300", - "000000000000003333333300", - "000000000000003333333300", - "000000000000003333333300", - "000000000000000000033300", - "000000000000000000033300", - "000000000000003333333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000000300000", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000000030000", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000000030000", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000003333000", - "000000000000000000000000", - "000000000000000000000000", - "000000000000000000000000", - "003333333300000000000000", - "000000000000000000330000", - "000000000000000003333000", - "000000000000000033333300", - "000000000000000033333300", - "000300003000000033333300", - "000003300000000000030000", - "000033330000000033333300", - "003333333333330033333300", - "003333333333330033333300", - "000000000003330033333300", - "003333333333330033333300", - "003333333333330000300000", - "003333333333330033333300", - "003333333333330033333300", - "003333333333330033333300", - "003333333333330033333300", - "003333333333333333333300", - "003333000000000033333300", - "003333000000000033333300", - "003333000000000033333300", - "003333000000000033333300", - "003333333333330033333300", - "003333333333330033333300", - "003333333333333333333300", - "000000000330003300300000", - "003333333333330033333300", - "000033333333330033333300", - "000033303333330033333300", - "000033333333330033333300", - "000033333333330033333300", - "000033333333330033333300", - "000033333333330033333300", - "000000033333330000000000", - "000000033333000000000000" - ], - "warps": [ - { - "x": 5, - "y": 13, - "dest_map": "Route2_ViridianForest_NorthEntrance", - "dest_warp": 3 - }, - { - "x": 6, - "y": 13, - "dest_map": "Route2_ViridianForest_NorthEntrance", - "dest_warp": 3 - }, - { - "x": 5, - "y": 51, - "dest_map": "Route2_ViridianForest_SouthEntrance", - "dest_warp": 1 - }, - { - "x": 17, - "y": 11, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 17, - "y": 22, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 18, - "y": 46, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 18, - "y": 41, - "dest_map": "", - "dest_warp": 3 - }, - { - "x": 19, - "y": 41, - "dest_map": "", - "dest_warp": 3 - }, - { - "x": 19, - "y": 46, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 6, - "y": 51, - "dest_map": "Route2_ViridianForest_SouthEntrance", - "dest_warp": 1 - } - ], - "objects": [ - { - "x": 16, - "y": 62, - "kind": "cut_tree", - "flag": "FLAG_TEMP_14", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 15, - "y": 69, - "kind": "cut_tree", - "flag": "FLAG_TEMP_13", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 11, - "y": 13, - "kind": "cut_tree", - "flag": "FLAG_TEMP_15", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 18, - "y": 26, - "kind": "cut_tree", - "flag": "FLAG_TEMP_16", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 17, - "y": 54, - "kind": "item_ball", - "flag": "FLAG_HIDE_ROUTE2_ETHER", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 17, - "y": 64, - "kind": "item_ball", - "flag": "FLAG_HIDE_ROUTE2_PARALYZE_HEAL", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 6, - "y": 85, - "kind": "cut_tree", - "flag": "", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [ - { - "direction": "north", - "offset": -12, - "map": "PewterCity" - }, - { - "direction": "south", - "offset": -12, - "map": "ViridianCity" - } - ], - "points": [], - "flag_sets": [] -} -)json"}, - {"Route2_ViridianForest_SouthEntrance", R"json({ - "name": "Route2_ViridianForest_SouthEntrance", - "width": 15, - "height": 12, - "tiles": [ - "###############", - "#######C#######", - "##...#...#...##", - "#.............#", - "#..........##.#", - "###........##.#", - "#.............#", - "#..........##.#", - "###........##.#", - "#.............#", - "#......v......#", - "###############" - ], - "elevation": [ - "000000000000000", - "000000030000000", - "003330333033300", - "033333333333330", - "033333333330030", - "000333333330030", - "033333333333330", - "033333333330030", - "000333333330030", - "033333333333330", - "033333333333330", - "000000000000000" - ], - "warps": [ - { - "x": 6, - "y": 10, - "dest_map": "Route2", - "dest_warp": 2 - }, - { - "x": 7, - "y": 10, - "dest_map": "Route2", - "dest_warp": 2 - }, - { - "x": 8, - "y": 10, - "dest_map": "Route2", - "dest_warp": 2 - }, - { - "x": 7, - "y": 1, - "dest_map": "ViridianForest", - "dest_warp": 0 - } - ], - "objects": [ - { - "x": 10, - "y": 6, - "kind": "woman_2", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 4, - "y": 7, - "kind": "woman_1", - "flag": "", - "wander_x": 1, - "wander_y": 1 - } - ], - "connections": [], - "points": [], - "flag_sets": [] -} -)json"}, - {"ViridianForest", R"json({ - "name": "ViridianForest", - "width": 54, - "height": 69, - "tiles": [ - "######################################################", - "######################################################", - "######################################################", - "######################################################", - "######################################################", - "###########.............###........................###", - "###########.............###........................###", - "###########.............###........................###", - "#..#####..#.............###.....###############....###", - "####CCC####.............###.....###############....###", - "####...####.............###.....###############....###", - "####...####.....###.....###.....###############....###", - "####..S####\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###############....###", - "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###############....###", - "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###############....###", - "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".............###", - "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".............###", - "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".............###", - "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\".......#########", - "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"........#########", - "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"\"######......#########", - "###\"\"\"\"\"###\"\"\"\"\"###\"\"\"\"\"###...\"\"\"######......#########", - "###\"\"\"\"\"###\"\"\"\"\"###.....###......######......#########", - "###\"\"\"\"\"###\"\"\"\"\"###..............######......#########", - "###\"\"\"\"\"###\"\"\"\"\"#####............######......#########", - "###\"\"\"\"\"###\"\"\"\"\"#####............######............###", - "###\"\"\"\"\"###\"\"\"\"\"\"\"#####################....S.......###", - "###\"\"\"\"\"...\"\"\"\"\"\"\"#####################............###", - "###...............#####################............###", - "###......S........#####################\"\"\"\"........###", - "###...............#####################\"\"\"\"\"###....###", - "###.....................###############\"\"\"\"\"###....###", - "###.....................###############\"\"\"\"\"###....###", - "###.....................###############\"\"\"\"\"###....###", - "##################......###############\"\"\"\"\"###....###", - "##################......###############\"\"\"\"\"###....###", - "#######################################\"\"\"\"\"###....###", - "#######################################\"\"\"\"\"###....###", - "#######################################\"\"\"\"\"###....###", - "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", - "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", - "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", - "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"#####################\"\"\"\"\"###....###", - "###\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"######\"\"\"\"........###", - "############\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"S..\"\"######\"\"\".........###", - "############\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"...\"\"######\"\"\".........###", - "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", - "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", - "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", - "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", - "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", - "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", - "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", - "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", - "############..\"\"\"#########\"\"...\"\"######\"\"\"...#########", - "###\"\"\"\"\"\"\"\"\"..\"\"\"\"\"\"\"\"\"\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"###", - "###\"\"\"\"\"\"\"\"\"..\"\"\"\"\"\"\"\"\"\"\"\"\"\"###\"\"\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"###", - "###\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"\"\"\"\"\"\".###.\"\"\"\"\"\"\"\"\"...\"\"\"\"\"\"\"###", - "###\"\"\"\"\"\"\"\"\"....\"\"\"\"\"\"\"\"\"\".......\"\"\"\"\"\"\"....\"\"\"\"\"\"\"###", - "###\"\"\"\"\"\"\"\"............................S....\"\"\"\"\"\"\"###", - "###\"\"\"\"\"\"\"\"....................S...........\"\"\"\"\"\"\"\"###", - "###\"\"\"\"\"\"\"\"................................\"\"\"\"\"\"\"\"###", - "###########################.vvv..#####################", - "######################################################", - "######################################################", - "######################################################", - "######################################################", - "######################################################", - "######################################################" - ], - "elevation": [ - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000003333333333333000333333333333333333333333000", - "000000000003333333333333000333333333333333333333333000", - "000000000003333333333333000333333333333333333333333000", - "033000003303333333333333000333330000000000000003333000", - "000033300003333333333333000333330000000000000003333000", - "000033300003333333333333000333330000000000000003333000", - "000033300003333300033333000333330000000000000003333000", - "000033000003333300033333000333330000000000000003333000", - "000333330003333300033333000333330000000000000003333000", - "000333330003333300033333000333330000000000000003333000", - "000333330003333300033333000333333333333333333333333000", - "000333330003333300033333000333333333333333333333333000", - "000333330003333300033333000333333333333333333333333000", - "000333330003333300033333000333333333333333333000000000", - "000333330003333300033333000333333333333333333000000000", - "000333330003333300033333000333333000000333333000000000", - "000333330003333300033333000333333000000333333000000000", - "000333330003333300033333000333333000000333333000000000", - "000333330003333300033333333333333000000333333000000000", - "000333330003333300000333333333333000000333333000000000", - "000333330003333300000333333333333000000333333333333000", - "000333330003333333000000000000000000000333303333333000", - "000333333333333333000000000000000000000333333333333000", - "000333333333333333000000000000000000000333333333333000", - "000333333033333333000000000000000000000333333333333000", - "000333333333333333000000000000000000000333330003333000", - "000333333333333333333333000000000000000333330003333000", - "000333333333333333333333000000000000000333330003333000", - "000333333333333333333333000000000000000333330003333000", - "000000000000000000333333000000000000000333330003333000", - "000000000000000000333333000000000000000333330003333000", - "000000000000000000000000000000000000000333330003333000", - "000000000000000000000000000000000000000333330003333000", - "000000000000000000000000000000000000000333330003333000", - "000333333333333333000000000000000000000333330003333000", - "000333333333333333000000000000000000000333330003333000", - "000333333333333333000000000000000000000333330003333000", - "000333333333333333000000000000000000000333330003333000", - "000333333333333333333333333333333000000333333333333000", - "000000000000333333333333333303333000000333333333333000", - "000000000000333333333333333333333000000333333333333000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000333333333333333333333333300033333333333333333333000", - "000333333333333333333333333300033333333333333333333000", - "000333333333333333333333333300033333333333333333333000", - "000333333333333333333333333333333333333333333333333000", - "000333333333333333333333333333333333333033333333333000", - "000333333333333333333333333333303333333333333333333000", - "000333333333333333333333333333333333333333333333333000", - "000000000000000000000000000333333000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000" - ], - "warps": [ - { - "x": 29, - "y": 62, - "dest_map": "Route2_ViridianForest_SouthEntrance", - "dest_warp": 3 - }, - { - "x": 28, - "y": 62, - "dest_map": "Route2_ViridianForest_SouthEntrance", - "dest_warp": 3 - }, - { - "x": 5, - "y": 9, - "dest_map": "Route2_ViridianForest_NorthEntrance", - "dest_warp": 1 - }, - { - "x": 6, - "y": 9, - "dest_map": "Route2_ViridianForest_NorthEntrance", - "dest_warp": 1 - }, - { - "x": 30, - "y": 62, - "dest_map": "Route2_ViridianForest_SouthEntrance", - "dest_warp": 3 - }, - { - "x": 4, - "y": 9, - "dest_map": "Route2_ViridianForest_NorthEntrance", - "dest_warp": 1 - } - ], - "objects": [ - { - "x": 29, - "y": 58, - "kind": "youngster", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 45, - "y": 58, - "kind": "boy", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 47, - "y": 45, - "kind": "bug_catcher", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 47, - "y": 29, - "kind": "bug_catcher", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 7, - "y": 22, - "kind": "bug_catcher", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 5, - "y": 41, - "kind": "item_ball", - "flag": "FLAG_HIDE_VIRIDIAN_FOREST_POKE_BALL", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 40, - "y": 21, - "kind": "item_ball", - "flag": "FLAG_HIDE_VIRIDIAN_FOREST_ANTIDOTE", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 21, - "y": 34, - "kind": "item_ball", - "flag": "FLAG_HIDE_VIRIDIAN_FOREST_POTION", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 43, - "y": 6, - "kind": "bug_catcher", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 16, - "y": 5, - "kind": "bug_catcher", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 49, - "y": 60, - "kind": "item_ball", - "flag": "FLAG_HIDE_VIRIDIAN_FOREST_POTION_2", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [], - "flag_sets": [] -} -)json"}, - {"Route2_ViridianForest_NorthEntrance", R"json({ - "name": "Route2_ViridianForest_NorthEntrance", - "width": 15, - "height": 12, - "tiles": [ - "###############", - "#######C#######", - "##...#...#...##", - "#.............#", - "#..........##.#", - "###........##.#", - "#.............#", - "#..........##.#", - "###........##.#", - "#.............#", - "#......v......#", - "###############" - ], - "elevation": [ - "000000000000000", - "000000030000000", - "003330333033300", - "033333333333330", - "033333333330030", - "000333333330030", - "033333333333330", - "033333333330030", - "000333333330030", - "033333333333330", - "033333333333330", - "000000000000000" - ], - "warps": [ - { - "x": 6, - "y": 10, - "dest_map": "ViridianForest", - "dest_warp": 2 - }, - { - "x": 7, - "y": 10, - "dest_map": "ViridianForest", - "dest_warp": 2 - }, - { - "x": 8, - "y": 10, - "dest_map": "ViridianForest", - "dest_warp": 2 - }, - { - "x": 7, - "y": 1, - "dest_map": "Route2", - "dest_warp": 0 - } - ], - "objects": [ - { - "x": 5, - "y": 4, - "kind": "youngster", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 4, - "y": 7, - "kind": "old_man_1", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 10, - "y": 5, - "kind": "cooltrainer_f", - "flag": "", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [], - "flag_sets": [] -} -)json"}, - {"PewterCity", R"json({ - "name": "PewterCity", - "width": 48, - "height": 40, - "tiles": [ - "################################################", - "#######################....#####################", - "####........#################.........##########", - "####........#################.........##########", - "####........#############D######......##########", - "####........###########...............##########", - "#######.....#####C#####..#######........########", - "####JJJ..JJJJJJJ...SJJJJJJJJJJJJJJJJJ...########", - "####....................................########", - "####............................#####...########", - "######..........................#####...########", - "######..........................#D###...########", - "######..................................########", - "######...##.#######.##..................########", - "######...#############..................########", - "######...##.#######.##..................########", - "######...##S..#D#...##....####..........########", - "######...............#....######........########", - "######...............#....SSD###........########", - "######...............#.................S########", - "######################..........................", - "######..........................................", - "######.......#########..........................", - "######.......#########....##########............", - "######.......#########....##########....########", - "######.......##SSD####....#####S#####...########", - "######....................#.........#...########", - "######....................#.........#...########", - "######..#####.............#.........#...########", - "######..#####.............#.........#...########", - "######..#D###.......S.....#JJJJ.JJJJ#...########", - "######..................................########", - "######..................................########", - "######..................................########", - "######..................................########", - "######..................................########", - "####################....########################", - "####################....########################", - "####################....########################", - "####################....########################" - ], - "elevation": [ - "000000000000000000000000000000000000000000000000", - "000000000000000000000003333000000000000000000000", - "000033333333000000000000000003333333330000000000", - "000033333333000000000000000003333333330000000000", - "000033333333000000000000000000003333330000000000", - "000033333333000000000003333333333333330000000000", - "000000033333000003000003300000003333333300000000", - "000000033000000033300000000000000000033300000000", - "000033333333333333333333333333333333333300000000", - "000033333333333333333333333333330000033300000000", - "000000333333333333333333333333330000033300000000", - "000000333333333333333333333333330000033300000000", - "000000333333333333333333333333333333333300000000", - "000000333003000000030033333333333333333300000000", - "000000333000000000000033333333333333333300000000", - "000000333003000000030033333333333333333300000000", - "000000333000330003330033330000333333333300000000", - "000000333333333333333033330000003333333300000000", - "000000333333333333333033330000003333333300000000", - "000000333333333333333033333333333333333000000000", - "000000000000000000000033333333333333333333333333", - "000000333333333333333333333333333333333333333333", - "000000333333300000000033333333333333333333333333", - "000000333333300000000033330000000000333333333333", - "000000333333300000000033330000000000333300000000", - "000000333333300000000033330000000000033300000000", - "000000333333333333333333330333333333033300000000", - "000000333333333333333333330333333333033300000000", - "000000330000033333333333330333333333033300000000", - "000000330000033333333333330333333333033300000000", - "000000330000033333330333330000030000033300000000", - "000000333333333333333333333333333333333300000000", - "000000333333333333333333333333333333333300000000", - "000000333333333333333333333333333333333300000000", - "000000333333333333333333333333333333333300000000", - "000000333333333333333333333333333333333300000000", - "000000000000000000003333000000000000000000000000", - "000000000000000000003333000000000000000000000000", - "000000000000000000003333000000000000000000000000", - "000000000000000000003333000000000000000000000000" - ], - "warps": [ - { - "x": 17, - "y": 6, - "dest_map": "PewterCity_Museum_1F", - "dest_warp": 1 - }, - { - "x": 25, - "y": 4, - "dest_map": "PewterCity_Museum_1F", - "dest_warp": 3 - }, - { - "x": 15, - "y": 16, - "dest_map": "PewterCity_Gym", - "dest_warp": 1 - }, - { - "x": 28, - "y": 18, - "dest_map": "PewterCity_Mart", - "dest_warp": 1 - }, - { - "x": 33, - "y": 11, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 17, - "y": 25, - "dest_map": "PewterCity_PokemonCenter_1F", - "dest_warp": 1 - }, - { - "x": 9, - "y": 30, - "dest_map": "", - "dest_warp": 1 - } - ], - "objects": [ - { - "x": 6, - "y": 15, - "kind": "lass", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 33, - "y": 17, - "kind": "man", - "flag": "FLAG_HIDE_PEWTER_MUSEUM_GUIDE", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 21, - "y": 28, - "kind": "fat_man", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 33, - "y": 27, - "kind": "bug_catcher", - "flag": "", - "wander_x": 2, - "wander_y": 0 - }, - { - "x": 42, - "y": 20, - "kind": "boy", - "flag": "FLAG_HIDE_PEWTER_CITY_GYM_GUIDE", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 30, - "y": 5, - "kind": "cut_tree", - "flag": "FLAG_TEMP_12", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 46, - "y": 20, - "kind": "scientist", - "flag": "FLAG_HIDE_PEWTER_CITY_RUNNING_SHOES_GUY", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [ - { - "direction": "south", - "offset": 12, - "map": "Route2" - } - ], - "points": [ - { - "name": "gym_front", - "x": 15, - "y": 17 - } - ], - "flag_sets": [] -} -)json"}, - {"PewterCity_PokemonCenter_1F", R"json({ - "name": "PewterCity_PokemonCenter_1F", - "width": 15, - "height": 10, - "tiles": [ - "#.#############", - "###############", - "....###..##....", - "....#######....", - "...............", - "...............", - "#L.........##..", - "...........##..", - ".......v.......", - "###############" - ], - "elevation": [ - "030000000000000", - "000000000000000", - "333300033003333", - "333300000003333", - "333333333333333", - "330333333333333", - "044033333330033", - "330333333330033", - "333333333333333", - "000000000000000" - ], - "warps": [ - { - "x": 6, - "y": 8, - "dest_map": "PewterCity", - "dest_warp": 5 - }, - { - "x": 7, - "y": 8, - "dest_map": "PewterCity", - "dest_warp": 5 - }, - { - "x": 8, - "y": 8, - "dest_map": "PewterCity", - "dest_warp": 5 - }, - { - "x": 1, - "y": 6, - "dest_map": "", - "dest_warp": 0 - } - ], - "objects": [ - { - "x": 2, - "y": 2, - "kind": "jigglypuff", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 4, - "y": 8, - "kind": "gentleman", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 7, - "y": 2, - "kind": "nurse", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 1, - "y": 2, - "kind": "youngster", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 13, - "y": 2, - "kind": "woman_1", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 10, - "y": 7, - "kind": "gba_kid", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 14, - "y": 6, - "kind": "gba_kid", - "flag": "", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [ - { - "name": "nurse_front", - "x": 7, - "y": 4 - } - ], - "flag_sets": [] -} -)json"}, - {"PewterCity_Mart", R"json({ - "name": "PewterCity_Mart", - "width": 11, - "height": 9, - "tiles": [ - "###########", - "###########", - "##.#......#", - "...#.......", - "####...##.#", - ".......##.#", - ".##....##.#", - "....v......", - "###########" - ], - "elevation": [ - "00000000000", - "00000000000", - "00303333330", - "33003333333", - "00003330030", - "33333330030", - "30033330030", - "33333333333", - "00000000000" - ], - "warps": [ - { - "x": 3, - "y": 7, - "dest_map": "PewterCity", - "dest_warp": 3 - }, - { - "x": 4, - "y": 7, - "dest_map": "PewterCity", - "dest_warp": 3 - }, - { - "x": 5, - "y": 7, - "dest_map": "PewterCity", - "dest_warp": 3 - } - ], - "objects": [ - { - "x": 8, - "y": 2, - "kind": "youngster", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 6, - "y": 4, - "kind": "boy", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 2, - "y": 3, - "kind": "clerk", - "flag": "", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [], - "flag_sets": [] -} -)json"}, - {"PewterCity_Museum_1F", R"json({ - "name": "PewterCity_Museum_1F", - "width": 28, - "height": 11, - "tiles": [ - "############################", - "############################", - "...............#............", - "...............#......#....#", - "...####........#...........#", - "...............#............", - "...........#...#...........#", - "...####..###...###.........#", - "........>###.....#..........", - "#........###..v.##...v..##..", - "############################" - ], - "elevation": [ - "0000000000000000000000000000", - "0000000000000000000000000000", - "3333333333333330333333333333", - "3333333333333330333333033330", - "3330000333333330333333333330", - "3333333333333330333333333333", - "3333333333303330333333333330", - "3330000330003330003333333330", - "3333333330003333303333333333", - "0333333330003333003333330033", - "0000000000000000000000000000" - ], - "warps": [ - { - "x": 13, - "y": 9, - "dest_map": "PewterCity", - "dest_warp": 0 - }, - { - "x": 14, - "y": 9, - "dest_map": "PewterCity", - "dest_warp": 0 - }, - { - "x": 15, - "y": 9, - "dest_map": "PewterCity", - "dest_warp": 0 - }, - { - "x": 21, - "y": 9, - "dest_map": "PewterCity", - "dest_warp": 1 - }, - { - "x": 22, - "y": 9, - "dest_map": "PewterCity", - "dest_warp": 1 - }, - { - "x": 8, - "y": 8, - "dest_map": "", - "dest_warp": 0 - } - ], - "objects": [ - { - "x": 16, - "y": 5, - "kind": "worker_m", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 2, - "y": 4, - "kind": "old_man_1", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 21, - "y": 3, - "kind": "scientist", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 22, - "y": 3, - "kind": "old_amber", - "flag": "FLAG_HIDE_OLD_AMBER", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 26, - "y": 4, - "kind": "scientist", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 26, - "y": 7, - "kind": "scientist", - "flag": "", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [], - "flag_sets": [] -} -)json"}, - {"PewterCity_Gym", R"json({ - "name": "PewterCity_Gym", - "width": 13, - "height": 16, - "tiles": [ - "#############", - "####.....####", - "#############", - "#....#.#....#", - "#...........#", - "#...#...#...#", - "#...........#", - "#..#.#.#.#..#", - "##.........##", - "#...#...#...#", - "##.........##", - "#...........#", - "#...S...S...#", - "#...........#", - "#.....v.....#", - "#############" - ], - "elevation": [ - "0000000000000", - "0000333330000", - "0000000000000", - "0333303033330", - "0333333333330", - "0333033303330", - "0333333333330", - "0330303030330", - "0033333333300", - "0333033303330", - "0033333333300", - "0333333333330", - "0333033303330", - "0333333333330", - "0333333333330", - "0000000000000" - ], - "warps": [ - { - "x": 5, - "y": 14, - "dest_map": "PewterCity", - "dest_warp": 2 - }, - { - "x": 6, - "y": 14, - "dest_map": "PewterCity", - "dest_warp": 2 - }, - { - "x": 7, - "y": 14, - "dest_map": "PewterCity", - "dest_warp": 2 - } - ], - "objects": [ - { - "x": 6, - "y": 5, - "kind": "brock", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 3, - "y": 8, - "kind": "camper", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 7, - "y": 12, - "kind": "gym_guy", - "flag": "", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [ - { - "name": "brock_front", - "x": 6, - "y": 6 - } - ], - "flag_sets": [] -} -)json"}, - {"CeruleanCity_PokemonCenter_1F", R"json({ - "name": "CeruleanCity_PokemonCenter_1F", - "width": 15, - "height": 10, - "tiles": [ - "#.#############", - "###############", - "....###..##....", - "....#######....", - "...............", - "...............", - "#L.........##..", - "...........##..", - ".......v.......", - "###############" - ], - "elevation": [ - "030000000000000", - "000000000000000", - "333300033003333", - "333300000003333", - "333333333333333", - "330333333333333", - "044033333330033", - "330333333330033", - "333333333333333", - "000000000000000" - ], - "warps": [ - { - "x": 6, - "y": 8, - "dest_map": "CeruleanCity", - "dest_warp": 3 - }, - { - "x": 7, - "y": 8, - "dest_map": "CeruleanCity", - "dest_warp": 3 - }, - { - "x": 8, - "y": 8, - "dest_map": "CeruleanCity", - "dest_warp": 3 - }, - { - "x": 1, - "y": 6, - "dest_map": "", - "dest_warp": 0 - } - ], - "objects": [ - { - "x": 7, - "y": 2, - "kind": "nurse", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 12, - "y": 5, - "kind": "gentleman", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 5, - "y": 4, - "kind": "rocker", - "flag": "", - "wander_x": 1, - "wander_y": 0 - }, - { - "x": 4, - "y": 8, - "kind": "youngster", - "flag": "", - "wander_x": 1, - "wander_y": 0 - }, - { - "x": 3, - "y": 3, - "kind": "lass", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 2, - "y": 1, - "kind": "0", - "flag": "FLAG_HIDE_POSTGAME_GOSSIPERS", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 3, - "y": 1, - "kind": "0", - "flag": "FLAG_HIDE_POSTGAME_GOSSIPERS", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [ - { - "name": "pc", - "x": 11, - "y": 2 - }, - { - "name": "nurse_front", - "x": 7, - "y": 4 - } - ], - "flag_sets": [] -} -)json"}, - {"CeruleanCity", R"json({ - "name": "CeruleanCity", - "width": 48, - "height": 40, - "tiles": [ - "################~~~~~#...#...#~~~~~~~~~~~~~~~~~~", - "################~~~~~#...#JJJ#~~~~~~~~~~~~~~~~~~", - "####~~~~~~~~~~~~~~~~~#...#...#~~~~~~~~~~~~~~~~~~", - "####~~~~~~~~~~~~~~~~~#...#...#~~~~~~~~~~~~~~~~~~", - "####~~~~~~~~~~~~~~~~~#...#...###################", - "####~~~###############...#...#.........#########", - "####~~~#.............#...#...#.........#########", - "####~~~#.............#...#...#.........#########", - "####~~~##.v.##########.......#.v.##...##########", - "####~~~###############......#######...##########", - "####~~~###############......#######...##########", - "####~~~###D######D####......##D####......#######", - "#C##~~~#..........................#......#######", - "....~~~#..........................#......#######", - "....~~~#..........................#......#######", - "....~~~#.....#######..............#......#######", - "~~~~~~~#...JJ############.........#......#......", - "~~~~~~~#.....##D#########.........#......#######", - "~~~~~~~#............#####JJJ#######.............", - "########............SSD##...#######.............", - "............................#######JJJ#..#######", - "...........................S..#D#.....#..#......", - "......................................#..#######", - "#######...............................#..#######", - "#######.....####......................#..#######", - "#######....#####....S.................#..#######", - "#######....#####.....###############..#..#######", - "#######....#####.....###############..#..#######", - "#######....S#CC#.....##D###SSD######..#..#######", - "#######...............................#..#######", - "#######...............................#..#######", - "#######...............................#..#######", - "###################S######.############..#######", - "#######..................................#######", - "#######..................................#######", - "###############....#........#....###############", - "###############....#JJJJJJJJ#....###############", - "###############....#........#....###############", - "###############....#........#....###############", - "###############....#........#....###############" - ], - "elevation": [ - "000000000000000011111033303330100000000000000000", - "000000000000000011111033300000100000000000000000", - "000011111111111111111033303330100000000000000000", - "000011111111111111111033303330111111111111111111", - "000011111111111111111033303330000000000000000000", - "000011100000000000000033303330333333333000000000", - "000011103333333333333033303330333333333000000000", - "000011103333333333333033303330333333333000000000", - "000011100333000000000033333330333003330000000000", - "000011100000000000000033333300000003330000000000", - "000011100000000000000033333300000003330000000000", - "000011100000000000000033333300000003333330000000", - "030011103333333333333333333333333303333330000000", - "333311103333333333333333333333333303333330000000", - "333311103333333333333333333333333303333330000000", - "333311103333300000003333333333333303333330000000", - "111111103330000000000000033333333303333330333333", - "111111103333300000000000033333333303333330000000", - "111111103333333333330000000000000003333333333333", - "000000003333333333330000033300000003333333333333", - "333333333333333333333333333300000000000330000000", - "333333333333333333333333333033000333330330333333", - "333333333333333333333333333333333333330330000000", - "000000033333333333333333333333333333330330000000", - "000000033333000033333333333333333333330330000000", - "000000033330000033330333333333333333330330000000", - "000000033330000033333000000000000000330330000000", - "000000033330000033333000000000000000330330000000", - "000000033330033033333000000000000000330330000000", - "000000033333333333333333333333333333330330000000", - "000000033333333333333333333333333333330330000000", - "000000033333333333333333333333333333330330000000", - "000000000000000000000000003000000000000330000000", - "000000033333333333333333333333333333333330000000", - "000000033333333333333333333333333333333330000000", - "000000000000000333303333333303333000000000000000", - "000000000000000333300000000003333000000000000000", - "000000000000000333303333333303333000000000000000", - "000000000000000333303333333303333000000000000000", - "000000000000000333303333333303333000000000000000" - ], - "warps": [ - { - "x": 10, - "y": 11, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 30, - "y": 11, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 15, - "y": 17, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 22, - "y": 19, - "dest_map": "CeruleanCity_PokemonCenter_1F", - "dest_warp": 1 - }, - { - "x": 31, - "y": 21, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 13, - "y": 28, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 29, - "y": 28, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 1, - "y": 12, - "dest_map": "CeruleanCave_1F", - "dest_warp": 0 - }, - { - "x": 10, - "y": 8, - "dest_map": "", - "dest_warp": 3 - }, - { - "x": 31, - "y": 8, - "dest_map": "", - "dest_warp": 3 - }, - { - "x": 31, - "y": 9, - "dest_map": "", - "dest_warp": 3 - }, - { - "x": 14, - "y": 28, - "dest_map": "", - "dest_warp": 1 - }, - { - "x": 23, - "y": 28, - "dest_map": "", - "dest_warp": 0 - }, - { - "x": 17, - "y": 11, - "dest_map": "", - "dest_warp": 0 - } - ], - "objects": [ - { - "x": 31, - "y": 12, - "kind": "policeman", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 33, - "y": 6, - "kind": "rocket_m", - "flag": "FLAG_HIDE_CERULEAN_ROCKET", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 16, - "y": 21, - "kind": "little_boy", - "flag": "", - "wander_x": 0, - "wander_y": 3 - }, - { - "x": 9, - "y": 23, - "kind": "balding_man", - "flag": "", - "wander_x": 1, - "wander_y": 1 - }, - { - "x": 32, - "y": 29, - "kind": "slowbro", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 33, - "y": 29, - "kind": "lass", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 34, - "y": 22, - "kind": "youngster", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 22, - "y": 0, - "kind": "blue", - "flag": "FLAG_HIDE_CERULEAN_RIVAL", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 26, - "y": 32, - "kind": "cut_tree", - "flag": "FLAG_TEMP_13", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 50, - "y": 18, - "kind": "cut_tree", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 12, - "y": 30, - "kind": "woman_1", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 1, - "y": 13, - "kind": "cooltrainer_m", - "flag": "FLAG_HIDE_CERULEAN_CAVE_GUARD", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [ - { - "direction": "north", - "offset": 12, - "map": "Route24" - } - ], - "points": [], - "flag_sets": [ - { - "name": "after_hall_of_fame", - "flags": [ - "FLAG_HIDE_CERULEAN_CAVE_GUARD", - "FLAG_HIDE_CERULEAN_RIVAL", - "FLAG_HIDE_CERULEAN_ROCKET" - ] - } - ] -} -)json"}, - {"Route24", R"json({ - "name": "Route24", - "width": 24, - "height": 40, - "tiles": [ - "########################", - "########################", - "########################", - "####.........J...J......", - "####.........J...J......", - "####.........J...J......", - "###JJJJ..JJJJ#...#JJJJJJ", - "###.....................", - "###.....................", - "###.....................", - "###..........###########", - "###..........#..........", - "###..........#...#######", - "###..........#...#######", - "###..........#...#######", - "###..........#...#######", - "###...~~~#...#...#######", - "###...~~~#...#...#######", - "###...~~~#...#...#######", - "###\"\"\"~~~#...#...#######", - "###\"\"\"~~~#...#...#######", - "###\"\"\"~~~#...#...#######", - "###\"\"\"~~~#...#...#######", - "###\"\"\"~~~#...#...#######", - "###\"\"\"~~~#...#...#######", - "###\"\"\"~~~#...#...#######", - "###\"\"\"~~~#...#...#######", - "###\"\"\"~~~#...#...#~~~~~~", - "###\"\"\"~~~#...#...#~~~~~~", - "###\"\"\"~~~#...#...#~~~~~~", - "###\"\"\"~~~#...#...#~~~~~~", - "###\"\"\"~~~#...#...#~~~~~~", - "####~~~~~#...#...#~~~~~~", - "####~~~~~#...#...#~~~~~~", - "####~~~~~#...#...#~~~~~~", - "####~~~~~#...#...#~~~~~~", - "####~~~~~#...#...#~~~~~~", - "####~~~~~#...#...#~~~~~~", - "####~~~~~#...#...#~~~~~~", - "####~~~~~#...#...#~~~~~~" - ], - "elevation": [ - "000000000000000000000000", - "000000000000000000000000", - "000000000000000000000000", - "000033333333303330333333", - "000033333333303330333333", - "000033333333303330333333", - "000000033000003330000000", - "000333333333333333333333", - "000333333333333333333333", - "000333333333333333333333", - "000333333333300000000000", - "000333333333303333333333", - "000333333333303330000000", - "000333333333303330000000", - "000333333333303330000000", - "000333333333303330000000", - "000333111033303330000000", - "000333111033303330000000", - "000333111033303330000000", - "000333111033303330000000", - "000333111033303330000000", - "000333111033303330000000", - "000333111033303330000000", - "000333111033303330000000", - "000333111033303330000000", - "000333111033303330000000", - "000333111033303330000000", - "000333111033303330111111", - "000333111033303330100000", - "000333111033303330100000", - "000333111033303330100000", - "000333111033303330100000", - "000011111033303330100000", - "000011111033303330100000", - "000011111033303330100000", - "000011111033303330100000", - "000011111033303330100000", - "000011111033303330100000", - "000011111033303330100000", - "000011111033303330100000" - ], - "warps": [], - "objects": [ - { - "x": 12, - "y": 15, - "kind": "man", - "flag": "FLAG_HIDE_NUGGET_BRIDGE_ROCKET", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 12, - "y": 19, - "kind": "camper", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 10, - "y": 22, - "kind": "lass", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 12, - "y": 25, - "kind": "youngster", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 10, - "y": 28, - "kind": "lass", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 12, - "y": 31, - "kind": "bug_catcher", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 5, - "y": 21, - "kind": "camper", - "flag": "", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 11, - "y": 4, - "kind": "item_ball", - "flag": "FLAG_HIDE_ROUTE24_TM45", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [ - { - "direction": "south", - "offset": -12, - "map": "CeruleanCity" - } - ], - "points": [], - "flag_sets": [] -} -)json"}, - {"CeruleanCave_1F", R"json({ - "name": "CeruleanCave_1F", - "width": 40, - "height": 23, - "tiles": [ - "########################################", - "#######...##.#########~~~~~~~~~#..##..##", - "#######...L..#########~~~~~~~~~#..L...##", - "#######..##..#~~~~~~~~~~~~~~~~~#......##", - "##L####..##..#~~~~~~~~~~#...#~~##.######", - "##.#.........#~~~~~~~~~~#...#~~~~~~~~~~#", - "#..#....##...#~~~#..........#~~~~~~~~~~#", - "#L.#....##...#~~~#..........#~~~~~~~~~~#", - "#..#....##...#~~~#.................#~~~#", - "####....##.###~~~#...######...#....#~~~#", - "##.#....#~~~##~~~#...##.####..L....#~~~#", - "##......#~~~##~~~##.###.L.##.......#~~~#", - "##......#~~~~~~~~#....#...##...#####~~~#", - "##......#~~~~~~~~#..#.##.###...###.....#", - "##..##..#~~~~~~~~#.........#...#.......#", - "##..#L..#~~~#....##......###...#.....###", - "##......#...#....####...####...#...#####", - "##......#...#..................#...#####", - "#####.###...##.#...............#...#####", - "#####..........#...............#...#####", - "#####..........#...............#...#####", - "#####..........#################.v.#####", - "########################################" - ], - "elevation": [ - "0000000000000000000000000000000000000000", - "0000000333003000000000111111111033003300", - "0000000333333000000000111111111033333300", - "0000000330033011111111111111111033333300", - "0030000330033011111111110444011003000000", - "0030333333333011111111110444011111111110", - "0330333300333011104444444444011111111110", - "0330333300333011104444444444011111111110", - "0330333300333011104444444444444444401110", - "0000333300300011104440000004440444401110", - "0030333301110011104440030000444444401110", - "0033333301110011100000033300444444401110", - "0033333301111111103333033300444000001110", - "0033333301111111103303003000444000333330", - "0033003301111111103333333330444033333330", - "0033033301110444400333333000444033333000", - "0033333303330444400003330000444033300000", - "0033333303330444444444444444444033300000", - "0000030003330000444444444444444033300000", - "0000033333333330444444444444444033300000", - "0000033333333330444444444444444033300000", - "0000033333333330000000000000000033300000", - "0000000000000000000000000000000000000000" - ], - "warps": [ - { - "x": 33, - "y": 21, - "dest_map": "CeruleanCity", - "dest_warp": 7 - }, - { - "x": 34, - "y": 2, - "dest_map": "CeruleanCave_2F", - "dest_warp": 0 - }, - { - "x": 1, - "y": 7, - "dest_map": "CeruleanCave_B1F", - "dest_warp": 0 - }, - { - "x": 10, - "y": 2, - "dest_map": "CeruleanCave_2F", - "dest_warp": 1 - }, - { - "x": 5, - "y": 15, - "dest_map": "CeruleanCave_2F", - "dest_warp": 2 - }, - { - "x": 30, - "y": 10, - "dest_map": "CeruleanCave_2F", - "dest_warp": 3 - }, - { - "x": 24, - "y": 11, - "dest_map": "CeruleanCave_2F", - "dest_warp": 4 - }, - { - "x": 2, - "y": 4, - "dest_map": "CeruleanCave_2F", - "dest_warp": 5 - } - ], - "objects": [ - { - "x": 7, - "y": 3, - "kind": "item_ball", - "flag": "FLAG_HIDE_CERULEAN_CAVE_1F_NUGGET", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 11, - "y": 16, - "kind": "item_ball", - "flag": "FLAG_HIDE_CERULEAN_CAVE_1F_FULL_RESTORE", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 25, - "y": 5, - "kind": "item_ball", - "flag": "FLAG_HIDE_CERULEAN_CAVE_1F_MAX_ELIXIR", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 7, - "y": 21, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_12", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 13, - "y": 21, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_13", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 5, - "y": 20, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_14", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 14, - "y": 20, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_15", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 11, - "y": 21, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_16", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 9, - "y": 18, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_17", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [ - { - "name": "entrance", - "x": 33, - "y": 21 - } - ], - "flag_sets": [] -} -)json"}, - {"CeruleanCave_2F", R"json({ - "name": "CeruleanCave_2F", - "width": 40, - "height": 23, - "tiles": [ - "########################################", - "########################################", - "########################################", - "####....####..##.....#............######", - "#######......L#..###.#.#########.L######", - "####..####.####.##.#.#.........#########", - "####.L...#.........###########....######", - "#######.############.........####.######", - "####.#...............#######....#.######", - "####.#################..#.L###.##.######", - "####.#....#............L#...#...#.######", - "####.#.##.#.#####.#######.#####.#.######", - "####.#..#.#.....#.......#.....#.#.######", - "####.#..#.#####.#######.#####.#.########", - "####.#.L#.#.....#.....#.....#.#.#.######", - "####.####.#.#####.###.#.#.#.#.#.#.######", - "####.#....#.........#.#.#.#.#.#.#.######", - "####.#.####.#########.#.#.#.###.#.######", - "####.#....#.....#.....#.#.#.....#.######", - "####.############.#####.#.#######.######", - "####..............#.....#.........######", - "########################################", - "########################################" - ], - "elevation": [ - "0000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000", - "0000333300003300333330333333333333000000", - "0000000333333303300030300000000033000000", - "0000330000300003003030333333333000000000", - "0000333330333333333000000000003333000000", - "0000000300000000000033333333300003000000", - "0000303333333333333330000000333303000000", - "0000300000000000000000330330003003000000", - "0000303333033333333333330333033303000000", - "0000303003030000030000000300000303000000", - "0000303303033333033333330333330303000000", - "0000303303000003000000030000030300000000", - "0000303303033333033333033333030303000000", - "0000300003030000030003030303030303000000", - "0000303333033333333303030303030303000000", - "0000303000030000000003030303000303000000", - "0000303333033333033333030303333303000000", - "0000300000000000030000030300000003000000", - "0000333333333333330333330333333333000000", - "0000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000" - ], - "warps": [ - { - "x": 33, - "y": 4, - "dest_map": "CeruleanCave_1F", - "dest_warp": 1 - }, - { - "x": 13, - "y": 4, - "dest_map": "CeruleanCave_1F", - "dest_warp": 3 - }, - { - "x": 7, - "y": 14, - "dest_map": "CeruleanCave_1F", - "dest_warp": 4 - }, - { - "x": 26, - "y": 9, - "dest_map": "CeruleanCave_1F", - "dest_warp": 5 - }, - { - "x": 23, - "y": 10, - "dest_map": "CeruleanCave_1F", - "dest_warp": 6 - }, - { - "x": 5, - "y": 6, - "dest_map": "CeruleanCave_1F", - "dest_warp": 7 - } - ], - "objects": [ - { - "x": 9, - "y": 18, - "kind": "item_ball", - "flag": "FLAG_HIDE_CERULEAN_CAVE_2F_PP_UP", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 29, - "y": 16, - "kind": "item_ball", - "flag": "FLAG_HIDE_CERULEAN_CAVE_2F_ULTRA_BALL", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 33, - "y": 12, - "kind": "item_ball", - "flag": "FLAG_HIDE_CERULEAN_CAVE_2F_FULL_RESTORE", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 33, - "y": 10, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_12", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 33, - "y": 9, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_13", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 25, - "y": 11, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_14", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 28, - "y": 20, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_15", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 30, - "y": 20, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_16", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 9, - "y": 13, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_17", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 23, - "y": 16, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_18", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 13, - "y": 6, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_19", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 4, - "y": 12, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_1A", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 10, - "y": 20, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_1B", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [], - "flag_sets": [] -} -)json"}, - {"CeruleanCave_B1F", R"json({ - "name": "CeruleanCave_B1F", - "width": 40, - "height": 23, - "tiles": [ - "########################################", - "##..............##.....############....#", - "##..............#........#######.......#", - "##..............#..####.....#######....#", - "##......#####.###..####.....#######....#", - "##......#..........########.#######.#..#", - "##..##..##........#########............#", - "##..#L..###......##########............#", - "##......#~~~~~##................#...####", - "#########~~~~~##................#...####", - "#~~~############................#...####", - "#~~~##############.########.###.#...####", - "#~~~#.#.#.########........#.###.#...####", - "#~~~#.....########........#.....#...####", - "#~~~#.....########........#.....#...####", - "#~~~###.###~~~~#......#...#.###.#...####", - "#~~~~~~~~~~~~~~#......#...#.###.#...####", - "#~~~~~~~~~~~~~~#......#...#.....#...####", - "#~~~~~~~~~~~~~~#......#...#.....#...####", - "######~~~~~~~~~##.##.##...###.###...####", - "######~~~~~~~~~~~~#.......###.......####", - "######~~~~~~~~~~~~##.....####.......####", - "########################################" - ], - "elevation": [ - "0000000000000000000000000000000000000000", - "0033333333333333003333300000000000033330", - "0033333333333333033333333000000033333330", - "0033333333333333033000033333000000033330", - "0033333300000300033000033333000000033330", - "0033333303333333333000000003000000030330", - "0033003300333333330000000003333333333330", - "0033033300033333300000000003333333333330", - "0033333301111100444444444444444403330000", - "0000000001111100444444444444444403330000", - "0111000000000000444444444444444403330000", - "0111000000000000000000000004000403330000", - "0111030303000000003333333304000403330000", - "0111033333000000003333333304444403330000", - "0111033333000000003333333304444403330000", - "0111000300011110444444033304000403330000", - "0111111111111110444444033304000403330000", - "0111111111111110444444033304444403330000", - "0111111111111110404444033304444403330000", - "0000001111111110030000033300000003330000", - "0000001111111111110333333300033333330000", - "0000001111111111110033333000033333330000", - "0000000000000000000000000000000000000000" - ], - "warps": [ - { - "x": 5, - "y": 7, - "dest_map": "CeruleanCave_1F", - "dest_warp": 2 - } - ], - "objects": [ - { - "x": 31, - "y": 9, - "kind": "item_ball", - "flag": "FLAG_HIDE_CERULEAN_CAVE_B1F_ULTRA_BALL", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 32, - "y": 2, - "kind": "item_ball", - "flag": "FLAG_HIDE_CERULEAN_CAVE_B1F_MAX_REVIVE", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 7, - "y": 12, - "kind": "mewtwo", - "flag": "FLAG_HIDE_MEWTWO", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 37, - "y": 1, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_12", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 38, - "y": 2, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_13", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 35, - "y": 1, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_14", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 37, - "y": 4, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_15", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 35, - "y": 5, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_16", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 2, - "y": 2, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_17", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 4, - "y": 1, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_18", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 6, - "y": 1, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_19", - "wander_x": 0, - "wander_y": 0 - }, - { - "x": 3, - "y": 4, - "kind": "rock_smash_rock", - "flag": "FLAG_TEMP_1A", - "wander_x": 0, - "wander_y": 0 - } - ], - "connections": [], - "points": [ - { - "name": "mewtwo", - "x": 7, - "y": 12 - } - ], - "flag_sets": [] -} -)json"}, - }; - return MAPS; -} - -std::vector test_overworld_maps(const std::set& set_flags){ - static const std::vector ALL = []{ - std::vector maps; - for (const auto& item : overworld_map_json()){ - maps.push_back(parse_map(item.second, item.first + " (test data)")); - if (maps.back().name != item.first){ - throw ParseException(item.first + " (test data): name is \"" + maps.back().name + "\"."); - } - } - return maps; - }(); - std::vector maps = ALL; - for (MapData& map : maps){ - hide_objects(map, set_flags); - } - return maps; -} - - - -} -} -} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.h deleted file mode 100644 index e392c38a8b..0000000000 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Overworld Maps Test Data - * - * From: https://github.com/PokemonAutomation/ - * - * The FRLG maps compiled into the program, for tests: CI runs without the - * map files in Packages. PokemonFRLG_OverworldMapsTestData.cpp holds the - * same JSON as the files in Resources/PokemonFRLG/Maps, written by - * devtools/maps/frlg_maps.py --cpp, which also checks it (--check). - * - */ - -#ifndef PokemonAutomation_PokemonFRLG_OverworldMapsTestData_H -#define PokemonAutomation_PokemonFRLG_OverworldMapsTestData_H - -#include -#include -#include -#include -#include "PokemonFRLG_OverworldMaps.h" - -namespace PokemonAutomation{ -namespace NintendoSwitch{ -namespace PokemonFRLG{ - - -// Every map's name and JSON text, as in its file in Packages. -const std::vector>& overworld_map_json(); - -// overworld_maps(), read from overworld_map_json() rather than from the -// files. Throws ParseException as parse_map(). -std::vector test_overworld_maps(const std::set& set_flags = {}); - - - -} -} -} -#endif diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp index 1f6ee6600d..85f69b12df 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp @@ -11,7 +11,7 @@ #include "Common/Cpp/TestRunners/UnitTest.h" #include "Pokemon/Navigation/Pokemon_LegPlanner.h" #include "PokemonFRLG_OverworldMaps.h" -#include "PokemonFRLG_OverworldMapsTestData.h" +#include "PokemonFRLG_OverworldTestMaps.h" #include "PokemonFRLG_OverworldRoute.h" namespace PokemonAutomation{ diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.cpp new file mode 100644 index 0000000000..47d912a999 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.cpp @@ -0,0 +1,39 @@ +/* Overworld Test Maps + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "Common/Cpp/Exceptions.h" +#include "PokemonFRLG_OverworldMaps.h" +#include "PokemonFRLG_OverworldTestMaps.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + + +std::vector test_overworld_maps(const std::set& set_flags){ + static const std::vector ALL = []{ + std::vector maps; + for (const auto& [name, json] : overworld_map_json()){ + const std::string source = "Maps/" + name + ".json (built in)"; + maps.push_back(parse_map(json, source)); + if (maps.back().name != name){ + throw ParseException(source + ": name is \"" + maps.back().name + "\"."); + } + } + return maps; + }(); + std::vector maps = ALL; + for (MapData& map : maps){ + hide_objects(map, set_flags); + } + return maps; +} + + + +} +} +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h index 61486c59a6..2366622535 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h @@ -14,9 +14,11 @@ #ifndef PokemonAutomation_PokemonFRLG_OverworldTestMaps_H #define PokemonAutomation_PokemonFRLG_OverworldTestMaps_H +#include #include #include #include +#include "PokemonFRLG_OverworldMap.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -27,6 +29,10 @@ namespace PokemonFRLG{ // build time. const std::vector>& overworld_map_json(); +// overworld_maps(), read from overworld_map_json() rather than from the +// files. Throws ParseException as parse_map(). +std::vector test_overworld_maps(const std::set& set_flags = {}); + } diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index a077350236..6e17fcecf0 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1768,11 +1768,10 @@ file(GLOB LIBRARY_SOURCES Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMap.h Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.h - Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.cpp - Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMapsTestData.h Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps_Tests.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.h + Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h From 42d7e0aca8a7a7160d55ac7e3130ad85293b4cf2 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 09:44:34 -0800 Subject: [PATCH 10/16] FRLG: the program loads the overworld maps built in from Overworld/Maps Until the maps go to Packages, overworld_maps() reads them from overworld_map_json(), the Maps/*.json files CMake builds in, instead of Resources/PokemonFRLG/Maps. The program and its tests read one copy, a deploy needs no map files, and the tests call overworld_maps() again, so test_overworld_maps() and PokemonFRLG_OverworldTestMaps.{h,cpp} go. TODOs at overworld_map_json() and in frlg_maps.py: move the maps to Packages when ready. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- SerialPrograms/CMakeLists.txt | 2 +- .../Overworld/PokemonFRLG_OverworldMaps.cpp | 15 ++++--- .../Overworld/PokemonFRLG_OverworldMaps.h | 19 ++++++--- .../Overworld/PokemonFRLG_OverworldRoute.cpp | 17 ++++---- .../PokemonFRLG_OverworldTestMaps.cpp | 39 ------------------ .../Overworld/PokemonFRLG_OverworldTestMaps.h | 41 ------------------- SerialPrograms/cmake/SourceFiles.cmake | 2 - devtools/maps/frlg_maps.py | 11 +++-- 8 files changed, 38 insertions(+), 108 deletions(-) delete mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.cpp delete mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index f9a9b0db5c..6a94155e3d 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -198,7 +198,7 @@ include(cmake/EmbedTextFiles.cmake) pa_embed_text_files(SerialProgramsLib Source/Pokemon/Navigation/TestMaps Pokemon/Navigation/Pokemon_Navigation_Tests.h PokemonAutomation::Pokemon navigation_test_map_json) pa_embed_text_files(SerialProgramsLib Source/VideoGames/PokemonFRLG/Overworld/Maps - VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h PokemonAutomation::NintendoSwitch::PokemonFRLG overworld_map_json) + VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.h PokemonAutomation::NintendoSwitch::PokemonFRLG overworld_map_json) # Create binary target diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.cpp index 92d83d5f5f..b5704590eb 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.cpp @@ -4,12 +4,12 @@ * */ +#include #include #include "Common/Cpp/Exceptions.h" #include "Common/Cpp/Json/JsonArray.h" #include "Common/Cpp/Json/JsonObject.h" #include "Common/Cpp/Json/JsonValue.h" -#include "CommonFramework/GlobalAutoPaths.h" #include "PokemonFRLG_OverworldMaps.h" namespace PokemonAutomation{ @@ -19,8 +19,6 @@ namespace PokemonFRLG{ namespace{ -const char MAP_FOLDER[] = "PokemonFRLG/Maps/"; - const char* const MAP_NAMES[] = { // From a new game to Brock. "PalletTown", @@ -53,7 +51,7 @@ const char* const MAP_NAMES[] = { // The readers below take `where`, the source and the path to the object -// being read (e.g. "PokemonFRLG/Maps/CeruleanCity.json: warps[2]."), and +// being read (e.g. "Maps/CeruleanCity.json: warps[2]."), and // name the field in what they throw. const JsonObject& as_object(const JsonValue& value, const std::string& where){ @@ -254,8 +252,13 @@ MapData parse_map(const std::string& json, const std::string& source){ } MapData load_map(const std::string& name){ - const std::string source = std::string(MAP_FOLDER) + name + ".json"; - MapData map = read_map(load_json_file(RESOURCE_PATH() + source), source); + const std::string source = "Maps/" + name + ".json"; + const std::vector>& files = overworld_map_json(); + const auto file = std::find_if(files.begin(), files.end(), [&](const auto& item){ return item.first == name; }); + if (file == files.end()){ + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, source + " is not built into the program."); + } + MapData map = read_map(parse_json(file->second), source); if (map.name != name){ throw ParseException(source + ": name is \"" + map.name + "\", not \"" + name + "\"."); } diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.h index 77d30dae4c..c9e8cd9d7b 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.h +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps.h @@ -8,9 +8,10 @@ * Center, Route 24 to its north, and the three floors of Cerulean Cave, * where Mewtwo waits on B1F. * - * Each map is a JSON file, Resources/PokemonFRLG/Maps/.json in - * Packages, generated by devtools/maps/frlg_maps.py. The schema (see the - * README.md next to the files) is MapData's: + * Each map is a JSON file, Maps/.json next to this file, generated by + * devtools/maps/frlg_maps.py and built into the program by CMake + * (pa_embed_text_files() in cmake/EmbedTextFiles.cmake), so the program and + * its tests read the same copy. The schema is MapData's: * * { * "name": "CeruleanCity", "width": 48, "height": 40, @@ -31,6 +32,7 @@ #include #include +#include #include #include "Common/Cpp/TestRunners/UnitTestDatabase.h" #include "PokemonFRLG_OverworldMap.h" @@ -45,12 +47,17 @@ namespace PokemonFRLG{ // doesn't fit the schema. MapData parse_map(const std::string& json, const std::string& source); -// Loads Resources/PokemonFRLG/Maps/.json. Throws FileException if -// the file is missing, and ParseException as parse_map(). +// (name, JSON text) of each file in Maps/, sorted by name. Generated at +// build time. +// TODO: move the maps to PokemonAutomation/Packages (Resources/PokemonFRLG/Maps) when ready. +const std::vector>& overworld_map_json(); + +// Reads map `name` from overworld_map_json(). Throws InternalProgramError if +// it isn't built in, and ParseException as parse_map(). MapData load_map(const std::string& name); // Every map, by its decompilation name ("CeruleanCity", "CeruleanCave_B1F", ...), -// with the objects the given event flags hide removed. The files are read +// with the objects the given event flags hide removed. The maps are parsed // once, on the first call. std::vector overworld_maps(const std::set& set_flags = {}); diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp index 85f69b12df..b9fe0751bd 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp @@ -11,7 +11,6 @@ #include "Common/Cpp/TestRunners/UnitTest.h" #include "Pokemon/Navigation/Pokemon_LegPlanner.h" #include "PokemonFRLG_OverworldMaps.h" -#include "PokemonFRLG_OverworldTestMaps.h" #include "PokemonFRLG_OverworldRoute.h" namespace PokemonAutomation{ @@ -485,7 +484,7 @@ UnitTestResult test_step_rules(){ // The maps after the Hall of Fame, which clears the way to Cerulean Cave. std::vector post_game_maps(){ - return test_overworld_maps(map_flag_set(test_overworld_maps(), "after_hall_of_fame")); + return overworld_maps(map_flag_set(overworld_maps(), "after_hall_of_fame")); } MapPosition point_on(const std::vector& maps, const std::string& map, const std::string& point){ @@ -515,7 +514,7 @@ UnitTestResult test_maps(){ if (object_at(*city, {1, 13}) != nullptr){ return "The cave guard is still there after the Hall of Fame."; } - if (object_at(*map_named(test_overworld_maps(), "CeruleanCity"), {1, 13}) == nullptr){ + if (object_at(*map_named(overworld_maps(), "CeruleanCity"), {1, 13}) == nullptr){ return "The cave guard is missing before the Hall of Fame."; } return true; @@ -595,7 +594,7 @@ UnitTestResult test_pokemon_center_to_mewtwo(){ UnitTestResult test_cave_guard_blocks(){ // Before the Hall of Fame the guard stands in the cave entrance. - const std::vector maps = test_overworld_maps(); + const std::vector maps = overworld_maps(); if (plan_overworld_route(maps, point_on(maps, "CeruleanCity_PokemonCenter_1F", "pc"), facing_mewtwo(maps))){ return "Planned past the cave guard."; } @@ -616,7 +615,7 @@ UnitTestResult test_mewtwo_tile_unreachable(){ } UnitTestResult test_story_maps(){ - const std::vector maps = test_overworld_maps(); + const std::vector maps = overworld_maps(); for (const char* name : { "PalletTown_PlayersHouse_2F", "PalletTown_ProfessorOaksLab", "Route1", "ViridianCity_Mart", "Route22", "Route2", "ViridianForest", "PewterCity", "PewterCity_Museum_1F", "PewterCity_Gym", @@ -640,7 +639,7 @@ std::vector maps_warped_into(const std::vector& route){ } UnitTestResult test_bedroom_to_oaks_lab(){ - const std::vector maps = test_overworld_maps(); + const std::vector maps = overworld_maps(); std::vector route; UnitTestResult result = check_route( maps, point_on(maps, "PalletTown_PlayersHouse_2F", "start"), @@ -657,7 +656,7 @@ UnitTestResult test_bedroom_to_oaks_lab(){ } UnitTestResult test_viridian_mart_to_pewter_gym(){ - const std::vector maps = test_overworld_maps(); + const std::vector maps = overworld_maps(); std::vector route; UnitTestResult result = check_route( maps, point_on(maps, "ViridianCity_Mart", "clerk_front"), @@ -732,7 +731,7 @@ UnitTestResult test_no_hold_into_ledge(){ } } route.clear(); - const std::vector world = test_overworld_maps(); + const std::vector world = overworld_maps(); result = check_route(world, {"ViridianCity", {26, 27}}, {{"ViridianCity", {26, 29}}, std::nullopt}, route); if (result.result != UnitTestResult::PASSED){ return result; @@ -751,7 +750,7 @@ UnitTestResult test_no_hold_into_ledge(){ // No wild battle can start between the bedroom and Oak's Lab: Pallet Town's // streets have no tall grass. Route 2 and Viridian Forest do. UnitTestResult test_wild_steps(){ - const std::vector maps = test_overworld_maps(); + const std::vector maps = overworld_maps(); std::vector route; UnitTestResult result = check_route( maps, point_on(maps, "PalletTown_PlayersHouse_2F", "start"), diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.cpp deleted file mode 100644 index 47d912a999..0000000000 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* Overworld Test Maps - * - * From: https://github.com/PokemonAutomation/ - * - */ - -#include "Common/Cpp/Exceptions.h" -#include "PokemonFRLG_OverworldMaps.h" -#include "PokemonFRLG_OverworldTestMaps.h" - -namespace PokemonAutomation{ -namespace NintendoSwitch{ -namespace PokemonFRLG{ - - -std::vector test_overworld_maps(const std::set& set_flags){ - static const std::vector ALL = []{ - std::vector maps; - for (const auto& [name, json] : overworld_map_json()){ - const std::string source = "Maps/" + name + ".json (built in)"; - maps.push_back(parse_map(json, source)); - if (maps.back().name != name){ - throw ParseException(source + ": name is \"" + maps.back().name + "\"."); - } - } - return maps; - }(); - std::vector maps = ALL; - for (MapData& map : maps){ - hide_objects(map, set_flags); - } - return maps; -} - - - -} -} -} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h deleted file mode 100644 index 2366622535..0000000000 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Overworld Test Maps - * - * From: https://github.com/PokemonAutomation/ - * - * The FRLG maps built into the program, for tests: CI has none of the map - * files in Packages. The .json files in Maps/ next to this file are what - * devtools/maps/frlg_maps.py writes, the same as Resources/PokemonFRLG/Maps - * in Packages; `frlg_maps.py --out --check` checks them. - * CMake builds their text in (pa_embed_text_files() in - * cmake/EmbedTextFiles.cmake). - * - */ - -#ifndef PokemonAutomation_PokemonFRLG_OverworldTestMaps_H -#define PokemonAutomation_PokemonFRLG_OverworldTestMaps_H - -#include -#include -#include -#include -#include "PokemonFRLG_OverworldMap.h" - -namespace PokemonAutomation{ -namespace NintendoSwitch{ -namespace PokemonFRLG{ - - -// (name, JSON text) of each file in Maps/, sorted by name. Generated at -// build time. -const std::vector>& overworld_map_json(); - -// overworld_maps(), read from overworld_map_json() rather than from the -// files. Throws ParseException as parse_map(). -std::vector test_overworld_maps(const std::set& set_flags = {}); - - - -} -} -} -#endif diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 6e17fcecf0..086ab6f2af 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1771,8 +1771,6 @@ file(GLOB LIBRARY_SOURCES Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldMaps_Tests.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.h - Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.cpp - Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldTestMaps.h Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_PlayerFacingReader.cpp diff --git a/devtools/maps/frlg_maps.py b/devtools/maps/frlg_maps.py index 345c3c306b..9049b75a07 100644 --- a/devtools/maps/frlg_maps.py +++ b/devtools/maps/frlg_maps.py @@ -1,7 +1,9 @@ """Writes FRLG overworld maps as JSON, from the pret/pokefirered decompilation. +TODO: move the maps to PokemonAutomation/Packages (Resources/PokemonFRLG/Maps) when ready. + Usage: - python3 devtools/maps/frlg_maps.py --out Packages/Resources/PokemonFRLG/Maps \ + python3 devtools/maps/frlg_maps.py --out SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps \ CeruleanCity_PokemonCenter_1F CeruleanCity Route24 \ CeruleanCave_1F CeruleanCave_2F CeruleanCave_B1F python3 devtools/maps/frlg_maps.py --out @@ -9,14 +11,15 @@ Downloads each map's data/maps//map.json, its layout's map.bin and its tilesets' metatile_attributes.bin at --commit into --cache, then writes -/.json in the schema of Packages/Resources/PokemonFRLG/Maps/README.md. +/.json in the schema given in PokemonFRLG_OverworldMaps.h. Warps and connections lead only to maps in the same run: others get an empty dest_map, or are left out. Named points and flag sets come from POINTS and FLAG_SETS below. Without map names, the maps are the ones already in --out. --check writes -nothing: it regenerates them and fails if any file differs, e.g. for the -copies the unit tests build into the program. +nothing: it regenerates them and fails if any file differs. The program +builds in the files of SerialPrograms/Source/VideoGames/PokemonFRLG/ +Overworld/Maps, the folder to write and check. """ import argparse import json From 91b12a241cfc0b0eda6ba0309071940e61d8b448 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 10:01:40 -0800 Subject: [PATCH 11/16] FRLG: regenerate the overworld maps without all-ground elevation grids 12 of the 25 maps drop their elevation grid (#117): 104 KB to 89 KB. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../Overworld/Maps/CeruleanCave_2F.json | 25 ------ .../Maps/PalletTown_PlayersHouse_1F.json | 12 --- .../Maps/PalletTown_ProfessorOaksLab.json | 16 ---- .../Maps/PalletTown_RivalsHouse.json | 12 --- .../Overworld/Maps/PewterCity.json | 42 ---------- .../Overworld/Maps/PewterCity_Gym.json | 18 ---- .../Overworld/Maps/PewterCity_Museum_1F.json | 13 --- .../PokemonFRLG/Overworld/Maps/Route1.json | 42 ---------- .../PokemonFRLG/Overworld/Maps/Route2.json | 82 ------------------- .../Route2_ViridianForest_NorthEntrance.json | 14 ---- .../Route2_ViridianForest_SouthEntrance.json | 14 ---- .../Overworld/Maps/ViridianForest.json | 71 ---------------- 12 files changed, 361 deletions(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_2F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_2F.json index 12acb62d1f..5150099e00 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_2F.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/CeruleanCave_2F.json @@ -27,31 +27,6 @@ "########################################", "########################################" ], - "elevation": [ - "0000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000", - "0000333300003300333330333333333333000000", - "0000000333333303300030300000000033000000", - "0000330000300003003030333333333000000000", - "0000333330333333333000000000003333000000", - "0000000300000000000033333333300003000000", - "0000303333333333333330000000333303000000", - "0000300000000000000000330330003003000000", - "0000303333033333333333330333033303000000", - "0000303003030000030000000300000303000000", - "0000303303033333033333330333330303000000", - "0000303303000003000000030000030300000000", - "0000303303033333033333033333030303000000", - "0000300003030000030003030303030303000000", - "0000303333033333333303030303030303000000", - "0000303000030000000003030303000303000000", - "0000303333033333033333030303333303000000", - "0000300000000000030000030300000003000000", - "0000333333333333330333330333333333000000", - "0000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000" - ], "warps": [ { "x": 33, diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_1F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_1F.json index 72843f10c5..c4b5a50cdc 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_1F.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_PlayersHouse_1F.json @@ -14,18 +14,6 @@ "#...v........", "#############" ], - "elevation": [ - "0000000000000", - "0000000000000", - "0333333333300", - "0333333333333", - "0333330033333", - "0333330033333", - "0333333333333", - "0033333333330", - "0333333333333", - "0000000000000" - ], "warps": [ { "x": 5, diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_ProfessorOaksLab.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_ProfessorOaksLab.json index 223450196d..0cc55ccd2b 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_ProfessorOaksLab.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_ProfessorOaksLab.json @@ -18,22 +18,6 @@ "#.....v.....#", "#############" ], - "elevation": [ - "0000000000000", - "0000000000000", - "3333333333333", - "0333333333333", - "0003333300033", - "3003333333333", - "3333333333333", - "3333333333333", - "0000033300000", - "3333333333333", - "3333333333333", - "3333333333333", - "0333333333330", - "0000000000000" - ], "warps": [ { "x": 6, diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_RivalsHouse.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_RivalsHouse.json index ce5634bf46..7e4d85de31 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_RivalsHouse.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PalletTown_RivalsHouse.json @@ -14,18 +14,6 @@ "#...v.......#", "#############" ], - "elevation": [ - "0000000000000", - "0000000000000", - "3333333333333", - "3333333333333", - "3333330033333", - "3333330033333", - "3333333333333", - "3333333333333", - "0333333333330", - "3330003333333" - ], "warps": [ { "x": 4, diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity.json index c01026d4f7..924deae088 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity.json @@ -44,48 +44,6 @@ "####################....########################", "####################....########################" ], - "elevation": [ - "000000000000000000000000000000000000000000000000", - "000000000000000000000003333000000000000000000000", - "000033333333000000000000000003333333330000000000", - "000033333333000000000000000003333333330000000000", - "000033333333000000000000000000003333330000000000", - "000033333333000000000003333333333333330000000000", - "000000033333000003000003300000003333333300000000", - "000000033000000033300000000000000000033300000000", - "000033333333333333333333333333333333333300000000", - "000033333333333333333333333333330000033300000000", - "000000333333333333333333333333330000033300000000", - "000000333333333333333333333333330000033300000000", - "000000333333333333333333333333333333333300000000", - "000000333003000000030033333333333333333300000000", - "000000333000000000000033333333333333333300000000", - "000000333003000000030033333333333333333300000000", - "000000333000330003330033330000333333333300000000", - "000000333333333333333033330000003333333300000000", - "000000333333333333333033330000003333333300000000", - "000000333333333333333033333333333333333000000000", - "000000000000000000000033333333333333333333333333", - "000000333333333333333333333333333333333333333333", - "000000333333300000000033333333333333333333333333", - "000000333333300000000033330000000000333333333333", - "000000333333300000000033330000000000333300000000", - "000000333333300000000033330000000000033300000000", - "000000333333333333333333330333333333033300000000", - "000000333333333333333333330333333333033300000000", - "000000330000033333333333330333333333033300000000", - "000000330000033333333333330333333333033300000000", - "000000330000033333330333330000030000033300000000", - "000000333333333333333333333333333333333300000000", - "000000333333333333333333333333333333333300000000", - "000000333333333333333333333333333333333300000000", - "000000333333333333333333333333333333333300000000", - "000000333333333333333333333333333333333300000000", - "000000000000000000003333000000000000000000000000", - "000000000000000000003333000000000000000000000000", - "000000000000000000003333000000000000000000000000", - "000000000000000000003333000000000000000000000000" - ], "warps": [ { "x": 17, diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Gym.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Gym.json index cbc7068f74..4c478d8e8e 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Gym.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Gym.json @@ -20,24 +20,6 @@ "#.....v.....#", "#############" ], - "elevation": [ - "0000000000000", - "0000333330000", - "0000000000000", - "0333303033330", - "0333333333330", - "0333033303330", - "0333333333330", - "0330303030330", - "0033333333300", - "0333033303330", - "0033333333300", - "0333333333330", - "0333033303330", - "0333333333330", - "0333333333330", - "0000000000000" - ], "warps": [ { "x": 5, diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Museum_1F.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Museum_1F.json index 1bb4797613..ecf6acb232 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Museum_1F.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/PewterCity_Museum_1F.json @@ -15,19 +15,6 @@ "#........###..v.##...v..##..", "############################" ], - "elevation": [ - "0000000000000000000000000000", - "0000000000000000000000000000", - "3333333333333330333333333333", - "3333333333333330333333033330", - "3330000333333330333333333330", - "3333333333333330333333333333", - "3333333333303330333333333330", - "3330000330003330003333333330", - "3333333330003333303333333333", - "0333333330003333003333330033", - "0000000000000000000000000000" - ], "warps": [ { "x": 13, diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route1.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route1.json index 735f2320d5..9c0ea3ca1d 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route1.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route1.json @@ -44,48 +44,6 @@ "############\"\"##########", "############\"\"##########" ], - "elevation": [ - "000000000033330000000000", - "000000000033330000000000", - "003333333333333333333300", - "003333333333333333333300", - "003333330033333333333300", - "000000000000000033333300", - "003333330033333333333300", - "003333330033333333333300", - "003333330033333333333300", - "003333330033333333333300", - "000000000033333333333300", - "003333330033333333333300", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "000000000000000033333300", - "000033333300000033333300", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "000030000330000000000000", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "000000000000333333333300", - "000000000000333333000000", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "000000333000000000000000", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "003333333333333333333300", - "000000000000330000000000", - "003333333330330333333300", - "000000000000330000000000", - "000000000000330000000000" - ], "warps": [], "objects": [ { diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2.json index b0beb72f22..6e4337074e 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2.json @@ -84,88 +84,6 @@ "#######.......##########", "#######.....############" ], - "elevation": [ - "000000003333000000000000", - "000000003333000000000000", - "003333333333000000000000", - "003333333333033333333300", - "003333333333033333333300", - "003333333333033333333300", - "003333333333000000000300", - "003333333333000000000300", - "003333333333000000000300", - "003333333333000000000300", - "003333333333000000000300", - "003333333333000003000300", - "003333333333030333333300", - "000033330003033333333300", - "000000000003333333333300", - "000000000033333333333300", - "000000000000003333333300", - "000000000000003333333300", - "000000000000003333333300", - "000000000000003333333300", - "000000000000003333333300", - "000000000000000000033300", - "000000000000000000033300", - "000000000000003333333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000000300000", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000000030000", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000000030000", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000033333300", - "000000000000000003333000", - "000000000000000000000000", - "000000000000000000000000", - "000000000000000000000000", - "003333333300000000000000", - "000000000000000000330000", - "000000000000000003333000", - "000000000000000033333300", - "000000000000000033333300", - "000300003000000033333300", - "000003300000000000030000", - "000033330000000033333300", - "003333333333330033333300", - "003333333333330033333300", - "000000000003330033333300", - "003333333333330033333300", - "003333333333330000300000", - "003333333333330033333300", - "003333333333330033333300", - "003333333333330033333300", - "003333333333330033333300", - "003333333333333333333300", - "003333000000000033333300", - "003333000000000033333300", - "003333000000000033333300", - "003333000000000033333300", - "003333333333330033333300", - "003333333333330033333300", - "003333333333333333333300", - "000000000330003300300000", - "003333333333330033333300", - "000033333333330033333300", - "000033303333330033333300", - "000033333333330033333300", - "000033333333330033333300", - "000033333333330033333300", - "000033333333330033333300", - "000000033333330000000000", - "000000033333000000000000" - ], "warps": [ { "x": 5, diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_NorthEntrance.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_NorthEntrance.json index 5058f58189..e7776b1911 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_NorthEntrance.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_NorthEntrance.json @@ -16,20 +16,6 @@ "#......v......#", "###############" ], - "elevation": [ - "000000000000000", - "000000030000000", - "003330333033300", - "033333333333330", - "033333333330030", - "000333333330030", - "033333333333330", - "033333333330030", - "000333333330030", - "033333333333330", - "033333333333330", - "000000000000000" - ], "warps": [ { "x": 6, diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_SouthEntrance.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_SouthEntrance.json index ea9cb605aa..d36530577d 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_SouthEntrance.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/Route2_ViridianForest_SouthEntrance.json @@ -16,20 +16,6 @@ "#......v......#", "###############" ], - "elevation": [ - "000000000000000", - "000000030000000", - "003330333033300", - "033333333333330", - "033333333330030", - "000333333330030", - "033333333333330", - "033333333330030", - "000333333330030", - "033333333333330", - "033333333333330", - "000000000000000" - ], "warps": [ { "x": 6, diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianForest.json b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianForest.json index ae6808cb11..5d359b42a4 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianForest.json +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/Maps/ViridianForest.json @@ -73,77 +73,6 @@ "######################################################", "######################################################" ], - "elevation": [ - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000003333333333333000333333333333333333333333000", - "000000000003333333333333000333333333333333333333333000", - "000000000003333333333333000333333333333333333333333000", - "033000003303333333333333000333330000000000000003333000", - "000033300003333333333333000333330000000000000003333000", - "000033300003333333333333000333330000000000000003333000", - "000033300003333300033333000333330000000000000003333000", - "000033000003333300033333000333330000000000000003333000", - "000333330003333300033333000333330000000000000003333000", - "000333330003333300033333000333330000000000000003333000", - "000333330003333300033333000333333333333333333333333000", - "000333330003333300033333000333333333333333333333333000", - "000333330003333300033333000333333333333333333333333000", - "000333330003333300033333000333333333333333333000000000", - "000333330003333300033333000333333333333333333000000000", - "000333330003333300033333000333333000000333333000000000", - "000333330003333300033333000333333000000333333000000000", - "000333330003333300033333000333333000000333333000000000", - "000333330003333300033333333333333000000333333000000000", - "000333330003333300000333333333333000000333333000000000", - "000333330003333300000333333333333000000333333333333000", - "000333330003333333000000000000000000000333303333333000", - "000333333333333333000000000000000000000333333333333000", - "000333333333333333000000000000000000000333333333333000", - "000333333033333333000000000000000000000333333333333000", - "000333333333333333000000000000000000000333330003333000", - "000333333333333333333333000000000000000333330003333000", - "000333333333333333333333000000000000000333330003333000", - "000333333333333333333333000000000000000333330003333000", - "000000000000000000333333000000000000000333330003333000", - "000000000000000000333333000000000000000333330003333000", - "000000000000000000000000000000000000000333330003333000", - "000000000000000000000000000000000000000333330003333000", - "000000000000000000000000000000000000000333330003333000", - "000333333333333333000000000000000000000333330003333000", - "000333333333333333000000000000000000000333330003333000", - "000333333333333333000000000000000000000333330003333000", - "000333333333333333000000000000000000000333330003333000", - "000333333333333333333333333333333000000333333333333000", - "000000000000333333333333333303333000000333333333333000", - "000000000000333333333333333333333000000333333333333000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000000000000333330000000003333333000000333333000000000", - "000333333333333333333333333300033333333333333333333000", - "000333333333333333333333333300033333333333333333333000", - "000333333333333333333333333300033333333333333333333000", - "000333333333333333333333333333333333333333333333333000", - "000333333333333333333333333333333333333033333333333000", - "000333333333333333333333333333303333333333333333333000", - "000333333333333333333333333333333333333333333333333000", - "000000000000000000000000000333333000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000" - ], "warps": [ { "x": 29, From 85fea601016ca47b6a44af68f5b82075296572e6 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 1 Nov 2026 14:31:55 -0800 Subject: [PATCH 12/16] FRLG walker: the D-pad mover as a function; the facing read on its own The shared LegMover is now a callable (#114): the D-pad hold is a plain function. Reading the player's facing at the start of a route moves into read_facing(), keeping walk_overworld_route() under the function size limit. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../Overworld/PokemonFRLG_OverworldWalk.cpp | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp index 1ad6f1bed7..c2f41b6c0a 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp @@ -184,12 +184,9 @@ DpadPosition dpad(Direction direction){ } // The leg mover: holds the D-pad. FRLG moves exactly a tile per 16 frames. -class DpadMover : public Pokemon::LegMover{ -public: - virtual void hold(ProControllerContext& context, Direction direction, Milliseconds duration) const override{ - pbf_press_dpad(context, dpad(direction), duration, STEP_RELEASE); - } -}; +void hold_dpad(ProControllerContext& context, Direction direction, Milliseconds duration){ + pbf_press_dpad(context, dpad(direction), duration, STEP_RELEASE); +} Pokemon::LegSpec leg_spec(const RouteStep& step){ return Pokemon::LegSpec{step.direction, step.tiles, step.to_wall, step.surfing ? SURF_TILE_TIME : TILE_TIME}; @@ -255,6 +252,20 @@ void check_warp_was_no_battle(ConsoleHandle& console, ProControllerContext& cont ); } +// Each leg starts with a turn tap unless it goes the way the player faces. +// A tap while already facing that way takes a step, so a facing not given +// is read from the screen. If that fails too it taps anyway. +std::optional read_facing(ConsoleHandle& console, ProControllerContext& context){ + context.wait_for_all_requests(); + VideoSnapshot screen = console.video().snapshot(); + std::optional facing; + if (screen){ + facing = read_player_facing(screen); + } + console.log(std::string("Route: the player faces ") + (facing ? Pokemon::direction_name(*facing) : "an unknown way") + "."); + return facing; +} + void start_surf(ConsoleHandle& console, ProControllerContext& context, Direction direction, bool facing_water){ // "The water is a deep blue... Would you like to SURF?", with YES selected. // An A pressed while the player is still turning is lost. @@ -344,18 +355,10 @@ void walk_overworld_route( std::optional facing, const OverworldInterruptSet& interrupts ){ - // Each leg starts with a turn tap unless it goes the way the player faces. - // A tap while already facing that way takes a step, so a facing not - // given is read from the screen. If that fails too it taps anyway. if (!facing){ - context.wait_for_all_requests(); - VideoSnapshot screen = console.video().snapshot(); - if (screen){ - facing = read_player_facing(screen); - } - console.log(std::string("Route: the player faces ") + (facing ? Pokemon::direction_name(*facing) : "an unknown way") + "."); + facing = read_facing(console, context); } - const DpadMover mover; + const Pokemon::LegMover mover = hold_dpad; for (const RouteStep& step : route){ console.log("Route: " + to_string(step)); check_overworld(console, context, step); From 79b03770d3a4fd2ac8a9e4ab1c211c3d5260ec4b Mon Sep 17 00:00:00 2001 From: dayfine Date: Mon, 2 Nov 2026 01:43:31 -0800 Subject: [PATCH 13/16] FRLG walker: expose its steps and timings in OverworldWalkSteps Visibility only: the timings and the step helpers (turn, hold, warp, Surf, the overworld and warp checks) move out of the unnamed namespace into OverworldWalkSteps, declared in the header, so a walker that runs a route its own way (#119's position recovery) reuses them instead of copying them. No behavior change. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../Overworld/PokemonFRLG_OverworldWalk.cpp | 38 ++++--------- .../Overworld/PokemonFRLG_OverworldWalk.h | 53 +++++++++++++++++++ 2 files changed, 63 insertions(+), 28 deletions(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp index c2f41b6c0a..df052e0f6c 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp @@ -24,41 +24,19 @@ namespace NintendoSwitch{ namespace PokemonFRLG{ using namespace std::chrono_literals; +using namespace OverworldWalkSteps; namespace{ -constexpr Milliseconds TILE_TIME = 267ms; // 16 frames at 60 fps, measured exact over 15 tiles -constexpr Milliseconds SURF_TILE_TIME = 133ms; // the game moves a surfing player at running speed -constexpr Milliseconds TURN_TAP = 40ms; // turns a player facing another way, without a step -constexpr Milliseconds TURN_SETTLE = 300ms; -constexpr Milliseconds FACE_HOLD = 40ms; // short enough to turn without stepping constexpr Milliseconds FACE_SETTLE = 300ms; // the turn animation, before A reaches what is ahead -constexpr Milliseconds STEP_RELEASE = 100ms; // From the end of the hold, through the fade out and in. constexpr Milliseconds WARP_TIMEOUT = 8000ms; constexpr Milliseconds SURF_PROMPT_TIMEOUT = 5000ms; constexpr Milliseconds SURF_ANIMATION = 3000ms; -// After a warp's fade: leaving by a door the game walks the player a tile out -// on its own, and a leg started before that ends loses tiles (on the console a -// 600ms wait cost 2 tiles). -constexpr Milliseconds AFTER_WARP = 1500ms; -// After a warp's fade, which a wild battle's flashes and wipe can pass for: -// a battle's HP box shows within this long (console B, 2026-11-01). -constexpr Milliseconds AFTER_WARP_BATTLE_WATCH = 5000ms; -// A message set off by a leg's last step shows after the hold ends. Caught -// here, before the next leg's turn tap, which the message would swallow. -constexpr Milliseconds AFTER_LEG_WATCH = 500ms; -// The same after a leg through grass. A battle whose flashes are missed is -// seen only by its "Wild appeared!", 3.7s after its step's press -// (twice on Route 1, console B, 2026-11-01, run 7). Unless the walker waits -// that long, the next leg is walked into the battle and lost: there, "east -// 4" and "west 4". -constexpr Milliseconds AFTER_WILD_LEG_WATCH = 3500ms; // After a message closes: a trainer who saw the player speaks first, then // the battle starts, with " would like to battle!" seconds later. constexpr Milliseconds TRAINER_BATTLE_WATCH = 6000ms; -constexpr size_t MAX_INTERRUPTIONS_PER_LEG = 5; // A wild battle, seen by the flashes it starts with. @@ -169,6 +147,15 @@ class RepelWoreOffInterrupt : public MessageInterrupt{ }; +Pokemon::LegSpec leg_spec(const RouteStep& step){ + return Pokemon::LegSpec{step.direction, step.tiles, step.to_wall, step.surfing ? SURF_TILE_TIME : TILE_TIME}; +} + +} + + +namespace OverworldWalkSteps{ + DpadPosition dpad(Direction direction){ switch (direction){ case Direction::NORTH: @@ -183,15 +170,10 @@ DpadPosition dpad(Direction direction){ return DPAD_NONE; } -// The leg mover: holds the D-pad. FRLG moves exactly a tile per 16 frames. void hold_dpad(ProControllerContext& context, Direction direction, Milliseconds duration){ pbf_press_dpad(context, dpad(direction), duration, STEP_RELEASE); } -Pokemon::LegSpec leg_spec(const RouteStep& step){ - return Pokemon::LegSpec{step.direction, step.tiles, step.to_wall, step.surfing ? SURF_TILE_TIME : TILE_TIME}; -} - // One watcher for the whole fade: a ladder's black is short enough to be // over before a second watcher, started once the fade is seen, looks. void wait_out_warp(ConsoleHandle& console, ProControllerContext& context, const RouteStep& step){ diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h index 2df795b774..c769b2b9d6 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h @@ -72,6 +72,59 @@ void walk_overworld_route( ); +// The pieces walk_overworld_route() is made of, for a walker that runs a +// route its own way. Each throws OperationFailedException as +// walk_overworld_route() describes. +namespace OverworldWalkSteps{ + +inline constexpr Milliseconds TILE_TIME(267); // 16 frames at 60 fps, measured exact over 15 tiles +inline constexpr Milliseconds SURF_TILE_TIME(133); // the game moves a surfing player at running speed +inline constexpr Milliseconds TURN_TAP(40); // turns a player facing another way, without a step +inline constexpr Milliseconds TURN_SETTLE(300); +inline constexpr Milliseconds FACE_HOLD(40); // short enough to turn without stepping +inline constexpr Milliseconds STEP_RELEASE(100); +// After a warp's fade: leaving by a door the game walks the player a tile out +// on its own, and a leg started before that ends loses tiles (on the console a +// 600ms wait cost 2 tiles). +inline constexpr Milliseconds AFTER_WARP(1500); +// After a warp's fade, which a wild battle's flashes and wipe can pass for: +// a battle's HP box shows within this long (console B, 2026-11-01). +inline constexpr Milliseconds AFTER_WARP_BATTLE_WATCH(5000); +// A message set off by a leg's last step shows after the hold ends. Caught +// here, before the next leg's turn tap, which the message would swallow. +inline constexpr Milliseconds AFTER_LEG_WATCH(500); +// The same after a leg through grass. A battle whose flashes are missed is +// seen only by its "Wild appeared!", 3.7s after its step's press +// (twice on Route 1, console B, 2026-11-01, run 7). Unless the walker waits +// that long, the next leg is walked into the battle and lost: there, "east +// 4" and "west 4". +inline constexpr Milliseconds AFTER_WILD_LEG_WATCH(3500); +inline constexpr size_t MAX_INTERRUPTIONS_PER_LEG = 5; + +DpadPosition dpad(Direction direction); + +// The leg mover: holds the D-pad. FRLG moves exactly a tile per 16 frames. +void hold_dpad(ProControllerContext& context, Direction direction, Milliseconds duration); + +// After a hold onto `step`'s warp: waits out its fade. +void wait_out_warp(ConsoleHandle& console, ProControllerContext& context, const RouteStep& step); + +// Before `step`: fails unless the overworld is up. +void check_overworld(ConsoleHandle& console, ProControllerContext& context, const RouteStep& step); + +// After `step`'s warp: fails, once the battle is fled, if its fade was a +// wild battle's. +void check_warp_was_no_battle(ConsoleHandle& console, ProControllerContext& context, const RouteStep& step); + +// The way the player faces, read from the screen; nothing if it can't be read. +std::optional read_facing(ConsoleHandle& console, ProControllerContext& context); + +// Facing `direction` (turning first unless `facing_water`), starts Surf. +void start_surf(ConsoleHandle& console, ProControllerContext& context, Direction direction, bool facing_water); + +} + + } } From c7ef69e4157b794141b4fd40dbb0eb89c76aa3b9 Mon Sep 17 00:00:00 2001 From: dayfine Date: Mon, 2 Nov 2026 12:43:29 -0800 Subject: [PATCH 14/16] FRLG walker: a run speed, B held with the D-pad walk_overworld_route() takes a MoveSpeed (WALK by default). RUN holds B with the D-pad for each leg's whole hold and times it at 133ms a tile (8 frames); turn taps stay without B. Each leg to a wall logs "[Speed] : N tiles in T ms, held H ms" so a console run can check the pace. Unit tests for the hold times and that line. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../Overworld/PokemonFRLG_OverworldWalk.cpp | 57 +++++++++- .../Overworld/PokemonFRLG_OverworldWalk.h | 52 ++++++++- .../PokemonFRLG_OverworldWalk_Tests.cpp | 107 ++++++++++++++++++ .../PokemonFRLG/PokemonFRLG_Tests.cpp | 2 + SerialPrograms/cmake/SourceFiles.cmake | 1 + 5 files changed, 208 insertions(+), 11 deletions(-) create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk_Tests.cpp diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp index df052e0f6c..d067197e97 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp @@ -147,8 +147,8 @@ class RepelWoreOffInterrupt : public MessageInterrupt{ }; -Pokemon::LegSpec leg_spec(const RouteStep& step){ - return Pokemon::LegSpec{step.direction, step.tiles, step.to_wall, step.surfing ? SURF_TILE_TIME : TILE_TIME}; +Pokemon::LegSpec leg_spec(const RouteStep& step, MoveSpeed speed){ + return Pokemon::LegSpec{step.direction, step.tiles, step.to_wall, tile_time(step, speed)}; } } @@ -174,6 +174,40 @@ void hold_dpad(ProControllerContext& context, Direction direction, Milliseconds pbf_press_dpad(context, dpad(direction), duration, STEP_RELEASE); } +void hold_dpad_running(ProControllerContext& context, Direction direction, Milliseconds duration){ + pbf_controller_state(context, BUTTON_B, dpad(direction), {0, 0}, {0, 0}, duration); + pbf_wait(context, STEP_RELEASE); +} + +Milliseconds tile_time(const RouteStep& step, MoveSpeed speed){ + if (step.surfing){ + return SURF_TILE_TIME; + } + return speed == MoveSpeed::RUN ? RUN_TILE_TIME : TILE_TIME; +} + +Pokemon::LegMover leg_mover(const RouteStep& step, MoveSpeed speed){ + if (speed == MoveSpeed::RUN && !step.surfing){ + return hold_dpad_running; + } + return hold_dpad; +} + +Milliseconds leg_hold_time(const RouteStep& step, MoveSpeed speed){ + return Pokemon::leg_hold(leg_spec(step, speed), step.tiles); +} + +std::string speed_note(const RouteStep& step, MoveSpeed speed){ + if (step.action != RouteAction::WALK || !step.to_wall || step.surfing){ + return ""; + } + return std::format( + "[Speed] {} {}: {} tiles in {} ms, held {} ms", + move_speed_name(speed), Pokemon::direction_name(step.direction), step.tiles, + (tile_time(step, speed) * step.tiles).count(), leg_hold_time(step, speed).count() + ); +} + // One watcher for the whole fade: a ladder's black is short enough to be // over before a second watcher, started once the fade is seen, looks. void wait_out_warp(ConsoleHandle& console, ProControllerContext& context, const RouteStep& step){ @@ -282,6 +316,16 @@ void start_surf(ConsoleHandle& console, ProControllerContext& context, Direction +const char* move_speed_name(MoveSpeed speed){ + switch (speed){ + case MoveSpeed::WALK: + return "walk"; + case MoveSpeed::RUN: + return "run"; + } + return "?"; +} + OverworldInterruptSet overworld_interrupts_with_repel(int max_repel_slot){ OverworldInterruptSet ret; ret.wild.emplace_back(std::make_unique()); @@ -335,12 +379,12 @@ void walk_overworld_route( ConsoleHandle& console, ProControllerContext& context, const std::vector& route, std::optional facing, - const OverworldInterruptSet& interrupts + const OverworldInterruptSet& interrupts, + MoveSpeed speed ){ if (!facing){ facing = read_facing(console, context); } - const Pokemon::LegMover mover = hold_dpad; for (const RouteStep& step : route){ console.log("Route: " + to_string(step)); check_overworld(console, context, step); @@ -352,7 +396,10 @@ void walk_overworld_route( if (facing != step.direction){ pbf_press_dpad(context, dpad(step.direction), TURN_TAP, TURN_SETTLE); } - Pokemon::walk_leg(console, context, mover, step.wild ? interrupts.wild : interrupts.other, leg_spec(step), MAX_INTERRUPTIONS_PER_LEG); + if (const std::string note = speed_note(step, speed); !note.empty()){ + console.log(note); + } + Pokemon::walk_leg(console, context, leg_mover(step, speed), step.wild ? interrupts.wild : interrupts.other, leg_spec(step, speed), MAX_INTERRUPTIONS_PER_LEG); if (step.warps){ wait_out_warp(console, context, step); static_assert(AFTER_WARP_BATTLE_WATCH >= AFTER_WARP); diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h index c769b2b9d6..c01c86c5b2 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h @@ -19,7 +19,9 @@ #include #include +#include #include +#include "Common/Cpp/TestRunners/UnitTestDatabase.h" #include "Pokemon/Navigation/Pokemon_LegWalker.h" #include "NintendoSwitch/Controllers/Procon/NintendoSwitch_ProController.h" #include "NintendoSwitch/NintendoSwitch_ConsoleHandle.h" @@ -59,16 +61,27 @@ OverworldInterruptSet overworld_interrupts_with_repel(int max_repel_slot); void use_max_repel_from_bag(ConsoleHandle& console, ProControllerContext& context, int slot); -// Walks `route` from where it was planned. The player must be standing still -// on the overworld, not running and not on the bike. `facing` is the way the -// player faces at the start; if not given, it is read from the screen. Throws OperationFailedException if a -// warp's fade or the Surf prompt doesn't show, or a leg is interrupted too -// many times. +// How the player moves on foot: walking, or running with B held, which +// needs the Running Shoes (FLAG_SYS_B_DASH, from Oak's aide in Pewter City +// after Brock). On the water the player surfs at its own pace either way. +enum class MoveSpeed{ + WALK, + RUN, +}; +const char* move_speed_name(MoveSpeed speed); + + +// Walks `route` from where it was planned, at `speed`. The player must be +// standing still on the overworld and not on the bike. `facing` is the way +// the player faces at the start; if not given, it is read from the screen. +// Throws OperationFailedException if a warp's fade or the Surf prompt +// doesn't show, or a leg is interrupted too many times. void walk_overworld_route( ConsoleHandle& console, ProControllerContext& context, const std::vector& route, std::optional facing = std::nullopt, - const OverworldInterruptSet& interrupts = default_overworld_interrupts() + const OverworldInterruptSet& interrupts = default_overworld_interrupts(), + MoveSpeed speed = MoveSpeed::WALK ); @@ -79,6 +92,9 @@ namespace OverworldWalkSteps{ inline constexpr Milliseconds TILE_TIME(267); // 16 frames at 60 fps, measured exact over 15 tiles inline constexpr Milliseconds SURF_TILE_TIME(133); // the game moves a surfing player at running speed +// 8 frames: running is 2 pixels a frame, twice walking. Not measured on the +// console yet; the walker logs each leg to a wall (speed_note()) for that. +inline constexpr Milliseconds RUN_TILE_TIME(133); inline constexpr Milliseconds TURN_TAP(40); // turns a player facing another way, without a step inline constexpr Milliseconds TURN_SETTLE(300); inline constexpr Milliseconds FACE_HOLD(40); // short enough to turn without stepping @@ -106,6 +122,27 @@ DpadPosition dpad(Direction direction); // The leg mover: holds the D-pad. FRLG moves exactly a tile per 16 frames. void hold_dpad(ProControllerContext& context, Direction direction, Milliseconds duration); +// The leg mover for running: holds the D-pad with B for the whole hold. +// Turn taps go without B: a tap only turns the player. +void hold_dpad_running(ProControllerContext& context, Direction direction, Milliseconds duration); + +// How long one tile of `step` takes at `speed`: on the water, the Surf +// pace whatever the speed. +Milliseconds tile_time(const RouteStep& step, MoveSpeed speed); + +// The mover for `step` at `speed`: hold_dpad_running() for a run on foot, +// hold_dpad() otherwise (B does nothing on the water). +Pokemon::LegMover leg_mover(const RouteStep& step, MoveSpeed speed); + +// How long the walker holds the D-pad for a WALK `step` at `speed` +// (Pokemon::leg_hold()). +Milliseconds leg_hold_time(const RouteStep& step, MoveSpeed speed); + +// For a leg to a wall on foot, the line the walker logs so a console run +// can check the pace: "[Speed] run west: 40 tiles in 5320 ms, held 5586 ms", +// the tiles at the assumed pace and the hold. Empty for other steps. +std::string speed_note(const RouteStep& step, MoveSpeed speed); + // After a hold onto `step`'s warp: waits out its fade. void wait_out_warp(ConsoleHandle& console, ProControllerContext& context, const RouteStep& step); @@ -125,6 +162,9 @@ void start_surf(ConsoleHandle& console, ProControllerContext& context, Direction } +void add_tests_OverworldWalk(UnitTestDatabase& database); + + } } diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk_Tests.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk_Tests.cpp new file mode 100644 index 0000000000..11c2f65945 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk_Tests.cpp @@ -0,0 +1,107 @@ +/* Overworld Walk Tests + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include +#include +#include +#include +#include "Common/Cpp/TestRunners/UnitTest.h" +#include "PokemonFRLG_OverworldWalk.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +using namespace OverworldWalkSteps; + + +namespace{ + +class Test_OverworldWalk : public UnitTest{ +public: + Test_OverworldWalk(std::string name, std::function body) + : UnitTest("PokemonFRLG::OverworldWalk - " + std::move(name)) + , m_body(std::move(body)) + {} + virtual UnitTestResult run(Logger&, CancellableScope&) const override{ + return m_body(); + } + +private: + std::function m_body; +}; + + +RouteStep walk_step(Direction direction, int tiles, bool to_wall, bool surfing){ + RouteStep step; + step.action = RouteAction::WALK; + step.direction = direction; + step.tiles = tiles; + step.to_wall = to_wall; + step.surfing = surfing; + return step; +} + +struct HoldCase{ + std::string name; + MoveSpeed speed; + int tiles; + bool to_wall; + bool surfing; + // How long the D-pad is held. + Milliseconds hold; + // speed_note()'s line, or empty. + std::string note; +}; + +// An open leg lets go half a tile before its last step would end; a leg +// to a wall is held two tiles longer. Walking is 267ms a tile, running and +// surfing 133ms. +const std::vector& hold_cases(){ + static const std::vector cases{ + {.name = "walk, open", .speed = MoveSpeed::WALK, .tiles = 5, .to_wall = false, .surfing = false, + .hold = Milliseconds(4 * 267 + 133), .note = ""}, + {.name = "walk, to a wall", .speed = MoveSpeed::WALK, .tiles = 5, .to_wall = true, .surfing = false, + .hold = Milliseconds(7 * 267), .note = "[Speed] walk west: 5 tiles in 1335 ms, held 1869 ms"}, + {.name = "run, open", .speed = MoveSpeed::RUN, .tiles = 5, .to_wall = false, .surfing = false, + .hold = Milliseconds(4 * 133 + 66), .note = ""}, + {.name = "run, to a wall", .speed = MoveSpeed::RUN, .tiles = 40, .to_wall = true, .surfing = false, + .hold = Milliseconds(42 * 133), .note = "[Speed] run west: 40 tiles in 5320 ms, held 5586 ms"}, + {.name = "run, surfing to a wall", .speed = MoveSpeed::RUN, .tiles = 3, .to_wall = true, .surfing = true, + .hold = Milliseconds(5 * 133), .note = ""}, + {.name = "walk, surfing", .speed = MoveSpeed::WALK, .tiles = 3, .to_wall = false, .surfing = true, + .hold = Milliseconds(2 * 133 + 66), .note = ""}, + }; + return cases; +} + +UnitTestResult check_hold(const HoldCase& test){ + const RouteStep step = walk_step(Direction::WEST, test.tiles, test.to_wall, test.surfing); + const Milliseconds hold = leg_hold_time(step, test.speed); + if (hold != test.hold){ + return std::format("Expected a hold of {}ms, got {}ms.", test.hold.count(), hold.count()); + } + const std::string note = speed_note(step, test.speed); + if (note != test.note){ + return "Expected the note \"" + test.note + "\", got \"" + note + "\"."; + } + return true; +} + +} + + +void add_tests_OverworldWalk(UnitTestDatabase& database){ + for (const HoldCase& test : hold_cases()){ + database.add("hold: " + test.name, [&test]{ return check_hold(test); }); + } +} + + + +} +} +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Tests.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Tests.cpp index 7378cf7599..f144a90940 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Tests.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Tests.cpp @@ -29,6 +29,7 @@ #include "Inference/PokemonFRLG_WildEncounterReader.h" #include "Overworld/PokemonFRLG_OverworldMaps.h" #include "Overworld/PokemonFRLG_OverworldRoute.h" +#include "Overworld/PokemonFRLG_OverworldWalk.h" #include "Overworld/PokemonFRLG_PlayerFacingReader.h" #include "PokemonFRLG_Navigation.h" #include "Tests/TestUtils.h" @@ -293,6 +294,7 @@ void add_tests(UnitTestDatabase& database){ add_tests_ExitWildBattle(database); add_tests_OverworldMaps(database); add_tests_OverworldRoute(database); + add_tests_OverworldWalk(database); add_tests_PlayerFacingReader(database); } diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index c17223a58e..9848f19dbf 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1802,6 +1802,7 @@ file(GLOB LIBRARY_SOURCES Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldRoute.h Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h + Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk_Tests.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_PlayerFacingReader.cpp Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_PlayerFacingReader.h Source/VideoGames/PokemonFRLG/PokemonFRLG_Navigation.cpp From f801b23fbdefd78e795c485ab12253f18696d731 Mon Sep 17 00:00:00 2001 From: dayfine Date: Mon, 2 Nov 2026 12:43:44 -0800 Subject: [PATCH 15/16] FRLG walker tests: no bool-parameter helper Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../PokemonFRLG_OverworldWalk_Tests.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk_Tests.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk_Tests.cpp index 11c2f65945..8265cb6bd2 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk_Tests.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk_Tests.cpp @@ -35,16 +35,6 @@ class Test_OverworldWalk : public UnitTest{ }; -RouteStep walk_step(Direction direction, int tiles, bool to_wall, bool surfing){ - RouteStep step; - step.action = RouteAction::WALK; - step.direction = direction; - step.tiles = tiles; - step.to_wall = to_wall; - step.surfing = surfing; - return step; -} - struct HoldCase{ std::string name; MoveSpeed speed; @@ -79,7 +69,11 @@ const std::vector& hold_cases(){ } UnitTestResult check_hold(const HoldCase& test){ - const RouteStep step = walk_step(Direction::WEST, test.tiles, test.to_wall, test.surfing); + RouteStep step; + step.direction = Direction::WEST; + step.tiles = test.tiles; + step.to_wall = test.to_wall; + step.surfing = test.surfing; const Milliseconds hold = leg_hold_time(step, test.speed); if (hold != test.hold){ return std::format("Expected a hold of {}ms, got {}ms.", test.hold.count(), hold.count()); From 9ed8ba561698fb89e3807c4577c42855562d4a45 Mon Sep 17 00:00:00 2001 From: dayfine Date: Mon, 2 Nov 2026 20:10:59 -0800 Subject: [PATCH 16/16] FRLG walker: hand a message open before a leg to the interrupts once A trainer who saw the player can speak after the leg's watch has ended (console B, 2026-11-02, Route 3's Lass Robin), and check_overworld() then failed the walk at once. clear_open_message() gives what shows to the leg's interrupts once (StoryMessage fights the trainer); check_overworld() still fails if the overworld isn't back. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- .../Overworld/PokemonFRLG_OverworldWalk.cpp | 14 ++++++++++++++ .../Overworld/PokemonFRLG_OverworldWalk.h | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp index d067197e97..348b57bcf6 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.cpp @@ -249,6 +249,19 @@ void check_overworld(ConsoleHandle& console, ProControllerContext& context, cons } } +void clear_open_message( + ConsoleHandle& console, ProControllerContext& context, + const OverworldInterrupts& interrupts, const RouteStep& step +){ + context.wait_for_all_requests(); + VideoSnapshot screen = console.video().snapshot(); + if (!screen || !WhiteDialogDetector(COLOR_RED).detect(screen)){ + return; + } + console.log("Route: a message is open before " + to_string(step) + "; handing it to the leg's interrupts.", COLOR_ORANGE); + Pokemon::clear_late_interrupts(console, context, interrupts, OPEN_MESSAGE_WATCH, 1); +} + // After a warp's fade: fails, once the battle is fled, if it was a wild // battle's. In run 7 (console B, 2026-11-01) the player had drifted onto // Route 1's grass, and the step meant for Oak's Lab's door set off a @@ -387,6 +400,7 @@ void walk_overworld_route( } for (const RouteStep& step : route){ console.log("Route: " + to_string(step)); + clear_open_message(console, context, step.wild ? interrupts.wild : interrupts.other, step); check_overworld(console, context, step); switch (step.action){ case RouteAction::WALK: diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h index c01c86c5b2..2c3b665033 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Overworld/PokemonFRLG_OverworldWalk.h @@ -115,6 +115,8 @@ inline constexpr Milliseconds AFTER_LEG_WATCH(500); // that long, the next leg is walked into the battle and lost: there, "east // 4" and "west 4". inline constexpr Milliseconds AFTER_WILD_LEG_WATCH(3500); +// How long clear_open_message() watches for the message it saw. +inline constexpr Milliseconds OPEN_MESSAGE_WATCH(1000); inline constexpr size_t MAX_INTERRUPTIONS_PER_LEG = 5; DpadPosition dpad(Direction direction); @@ -149,6 +151,15 @@ void wait_out_warp(ConsoleHandle& console, ProControllerContext& context, const // Before `step`: fails unless the overworld is up. void check_overworld(ConsoleHandle& console, ProControllerContext& context, const RouteStep& step); +// Before `step`: if a message is open (a trainer who saw the player on the +// last leg and spoke after its watch), hands what shows to `interrupts`, +// once, instead of failing at once. check_overworld() then fails if the +// overworld still isn't up. +void clear_open_message( + ConsoleHandle& console, ProControllerContext& context, + const OverworldInterrupts& interrupts, const RouteStep& step +); + // After `step`'s warp: fails, once the battle is fled, if its fade was a // wild battle's. void check_warp_was_no_battle(ConsoleHandle& console, ProControllerContext& context, const RouteStep& step);