feat(rules): alignment-gated protection from evil/law wards via attacker context

Add attacker-alignment modifier conditions (attacker_is_evil/lawful/good/
chaotic) evaluated against an optional attacker context threaded through
_stat_modifiers/_modifier_condition_holds, _attack_ac_mods (resolve_attack
AC path), resolve_save and _area_save (spell save paths), plus the fear
aura. Without a source in scope the condition is False, so existing rolls
are untouched (golden transcripts bit-identical).

Give the four protection_from_evil/law(+communal) JSONs their SRD buff:
+2 deflection to AC and +2 resistance on fort/ref/will, gated on the
attacker/caster alignment (SRD: bonuses apply 'against attacks or effects
created by evil creatures'); duration 1 min/level approximated as 10
rounds (engine convention). Descriptions document the unmodeled mental-
control suppression and communal duration-split clauses. Level/range/
save/SR verified against the KB.
This commit is contained in:
2026-09-20 12:57:29 +02:00
parent 6a18d456f6
commit 3be22b9c55
8 changed files with 452 additions and 22 deletions
+12 -3
View File
@@ -1035,11 +1035,20 @@ Règles modélisées :
- Modificateurs conditionnés : un `StatModifier` avec `condition=` n'est appliqué
que si la condition tient au moment de la résolution (`_modifier_condition_holds`) :
`target_within_30ft_ranged` (arme à distance à ≤ 30 ft), `axe` (arme dont le nom
contient « axe »), et les descripteurs de sauvegarde (`fear`, `cold`,
contient « axe »), les descripteurs de sauvegarde (`fear`, `cold`,
`electricity`, `fey`, `divination`, `poison`, `disease`, `mind_affecting`) — les
descripteurs sont portés par l'aura de terreur, les sorts (types de dégâts,
conditions de peur, écoles enchantement/divination) et les effets de zone. Toute
condition inconnue ou non supportée reste exclue (False).
conditions de peur, écoles enchantement/divination) et les effets de zone — et
les conditions d'alignement de la source (`attacker_is_evil`, `attacker_is_lawful`,
`attacker_is_good`, `attacker_is_chaotic`) évaluées contre l'attaquant / la
créature qui crée l'effet, passé en contexte `attacker` par la résolution
d'attaque (CA), les sauvegardes de sorts (chemin ciblé et zone) et l'aura de
terreur ; sans source en contexte, la condition est Fausse. C'est ce qui porte
les protections alignement-dépendantes du SRD (protection from evil/law :
« +2 deflection bonus to AC and a +2 resistance bonus on saves against attacks
or effects created by evil creatures » — jamais contre une source qui n'est pas
du côté aligné en face). Toute condition inconnue ou non supportée reste exclue
(False).
- Incantation : chaque `CombatantState` porte `spell_slots_left` (initialisé depuis
le champ `spell_slots` du JSON, ex. `{"1": 4, ...}`) — convention de données :
`spell_slots` est une valeur **finale** par rencontre et le moteur ne calcule