namespace AcDream.UI.Abstractions.Panels.Vitals;
///
/// First real UI panel — shows the local player's vitals as progress bars.
/// Backend-agnostic; renders exclusively through
/// so the same file works under ImGui.NET (D.2a) and the future custom
/// retail-look toolkit (D.2b).
///
///
/// D.2a shows only HP (percent). /
/// return null until a
/// LocalPlayerState is wired (follow-up issue). When they start
/// returning non-null, this panel picks them up automatically.
///
///
public sealed class VitalsPanel : IPanel
{
private const float BarWidth = 200f;
private readonly VitalsVM _vm;
public VitalsPanel(VitalsVM vm)
{
_vm = vm ?? throw new ArgumentNullException(nameof(vm));
}
///
public string Id => "acdream.vitals";
///
public string Title => "Vitals";
///
public bool IsVisible { get; set; } = true;
///
public void Render(PanelContext ctx, IPanelRenderer renderer)
{
if (!renderer.Begin(Title))
{
renderer.End();
return;
}
// HP — always available from CombatState. If LocalPlayer has the
// absolute values too, prefer "current/max (percent)" overlay.
float hp = _vm.HealthPercent;
renderer.Text("HP");
renderer.SameLine();
renderer.ProgressBar(hp, BarWidth, overlay: FormatOverlay(
hp, _vm.HealthCurrent, _vm.HealthMax));
// Stamina — show only when the VM has a real value.
if (_vm.StaminaPercent is float stam)
{
renderer.Text("Stam");
renderer.SameLine();
renderer.ProgressBar(stam, BarWidth, overlay: FormatOverlay(
stam, _vm.StaminaCurrent, _vm.StaminaMax));
}
// Mana — show only when the VM has a real value.
if (_vm.ManaPercent is float mana)
{
renderer.Text("Mana");
renderer.SameLine();
renderer.ProgressBar(mana, BarWidth, overlay: FormatOverlay(
mana, _vm.ManaCurrent, _vm.ManaMax));
}
renderer.End();
}
///
/// Format a vital-bar overlay. Prefers current / max (percent%)
/// when absolute values are available; falls back to percent-only
/// when not (e.g. HP pre-PlayerDescription, where only the
/// CombatState percent has been wired).
///
private static string FormatOverlay(float percent, uint? current, uint? max)
{
if (current is uint c && max is uint m && m > 0)
return $"{c} / {m} ({percent * 100f:F0}%)";
return $"{percent * 100f:F0}%";
}
}