Initial commit: Theriapolis baseline at port/godot branch point
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>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
namespace Theriapolis.Core.Rules.Character;
|
||||
|
||||
/// <summary>
|
||||
/// Phase 6.5 M4 — universal Hybrid detriments, applied automatically to
|
||||
/// every <see cref="HybridState"/>-bearing character per
|
||||
/// <c>theriapolis-rpg-clades.md</c> HYBRID ORIGIN section.
|
||||
///
|
||||
/// The four detriments are *invariant rules*, not authored content —
|
||||
/// they don't vary per hybrid character — so they ship as code constants
|
||||
/// rather than a JSON content block. (Plan §3.1's "HybridDetrimentsDef
|
||||
/// loader" is documented as deviation: code constants are simpler and
|
||||
/// match the design's universality.)
|
||||
///
|
||||
/// 1. <see cref="ScentDysphoriaSaveDc"/> — WIS save DC 10 imposed on the
|
||||
/// first NPC interaction; failure → disadvantage on first CHA check.
|
||||
/// 2. <see cref="IllegibleBodyLanguagePenalty"/> — disadvantage on
|
||||
/// nonverbal CHA checks with purebred NPCs.
|
||||
/// 3. <see cref="SocialStigmaFirstCheckPenalty"/> — -2 to first CHA check
|
||||
/// with strangers in non-progressive settlements.
|
||||
/// 4. <see cref="MedicalIncompatibilityMultiplier"/> — healing from
|
||||
/// potions / Field Repair / Lay on Paws scaled by 0.75.
|
||||
/// </summary>
|
||||
public static class HybridDetriments
|
||||
{
|
||||
/// <summary>WIS save DC for Scent Dysphoria detection check.</summary>
|
||||
public const int ScentDysphoriaSaveDc = 10;
|
||||
|
||||
/// <summary>Magnitude of the Social Stigma first-CHA-check penalty (negative).</summary>
|
||||
public const int SocialStigmaFirstCheckPenalty = -2;
|
||||
|
||||
/// <summary>
|
||||
/// Multiplier applied to healing received by a hybrid character.
|
||||
/// 0.75 = three-quarters effective per <c>clades.md</c>; round down.
|
||||
/// </summary>
|
||||
public const float MedicalIncompatibilityMultiplier = 0.75f;
|
||||
|
||||
/// <summary>True if Illegible Body Language imposes disadvantage on the given check.</summary>
|
||||
public static bool IllegibleBodyLanguagePenalty => true;
|
||||
|
||||
/// <summary>
|
||||
/// Apply the Medical Incompatibility multiplier to a heal amount when
|
||||
/// the recipient is a hybrid PC. Round down per <c>clades.md</c>.
|
||||
/// Non-hybrid recipients pass through unchanged.
|
||||
/// </summary>
|
||||
public static int ScaleHealForHybrid(Character recipient, int rawHeal)
|
||||
{
|
||||
if (recipient.Hybrid is null) return rawHeal;
|
||||
if (rawHeal <= 0) return rawHeal;
|
||||
// Round down — clades.md says "function at 75% effectiveness (round
|
||||
// down)". (int)(0.75 * 7) = 5; (int)(0.75 * 1) = 0 → clamp to 1
|
||||
// because "no heal" is mechanically harsher than "small heal".
|
||||
int scaled = (int)(rawHeal * MedicalIncompatibilityMultiplier);
|
||||
return System.Math.Max(1, scaled);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user