openthebox/src/OpenTheBox/Rendering/Panels/StatsPanel.cs
2026-03-11 22:19:25 +01:00

53 lines
1.7 KiB
C#

using OpenTheBox.Core;
using OpenTheBox.Core.Enums;
using OpenTheBox.Localization;
using Spectre.Console;
using Spectre.Console.Rendering;
namespace OpenTheBox.Rendering.Panels;
/// <summary>
/// Renders the player stat values in a framed panel.
/// </summary>
public static class StatsPanel
{
/// <summary>
/// Builds a renderable stats display from the current game state.
/// Only stats present in <see cref="GameState.VisibleStats"/> are shown.
/// </summary>
public static IRenderable Render(GameState state, LocalizationManager? loc = null)
{
var rows = new List<IRenderable>();
foreach (var statType in state.VisibleStats.OrderBy(s => s.ToString()))
{
if (!state.Stats.TryGetValue(statType, out int value))
continue;
string label = statType.ToString();
string color = GetStatColor(statType);
rows.Add(new Markup($" [{color}]{Markup.Escape(label)}:[/] [bold]{value}[/]"));
}
// Add total boxes opened as a bonus stat
string boxesLabel = loc?.Get("stats.boxes_opened") ?? "Boxes Opened";
rows.Add(new Markup($" [silver]{Markup.Escape(boxesLabel)}:[/] [bold]{state.TotalBoxesOpened}[/]"));
string title = loc?.Get("stats.title") ?? "Stats";
return new Panel(new Rows(rows))
.Header($"[bold magenta]{Markup.Escape(title)}[/]")
.Border(BoxBorder.Rounded);
}
private static string GetStatColor(StatType type) => type.ToString().ToLowerInvariant() switch
{
"strength" or "power" => "red",
"defense" or "armor" => "blue",
"speed" or "agility" => "green",
"luck" => "gold1",
"intelligence" or "wisdom" => "purple",
_ => "silver"
};
}