b451f83174
Captures the pre-Godot-port state of the codebase. This is the rollback anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md). All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
56 lines
2.4 KiB
C#
56 lines
2.4 KiB
C#
using Theriapolis.Core.Data;
|
|
using Theriapolis.Game.CodexUI.Core;
|
|
using Theriapolis.Game.CodexUI.Screens;
|
|
using Theriapolis.Game.CodexUI.Widgets;
|
|
using Theriapolis.Game.UI;
|
|
|
|
namespace Theriapolis.Game.CodexUI.Steps;
|
|
|
|
/// <summary>
|
|
/// Step II — Species. Card grid filtered to the selected clade. Each card
|
|
/// shows name + size + base speed + ability mods + traits.
|
|
/// </summary>
|
|
public static class StepSpecies
|
|
{
|
|
public static CodexWidget Build(CodexCharacterCreationScreen s, CodexAtlas atlas, CodexHoverPopover popover)
|
|
{
|
|
var col = new Column { Spacing = 14 };
|
|
col.Add(StepCommon.PageIntro(
|
|
$"Folio II — Of Lineage within {s.Clade?.Name ?? "—"}",
|
|
"Choose your Species",
|
|
"Within every clade are kindreds — different statures, ranges, and inheritances. The species refines what the clade began."));
|
|
|
|
var grid = new Grid { Columns = 3 };
|
|
foreach (var sp in s.AllSpecies.Where(x => s.Clade is null || x.CladeId == s.Clade.Id))
|
|
grid.Add(BuildCard(s, atlas, popover, sp));
|
|
col.Add(grid);
|
|
return col;
|
|
}
|
|
|
|
private static CodexWidget BuildCard(CodexCharacterCreationScreen s, CodexAtlas atlas, CodexHoverPopover popover, SpeciesDef sp)
|
|
{
|
|
var content = new Column { Spacing = 8 };
|
|
content.Add(new CodexLabel(sp.Name, CodexFonts.DisplayMedium, CodexColors.Ink));
|
|
content.Add(new CodexLabel($"{CodexCopy.SizeLabel(sp.Size).ToUpperInvariant()} · {sp.BaseSpeedFt} FT.",
|
|
CodexFonts.MonoTagSmall, CodexColors.InkMute));
|
|
|
|
if (sp.AbilityMods.Count > 0)
|
|
{
|
|
var mods = new WrapRow();
|
|
foreach (var kv in sp.AbilityMods) mods.Add(new ModChipMini(atlas, kv.Key, kv.Value));
|
|
content.Add(mods);
|
|
}
|
|
|
|
if (sp.Traits.Length > 0 || sp.Detriments.Length > 0)
|
|
{
|
|
var traits = new WrapRow();
|
|
foreach (var t in sp.Traits) traits.Add(new HoverableChip(atlas, popover, t.Name, t.Name, t.Description, null, ChipKind.Trait));
|
|
foreach (var t in sp.Detriments) traits.Add(new HoverableChip(atlas, popover, t.Name, t.Name, t.Description, "DETRIMENT", ChipKind.TraitDetriment));
|
|
content.Add(traits);
|
|
}
|
|
|
|
return new CodexCard(atlas, content, s.Species == sp,
|
|
onClick: () => { s.Species = sp; s.InvalidateLayout(); });
|
|
}
|
|
}
|