fix(combat): correct concentration DCs by situation
This commit is contained in:
@@ -748,21 +748,41 @@ class CombatEngine:
|
||||
# Concentration check if damaged
|
||||
dmg = hp_before - caster.hp
|
||||
if dmg > 0 and not self._check_concentration(caster, spell_level, dmg):
|
||||
dc = self._concentration_dc(caster, spell_level, dmg)
|
||||
self._log(
|
||||
f"round {self._current_round} {caster.combatant.id}: "
|
||||
f"concentration check failed (DC {15 + 2 * spell_level}), spell fizzles"
|
||||
f"concentration check failed (DC {dc}), spell fizzles"
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
def _concentration_dc(
|
||||
self, caster: CombatantState, spell_level: int, damage_taken: int
|
||||
) -> int:
|
||||
"""Concentration DC for the caster's current situation.
|
||||
|
||||
- injured while casting: => 10 + damage_taken + spell_level
|
||||
- grappled or pinned: => 10 + grappler's CMB + spell_level
|
||||
- casting defensively: => 15 + 2 * spell_level
|
||||
"""
|
||||
if caster.grappled_with is not None:
|
||||
grappler = next(
|
||||
(s for s in self._states if s.combatant.id == caster.grappled_with), None
|
||||
)
|
||||
cmb = self._maneuver_cmb(grappler) if grappler is not None else 0
|
||||
return 10 + cmb + spell_level
|
||||
if damage_taken > 0:
|
||||
return 10 + damage_taken + spell_level
|
||||
return 15 + 2 * spell_level
|
||||
|
||||
def _check_concentration(
|
||||
self, caster: CombatantState, spell_level: int, damage_taken: int
|
||||
) -> bool:
|
||||
"""Concentration check: DC = 15 + 2 * spell_level + damage_taken.
|
||||
"""Concentration check: DC depends on situation.
|
||||
|
||||
Combat Casting feat gives +4 bonus.
|
||||
Roll = d20 + caster_level + casting ability mod (+4 Combat Casting).
|
||||
"""
|
||||
dc = 15 + 2 * spell_level + damage_taken
|
||||
dc = self._concentration_dc(caster, spell_level, damage_taken)
|
||||
has_combat_casting = any(f.name == "Combat Casting" for f in caster.combatant.features)
|
||||
bonus = 4 if has_combat_casting else 0
|
||||
roll = self._rng.d20()
|
||||
|
||||
Reference in New Issue
Block a user