You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fabula/actions.py

97 lines
2.8 KiB

from dataclasses import dataclass
from typing import Union
from effects import DamageEffect
from enums import CombatSide
from jsonable import JsonableDataclassArgs
from model import Action, Target, Effect, Character, Clock, CombatStatus, log_substitute
@dataclass(**JsonableDataclassArgs)
class RoleplayAction(Action):
text: str
user: Target | None
effects: tuple[Effect, ...]
def do(self, combat: "CombatStatus", source: Union["Action", "Effect", None] = None) -> "CombatStatus":
for effect in self.effects:
combat = effect.do(combat, self)
return combat
def undo(self, combat: "CombatStatus", source: Union["Action", "Effect", None] = None) -> "CombatStatus":
for effect in reversed(self.effects):
combat = effect.undo(combat, self)
return combat
def log_message(self, user: Target | None = None) -> str | None:
return "\n ".join(
[log_substitute(self.text, user=self.user, target=self.user)] +
[log_substitute(t, user=self.user, target=self.user)
for t in [v.log_message(self.user) for v in self.effects]
if t is not None]
)
@dataclass(**JsonableDataclassArgs)
class AbilityAction(Action):
name: str
user: Target | None
costs: tuple[DamageEffect, ...]
effects: tuple[Effect, ...]
@dataclass(**JsonableDataclassArgs)
class ModifyCharacterAction(Action):
index: int
old_character_data: Character | None
new_character_data: Character | None
def __post_init__(self):
if self.old_character_data is None and self.new_character_data is None:
raise ValueError("At least one of old_character_data or new_character_data must be non-None")
@dataclass(**JsonableDataclassArgs)
class ModifyClockAction(Action):
index: int
old_clock_data: Clock | None
new_clock_data: Clock | None
def __post_init__(self):
if self.old_clock_data is None and self.new_clock_data is None:
raise ValueError("At least one of old_clock_data or new_clock_data must be non-None")
@dataclass(**JsonableDataclassArgs)
class EndTurnAction(Action):
turn_ending_index: int
activating_side: CombatSide
@dataclass(**JsonableDataclassArgs)
class StartTurnAction(Action):
turn_starting_index: int
old_active_side: CombatSide
@dataclass(**JsonableDataclassArgs)
class StartRoundAction(Action):
last_round: int
old_active_side: CombatSide
old_turns_remaining: tuple[int, ...]
next_round: int
activating_side: CombatSide
@dataclass(**JsonableDataclassArgs)
class StartBattleAction(Action):
starting_side: CombatSide
starting_round: int
@dataclass(**JsonableDataclassArgs)
class EndBattleAction(Action):
old_round_number: int
old_active_side: CombatSide
old_starting_side: CombatSide
old_turns_remaining: tuple[int, ...]