fix(rules): shield of faith grants its SRD deflection AC buff (+2, +1 per six caster levels, max +5) via a new BuffEffect flat scaling

This commit is contained in:
2026-09-17 22:36:18 +02:00
parent 27f962920f
commit 47f563e11a
5 changed files with 154 additions and 31 deletions
+38 -5
View File
@@ -6461,7 +6461,10 @@ class CombatEngine:
effect, target, caster=caster, saved=saved,
empower=empower, maximize=maximize, spell_name=spell_name,
)
return self._apply_buff_effect(effect, target, spell_name=spell_name)
return self._apply_buff_effect(
effect, target, spell_name=spell_name,
caster_level=caster.combatant.level,
)
def _apply_damage_effect(
self,
@@ -6678,16 +6681,42 @@ class CombatEngine:
return f"+{actual} HP"
def _apply_buff_effect(
self, effect: BuffEffect, target: CombatantState, *, spell_name: str
self,
effect: BuffEffect,
target: CombatantState,
*,
spell_name: str,
caster_level: int,
) -> str:
# PF1e caster-level scaling on buff values (SRD shield of faith
# "+2 deflection, +1 per six caster levels (maximum +5)"): the flat
# extra is added to EVERY modifier of the buff.
modifiers = effect.modifiers
if effect.scaling_flat is not None:
extra = min(
effect.scaling_flat.max_amount,
(caster_level // effect.scaling_flat.per_levels)
* effect.scaling_flat.amount,
)
if extra > 0:
modifiers = tuple(
StatModifier(
target=mod.target,
value=mod.value + extra,
bonus_type=mod.bonus_type,
condition=mod.condition,
weapon_filter=mod.weapon_filter,
)
for mod in modifiers
)
target.active_buffs.append(
ActiveBuff(
modifiers=effect.modifiers,
modifiers=modifiers,
rounds_left=effect.duration_rounds,
source=f"spell: {spell_name}",
)
)
return f"buff {len(effect.modifiers)} mods ({effect.duration_rounds}r)"
return f"buff {len(modifiers)} mods ({effect.duration_rounds}r)"
def _apply_penalty_effect(
self,
@@ -6912,7 +6941,11 @@ class CombatEngine:
)
if isinstance(effect, BuffEffect):
duration = effect.duration_rounds * 2 if has_extend else effect.duration_rounds
return BuffEffect(modifiers=effect.modifiers, duration_rounds=duration)
return BuffEffect(
modifiers=effect.modifiers,
duration_rounds=duration,
scaling_flat=effect.scaling_flat,
)
if isinstance(effect, PenaltyEffect):
duration = (
effect.duration_rounds_per_level * 2