fix(rules): correct the inspire courage bonus type and saves
PF1e CRB (Bardic Performance - Inspire Courage): the attack/weapon-damage bonus is a COMPETENCE bonus (not morale), so it stacks with morale sources like Heroism; the performance also grants a +1 MORALE bonus on saving throws against charm and fear effects, implemented as two descriptor-conditional will modifiers (fear / mind_affecting) that dedupe via morale stacking. Simplifications (documented): flat +1 (no scaling per four bard levels) and mind_affecting stands in for the missing charm descriptor. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -4454,7 +4454,18 @@ class CombatEngine:
|
||||
def _execute_inspire_courage(
|
||||
self, state: CombatantState, target: CombatantState | None
|
||||
) -> None:
|
||||
"""Execute Inspire Courage (morale +1 attack/damage, 30ft radius, costs bardic_rounds)."""
|
||||
"""Execute Inspire Courage (30ft radius, costs bardic_rounds).
|
||||
|
||||
PF1e (CRB, Bardic Performance — Inspire Courage): +1 competence bonus
|
||||
on attack rolls and weapon damage rolls, and a +1 morale bonus on
|
||||
saving throws against charm and fear effects. Simplifications: the
|
||||
scaling (+1 per four bard levels) is not modeled (flat +1), and the
|
||||
engine has no "charm" descriptor, so mind_affecting stands in for it
|
||||
(documented over-coverage: compulsion effects also count). The save
|
||||
bonus is carried by two conditional modifiers (fear /
|
||||
mind_affecting); a save with both descriptors still totals +1 because
|
||||
morale does not stack with itself.
|
||||
"""
|
||||
if not state.spend_resource("bardic_rounds", 1):
|
||||
self._log(
|
||||
f"round {self._current_round} {state.combatant.id}: inspire courage "
|
||||
@@ -4481,13 +4492,21 @@ class CombatEngine:
|
||||
)
|
||||
return
|
||||
|
||||
# Apply +1 morale bonus to attack and damage
|
||||
# Apply +1 competence attack/damage and +1 morale vs charm/fear saves
|
||||
for ally in affected:
|
||||
ally.active_buffs.append(
|
||||
ActiveBuff(
|
||||
modifiers=(
|
||||
StatModifier(target="attack", value=1, bonus_type="morale"),
|
||||
StatModifier(target="damage", value=1, bonus_type="morale"),
|
||||
StatModifier(target="attack", value=1, bonus_type="competence"),
|
||||
StatModifier(target="damage", value=1, bonus_type="competence"),
|
||||
StatModifier(
|
||||
target="will", value=1, bonus_type="morale",
|
||||
condition="fear",
|
||||
),
|
||||
StatModifier(
|
||||
target="will", value=1, bonus_type="morale",
|
||||
condition="mind_affecting",
|
||||
),
|
||||
),
|
||||
rounds_left=1,
|
||||
source=f"inspire courage by {state.combatant.id}",
|
||||
@@ -4495,7 +4514,8 @@ class CombatEngine:
|
||||
)
|
||||
self._log(
|
||||
f"round {self._current_round} {state.combatant.id}: "
|
||||
f"inspire courage +1 morale attack/damage to {len(affected)} allies"
|
||||
f"inspire courage +1 competence attack/damage, +1 morale vs "
|
||||
f"charm/fear saves to {len(affected)} allies"
|
||||
)
|
||||
def _execute_attack(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user