fix(rules): knock prone only on a 5-point overrun margin
PF1e CRB 'Overrun': 'If your maneuver is successful, you move through the target's space. If your attack exceeds your opponent's CMD by 5 or more, ... the target is knocked prone.' The engine knocked the target prone on ANY success. A plain success (margin 0-4) now only moves the attacker through; prone requires total - CMD >= 5 (_OVERRUN_PRONE_MARGIN). Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
+21
-2
@@ -123,11 +123,13 @@ def test_escape_from_grapple_consumes_single_d20() -> None:
|
||||
|
||||
|
||||
def test_overrun_knocks_prone_and_moves_through() -> None:
|
||||
# d20=15+2=17 vs CMD 12: margin 5 -> prone AND moved through (CRB
|
||||
# "Overrun": prone only when the attack exceeds CMD by 5 or more).
|
||||
a_spec = make_combatant("a", attack_bonus=2)
|
||||
b_spec = make_combatant("b")
|
||||
a = make_state(a_spec, "players", (1, 1))
|
||||
b = make_state(b_spec, "monsters", (1, 2))
|
||||
engine = make_engine([1, 12], [a, b])
|
||||
engine = make_engine([1, 15], [a, b])
|
||||
engine._execute_maneuver(a, b, "overrun")
|
||||
prone = next(c for c in b.active_conditions if c.condition.name == "prone")
|
||||
assert prone.rounds_left == 1
|
||||
@@ -135,14 +137,31 @@ def test_overrun_knocks_prone_and_moves_through() -> None:
|
||||
assert a.pos == (1, 3)
|
||||
|
||||
|
||||
def test_overrun_small_margin_moves_through_without_prone() -> None:
|
||||
# d20=14+2=16 vs CMD 12: margin 4 -> plain success: moved through,
|
||||
# NOT prone (CRB "Overrun").
|
||||
a_spec = make_combatant("a", attack_bonus=2)
|
||||
b_spec = make_combatant("b")
|
||||
a = make_state(a_spec, "players", (1, 1))
|
||||
b = make_state(b_spec, "monsters", (1, 2))
|
||||
engine = make_engine([1, 14], [a, b])
|
||||
engine._execute_maneuver(a, b, "overrun")
|
||||
assert not any(c.condition.name == "prone" for c in b.active_conditions)
|
||||
assert a.pos == (1, 3)
|
||||
assert "SUCCESS (moved through)" in engine._transcript[-1]
|
||||
assert "prone" not in engine._transcript[-1]
|
||||
|
||||
|
||||
def test_overrun_prone_but_no_space() -> None:
|
||||
# d20=15+2=17 vs CMD 12: margin 5 -> prone; the beyond cell is occupied,
|
||||
# so no move-through.
|
||||
a_spec = make_combatant("a", attack_bonus=2)
|
||||
b_spec = make_combatant("b")
|
||||
c_spec = make_combatant("c")
|
||||
a = make_state(a_spec, "players", (1, 1))
|
||||
b = make_state(b_spec, "monsters", (1, 2))
|
||||
c = make_state(c_spec, "monsters", (1, 3))
|
||||
engine = make_engine([1, 12], [a, b, c])
|
||||
engine = make_engine([1, 15], [a, b, c])
|
||||
engine._execute_maneuver(a, b, "overrun")
|
||||
assert any(cond.condition.name == "prone" for cond in b.active_conditions)
|
||||
assert a.pos == (1, 1)
|
||||
|
||||
Reference in New Issue
Block a user