Remove QuitAction and ActionWithActor!
Move quit event handling to the interface and flatten the Action class hierarchy. There are no longer any actions that don't take an Actor. This has the happy side effect of resolving some pylint errors too. :)
This commit is contained in:
parent
02ed3d1e4a
commit
327cc90b2e
6 changed files with 24 additions and 43 deletions
|
@ -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})'
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue