feat(ui): importer Fix 5 — build meter text children; drop character XP injection hacks
LayoutImporter.BuildWidget gains a UiMeter-specific branch after the ConsumesDatChildren gate: Type-3 slice containers (already consumed by DatWidgetFactory.BuildMeter to extract sprite ids) are skipped, but all other children (Type-12 UIElement_Text overlays) are built normally, registered in byId, and attached as UiElement children of the meter. This fixes the XP meter (0x10000236): its two Type-12 children 0x10000237 "XP for next level:" label 0x10000238 XP-to-next-level value are now real UiText widgets in the tree, findable via FindElement. CharacterStatController.Bind now uses FindElement + LinesProvider binding instead of injecting runtime AddChild nodes. The two previously-injected UiText overlays are removed; the controller binds Padding=0, ClickThrough, RightAligned on the dat-origin widgets instead. New constants XpNextLabelId + XpNextValueId replace the old comment block. TAB GROUPS (SKIPPED — documented): UiText.ConsumesDatChildren flipping is NOT safe globally (risks chat/vitals) and the page-visibility pass in CharacterStatController depends on tab group Children.Count==0. Tab sprite injection onto layout.Root stays and is explicitly commented as deliberate. VITALS SAFE: health/stamina/mana meters have only Type-3 children → new loop finds nothing → zero UiElement children added → byte-identical render. VitalsController.BindMeter AddChild(number) pattern unchanged. Tests: 3 new LayoutImporterTests (slice-only, Fix-5 text children, vitals regression guard) + 3 CharacterStatControllerTests (label bound, value bound, missing children no-throw). 715 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1b9dd6c7a8
commit
ad4ed51d6b
4 changed files with 241 additions and 58 deletions
|
|
@ -130,6 +130,32 @@ public static class LayoutImporter
|
|||
if (cw is not null) w.AddChild(cw);
|
||||
}
|
||||
}
|
||||
else if (w is UiMeter)
|
||||
{
|
||||
// Fix 5: UiMeter.ConsumesDatChildren=true swallows ALL children, including text
|
||||
// label/value overlays that are separate renderable widgets (not part of the bar
|
||||
// art). BuildMeter in DatWidgetFactory already consumed the Type-3 slice containers
|
||||
// (reads their grandchild sprite ids to populate Back*/Front* properties). The
|
||||
// remaining non-Type-3 children (typically Type-12 UIElement_Text overlays such
|
||||
// as the XP meter's 0x10000237 label + 0x10000238 value) ARE renderable and belong
|
||||
// in the widget tree. We build them here explicitly, registered in byId so
|
||||
// FindElement can locate them, and attached as children of the meter so they render
|
||||
// as overlays at their dat-local coordinates. The controller can then locate these
|
||||
// widgets via FindElement and bind LinesProvider without injecting new runtime nodes.
|
||||
//
|
||||
// Type-3 children are SKIPPED here because BuildMeter already consumed them (they
|
||||
// carry the 3-slice sprite ids, not text content; building them again would
|
||||
// double-draw the bar art). All other child types are built normally.
|
||||
//
|
||||
// Safe for vitals: the health/stamina/mana meters have ONLY Type-3 slice children
|
||||
// (no text children). This loop finds nothing for them → no change to vitals.
|
||||
foreach (var child in info.Children)
|
||||
{
|
||||
if (child.Type == 3) continue; // slice containers: already consumed by BuildMeter
|
||||
var cw = BuildWidget(child, resolve, datFont, fontResolve, byId);
|
||||
if (cw is not null) w.AddChild(cw);
|
||||
}
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue