fix(combat): restore retail power bar layers
Preserve the authored gray track, trained-Recklessness range, live bright charge meter, and independent desired-power thumb while keeping Speed and Power over gray side regions. Correct retail text justification value 2 to left alignment and retain direct RenderSurface decoding in the texture inspection tool used to verify the assets. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
0f2d98c501
commit
256c1930bd
18 changed files with 200 additions and 32 deletions
|
|
@ -42,6 +42,14 @@ public sealed class UiScrollbar : UiElement
|
|||
public Func<float?> ScalarFill { get; set; } = () => null;
|
||||
public uint ScalarFillSprite { get; set; }
|
||||
/// <summary>
|
||||
/// Optional authored texture beneath the live scalar fill. gmCombatUI uses
|
||||
/// element <c>0x100005EF</c> for the trained-Recklessness range.
|
||||
/// </summary>
|
||||
public uint ScalarRangeSprite { get; set; }
|
||||
public Func<bool> ScalarRangeVisible { get; set; } = () => false;
|
||||
public float ScalarRangeLeft { get; set; }
|
||||
public float ScalarRangeWidth { get; set; } = float.PositiveInfinity;
|
||||
/// <summary>
|
||||
/// Draw the scalar meter from the power end (right) toward the speed end
|
||||
/// (left). This is the authored gmCombatUI power meter direction.
|
||||
/// </summary>
|
||||
|
|
@ -113,9 +121,15 @@ public sealed class UiScrollbar : UiElement
|
|||
/// <summary>Returns the clipped scalar-meter span in local pixels.</summary>
|
||||
public static (float x, float width) ScalarFillRect(
|
||||
float totalWidth, float fill, bool fromRight)
|
||||
=> ScalarFillRect(0f, totalWidth, fill, fromRight);
|
||||
|
||||
/// <summary>Returns a clipped scalar-meter span inside an authored sub-range.</summary>
|
||||
public static (float x, float width) ScalarFillRect(
|
||||
float rangeLeft, float rangeWidth, float fill, bool fromRight)
|
||||
{
|
||||
float visibleWidth = totalWidth * Math.Clamp(fill, 0f, 1f);
|
||||
return (fromRight ? totalWidth - visibleWidth : 0f, visibleWidth);
|
||||
float safeWidth = MathF.Max(0f, rangeWidth);
|
||||
float visibleWidth = safeWidth * Math.Clamp(fill, 0f, 1f);
|
||||
return (fromRight ? rangeLeft + safeWidth - visibleWidth : rangeLeft, visibleWidth);
|
||||
}
|
||||
|
||||
protected override void OnDraw(UiRenderContext ctx)
|
||||
|
|
@ -124,14 +138,16 @@ public sealed class UiScrollbar : UiElement
|
|||
if (Horizontal)
|
||||
{
|
||||
DrawTiled(ctx, resolve, TrackSprite, 0f, 0f, Width, Height);
|
||||
(float rangeLeft, float rangeWidth) = ScalarRangeRect();
|
||||
if (ScalarRangeVisible() && ScalarRangeSprite != 0)
|
||||
DrawTiled(ctx, resolve, ScalarRangeSprite,
|
||||
rangeLeft, 0f, rangeWidth, Height);
|
||||
if (ScalarFill() is float fill && ScalarFillSprite != 0)
|
||||
{
|
||||
var (fillX, visibleWidth) = ScalarFillRect(Width, fill, ScalarFillFromRight);
|
||||
if (ScalarFillFromRight)
|
||||
DrawTiledRightClipped(
|
||||
ctx, resolve, ScalarFillSprite, fillX, visibleWidth, Height);
|
||||
else
|
||||
DrawTiled(ctx, resolve, ScalarFillSprite, 0f, 0f, visibleWidth, Height);
|
||||
var (fillX, visibleWidth) = ScalarFillRect(
|
||||
rangeLeft, rangeWidth, fill, ScalarFillFromRight);
|
||||
DrawTiledClipped(ctx, resolve, ScalarFillSprite,
|
||||
rangeLeft, fillX, visibleWidth, Height);
|
||||
}
|
||||
float thumbWidth = ScalarThumbWidth(resolve);
|
||||
float travel = MathF.Max(0f, Width - thumbWidth);
|
||||
|
|
@ -196,14 +212,14 @@ public sealed class UiScrollbar : UiElement
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the rightmost portion of a full-width tiled scalar image. UVs
|
||||
/// start at the same offset they would have in the uncut image, matching
|
||||
/// retail meter clipping rather than restarting the wave at the clip edge.
|
||||
/// Draws a clipped portion of a tiled range without restarting the texture
|
||||
/// phase at the clip edge. This mirrors retail meter child clipping.
|
||||
/// </summary>
|
||||
private void DrawTiledRightClipped(
|
||||
private void DrawTiledClipped(
|
||||
UiRenderContext ctx,
|
||||
Func<uint, (uint tex, int w, int h)> resolve,
|
||||
uint id,
|
||||
float rangeLeft,
|
||||
float x,
|
||||
float w,
|
||||
float h)
|
||||
|
|
@ -211,7 +227,19 @@ public sealed class UiScrollbar : UiElement
|
|||
if (id == 0 || w <= 0f || h <= 0f) return;
|
||||
var (tex, tw, th) = resolve(id);
|
||||
if (tex == 0 || tw == 0 || th == 0) return;
|
||||
ctx.DrawSprite(tex, x, 0f, w, h, x / tw, 0f, (x + w) / tw, h / th, Vector4.One);
|
||||
float u0 = (x - rangeLeft) / tw;
|
||||
float u1 = u0 + w / tw;
|
||||
ctx.DrawSprite(tex, x, 0f, w, h, u0, 0f, u1, h / th, Vector4.One);
|
||||
}
|
||||
|
||||
private (float left, float width) ScalarRangeRect()
|
||||
{
|
||||
float left = Math.Clamp(ScalarRangeLeft, 0f, Width);
|
||||
float requestedWidth = float.IsPositiveInfinity(ScalarRangeWidth)
|
||||
? Width - left
|
||||
: MathF.Max(0f, ScalarRangeWidth);
|
||||
float width = Math.Clamp(requestedWidth, 0f, Width - left);
|
||||
return (left, width);
|
||||
}
|
||||
|
||||
public override bool OnEvent(in UiEvent e)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue