fix(rules): exempt retrieve and repair weapon from the disabled hit-point cost
PF1e (CRB, Disabled): a disabled creature can take move actions without further injuring itself. retrieve_weapon and repair_weapon are budget-classified move actions (_ACTION_ECONOMY_MOVE_KINDS) but were absent from _DISABLED_MOVE_KINDS, so a creature at 0 hp paid 1 hp to draw or mend a weapon. Added both kinds to the exempt set. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -338,6 +338,57 @@ def test_disabled_move_action_costs_no_hp() -> None:
|
||||
assert not any("costs 1 hp" in ln for ln in eng._transcript)
|
||||
|
||||
|
||||
def _disabled_one_action_policy(action: Action) -> PolicyFn:
|
||||
def policy(_engine: CombatEngine, state: CombatantState) -> tuple[Action, ...]:
|
||||
if state.combatant.id == "hero":
|
||||
return (action,)
|
||||
return (Action(kind="wait"),)
|
||||
|
||||
return policy
|
||||
|
||||
|
||||
def test_disabled_retrieve_weapon_costs_no_hp() -> None:
|
||||
# PF1e (CRB, Disabled): "Taking move actions doesn't risk further injury."
|
||||
# Drawing/retrieving a weapon is a move action, so it must not cost 1 hp.
|
||||
hero = _combatant("hero")
|
||||
foe = _combatant("foe")
|
||||
eng = _engine(
|
||||
[hero, foe], [(0, 0), (0, 7)], ["players", "monsters"], [],
|
||||
policy=_disabled_one_action_policy(
|
||||
Action(kind="retrieve_weapon", weapon_id="hero-sword")
|
||||
),
|
||||
)
|
||||
s = eng._states[0]
|
||||
s.hp = 0
|
||||
s.weapon_stolen.add("hero-sword") # make the retrieve meaningful
|
||||
eng._current_round = 1
|
||||
eng._take_turn(s)
|
||||
assert s.hp == 0
|
||||
assert "hero-sword" not in s.weapon_stolen # the retrieve ran
|
||||
assert not any("costs 1 hp" in ln for ln in eng._transcript)
|
||||
|
||||
|
||||
def test_disabled_repair_weapon_costs_no_hp() -> None:
|
||||
# Mending a broken weapon is likewise a move action: no hp cost while 0 hp.
|
||||
hero = _combatant("hero")
|
||||
foe = _combatant("foe")
|
||||
eng = _engine(
|
||||
[hero, foe], [(0, 0), (0, 7)], ["players", "monsters"], [],
|
||||
policy=_disabled_one_action_policy(
|
||||
Action(kind="repair_weapon", weapon_id="hero-sword")
|
||||
),
|
||||
)
|
||||
s = eng._states[0]
|
||||
s.hp = 0
|
||||
s.weapon_damage["hero-sword"] = 10 # a broken weapon, repairable
|
||||
s.weapon_broken.add("hero-sword")
|
||||
eng._current_round = 1
|
||||
eng._take_turn(s)
|
||||
assert s.hp == 0
|
||||
assert "hero-sword" not in s.weapon_broken # the repair ran
|
||||
assert not any("costs 1 hp" in ln for ln in eng._transcript)
|
||||
|
||||
|
||||
# ── B12: death threshold is -CON, no -10 floor ───────────────────────────────
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user