feat(combat): class-ability action kinds, engine RNG only

This commit is contained in:
2026-09-04 22:55:54 +02:00
parent 0058e71550
commit 073da40fca
2 changed files with 122 additions and 10 deletions
+27 -10
View File
@@ -277,12 +277,15 @@ class Action:
kind: Literal[
"attack", "move", "wait", "swift", "free", "immediate", "full_round",
"full_attack", "charge", "withdraw", "5foot_step", "cast_spell",
"maneuver", "channel_energy", "hex",
"maneuver", "channel_energy", "hex", "deed", "spell_combat",
"inspire_courage",
]
target_id: str | None = None
spell_name: str | None = None
maneuver: str | None = None # "trip", "disarm", "bull_rush", "sunder", "grapple", "escape"
hex_name: str | None = None # "evil_eye", "slumber", "cackle"
deed_name: str | None = None # "up_close_and_deadly", "quick_clear"
class_ability: str | None = None # "deed"|"spell_combat"|"inspire_courage"|"hex"|"channel"
@dataclass(frozen=True)
@@ -951,22 +954,36 @@ class CombatEngine:
def _execute(self, state: CombatantState, action: Action) -> None:
target = next((s for s in self._states if s.combatant.id == action.target_id), None)
kind = action.kind
if kind in ("attack", "full_attack"):
self._execute_attack(state, target, kind)
if kind == "cast_spell":
self._execute_cast_spell(state, target, action.spell_name)
elif kind == "maneuver":
self._execute_maneuver(state, target, action.maneuver)
elif kind in ("channel_energy", "hex", "deed", "spell_combat", "inspire_courage"):
self._execute_class_ability(state, target, action)
elif kind == "charge":
self._execute_charge(state, target)
elif kind == "withdraw":
self._withdraw(state, target)
elif kind == "cast_spell":
self._execute_cast_spell(state, target, action.spell_name)
elif kind == "maneuver":
self._execute_maneuver(state, target, action.maneuver)
elif kind == "channel_energy":
elif kind in ("attack", "full_attack"):
self._execute_attack(state, target, kind)
else:
self._execute_movement(state, target, kind)
def _execute_class_ability(
self, state: CombatantState, target: CombatantState | None, action: Action
) -> None:
"""Dispatch a class-ability action by kind, reading its carrier field."""
kind = action.kind
if kind == "channel_energy":
self._execute_channel_energy(state, target)
elif kind == "hex":
self._execute_hex(state, target, action.hex_name)
else:
self._execute_movement(state, target, kind)
elif kind == "deed":
self._execute_deed(state, target, action.deed_name)
elif kind == "spell_combat":
self._execute_spell_combat(state, target, action.spell_name)
elif kind == "inspire_courage":
self._execute_inspire_courage(state, target)
def _execute_movement(
self, state: CombatantState, target: CombatantState | None, kind: str