diff --git a/erynrl/actions/action.py b/erynrl/actions/action.py index 584d102..c2a9660 100644 --- a/erynrl/actions/action.py +++ b/erynrl/actions/action.py @@ -12,6 +12,10 @@ if TYPE_CHECKING: class Action: '''An action with no specific actor''' + def __init__(self, actor: Actor): + super().__init__() + self.actor = actor + # pylint: disable=unused-argument def perform(self, engine: 'Engine') -> ActionResult: '''Perform this action. @@ -42,17 +46,3 @@ class Action: def __repr__(self): return f'{self.__class__.__name__}()' - - -class ActionWithActor(Action): - '''An action that assigned to an actor''' - - def __init__(self, actor: Actor): - super().__init__() - self.actor = actor - - def __str__(self) -> str: - return f'{self.__class__.__name__} for {self.actor!s}' - - def __repr__(self): - return f'{self.__class__.__name__}({self.actor!r})' diff --git a/erynrl/actions/game.py b/erynrl/actions/game.py index ad960fa..71d7485 100644 --- a/erynrl/actions/game.py +++ b/erynrl/actions/game.py @@ -11,7 +11,6 @@ Action : Base class of all actions BumpAction WalkAction MeleeAction - ExitAction WaitAction ''' @@ -22,21 +21,14 @@ from .. import items from .. import log from ..geometry import Vector from ..object import Actor, Item -from .action import Action, ActionWithActor +from .action import Action from .result import ActionResult if TYPE_CHECKING: from ..engine import Engine -class ExitAction(Action): - '''Exit the game.''' - - def perform(self, engine: 'Engine') -> ActionResult: - raise SystemExit() - - -class MoveAction(ActionWithActor): +class MoveAction(Action): '''An abstract Action that requires a direction to complete.''' def __init__(self, actor: Actor, direction: Vector): @@ -157,7 +149,7 @@ class MeleeAction(MoveAction): return self.success() -class WaitAction(ActionWithActor): +class WaitAction(Action): '''Wait a turn''' def perform(self, engine: 'Engine') -> ActionResult: @@ -174,7 +166,7 @@ class WaitAction(ActionWithActor): return self.success() -class DieAction(ActionWithActor): +class DieAction(Action): '''Kill an Actor''' def perform(self, engine: 'Engine') -> ActionResult: @@ -193,7 +185,7 @@ class DieAction(ActionWithActor): return self.success() -class DropItemAction(ActionWithActor): +class DropItemAction(Action): '''Drop an item''' def __init__(self, actor: 'Actor', item: 'Item'): @@ -205,7 +197,7 @@ class DropItemAction(ActionWithActor): return self.success() -class HealAction(ActionWithActor): +class HealAction(Action): '''Heal a target actor some number of hit points''' def __init__(self, actor: 'Actor', hit_points_to_recover: int): diff --git a/erynrl/ai.py b/erynrl/ai.py index cca9331..c37b186 100644 --- a/erynrl/ai.py +++ b/erynrl/ai.py @@ -7,7 +7,7 @@ import numpy as np import tcod from . import log -from .actions.action import ActionWithActor +from .actions.action import Action from .actions.game import BumpAction, WaitAction from .components import Component from .geometry import Direction, Point @@ -26,7 +26,7 @@ class AI(Component): super().__init__() self.entity = entity - def act(self, engine: 'Engine') -> Optional[ActionWithActor]: + def act(self, engine: 'Engine') -> Optional[Action]: '''Produce an action to perform''' raise NotImplementedError() @@ -38,7 +38,7 @@ class HostileEnemy(AI): beeline for her. ''' - def act(self, engine: 'Engine') -> Optional[ActionWithActor]: + def act(self, engine: 'Engine') -> Optional[Action]: visible_tiles = tcod.map.compute_fov( engine.map.tiles['transparent'], pov=tuple(self.entity.position), diff --git a/erynrl/engine.py b/erynrl/engine.py index d394852..8b13350 100644 --- a/erynrl/engine.py +++ b/erynrl/engine.py @@ -9,7 +9,7 @@ import tcod from . import log from . import monsters -from .actions.action import Action, ActionWithActor +from .actions.action import Action from .actions.result import ActionResult from .ai import HostileEnemy from .configuration import Configuration @@ -110,7 +110,7 @@ class Engine: def process_input_action(self, action: Action): '''Process an Action from player input''' - if not isinstance(action, ActionWithActor): + if not isinstance(action, Action): action.perform(self) return @@ -159,7 +159,7 @@ class Engine: if action: self._perform_action_until_done(action) - def _perform_action_until_done(self, action: ActionWithActor) -> ActionResult: + def _perform_action_until_done(self, action: Action) -> ActionResult: '''Perform the given action and any alternate follow-up actions until the action chain is done.''' result = action.perform(self) @@ -184,7 +184,7 @@ class Engine: if log.ACTIONS_TREE.isEnabledFor(log.INFO) and self.map.visible[tuple(action.actor.position)]: if result.alternate: - alternate_string = f'{result.alternate.__class__.__name__}[{result.alternate.actor.symbol}]' + alternate_string = f'{result.alternate.__class__.__name__}[{result.alternate.actor}]' else: alternate_string = str(result.alternate) log.ACTIONS_TREE.info( diff --git a/erynrl/events.py b/erynrl/events.py index cc6928b..3a9bcf0 100644 --- a/erynrl/events.py +++ b/erynrl/events.py @@ -6,7 +6,7 @@ import tcod import tcod.event as tev from .actions.action import Action -from .actions.game import BumpAction, ExitAction, WaitAction +from .actions.game import BumpAction, WaitAction from .geometry import Direction if TYPE_CHECKING: @@ -51,9 +51,6 @@ class EngineEventHandler(tev.EventDispatch[Action]): return action - def ev_quit(self, event: tcod.event.Quit) -> Optional[Action]: - return ExitAction() - class GameOverEventHandler(tev.EventDispatch[Action]): '''When the game is over (the hero dies, the player quits, etc), this event handler takes over.''' @@ -61,6 +58,3 @@ class GameOverEventHandler(tev.EventDispatch[Action]): def __init__(self, engine: 'Engine'): super().__init__() self.engine = engine - - def ev_quit(self, event: tev.Quit) -> Optional[Action]: - return ExitAction() diff --git a/erynrl/interface/events.py b/erynrl/interface/events.py index bd8e5fc..09d0447 100644 --- a/erynrl/interface/events.py +++ b/erynrl/interface/events.py @@ -2,7 +2,7 @@ '''Defines event handling mechanisms.''' -from typing import TYPE_CHECKING +from typing import NoReturn, TYPE_CHECKING from tcod import event as tev @@ -42,6 +42,11 @@ class InterfaceEventHandler(tev.EventDispatch[bool]): def ev_mousebuttonup(self, event: tev.MouseButtonUp) -> bool: return self._handle_event(event) + def ev_quit(self, event: tev.Quit) -> NoReturn: + # TODO: Maybe show a "do you want to quit?" alert? + # TODO: Probably inform the engine that we're shutting down. + raise SystemExit() + def _handle_event(self, event: tev.Event) -> bool: for handler in self._handlers: if handler and handler.dispatch(event):