From 312e123fb774629a0653b3e49a7f98beef27bf2f Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 22 Aug 2026 18:17:03 +0700 Subject: [PATCH] windows take turns, the gossip page waits, the shot bar counts down MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - the UIPanel registry is re-derived from the reference's bytes: the readable-item page finally registers, so a note or letter closes when a gossip window opens instead of interleaving with it line for line; the character sheet takes its real pushable-2 seat (an NPC window slides it over instead of replacing it), and the spellbook, quest log, talents and character sheet open for dead players again — a refused open now says "You can't do that when you're dead." instead of doing nothing - the gossip window waits for its greeting: the first packet carries only the options and a text id, and we used to show the frame with a blank page for the round trip the text needed — the menu now exists only once the text has answered, a mid-flight click is refused, and a revisit is instant off the cache - a bag slot whose stack count changes on the server now fires `ITEM_LOCK_CHANGED` just ahead of its `BAG_UPDATE` — the one signal 1.12 hunter addons use to detect a spent arrow — so Quiver's auto-shot bar drains per shot instead of pinning at 100%; a swap or create deliberately does not fire it, so rearranging bags can't read as a shot - the outdoor minimap tiles' gamma byte reaches the screen exactly once — the ordinary decode arm learns the same skip the fast path already had Co-Authored-By: Claude Fable 5 --- .../benilla-app/assets/ui/CharacterFrame.xml | 10 +- .../benilla-app/assets/ui/QuestLogFrame.xml | 3 +- crates/benilla-app/assets/ui/UiPanels.xml | 114 +++++-- crates/benilla-app/src/minimap/mod.rs | 17 +- crates/benilla-app/src/net/apply/npc.rs | 38 +-- crates/benilla-app/src/shaders/ui_quad.wgsl | 22 +- crates/benilla-app/src/ui_gossip.rs | 248 ++++++++++++++- crates/benilla-app/src/ui_items/feed.rs | 110 +++++++ crates/benilla-app/src/ui_pass.rs | 59 ++-- .../benilla-app/src/ui_script/extract/text.rs | 2 + .../benilla-app/src/ui_script/fade_tests.rs | 119 +++++++ crates/benilla-app/src/ui_script/mod.rs | 3 + .../benilla-app/src/ui_script/panel_tests.rs | 227 ++++++++----- .../benilla-app/src/ui_script/quiver_tests.rs | 298 ++++++++++++++++++ crates/benilla-app/tests/item_text_frame.rs | 78 +++++ crates/benilla-ui/src/script/gossip.rs | 23 +- crates/benilla-ui/src/script/mod.rs | 2 + crates/benilla-ui/src/script/ui_errors.rs | 35 ++ 18 files changed, 1204 insertions(+), 204 deletions(-) create mode 100644 crates/benilla-app/src/ui_script/fade_tests.rs create mode 100644 crates/benilla-ui/src/script/ui_errors.rs diff --git a/crates/benilla-app/assets/ui/CharacterFrame.xml b/crates/benilla-app/assets/ui/CharacterFrame.xml index 0c7306b5..4e132926 100644 --- a/crates/benilla-app/assets/ui/CharacterFrame.xml +++ b/crates/benilla-app/assets/ui/CharacterFrame.xml @@ -12,10 +12,12 @@ defined in `UiPanels.xml:507-563` (battle-tested by Merchant/QuestLog, 0138) — reused here, not redefined. - Docks the left UIPanel slot exactly like Gossip/Merchant/Quest/QuestLog (`UiPanels.xml` - `UIPanelWindows["CharacterFrame"] = { area = "left", pushable = 0 }`, mirroring the - ref's own `CharacterFrame` row, `UIParent.lua` pin cited in `UiPanels.xml`'s header) — so it - competes for/replaces those windows, never stacks with them. `ToggleCharacter(tab)` (ref + Docks the left UIPanel slot (`UiPanels.xml` `UIPanelWindows["CharacterFrame"] = + { area = "left", pushable = 2, whileDead = 1 }`, the ref's own `UIParent.lua l.19` row — + decision 1507; pushable was wrongly 0 from 0208 until then). pushable=2 means it does NOT + simply replace the NPC-session windows: a pushable-0 window opening under it slides this + sheet to the CENTER seat (vendor left, your equipment beside it), and showing this over a + pushable-0 occupant parks it at center likewise. `ToggleCharacter(tab)` (ref `CharacterFrame.lua:3-23`) is the show/hide/tab-switch entry point; the app's 'C' binding calls it (`ui_script/mod.rs`). diff --git a/crates/benilla-app/assets/ui/QuestLogFrame.xml b/crates/benilla-app/assets/ui/QuestLogFrame.xml index db53e289..ed9a5c3b 100644 --- a/crates/benilla-app/assets/ui/QuestLogFrame.xml +++ b/crates/benilla-app/assets/ui/QuestLogFrame.xml @@ -13,7 +13,8 @@ construction regardless (`widget/mod.rs`'s ctor comment). Docks the left UIPanel slot exactly like Gossip/Merchant/Quest (`UiPanels.xml` - `UIPanelWindows["QuestLogFrame"] = { area = "left", pushable = 0 }`, pin §8's + `UIPanelWindows["QuestLogFrame"] = { area = "left", pushable = 0, whileDead = 1 }` + (whileDead carried since 1507), pin §8's `UIParent.lua l.25` quote) — so it competes for/replaces those windows, never stacks with them. UNLIKE those windows this is not an NPC session: no `CloseX()` on hide, no range guard; it is durable player state the app can push at any time (`benilla-ui`'s `quest_log.rs` module diff --git a/crates/benilla-app/assets/ui/UiPanels.xml b/crates/benilla-app/assets/ui/UiPanels.xml index 9489f19f..d0233f85 100644 --- a/crates/benilla-app/assets/ui/UiPanels.xml +++ b/crates/benilla-app/assets/ui/UiPanels.xml @@ -11,36 +11,51 @@ reference's window arbitration (a different number is a different window order), and the `UISpecialFrames` seeds. The code around that data is ours. - Scope: `left`, `center` and `full` are all live. `doublewide` and `UIChildWindows` are not - — nothing benilla ships wants them — but the registration table keeps their exact shape so - a later row drops in unchanged. **`UISpecialFrames` is not ours to write into** (decision - 1206): it is the table an ADDON puts its own window in, and 34 corpus call sites do. + Scope: `left`, `center` and `full` are all live, and so is `UIChildWindows` (decision 1507 + — all four of the reference's child windows ship now). `doublewide` is not — its one 1.12 + tenant is the auction house, which benilla doesn't ship — but the registration table keeps + its exact shape so a later row drops in unchanged. **`UISpecialFrames` is not ours to write + into** (decision 1206): it is the table an ADDON puts its own window in, and 34 corpus call + sites do. Rows are keyed by the frame names we actually ship. Most of those ARE the reference's own (`GossipFrame`, `MerchantFrame`, `LootFrame`); where ours differs, the row is `Benilla*` and its comment names the reference row it stands in for. -->