feat(ui): port retail jump power bar

Import gmFloatyPowerBarUI LayoutDesc 0x21000072, teach the meter factory its stateful single-image shape, and project the movement-owned retail jump charge through a focused retained controller. Preserve authored resize constraints and state-managed visibility, with named-decomp pseudocode plus controller, movement, and production-DAT conformance coverage.

Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-13 10:22:03 +02:00
parent 27619b2328
commit db03b4bda8
18 changed files with 3045 additions and 10 deletions

View file

@ -14,8 +14,10 @@ namespace AcDream.App.UI;
/// retail's vitals are bars exactly like this, just sprited.
/// </para>
/// </summary>
public sealed class UiMeter : UiElement
public sealed class UiMeter : UiElement, IUiDatStateful
{
private readonly Dictionary<uint, uint> _stateFillSprites = new();
/// <summary>Dat element id, set by the layout importer so duplicated page copies can be scoped.</summary>
public uint ElementId { get; set; }
@ -57,6 +59,32 @@ public sealed class UiMeter : UiElement
/// <summary>Coloured-fill right-cap RenderSurface id.</summary>
public uint FrontRight { get; set; }
/// <summary>The active numeric DAT state for a stateful fill meter.</summary>
public uint ActiveRetailStateId { get; private set; }
/// <summary>
/// Registers a fill sprite carried by a child state of the imported meter.
/// Used by the powerbar shape in LayoutDesc 0x21000072, whose track is on
/// the meter and whose Jump/Melee/Missile/DDD fills are states of one child.
/// </summary>
internal void ConfigureStateFill(uint stateId, uint spriteId)
{
if (stateId != 0 && spriteId != 0)
_stateFillSprites[stateId] = spriteId;
}
public bool TrySetRetailState(uint stateId)
{
if (!_stateFillSprites.TryGetValue(stateId, out uint spriteId))
return false;
ActiveRetailStateId = stateId;
FrontLeft = 0;
FrontTile = spriteId;
FrontRight = 0;
return true;
}
/// <summary>Vertical orientation (retail <c>m_eDirection</c> 2/4). Default false =
/// horizontal (direction 1). The burden bar is the only vertical meter today.</summary>
public bool Vertical { get; set; }