feat(combat): add retrieve_weapon action to recover stolen weapons

This commit is contained in:
2026-09-06 10:01:07 +02:00
parent b640e29a91
commit 8e957c9fac
2 changed files with 181 additions and 1 deletions
+28 -1
View File
@@ -358,7 +358,7 @@ class Action:
"attack", "move", "wait", "swift", "free", "immediate", "full_round",
"full_attack", "charge", "withdraw", "5foot_step", "cast_spell",
"maneuver", "channel_energy", "hex", "deed", "spell_combat",
"inspire_courage",
"inspire_courage", "retrieve_weapon",
]
target_id: str | None = None
spell_name: str | None = None
@@ -370,6 +370,7 @@ class Action:
channel_mode: Literal["heal", "harm"] | None = None # channel energy polarity for this use
direction: tuple[int, int] | None = None # steering for directional maneuvers
trick_condition: TrickCondition | None = None # dirty trick condition choice
weapon_id: str | None = None # weapon id for retrieve_weapon / repair_weapon
@dataclass(frozen=True)
@@ -1475,6 +1476,8 @@ class CombatEngine:
state, target, action.maneuver,
direction=action.direction, trick_condition=action.trick_condition,
)
elif kind == "retrieve_weapon":
self._retrieve_weapon(state, action.weapon_id)
elif kind in ("channel_energy", "hex", "deed", "spell_combat", "inspire_courage"):
self._execute_class_ability(state, target, action)
elif kind == "charge":
@@ -1621,6 +1624,30 @@ class CombatEngine:
}
handlers[maneuver]()
def _retrieve_weapon(self, state: CombatantState, weapon_id: str | None) -> None:
"""Restore a stolen weapon to its owner (remove it from ``weapon_stolen``).
No-op (with a log line) when ``weapon_id`` is None or the id was never
stolen. Once restored, the weapon is usable again via ``usable_attacks()``.
"""
if weapon_id is None:
self._log(
f"round {self._current_round} {state.combatant.id}: "
f"retrieve: nothing to retrieve"
)
return
if weapon_id not in state.weapon_stolen:
self._log(
f"round {self._current_round} {state.combatant.id}: "
f"retrieve {weapon_id}: nothing to retrieve"
)
return
state.weapon_stolen.remove(weapon_id)
self._log(
f"round {self._current_round} {state.combatant.id}: "
f"retrieve {weapon_id} (restored)"
)
def _maneuver_cmb(self, state: CombatantState) -> int:
return (
state.combatant.cmb