using System.Text.Json.Serialization; namespace Theriapolis.Core.Data; /// /// Immutable class definition loaded from classes.json. Phase 5 reads /// every field — including the full level table — but only level-1 /// features have runtime effect; higher-level entries are forward-compat /// scaffolding for the level-up flow shipped in Phase 5.5 / 6. /// public sealed record ClassDef { [JsonPropertyName("id")] public string Id { get; init; } = ""; [JsonPropertyName("name")] public string Name { get; init; } = ""; /// Codex-voice calling description: in-character quote followed /// by a one-paragraph profile (mirrors CladeDef / SpeciesDef). Surfaced /// on the Step III calling card. [JsonPropertyName("description")] public string Description { get; init; } = ""; /// Hit die size: 6 / 8 / 10 / 12. [JsonPropertyName("hit_die")] public int HitDie { get; init; } = 8; /// Primary ability key(s) (STR / DEX / CON / INT / WIS / CHA). [JsonPropertyName("primary_ability")] public string[] PrimaryAbility { get; init; } = Array.Empty(); /// Saving-throw proficiencies. [JsonPropertyName("saves")] public string[] Saves { get; init; } = Array.Empty(); /// Armor proficiency tags: "light", "medium", "heavy", "shields". [JsonPropertyName("armor_proficiencies")] public string[] ArmorProficiencies { get; init; } = Array.Empty(); /// Weapon proficiency tags: "simple", "martial", "natural", or specific item ids. [JsonPropertyName("weapon_proficiencies")] public string[] WeaponProficiencies { get; init; } = Array.Empty(); /// Tool proficiency tags. [JsonPropertyName("tool_proficiencies")] public string[] ToolProficiencies { get; init; } = Array.Empty(); [JsonPropertyName("skills_choose")] public int SkillsChoose { get; init; } = 0; [JsonPropertyName("skill_options")] public string[] SkillOptions { get; init; } = Array.Empty(); /// /// Per-level entries. Level 1..20. Phase 5 only consults level 1, but /// the full table loads so the level-up flow doesn't need a schema bump. /// [JsonPropertyName("level_table")] public ClassLevelEntry[] LevelTable { get; init; } = Array.Empty(); /// Description of each named feature referenced from level_table. [JsonPropertyName("feature_definitions")] public Dictionary FeatureDefinitions { get; init; } = new(); /// Allowed subclass ids (cross-reference into subclasses.json). [JsonPropertyName("subclass_ids")] public string[] SubclassIds { get; init; } = Array.Empty(); /// /// Items handed to a level-1 character of this class at creation time. /// adds each entry to the /// inventory and, if is true, /// equips it into . /// [JsonPropertyName("starting_kit")] public StartingKitItem[] StartingKit { get; init; } = Array.Empty(); } /// /// One row in : the item id, quantity, and /// optional auto-equip target. ItemId must resolve against items.json. /// public sealed record StartingKitItem { [JsonPropertyName("item_id")] public string ItemId { get; init; } = ""; [JsonPropertyName("qty")] public int Qty { get; init; } = 1; /// If true, the item is equipped into at creation. [JsonPropertyName("auto_equip")] public bool AutoEquip { get; init; } = false; /// "main_hand" / "off_hand" / "body" / "helm" / "cloak" / "boots" / "adaptive_pack" / etc. [JsonPropertyName("equip_slot")] public string EquipSlot { get; init; } = ""; } public sealed record ClassLevelEntry { [JsonPropertyName("level")] public int Level { get; init; } = 1; [JsonPropertyName("prof")] public int ProficiencyBonus { get; init; } = 2; /// Feature ids unlocked at this level. Resolves into . [JsonPropertyName("features")] public string[] Features { get; init; } = Array.Empty(); } public sealed record ClassFeatureDef { [JsonPropertyName("name")] public string Name { get; init; } = ""; [JsonPropertyName("description")] public string Description { get; init; } = ""; /// "passive", "active", "choice", "bonus_action", "reaction", "stub". [JsonPropertyName("kind")] public string Kind { get; init; } = "passive"; [JsonPropertyName("uses_per_short_rest")] public int? UsesPerShortRest { get; init; } [JsonPropertyName("uses_per_long_rest")] public int? UsesPerLongRest { get; init; } /// For "choice" features: the available pick ids. [JsonPropertyName("options")] public string[]? Options { get; init; } }