diff --git a/services/flysim/crates/flybrain-gb/src/pokemon_red/macros/geography.rs b/services/flysim/crates/flybrain-gb/src/pokemon_red/macros/geography.rs index f32c354..8abc285 100644 --- a/services/flysim/crates/flybrain-gb/src/pokemon_red/macros/geography.rs +++ b/services/flysim/crates/flybrain-gb/src/pokemon_red/macros/geography.rs @@ -112,6 +112,14 @@ const LINKS: &[(u8, u8)] = &[ (maps::VIRIDIAN_FOREST_NORTH_GATE, maps::ROUTE_2), (maps::VIRIDIAN_FOREST_NORTH_GATE, maps::VIRIDIAN_FOREST), (maps::PEWTER_GYM, maps::PEWTER_CITY), + // The museum, both floors. It is on the graph for the same reason the gym is: the rung-10 + // loop of 2026-09-22 spent its hours on these two maps with `GO OBJECTIVE` off the pad + // entirely, because a map with no row here has no neighbours, so `next_hop` answers nothing + // and `area_of` answers nothing -- no road to the gym from indoors, and no errand either. + // Both rows are the cartridge's own warp table, surveyed from the rung-10 checkpoint: Pewter + // City names `$34` at (14, 7) and (19, 5), and `$34` names `$35` at (7, 7). + (maps::PEWTER_MUSEUM_1F, maps::PEWTER_CITY), + (maps::PEWTER_MUSEUM_2F, maps::PEWTER_MUSEUM_1F), (maps::PEWTER_MART, maps::PEWTER_CITY), (maps::PEWTER_POKECENTER, maps::PEWTER_CITY), (maps::MT_MOON_1F, maps::ROUTE_3), @@ -551,6 +559,40 @@ mod tests { ); } + #[test] + fn the_museums_two_floors_know_the_road_to_the_gym() { + // The rung-10 loop of 2026-09-22: five and a half hours on `PEWTER_CITY` with the + // objective two doors away, and inside the museum `GO OBJECTIVE` was off the pad because + // the map had no row here at all. Both floors, because the fly spent the run on both. + let at = |map: u8| Region::whole(map); + assert_eq!( + next_hop(at(maps::PEWTER_MUSEUM_1F), maps::PEWTER_GYM), + Some(maps::PEWTER_CITY), + "the way to the gym from the museum's ground floor is out of its front door" + ); + assert_eq!( + next_hop(at(maps::PEWTER_MUSEUM_2F), maps::PEWTER_GYM), + Some(maps::PEWTER_MUSEUM_1F), + "and from the upper floor it is the staircase" + ); + assert_eq!(next_hop(at(maps::PEWTER_CITY), maps::PEWTER_GYM), Some(maps::PEWTER_GYM)); + // The other direction, which is what `GO OBJECTIVE` asks when the errand is the museum's + // own town: the museum is one hop from Pewter City and two from its upper floor. + assert_eq!( + next_hop(at(maps::PEWTER_CITY), maps::PEWTER_MUSEUM_2F), + Some(maps::PEWTER_MUSEUM_1F) + ); + // And the area, which is what puts the town's errands on the pad indoors. The upper + // floor has no area, exactly as `REDS_HOUSE_2F` has none: a floor with no front door of + // its own is not "in" anywhere, so it offers no errand -- and the road out is still the + // staircase above, which is what the fly needs there. + assert_eq!(area_of(maps::PEWTER_MUSEUM_1F), Some(maps::PEWTER_CITY)); + assert_eq!(area_of(maps::PEWTER_MUSEUM_2F), None); + // The museum is neither a mart nor a centre, so it is nobody's errand. + assert_eq!(amenity_at(maps::PEWTER_MUSEUM_1F), None); + assert_eq!(amenity_at(maps::PEWTER_MUSEUM_2F), None); + } + #[test] fn a_maps_area_is_its_town_indoors_and_out() { // Outdoors a map is its own area, including a route -- which has no amenity row, so it diff --git a/services/flysim/crates/flybrain-gb/src/pokemon_red/maps.rs b/services/flysim/crates/flybrain-gb/src/pokemon_red/maps.rs index 986b6f4..fd1b4e8 100644 --- a/services/flysim/crates/flybrain-gb/src/pokemon_red/maps.rs +++ b/services/flysim/crates/flybrain-gb/src/pokemon_red/maps.rs @@ -18,6 +18,13 @@ //! `PEWTER_MART` `$38` and `PEWTER_POKECENTER` `$3a` sit in the five ids between `PEWTER_GYM` //! `$36` and `MT_MOON_1F` `$3b`; `CERULEAN_POKECENTER` `$40` and `CERULEAN_MART` `$43` sit around //! `CERULEAN_GYM` `$41`. [`super::tests`] pins each against its neighbour rather than on its own. +//! +//! **2026-09-22, the rung-10 museum.** `PEWTER_MUSEUM_1F` `$34` and `PEWTER_MUSEUM_2F` `$35` are +//! the two ids between `VIRIDIAN_FOREST` `$33` and `PEWTER_GYM` `$36`, and both are confirmed by +//! the cartridge rather than by counting: Pewter City's warp table names `$34` at (14, 7) and at +//! (19, 5) -- the museum's two doors -- and `$34`'s own warp at (7, 7) names `$35`, which is the +//! staircase. Surveyed from the release container's rung-10 checkpoint +//! (`infra/docs/macros-traps.md`, 2026-09-22). // Outdoors: `$00`..`$24`. pub const PALLET_TOWN: u8 = 0x00; @@ -68,6 +75,8 @@ pub const VIRIDIAN_GYM: u8 = 0x2d; pub const VIRIDIAN_FOREST_NORTH_GATE: u8 = 0x2f; pub const VIRIDIAN_FOREST_SOUTH_GATE: u8 = 0x32; pub const VIRIDIAN_FOREST: u8 = 0x33; +pub const PEWTER_MUSEUM_1F: u8 = 0x34; +pub const PEWTER_MUSEUM_2F: u8 = 0x35; pub const PEWTER_GYM: u8 = 0x36; pub const PEWTER_MART: u8 = 0x38; pub const PEWTER_POKECENTER: u8 = 0x3a;