fix(rules): total defense denies attacks of opportunity (SRD Total Defense: allowance drops to 0 while the bonus is active)
This commit is contained in:
@@ -224,3 +224,35 @@ def test_no_defensive_actions_transcript_is_pinned() -> None:
|
||||
for state in eng._states:
|
||||
assert state.defensive_ac_bonus == 0
|
||||
assert state.fight_defensively is False
|
||||
|
||||
|
||||
# ── (f) total defense denies attacks of opportunity ────────────────────────────
|
||||
|
||||
|
||||
def test_total_defense_denies_attacks_of_opportunity() -> None:
|
||||
# SRD "Total Defense": "You can't make attacks of opportunity while using
|
||||
# total defense." A foe that leaves the hero's threatened squares takes
|
||||
# no AoO while the hero is using it (no die rolled, allowance 0).
|
||||
def moving_foe(_engine: CombatEngine, state: CombatantState) -> tuple[Action, ...]:
|
||||
if state.combatant.id == "hero":
|
||||
return (Action(kind="total_defense"),)
|
||||
return (Action(kind="move", destination=(0, 4)),)
|
||||
|
||||
eng = _duel(moving_foe, [10, 5], round_cap=1)
|
||||
t = eng.run().transcript
|
||||
assert not any("AoO" in line for line in t)
|
||||
hero = eng._states[0]
|
||||
assert hero.total_defense is True
|
||||
assert eng._aoo_allowance(hero) == 0
|
||||
|
||||
|
||||
def test_control_moving_foe_does_provoke_aoo() -> None:
|
||||
def moving_foe(_engine: CombatEngine, state: CombatantState) -> tuple[Action, ...]:
|
||||
if state.combatant.id == "hero":
|
||||
return _WAIT
|
||||
return (Action(kind="move", destination=(0, 4)),)
|
||||
|
||||
# AoO d20=8+5=13 vs AC 10 -> HIT (d6=3).
|
||||
eng = _duel(moving_foe, [10, 5, 8, 3], round_cap=1)
|
||||
t = eng.run().transcript
|
||||
assert any("AoO vs foe" in line for line in t)
|
||||
|
||||
Reference in New Issue
Block a user