Seat the map catalog in the harness, and print the real map selection

Two instruments, both because a diagnosis went wrong on this data today.

The zone line said "world map shows" while printing the player's *resolved*
zone, not the selection. Those are not the same fact, and conflating them cost
a whole diagnosis: GetPlayerMapPosition projects onto the **displayed** map, so
a selection sitting a zone behind is exactly what leaves every map-derived
overlay stale — and from the log it looked identical to a selection that had
followed. Both pairs are now printed, with an explicit "STALE: the map is not on
the player's zone" marker, so a plain run answers it with no flags.

The harness never seated the world-map catalog, so C_Map.GetMapWorldSize had no
rects there. pfQuest's minimap_sizes metatable caches a false per zone on a miss,
so a probe of its pin gate reported "no zone sizes" for Dun Morogh, Elwynn,
Orgrimmar, Thunder Bluff, Darnassus and Loch Modan — and the four zones that did
answer were the four whose sizes the addon still ships. Every number was real
and the conclusion was false. With the catalog seated (and the C_TaxiMap table
beside it, for the same reason) all six answer and SearchFlightNodes adds 69
nodes. seat_a_session already carried the area-name column against exactly this
fault class; this is the next feed in the same wall.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
This commit is contained in:
2026-10-22 07:42:33 -06:00
co-authored by Claude Opus 5
parent ce8992bc3e
commit e282410938
@@ -1108,6 +1108,11 @@ fn seat_a_session(script: &mut UiScript) {
if let Some(names) = area_names() {
script.set_area_names(names.clone());
}
// The map rects and the flight-master table, for the reason [`world_map_catalog`] gives.
if let Some((continents, taxi)) = world_map_catalog() {
script.set_world_map_catalog(continents.clone());
script.set_taxi_map_catalog(taxi.clone());
}
script.set_unit(
"player",
Some(benilla_ui::script::UnitState {
@@ -1417,6 +1422,46 @@ fn area_names() -> Option<&'static std::collections::BTreeMap<u32, String>> {
.as_ref()
}
/// The world-map catalog — `WorldMapArea`, `WorldMapContinent`, `WorldMapOverlay` and the taxi
/// nodes resolved against them — read once per process; `None` with no install.
///
/// Seated for the same reason the area-name column above is, and it was the next gap in the same
/// wall: the live client pushes this at every VM build (`ui_world_map::seed_world_map_catalog`),
/// so an in-world session with an empty catalog is a state only the harness reaches — and the
/// faults it hides are silent in exactly the same way. pfQuest's minimap pass gates its whole pin
/// loop on `minimap_sizes[mapID]` (`map.lua:1383`), a table whose `__index` asks
/// `C_Map.GetMapWorldSize` and **caches a `false` for ever** on a miss, so an empty catalog here
/// reads as "this client has no zone sizes" with no raise and no log line. Without this, a probe
/// of that gate measures the shipped fallback table rather than the client — which is a way to
/// conclude a live bug exists when it does not.
fn world_map_catalog() -> Option<&'static (
Vec<benilla_ui::script::WorldMapContinentView>,
Vec<benilla_ui::script::TaxiMapNode>,
)> {
use std::sync::OnceLock;
#[allow(clippy::type_complexity)]
static CATALOG: OnceLock<
Option<(
Vec<benilla_ui::script::WorldMapContinentView>,
Vec<benilla_ui::script::TaxiMapNode>,
)>,
> = OnceLock::new();
CATALOG
.get_or_init(|| {
let data = benilla_formats::wow_data()?;
let mut chain = benilla_formats::open_chain(&data).ok()?;
let areas = benilla_formats::load_area_table_catalog(&mut chain).ok()?;
let maps =
benilla_assets::MapCatalogRes(benilla_formats::load_map_catalog(&mut chain).ok()?);
let (views, ui_data) = crate::ui_world_map::build_catalog(&mut chain, &areas, &maps)?;
let nodes = benilla_formats::load_taxi_nodes(&mut chain)
.map(|n| crate::ui_taxi::taxi_map_catalog(&n, &ui_data, &areas))
.unwrap_or_default();
Some((views, nodes))
})
.as_ref()
}
/// `SpellDuration.dbc`, behind nampower's `GetSpellDuration`; `None` when the chain lacks it.
fn spell_durations() -> Option<&'static benilla_formats::SpellDurationCatalog> {
use std::sync::OnceLock;