feat(player): port retail augmentation stat chain
This commit is contained in:
parent
0cb60d98a0
commit
461a1fb7b4
22 changed files with 953 additions and 138 deletions
|
|
@ -32,6 +32,11 @@ public sealed class UiText : UiElement, IUiDatStateful
|
|||
/// <summary>One display line: pre-formatted text + its colour.</summary>
|
||||
public readonly record struct Line(string Text, Vector4 Color);
|
||||
|
||||
/// <summary>
|
||||
/// One inline fragment in a retail <c>AppendTextWithFont</c> line.
|
||||
/// </summary>
|
||||
public readonly record struct TextRun(string Text, Vector4 Color);
|
||||
|
||||
/// <summary>A caret position: a line index into the cached line list plus a
|
||||
/// character index (0..line.Text.Length, i.e. a caret slot between glyphs).</summary>
|
||||
public readonly record struct Pos(int Line, int Col);
|
||||
|
|
@ -39,6 +44,13 @@ public sealed class UiText : UiElement, IUiDatStateful
|
|||
/// <summary>Provider of the lines to show, oldest-first. Polled each frame.</summary>
|
||||
public Func<IReadOnlyList<Line>> LinesProvider { get; set; } = static () => Array.Empty<Line>();
|
||||
|
||||
/// <summary>
|
||||
/// Optional inline fragments for a static one-line element. When present
|
||||
/// this reproduces retail's per-append font-state colors while preserving
|
||||
/// the element's authored alignment as one composed line.
|
||||
/// </summary>
|
||||
public Func<IReadOnlyList<TextRun>>? RunsProvider { get; set; }
|
||||
|
||||
/// <summary>Font for the transcript; falls back to the context default.</summary>
|
||||
public BitmapFont? Font { get; set; }
|
||||
|
||||
|
|
@ -381,6 +393,12 @@ public sealed class UiText : UiElement, IUiDatStateful
|
|||
|
||||
private void DrawClippedText(UiRenderContext ctx)
|
||||
{
|
||||
if (OneLine && RunsProvider is { } runsProvider)
|
||||
{
|
||||
DrawSingleLineRuns(ctx, runsProvider());
|
||||
return;
|
||||
}
|
||||
|
||||
// Static centered single-line mode (vitals cur/max numbers etc.): draw the first
|
||||
// line centered H+V (or H+Top/Bottom per VerticalJustify) with the SAME formula
|
||||
// UIElement_Meter used for its label, then skip the scroll/selection machinery entirely.
|
||||
|
|
@ -533,6 +551,54 @@ public sealed class UiText : UiElement, IUiDatStateful
|
|||
}
|
||||
}
|
||||
|
||||
private void DrawSingleLineRuns(
|
||||
UiRenderContext ctx,
|
||||
IReadOnlyList<TextRun> runs)
|
||||
{
|
||||
if (runs.Count == 0) return;
|
||||
|
||||
UiDatFont? datFont = DatFont;
|
||||
BitmapFont? bitmapFont = datFont is null
|
||||
? Font ?? ctx.DefaultFont
|
||||
: null;
|
||||
if (datFont is null && bitmapFont is null) return;
|
||||
|
||||
float totalWidth = 0f;
|
||||
foreach (TextRun run in runs)
|
||||
{
|
||||
totalWidth += datFont is not null
|
||||
? datFont.MeasureWidth(run.Text)
|
||||
: bitmapFont!.MeasureWidth(run.Text);
|
||||
}
|
||||
|
||||
float x = Centered
|
||||
? Math.Max(Padding, (Width - totalWidth) * 0.5f)
|
||||
: RightAligned
|
||||
? Math.Max(Padding, Width - Padding - totalWidth)
|
||||
: Padding;
|
||||
float lineHeight = datFont?.LineHeight ?? bitmapFont!.LineHeight;
|
||||
float y = VOffset(
|
||||
Height,
|
||||
lineHeight,
|
||||
Padding,
|
||||
VerticalJustify);
|
||||
|
||||
foreach (TextRun run in runs)
|
||||
{
|
||||
if (run.Text.Length == 0) continue;
|
||||
if (datFont is not null)
|
||||
{
|
||||
ctx.DrawStringDat(datFont, run.Text, x, y, run.Color);
|
||||
x += datFont.MeasureWidth(run.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.DrawString(run.Text, x, y, run.Color, bitmapFont);
|
||||
x += bitmapFont!.MeasureWidth(run.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True when any vertical portion of a line intersects a text viewport. Retail
|
||||
/// clips the glyphs at the viewport edge; it does not require the full line box to fit.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue