diff --git a/roguebasin/actions.py b/roguebasin/actions.py index b12bafd..ff59daa 100644 --- a/roguebasin/actions.py +++ b/roguebasin/actions.py @@ -3,7 +3,7 @@ import logging from .geometry import Direction -from typing import TYPE_CHECKING +from typing import Optional, TYPE_CHECKING if TYPE_CHECKING: from .engine import Engine @@ -11,11 +11,41 @@ if TYPE_CHECKING: LOG = logging.getLogger('events') +class ActionResult: + '''An object that represents the result of an Action. + + + Attributes + ---------- + success : bool + True if the action succeeded + done : bool + True if the action is complete, and no follow-up action is needed. + alternate : Action, optional + An alternate action to perform if this action failed + ''' + + def __init__(self, success: bool, done: bool = True, alternate: Optional['Action'] = None): + self.success = success + self.done = done + self.alternate = alternate + class Action: - def perform(self, engine: 'Engine', entity: 'Entity') -> None: - ''' - Perform this action. This is an abstract method that all subclasses - should implement. + def perform(self, engine: 'Engine', entity: 'Entity') -> ActionResult: + '''Perform this action. + + Parameters + ---------- + engine : Engine + The game engine + entity : Entity + The entity that this action is being performed on + + Returns + ------- + ActionResult + A result object reflecting how the action was handled, and what follow-up actions, if any, are needed to + complete the action. ''' raise NotImplementedError() @@ -23,12 +53,12 @@ class Action: return f'{self.__class__.__name__}()' class ExitAction(Action): - def perform(self, engine: 'Engine', entity: 'Entity') -> None: + def perform(self, engine: 'Engine', entity: 'Entity') -> ActionResult: raise SystemExit() class RegenerateRoomsAction(Action): - def perform(self, engine: 'Engine', entity: 'Entity') -> None: - ... + def perform(self, engine: 'Engine', entity: 'Entity') -> ActionResult: + return ActionResult(True) class MovePlayerAction(Action): def __init__(self, direction: Direction): diff --git a/roguebasin/engine.py b/roguebasin/engine.py index 3f6bddf..136a08b 100644 --- a/roguebasin/engine.py +++ b/roguebasin/engine.py @@ -1,17 +1,21 @@ #!/usr/bin/env python3 # Eryn Wells +'''Defines the core game engine.''' + import logging import random +from dataclasses import dataclass +from typing import MutableSet + import tcod + from . import monsters from .events import EventHandler from .geometry import Direction, Size from .map import Map from .monsters import Monster from .object import Entity, Hero -from dataclasses import dataclass -from typing import MutableSet LOG = logging.getLogger('engine') EVENT_LOG = logging.getLogger('events') @@ -82,6 +86,7 @@ class Engine: self.update_field_of_view() def print_to_console(self, console): + '''Print the whole game to the given console.''' self.map.print_to_console(console) for ent in self.entities: diff --git a/roguebasin/map.py b/roguebasin/map.py index 8ed4f0a..260b683 100644 --- a/roguebasin/map.py +++ b/roguebasin/map.py @@ -205,6 +205,7 @@ class RoomsAndCorridorsGenerator(MapGenerator): return tiles def __rect_from_bsp_node(self, node: tcod.bsp.BSP) -> Rect: + '''Create a Rect from the given BSP node object''' return Rect(Point(node.x, node.y), Size(node.width, node.height)) class Room: @@ -215,11 +216,21 @@ class Room: raise NotImplementedError() class RectangularRoom(Room): + '''A rectangular room defined by a Rect. + + Attributes + ---------- + bounds : Rect + A rectangle that defines the room. This rectangle includes the tiles used for the walls, so the floor is 1 tile + inset from the bounds. + ''' + def __init__(self, bounds: Rect): self.bounds = bounds @property def center(self) -> Point: + '''The center of the room, truncated according to integer math rules''' return self.bounds.midpoint @property