diff --git a/crates/benilla-app/src/area.rs b/crates/benilla-app/src/area.rs index 2f49d4f6..1d9dfab5 100644 --- a/crates/benilla-app/src/area.rs +++ b/crates/benilla-app/src/area.rs @@ -261,7 +261,14 @@ impl Plugin for AreaPlugin { // spurious splash. feed_zone_events .after(crate::ui_script::UiInput) - .after(benilla_world::terrain_stream::AreaAuthoritySet), + .after(benilla_world::terrain_stream::AreaAuthoritySet) + // `ZONE_CHANGED*` is the signal pfQuest answers with `SetMapToCurrentZone()` + // (`pfQuest/map.lua:1466`), and that verb reads the zone + // `ui_world_map::feed_world_map` publishes. Unordered, the two could run + // either way round, and the wrong way reselects the zone the player just + // left — leaving every map-derived overlay a zone behind until something + // else reselects. See `WorldMapFeedSet`. + .after(crate::ui_world_map::WorldMapFeedSet), ); } } diff --git a/crates/benilla-app/src/ui_world_map.rs b/crates/benilla-app/src/ui_world_map.rs index 86a36545..662bdce9 100644 --- a/crates/benilla-app/src/ui_world_map.rs +++ b/crates/benilla-app/src/ui_world_map.rs @@ -878,6 +878,16 @@ fn dev_map_jump( }); } +/// The set of [`feed_world_map`], which publishes the player's `(continent, zone)` into the VM. +/// +/// Anything that fires a Lua event an addon answers by calling `SetMapToCurrentZone()` must order +/// **after** this set, because that verb reads the zone this feed publishes +/// (`benilla_ui::script::worldmap`'s `player_zone`) and a stale read reselects the zone the player +/// just left. In the reference there is nothing to order: `SetMapToCurrentZone` calls the resolver +/// `0x4a6650`, which reads the player's current area live, where ours reads a per-frame feed. +#[derive(SystemSet, Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct WorldMapFeedSet; + /// The world-map data feed. pub(crate) struct WorldMapUiPlugin; @@ -887,7 +897,7 @@ impl Plugin for WorldMapUiPlugin { Update, ( // After the script tick: a selection changed this tick projects on the next. - feed_world_map.after(UiInput), + feed_world_map.after(UiInput).in_set(WorldMapFeedSet), // After the script tick, so the jump hit-tests this tick's frame rects. dev_map_jump.after(UiInput), ),