the NPC, loot and quest windows register their handlers

- the six NPC windows — gossip, vendor, bank, trainer, stable master, taxi — register their own packet handlers and net/apply/npc.rs leaves the drain; a handler call measures ~25 ns, so the table can carry the busy families as it is (2318)
- the loot window, the group rolls and the inventory refusal register theirs (2319), then the questgiver panels, the quest log and the party share (2320): 273 → 149 kinds in the dispatch match since the table opened
- the show cascade is pinned against the reference's: ours notifies a parent before its children and snapshots the list, theirs is post-order and re-reads — a recorded gap, held by a test on the auction window (2317)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-09-19 17:11:59 +07:00
co-authored by Claude Fable 5.1
parent 5381a79842
commit d0e29635d0
31 changed files with 1465 additions and 920 deletions
@@ -1179,7 +1179,7 @@ fn ctrl_and_shift_on_a_vendor_row_preview_and_post_without_buying() {
num_available: -1,
item_id: 159,
stats: None,
// Fed exactly as `ui_merchant.rs` builds it off the row's template answer.
// Fed exactly as `ui_merchant` builds it off the row's template answer.
link: Some(WATER_LINK.into()),
max_stack: Some(1),
}],
@@ -296,7 +296,7 @@ fn shipped_gossip_frame_renders_quest_rows_above_options() {
assert!(s.errors().is_empty(), "script errors: {:?}", s.errors());
// Rows 1-2 carry the quest titles (active first, matching the order the menu supplied them —
// benilla's seam already flattens available/active into one ordered list, ui_gossip.rs), row 3
// benilla's seam already flattens available/active into one ordered list, `ui_gossip`), row 3
// the option, row 4+ hidden.
let (r1_text, r1_vis, r2_vis, r3_text, r3_vis, r4_vis, r5_text, r5_vis, r6_vis): (
String,