fix(combat): evaluate conditional stat modifiers with action context

This commit is contained in:
2026-09-05 12:17:58 +02:00
parent 31d970dd5f
commit 2f2acd992f
4 changed files with 597 additions and 29 deletions
+28
View File
@@ -108,6 +108,34 @@ def spell_range_ft(spell: SpellSpec, caster_level: int) -> int:
return 400 + 40 * caster_level
_FEAR_CONDITIONS = frozenset({"frightened", "panicked", "shaken", "cowering"})
def save_descriptors_for_effects(effects: tuple[SpellEffect, ...]) -> frozenset[str]:
descriptors: set[str] = set()
for effect in effects:
if isinstance(effect, DamageEffect):
descriptors.update(effect.types)
elif isinstance(effect, ConditionEffect) and effect.condition_name in _FEAR_CONDITIONS:
descriptors.add("fear")
elif isinstance(effect, AreaEffect):
descriptors.update(save_descriptors_for_effects(effect.effects))
return frozenset(descriptors)
def spell_save_descriptors(spell: SpellSpec) -> frozenset[str]:
"""Spell save descriptors: effect-derived plus CRB school tags.
Enchantment is mind_affecting, divination is divination.
"""
descriptors = set(save_descriptors_for_effects(spell.effects))
if spell.school == "enchantment":
descriptors.add("mind_affecting")
elif spell.school == "divination":
descriptors.add("divination")
return frozenset(descriptors)
def _as_dict(value: Json) -> dict[str, Json]:
if isinstance(value, dict):
return value