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 thetcod.Consolethe 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 anOrderedSet(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 returnTruefrom 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 aRect. 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 (seepoint_to_screenandscreen_to_pointfor translations to root console coordinates).colors: aColorSetcontaining 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): Registerswidgetas a child of this one, adding it to the list ofchildrenand setting the new widget'sparent. 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): Removeswidgetfrom the list of children and unsets itsparent.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.OrderedSetensures render order is from first-added to last-added.dispatch(event): If an event handler exists for this widget, it gets called; if it returnsTrue, 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'spositioninside theparentwidget. Optionally centers only horizontally, or only vertically. If the widget has no parent, centers in theconsoleinstead.
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'ssize(orwidthandheightattributes) 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 theboundsRect. 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 withutils.key_check(). May beNone, in which case it is your responsibility to setkey_matchto a suitable value.key_match: A method matching the prototypekey_match(event_data)to be called from the button'sKEYhandler. Automatically populated when thekeyproperty is set to a valid key name, it should returnTrueif the event data (usually atcod.Keyobject) should activate the button.action: A method matching the prototypeaction(widget)to be called from the button'sACTIVATEhandler. It will be passed the button widget.
Handlers:
events.KEY: A handler which posts anACTIVATEevent when thedataof 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 theself.actionmethod.
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 anactivateevent.scroll_pos: A tuple (top, bottom) of the current scrolling position. This is also exposed asbounds.topandbounds.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 defaultregister_child, this also changes the widget's console to be the List'ssub_console, and itspositionto reflect the location insub_consolewhere the child will be rendered. If the List is width-restricted, the child'swidthwill also be restricted.scroll_by(amount): Scrolls the list byamountlines, limited to the actualboundsof 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: Amethod()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 useadd_item(), below, for adding to this dictionary.
Methods:
add_item(key, item): AsList.add_item(item)above, but also records the key which, when pressed, will select the item.