M6.6: StepReview signing + hybrid math revision

- New Step VIII (Review): name input and Confirm button that
  saves the finalized character to user://character.tres.
- Hybrid lineage rules simplified per project decision: drop
  the "no-stack on overlap, take +1 free elsewhere" rule from
  theriapolis-rpg-clades.md. Hybrids now pick one ability mod
  from each parent clade and they sum if they overlap.
  Removes HybridFreeAbility, the free-bonus picker row, and the
  overlap special case from AbilityCalc + WizardValidation.
- StepClade bonus rows now mutate in place (sync ButtonPressed)
  instead of tearing down on every Refresh — the old path freed
  the very button mid-Pressed-signal, leaving stale buttons next
  to the new ones.
- StepSkills drops the redundant "Calling: X · History: Y" meta
  line; both are already shown in the Aside summary.
- Aside hybrid section adds dual-species traits and the
  universal-hybrid detriment pills.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Christopher Wiebe
2026-05-03 20:51:55 -07:00
parent 0e5d4b7425
commit bb986d49f9
8 changed files with 364 additions and 31 deletions
+51 -7
View File
@@ -259,14 +259,21 @@ public partial class Aside : MarginContainer
AddCladeTraits(flow, CodexContent.Clade(_draft.CladeId));
}
// Species traits.
var sp = CodexContent.SpeciesById(_draft.EffectiveSpeciesId);
if (sp is not null)
// Species traits — purebred uses the single species; hybrids show
// BOTH parent species per theriapolis-rpg-clades.md ("Choose ONE
// species trait from each parent").
if (_draft.IsHybrid)
{
foreach (var t in sp.Traits)
flow.AddChild(new TraitChip { TraitName = t.Name, Description = t.Description });
foreach (var d in sp.Detriments)
flow.AddChild(new TraitChip { TraitName = d.Name, Description = d.Description, Detriment = true });
AddSpeciesTraits(flow, CodexContent.SpeciesById(_draft.SireSpeciesId));
AddSpeciesTraits(flow, CodexContent.SpeciesById(_draft.DamSpeciesId));
// Universal hybrid detriments — every hybrid has all four.
foreach (var (name, desc) in UniversalHybridDetriments)
flow.AddChild(new TraitChip { TraitName = name, Description = desc, Detriment = true });
}
else
{
AddSpeciesTraits(flow, CodexContent.SpeciesById(_draft.SpeciesId));
}
// Class level-1 features.
@@ -321,6 +328,43 @@ public partial class Aside : MarginContainer
flow.AddChild(new TraitChip { TraitName = d.Name, Description = d.Description, Detriment = true });
}
private static void AddSpeciesTraits(HFlowContainer flow, Theriapolis.Core.Data.SpeciesDef? species)
{
if (species is null) return;
foreach (var t in species.Traits)
flow.AddChild(new TraitChip { TraitName = t.Name, Description = t.Description });
foreach (var d in species.Detriments)
flow.AddChild(new TraitChip { TraitName = d.Name, Description = d.Description, Detriment = true });
}
/// <summary>
/// Hardcoded from theriapolis-rpg-clades.md "Universal Hybrid Detriments"
/// (lines 749-753). Every hybrid character has all four. The schema
/// doesn't carry these yet — they live in the clades doc as canonical
/// rules text.
/// </summary>
private static readonly (string Name, string Description)[] UniversalHybridDetriments =
{
("Scent Dysphoria",
"Your scent broadcasts conflicting Clade signals. Creatures with scent ability "
+ "who detect you must make a WIS save (DC 10) or experience instinctive unease, "
+ "imposing disadvantage on their first CHA check with you. Scent-masking products "
+ "can suppress this for 1d4 hours but fail under stress."),
("Illegible Body Language",
"Your tail and ear movements blend two Clade grammars. Disadvantage on nonverbal "
+ "communication checks (CHA checks relying on body language) with purebred creatures. "
+ "Other hybrids read you normally."),
("Social Stigma",
"In non-progressive settlements, disadvantage on CHA checks with strangers and on "
+ "checks to secure housing, employment, or official services. Even in progressive "
+ "areas, the first CHA check with any new NPC is made at -2 until you've established "
+ "rapport."),
("Medical Incompatibility",
"Healing potions and magical healing function at 75% effectiveness (round down). "
+ "Medical treatment calibrated for purebred physiologies works imperfectly on your "
+ "blended body. Hybrid-specific medicine exists but is expensive and rare."),
};
private static void AddSkillChip(HFlowContainer flow, string skillId, string tag)
{
var s = SkillsCatalog.Get(skillId);