X-Git-Url: https://git.ctpug.org.za/?a=blobdiff_plain;f=naja%2Fwidgets%2Finfo_area.py;h=0022b7351868c37efe0d0701c193ecc3a4c75502;hb=3a29cd975cba07c2b0683e2d5449de37de9842f3;hp=2f9331169284415cb2875de7c43c829d1ca971f7;hpb=0f233e6d450d863f06f5acddee3bd94f53594d08;p=naja.git diff --git a/naja/widgets/info_area.py b/naja/widgets/info_area.py index 2f93311..0022b73 100644 --- a/naja/widgets/info_area.py +++ b/naja/widgets/info_area.py @@ -1,19 +1,168 @@ """ Widget for the game board information area. """ +import pygame +import pygame.locals as pgl -from .base import Widget +from naja.constants import (INFO_SIZE, EIGHT_BIT_SCALE, ACT, KEYS, + EXAMINE, PALETTE) +from naja.events import finish_event +from naja.resources import resources +from naja.resources.mutators import EIGHT_BIT +from naja.sound import sound +from naja.utils import bit_glyphs + +from naja.widgets.base import Widget +from naja.widgets.tile import BIT_MAP +from naja.widgets.text import TextBoxWidget, TextWidget + + +HINTS = { + ACT: ("Choose an action using the Up/Down keys.\n" + "Press Return to execute the action."), + EXAMINE: "Select a card to examine using the arrow keys.", +} + +HINT_LEGAL_MOVE = "\nPress Return to move to this card." + +TITLES = { + ACT: "Choose an Action", + EXAMINE: "Select a Card", +} class InfoAreaWidget(Widget): """ Widget for the game board information area. """ - def __init__(self, pos, image=None): - super(InfoAreaWidget, self).__init__(pos, (96, 96)) + def __init__(self, pos, state): + super(InfoAreaWidget, self).__init__(pos, INFO_SIZE) + self.state = state + self.chosen = None + self.card_position = state.player.position + self.set_position(state.player.position) def prepare(self): - pass + if self.state.gameboard.player_mode == ACT: + self.set_position(self.state.player.position) + self.surface = pygame.surface.Surface(INFO_SIZE) + self.surface.fill((0, 0, 0)) + # Extract actions and such from the card + title = TextWidget((0, 0), TITLES[self.state.gameboard.player_mode], + colour=PALETTE.WHITE) + title.render(self.surface) + y_offset = title.surface.get_rect().height + 8 + + # TODO: Make this better. + bits_text = ''.join('1' if bit in self.card.bitwise_operand else '0' + for bit in reversed(range(8))) + if self.card.bitwise_operand: + bits_text = '%s %s' % ( + bits_text, bit_glyphs(self.card.bitwise_operand)) + card_bits = TextBoxWidget((0, y_offset), bits_text, + box_width=INFO_SIZE[0], + colour=PALETTE.LIGHT_TURQUOISE, + bg_colour=PALETTE.BLACK) + card_bits.render(self.surface) + y_offset += card_bits.surface.get_rect().height + 8 + + for choice, action in enumerate(self.card.actions): + y_offset = self.prepare_action(choice, action, y_offset) + # We cheat horribly for layout reasons + hint_text = HINTS[self.state.gameboard.player_mode] + if self.state.gameboard.player_mode == EXAMINE: + if self.card_position in self.state.player.legal_moves(): + hint_text += HINT_LEGAL_MOVE + + hint = TextBoxWidget((4, 0), hint_text, padding=2, + box_width=(INFO_SIZE[0] - 4) // EIGHT_BIT_SCALE) + hint.prepare() + y_offset = INFO_SIZE[1] - hint.surface.get_rect().height + self.surface.blit(hint.surface, (4, y_offset)) + + def prepare_action(self, choice, action, y_offset): + x_offset = 18 + action_viable = action.check_available(self.state.player) + text_colour = PALETTE.BLACK if action_viable else PALETTE.GREY + + text = TextBoxWidget( + (x_offset, y_offset), action.get_text(), + box_width=(INFO_SIZE[0] - 16) // EIGHT_BIT_SCALE, + fontsize=28, colour=text_colour) + text.render(self.surface) + + border_colour = None + if choice == self.chosen: + border_colour = PALETTE.GREEN if action_viable else PALETTE.ORANGE + if border_colour: + bottom = y_offset + text.surface.get_rect().height + right = text.surface.get_rect().width + x_offset + pygame.draw.lines(self.surface, border_colour, True, + [(x_offset, y_offset), (right, y_offset), + (right, bottom), (x_offset, bottom)], 4) + if action.required_bits: + img_name = BIT_MAP[action.required_bits].replace( + '.png', '_small.png') + img = resources.get_image(img_name, + transforms=(EIGHT_BIT,)) + self.surface.blit(img, (0, y_offset)) + return y_offset + text.surface.get_rect().height + 16 + + def set_position(self, position): + self.card_position = position + self.card = self.state.board_locations[self.card_position] + if self.state.gameboard.player_mode == ACT: + if self.chosen is None: + self.chosen = 0 + else: + self.chosen = None def draw(self, surface): - surface.blit(self.surface, self.rect) + surface.blit(self.surface, self.pos) + + def next_action(self, viable_only=False, step=1): + num_actions = len(self.card.actions) + if num_actions == 0: + return + player = self.state.player + chosen = self.chosen + for i in range(num_actions - 1): + # loop through each action at most once. + chosen = (chosen + step) % num_actions + action = self.card.actions[chosen] + if not viable_only or action.check_available(player): + sound.play_sound('zoop.ogg', volume=0.05) + self.chosen = chosen + + def prev_action(self, viable_only=False): + return self.next_action(viable_only=viable_only, step=-1) + + def try_perform_action(self): + player = self.state.player + action = self.card.actions[self.chosen] + if not action.check_available(player): + sound.play_sound('error.ogg') + else: + sound.play_sound('chirp.ogg', volume=0.5) + action.perform_action(self.state.gameboard, self.card) + self.state.gameboard.replace_card(player.position) + self.state.gameboard.change_mode(EXAMINE) + self.set_position(player.position) + + def handle_event(self, ev): + if self.state.gameboard.player_mode == EXAMINE: + return super(InfoAreaWidget, self).handle_event(ev) + if ev.type == pgl.KEYDOWN: + if ev.key in KEYS.SELECT: + self.try_perform_action() + return finish_event() + if ev.key in KEYS.UP: + self.next_action() + return finish_event() + if ev.key in KEYS.DOWN: + self.prev_action() + return finish_event() + if ev.key in KEYS.SWITCH: + self.next_action(viable_only=True) + return finish_event() + return super(InfoAreaWidget, self).handle_event(ev)