feat(D.2b): vital bars use retail dat sprites (back track + fill-cropped front)
UiMeter gains SpriteResolve/BackSpriteId/FrontSpriteId; when both are set, OnDraw draws the empty-track sprite full-width then the colored-fill sprite UV-cropped to the live fill fraction (left-to-right drain). Falls back to solid rects when sprite ids are absent, keeping existing behavior and tests intact. MarkupDocument.Build() parses `back`/`front` hex attrs on <meter> and passes `resolve` into every UiMeter. vitals.xml wires the authoritative LayoutDesc 0x21000014 sprites (Health 0x06005F3C/3D, Stamina 3E/3F, Mana 40/41). The bar prove-out block in GameWindow.cs was already gone. If the sprites decode as 1x1 magenta at runtime they are paletted (INDEX16/P8) — the solid-color fallback will display instead and can be investigated separately. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
56ee5eff60
commit
84630517e3
4 changed files with 68 additions and 16 deletions
|
|
@ -58,14 +58,17 @@ public static class MarkupDocument
|
|||
var max = BindUint((string?)el.Attribute("max"), binding);
|
||||
panel.AddChild(new UiMeter
|
||||
{
|
||||
Left = F(el, "x"),
|
||||
Top = F(el, "y"),
|
||||
Width = F(el, "w"),
|
||||
Height = F(el, "h"),
|
||||
BarColor = Color((string?)el.Attribute("color")),
|
||||
Fill = BindFloat((string?)el.Attribute("fill"), binding),
|
||||
Label = () => (cur(), max()) is (uint c, uint m) ? $"{c}/{m}" : null,
|
||||
Anchors = Anchor((string?)el.Attribute("anchor")),
|
||||
Left = F(el, "x"),
|
||||
Top = F(el, "y"),
|
||||
Width = F(el, "w"),
|
||||
Height = F(el, "h"),
|
||||
BarColor = Color((string?)el.Attribute("color")),
|
||||
Fill = BindFloat((string?)el.Attribute("fill"), binding),
|
||||
Label = () => (cur(), max()) is (uint c, uint m) ? $"{c}/{m}" : null,
|
||||
Anchors = Anchor((string?)el.Attribute("anchor")),
|
||||
SpriteResolve = resolve,
|
||||
BackSpriteId = Hex((string?)el.Attribute("back")),
|
||||
FrontSpriteId = Hex((string?)el.Attribute("front")),
|
||||
});
|
||||
break;
|
||||
// future element kinds (label, button, image) added here
|
||||
|
|
@ -125,6 +128,15 @@ public static class MarkupDocument
|
|||
return binding.GetType().GetProperty(expr[1..^1]);
|
||||
}
|
||||
|
||||
private static uint Hex(string? s)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(s)) return 0;
|
||||
var t = s.Trim();
|
||||
if (t.StartsWith("0x", System.StringComparison.OrdinalIgnoreCase)) t = t[2..];
|
||||
return uint.TryParse(t, System.Globalization.NumberStyles.HexNumber,
|
||||
System.Globalization.CultureInfo.InvariantCulture, out var v) ? v : 0u;
|
||||
}
|
||||
|
||||
private static AnchorEdges Anchor(string? csv)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(csv)) return AnchorEdges.Left | AnchorEdges.Top;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue