held weapons pick, book images size to their art, the panel opens again

- a unit's pick geometry is every model chained to it — body, held items, mount — one candidate per root resolving to the same unit, which is how the reference registers its pick (it walks the attachment tree and registers each model); Naxxramas' floating weapons could only be selected by their name plate before (no body, no candidate), and every armed unit gains its gear as clickable surface (our own body 12 → 21 tested parts); the broad phase stays the body's sphere, so a very long polearm on a small body is the named residual
- the selection ring's writer has two branches and we had transcribed one: a model whose stand box is degenerate (zero extent in x and y) rings at the literal 1.2 × scale — 2.7 yd under a trigger creature — instead of `sqrt(0.5·sqrt(dx²+dy²))` = 0 clamped to an invented 0.05 floor; both invented fallbacks are gone
- an HTML book image with no width/height is its art's texel square (one texel = one FrameXML unit, bit-for-bit the `<AbsDimension>` converter), not the rest of the page — *A Treatise on Military Ranks* drew its crest twice too big and stretched to the page's aspect; a texture-size oracle answers off the same decoder the renderer draws with, and an unfloated height-less `<IMG>` reserves its art's height in the flow; 797 shipped textures swept, exactly two zero-size axes move and neither is visible
- the dev debug panel killed the client on open with "Attachments have differing sample counts": Bevy's 2-D depth texture is keyed on the render target alone, so two Camera2ds on one window at different MSAA counts cannot both be valid, and the egui overlay camera had silently kept the default 4× after the player-UI camera went to Off; it now says `Msaa::Off`, and a preflight check reports any two 2-D cameras that disagree on a shared target, every run

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-08-29 17:16:04 +07:00
co-authored by Claude Fable 5
parent 80551cab5e
commit 18858046f9
21 changed files with 862 additions and 118 deletions
+16 -4
View File
@@ -43,9 +43,6 @@
//! `SimpleHTML:SetSpacing` *does* honour here is the half SimpleHTML itself owns and computes:
//! the inter-block step. That is a real, drawn effect rather than a stored-and-ignored number,
//! which is why this pair ships where the FontString/Font ones do not.
//! - **An `<IMG>` with no declared height reserves nothing in the flow.** The reference
//! substitutes the texture's natural pixel height (`0x770790`), which needs the BLP loaded —
//! knowledge the engine core does not have at `SetText` time.
//! - **A block's wrap width of 0** (a SimpleHTML sized only by anchors) lets the measure
//! round-trip supply the natural text width, where the reference leaves the block at width 0.
//! That is this engine's standing law for every height-less/width-less FontString, and inverting
@@ -375,8 +372,23 @@ fn build(model: &mut Model, fh: FrameHandle, blocks: &[Block]) {
// `prevBlock` is **never** written by the image path (three reads of `+0x348` in
// the whole function, zero writes) — the next block still hangs off the last TEXT
// block, only lower.
//
// The height it reserves is `texture.GetHeight()`, which is `CSimpleTexture`'s
// **override**: a `<IMG>` with no `height=` reserves its art's own texel height,
// not nothing (decision 1349 — one texel is one FrameXML unit). Asked of the same
// host oracle the resolve derives the region's rect from, so the space the flow
// leaves and the space the image fills are one number.
if !*floated {
next_y -= *h;
let reserved = if *h == 0.0 {
src.as_deref()
.and_then(|p| {
super::layout::texel_span(model.texture_size_probe.as_ref(), p)
})
.map_or(0.0, |(_, th)| th)
} else {
*h
};
next_y -= reserved;
}
made.push(rh);
}