a corpse is not a shop, and Darnassus draws through its doorways

- mounted, over a dead wolf, a right-click answered "That merchant doesn't like you." three times: the click was sending `CMSG_LIST_INVENTORY` — a vendor packet — at the corpse, because the unit block was an if/else-if chain whose LAST arm was the NPC-service dispatch, and the mounted-loot fall-through gave it a newly reachable state — dead target, no leg taken, so the click fell into the arm that means "live friendly service NPC", which dispatched on the CURSOR, and a lootable corpse wears the same pouch a vendor does; the reference splits on death first and never rejoins (`0x60bf80`), so the fork is now `Attack / Dead / Service`, matched exhaustively, with a test over all sixteen combinations of its inputs
- Darnassus draws through its doorways: the reference's Pass 2 ends in the portal RECURSION (`0x6b3d39 call 0x6b41c0`), not a mark — a doorway admits everything the walk reaches through it, and in a city whose outdoor areas are stitched together by portals that is most of it (standing in a shop, 36 groups the marking pass had culled); the narrowness reject turns out to be the open-world walk's entry gate alone, not the shared volume builder (applying it to both had blanked the containing building's shell for every window in the [0.001, 0.02) NDC band), and the depth cap is `[0x86b6b8]` = 10, not a guessed 64; `WOW_PIN_SITE=darnassus` replays the report offline in 0.2 s
- the tab clamp was reading a return the reference's `PanelTemplates_TabResize` does not have, so since the panel kit came off the chain the rule that a tab never grows past its window's drawn right edge raised `attempt to compare number with nil` once per tab per width change on all seven windows built from `CharacterFrameTabButtonTemplate`; it reads the fit back off the art the reference's own verb just wrote (a Texture's width is its authored size, no resolved rect consulted)
- footfalls have one gate, one origin, one kernel: the 50 yd camera-distance cut (`0x5fc00a`) is measured from the CAMERA EYE, unconditional (no self exemption — an earlier slice reused a predicate it had just derived for the ring pools, and no RE note ever recorded one), rounded once with a strict compare — and it sits above the decal, the camera shake AND the 25 yd spray, not copied per consumer; the shake's second suspend arm is the shared fly-or-swim spline bit read off the FOLLOWED unit, so under Mind Vision or Eye of Kilrogg the shake frames on the right body and suspends on the right swim state

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-09-02 17:08:31 +07:00
co-authored by Claude Fable 5.1
parent 1646addd6c
commit dd7de2aa41
14 changed files with 1063 additions and 334 deletions
@@ -520,3 +520,61 @@ fn tab_resize_falls_back_to_this_when_no_tab_is_passed() {
let width = s.eval::<f64>("return ProbeTab:GetWidth()").unwrap();
assert!(width > 0.0, "the tab got a width, got {width}");
}
/// **The window tab's structural clamp, driven the way the client drives it — from `OnUpdate`.**
///
/// 1002's law is that a tab may never grow past its window's drawn right edge, whatever fit the
/// instance asked for. `BenillaTabButton_OnUpdate` enforces it by comparing the fitted width
/// against the room, and it used to read that width from `PanelTemplates_TabResize`'s return —
/// a benilla-only line on OUR copy of that verb.
///
/// 1837 put `Interface\FrameXML\UIPanelTemplates.lua` on the chain BELOW `UiPanels.xml`, so the
/// reference's `PanelTemplates_TabResize` is the one that runs, and it returns nothing. The
/// comparison became `nil > number`: a raise, once per tab per width change, with the clamp
/// silently off the air and the tab already sized by the unclamped first call.
///
/// The existing tab test drives `OnLoad` and never ticks, which is why nothing caught it.
#[test]
fn a_tab_never_grows_past_its_windows_right_edge() {
let _data = benilla_formats::wow_data_or_skip!();
let mut s = harness();
s.set_text_measurer(Box::new(super::FixedWidthFont(6.0)));
// A deliberately narrow window and a long label: the natural fit does not fit.
let doc = benilla_ui::framexml::parse(
r#"<Ui>
<Frame name="ProbeWindow">
<Size><AbsDimension x="160" y="200"/></Size>
<Anchors><Anchor point="TOPLEFT"/></Anchors>
<Frames>
<Button name="ProbeTab" inherits="CharacterFrameTabButtonTemplate"
text="A Very Long Tab Label Indeed">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-10"/></Offset></Anchor>
</Anchors>
</Button>
</Frames>
</Frame>
</Ui>"#,
)
.unwrap();
let report = benilla_ui::loader::load_in(&s, &doc, "test", &|_: &str| None);
assert!(report.errors.is_empty(), "load: {:?}", report.errors);
// Two ticks: the first lands the measure, the second settles against it.
s.tick(0.1);
s.tick(0.1);
assert!(
s.errors().is_empty(),
"the settle must not raise — the clamp reads the fit back, not a return value: {:?}",
s.errors()
);
let (left, width) = s
.eval::<(f64, f64)>("return ProbeTab:GetLeft(), ProbeTab:GetWidth()")
.unwrap();
let right = s.eval::<f64>("return ProbeWindow:GetRight()").unwrap();
assert!(
left + width <= right + 0.5,
"the tab ran past its window: left {left} + width {width} > right {right}"
);
}