NP-Complete, a sci-fi roguelike

I wrote up some back story and stuff, but that's pretty much all the game parts right now.

Designy stuff

Widget library

NP-Complete is currently not much more than a widget library that prints using libtcod; that said, it's been exercised enough to have grown some hair that just begs for a reorganization. So let's see what widgets there are and what they should do.

Widget: the base class. All widgets are a subclass of Widget, so this is where we put things that all widgets must be able to do.

Properties:

  • console: this is the tcod.Console the widget will ultimately be drawn on.
  • parent: widgets form a tree, wherein a widget can have any number of children. The inverse relationship must also be available.
  • children: as stated above. Implementation detail: the children are actually stored in an OrderedSet (as per this recipe).
  • handlers: events get posted to root-level widgets and can be passed down the tree of children; the first widget to return True from a handler is considered to have handled the event, and it will not be bubbled further. This dictionary defines the handlers this widget has for each event type it's interested in.
  • bounds: the widget's area, defined as a Rect. The width and height are determined by the equivalent constructor parameters; the position is up to the widget's interpretation.
  • placement: the widget's on-screen position and size. May be smaller than its full bounds. Position is relative to the parent widget (see point_to_screen and screen_to_point for translations to root console coordinates).
  • colors: a ColorSet containing all applicable colors (at minimum, foreground and background) to draw this widget.
  • effect: The background effect to be used when rendering the widget.

Methods:

  • register_child(widget): Registers widget as a child of this one, adding it to the list of children and setting the new widget's parent. This is normally automatically invoked by the widget constructor when a parent is provided. If the widget already had a parent, that parent is asked to abandon the widget first.
  • abandon_child(widget): Removes widget from the list of children and unsets its parent.
  • to_screen(point): Translates widget-relative coordinates to screen-relative.
  • to_local(point): Translates the other way.
  • render(): Asks the widget to render itself and its children. Usually called on the top-level widget. OrderedSet ensures render order is from first-added to last-added.
  • dispatch(event): If an event handler exists for this widget, it gets called; if it returns True, the event is handled. Otherwise, the event is passed on to the children, in the same order as for rendering.
  • center(horizontal=True, vertical=True): Centers the widget's position inside the parent widget. Optionally centers only horizontally, or only vertically. If the widget has no parent, centers in the console instead.

Dialog(Widget): A widget that renders a frame inside itself. Primarily intended as a root widget for (what else) dialog boxes.


Image(Widget): A widget that displays an image using libtcod's image handling.

Properties:

  • image: The TCODImage that will be blitted into the widget's display area.
  • bounds: Non-zero coordinates may be provided to display a different region of the image. Use the image's size (or width and height attributes) to determine the maximum size of the image.

Label(Widget): A widget that displays text and can be dynamically sized. A label's width can be constrained, in which case it will only grow in height as more text is piled on.

Properties:

  • text: The text to be rendered. May have multiple lines.
  • align: Alignment to use when rendering the text.
  • max_width: The maximum width of the label. Note that, internally, this is stored as the width of the bounds Rect. Further note that the bounds' height is ignored.

Button(Label): A clickable, focusable, shortcut-key-responding label.

Properties:

  • key: The name of the shortcut key assigned to this button. Should be compatible with utils.key_check(). May be None, in which case it is your responsibility to set key_match to a suitable value.
  • key_match: A method matching the prototype key_match(event_data) to be called from the button's KEY handler. Automatically populated when the key property is set to a valid key name, it should return True if the event data (usually a tcod.Key object) should activate the button.
  • action: A method matching the prototype action(widget) to be called from the button's ACTIVATE handler. It will be passed the button widget.

Handlers:

  • events.KEY: A handler which posts an ACTIVATE event when the data of this event matches the button's shortcut key. Automatically generated, and should not need to be changed in normal operation.
  • events.ACTIVATE: Another auto-generated handler, this simply calls the self.action method.

List(Widget): Displays a list of Labels or derivatives, can be restricted in width, height, or both, can be scrolled vertically, focused, and clicked.

Properties:

  • selected_child: The child which is currently selected. It will be the only child to receive an activate event.
  • scroll_pos: A tuple (top, bottom) of the current scrolling position. This is also exposed as bounds.top and bounds.top + placement.height.
  • sub_console: This is an inner tcod console that keeps the entire list rendered; scrolling is implemented as choosing what part of this sub-console to blit onto the widget's actual target console.

Methods:

  • register_child(child): On top of Widget's default register_child, this also changes the widget's console to be the List's sub_console, and its position to reflect the location in sub_console where the child will be rendered. If the List is width-restricted, the child's width will also be restricted.
  • scroll_by(amount): Scrolls the list by amount lines, limited to the actual bounds of the list.
  • scroll_to(top, bottom=None): Scrolls the list to bring whichever of top or bottom is furthest into view (i.e. scroll up to reveal top, down to reveal bottom).

DynamicLabel(Label): A special label that automatically fetches its text from a callback whenever its activate handler returns True.

Properties:

  • on_label: A method() that returns a string to be used as the label text.

Menu(List): A special kind of list that supports using keyboard shortcuts to select specific list items.

Properties:

  • keys: A dictionary of key codes to list items, determining which item will get selected by a given key. It is highly preferable to use add_item(), below, for adding to this dictionary.

Methods:

  • add_item(key, item): As List.add_item(item) above, but also records the key which, when pressed, will select the item.