2026-05-02 19:35:03 -07:00
|
|
|
using Godot;
|
|
|
|
|
using Theriapolis.GodotHost.UI;
|
|
|
|
|
|
|
|
|
|
namespace Theriapolis.GodotHost.Scenes;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Right-rail summary of the in-progress character. Single
|
|
|
|
|
/// <see cref="Refresh"/> rebuilds every section per
|
|
|
|
|
/// GODOT_PORTING_GUIDE.md §10 — the panel is small enough that full
|
|
|
|
|
/// rebuild is cheap and partial-update logic isn't worth it. Connect
|
|
|
|
|
/// the draft via <see cref="SetDraft"/>; the Wizard does this on _Ready.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public partial class Aside : MarginContainer
|
|
|
|
|
{
|
|
|
|
|
private CharacterDraft? _draft;
|
|
|
|
|
private VBoxContainer _content = null!;
|
|
|
|
|
|
|
|
|
|
public override void _Ready()
|
|
|
|
|
{
|
|
|
|
|
AddThemeConstantOverride("margin_left", 18);
|
|
|
|
|
AddThemeConstantOverride("margin_right", 18);
|
|
|
|
|
AddThemeConstantOverride("margin_top", 18);
|
|
|
|
|
AddThemeConstantOverride("margin_bottom", 18);
|
|
|
|
|
|
|
|
|
|
_content = new VBoxContainer();
|
|
|
|
|
_content.AddThemeConstantOverride("separation", 18);
|
|
|
|
|
AddChild(_content);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetDraft(CharacterDraft draft)
|
|
|
|
|
{
|
|
|
|
|
_draft = draft;
|
|
|
|
|
_draft.Changed += Refresh;
|
|
|
|
|
Refresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Refresh()
|
|
|
|
|
{
|
|
|
|
|
if (_draft is null || _content is null) return;
|
|
|
|
|
foreach (var c in _content.GetChildren()) c.QueueFree();
|
|
|
|
|
|
|
|
|
|
_content.AddChild(new Label { Text = "SUMMARY" });
|
2026-05-02 22:24:33 -07:00
|
|
|
|
|
|
|
|
if (_draft.IsHybrid)
|
|
|
|
|
{
|
|
|
|
|
AddBlock("Origin", "Hybrid");
|
|
|
|
|
AddBlock(_draft.DominantParent == "sire" ? "Sire (dominant)" : "Sire",
|
|
|
|
|
FormatLineage(_draft.SireCladeId, _draft.SireSpeciesId));
|
|
|
|
|
AddBlock(_draft.DominantParent == "dam" ? "Dam (dominant)" : "Dam",
|
|
|
|
|
FormatLineage(_draft.DamCladeId, _draft.DamSpeciesId));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
AddBlock("Clade", CodexContent.Clade(_draft.CladeId)?.Name);
|
|
|
|
|
AddBlock("Species", CodexContent.SpeciesById(_draft.SpeciesId)?.Name);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 19:35:03 -07:00
|
|
|
AddBlock("Calling", CodexContent.Class(_draft.ClassId)?.Name);
|
|
|
|
|
AddBlock("Background", CodexContent.Background(_draft.BackgroundId)?.Name);
|
|
|
|
|
AddBlock("Name", string.IsNullOrEmpty(_draft.CharacterName) ? null : _draft.CharacterName);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 22:24:33 -07:00
|
|
|
private static string? FormatLineage(string cladeId, string speciesId)
|
|
|
|
|
{
|
|
|
|
|
var clade = CodexContent.Clade(cladeId);
|
|
|
|
|
var species = CodexContent.SpeciesById(speciesId);
|
|
|
|
|
if (clade is null && species is null) return null;
|
|
|
|
|
if (species is not null) return $"{species.Name} ({clade?.Name ?? cladeId})";
|
|
|
|
|
return clade?.Name;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 19:35:03 -07:00
|
|
|
private void AddBlock(string label, string? value)
|
|
|
|
|
{
|
|
|
|
|
var v = new VBoxContainer();
|
|
|
|
|
v.AddThemeConstantOverride("separation", 4);
|
|
|
|
|
_content.AddChild(v);
|
|
|
|
|
v.AddChild(new Label { Text = label.ToUpperInvariant() });
|
|
|
|
|
v.AddChild(new Label { Text = value ?? "—" });
|
|
|
|
|
}
|
|
|
|
|
}
|