fix(rules): avoid the firing-into-melee penalty at 10 feet

SRD 'Attack - Shooting or Throwing into a Melee': a target at least 10 ft from the nearest friendly character lets you avoid the -4 penalty entirely (0, not -2). The -2 is reserved for targets two size categories larger than the engaged friendlies (0 at three+), which is not modeled (documented). Golden transcript unaffected (shot still misses).

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-09-12 13:21:26 +02:00
parent 84bcf004c3
commit d152d42af9
4 changed files with 29 additions and 12 deletions
+7 -3
View File
@@ -337,7 +337,11 @@ def test_firing_into_melee_minus4() -> None:
assert t.hp == 100
def test_firing_into_melee_minus2_when_target_10ft_away() -> None:
def test_firing_into_melee_avoided_when_target_10ft_away() -> None:
# PF1e (SRD "Attack" — Shooting or Throwing into a Melee): "If your target
# [...] is at least 10 feet away from the nearest friendly character, you
# can avoid the -4 penalty" — the 10+ ft clause is 0, not -2 (the -2 is
# reserved for targets two size categories larger, not modeled).
archer = _combatant("archer", ac=99, attacks=(_bow("archer", attack_bonus=8),))
tgt = _combatant("tgt", ac=15, attacks=(_bow("tgt"),))
guard = _combatant("guard", ac=99)
@@ -349,8 +353,8 @@ def test_firing_into_melee_minus2_when_target_10ft_away() -> None:
)
a, t, _g = eng._states
result = eng.resolve_attack(a, t, a.combatant.attacks[0])
assert result.total == 15
assert result.melee_penalty == -2
assert result.total == 17
assert result.melee_penalty == 0
assert result.hit is True
assert result.damage == 3
+1 -1
View File
@@ -816,7 +816,7 @@ def test_ranged_attack_ignores_flanking() -> None:
"initiative: aly d20=9+0=9",
"initiative: tgt d20=8+0=8",
"round 1 tgt: AoO vs arc d20=15+2=17 AC 13 -> HIT 3 damage (6->3)",
"round 1 arc: short bow vs tgt d20=12+2-2(melee)=12 AC 15 -> MISS",
"round 1 arc: short bow vs tgt d20=12+2=14 AC 15 -> MISS",
"round 1 aly: short sword vs tgt d20=10+0=10 AC 15 -> MISS",
"round 1 tgt: short sword vs arc d20=5+2=7 AC 13 -> MISS",
"battle over: draw after 1 rounds",