コード例 #1
0
def create_shop_menu(items, gold):
    entries = []
    row = []
    for i, it in enumerate(items):
        entry = {
            'type': 'item_button',
            'item': it,
            'price': it.price,
            'index': i,
            'id': BuyMenu.INTERAC_BUY
        }
        row.append(entry)
        if len(row) == 2:
            entries.append(row)
            row = []

    if row:
        entries.append(row)

    # Gold at end
    entry = [{
        'type': 'text',
        'text': 'Your gold : ' + str(gold),
        'font': fonts['ITEM_DESC_FONT']
    }]
    entries.append(entry)

    return InfoBox("Shop - Buying",
                   BuyMenu,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   ITEM_MENU_WIDTH,
                   close_button=UNFINAL_ACTION,
                   title_color=ORANGE)
コード例 #2
0
    def create_options_menu():
        entries = [[
            StartScreen.load_parameter_entry("move_speed", "Move speed : ",
                                             [{
                                                 'label': 'Slow',
                                                 'value': ANIMATION_SPEED // 2
                                             }, {
                                                 'label': 'Normal',
                                                 'value': ANIMATION_SPEED
                                             }, {
                                                 'label': 'Fast',
                                                 'value': ANIMATION_SPEED * 2
                                             }], OptionsMenu.CHANGE_MOVE_SPEED)
        ],
                   [
                       StartScreen.load_parameter_entry(
                           "screen_size", "Screen mode : ",
                           [{
                               'label': 'Window',
                               'value': SCREEN_SIZE // 2
                           }, {
                               'label': 'Full',
                               'value': SCREEN_SIZE
                           }], OptionsMenu.CHANGE_SCREEN_SIZE)
                   ]]
        for row in entries:
            for entry in row:
                entry['type'] = 'parameter_button'

        return InfoBox("Options",
                       OptionsMenu,
                       "imgs/interface/PopUpMenu.png",
                       entries,
                       START_MENU_WIDTH,
                       close_button=1)
コード例 #3
0
def create_main_menu(initialization_phase, pos):
    # Transform pos tuple into rect
    tile = pg.Rect(pos[0], pos[1], 1, 1)
    entries = [[{
        'name': 'Save',
        'id': MainMenu.SAVE
    }], [{
        'name': 'Suspend',
        'id': MainMenu.SUSPEND
    }]]

    if initialization_phase:
        entries.append([{'name': 'Start', 'id': MainMenu.START}])
    else:
        entries.append([{'name': 'End Turn', 'id': MainMenu.END_TURN}])

    for row in entries:
        for entry in row:
            entry['type'] = 'button'

    return InfoBox("Main Menu",
                   MainMenu,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   ACTION_MENU_WIDTH,
                   el_rect_linked=tile)
コード例 #4
0
def create_equipment_menu(equipments):
    entries = []
    body_parts = [['head'], ['body'], ['right_hand', 'left_hand'], ['feet']]
    for part in body_parts:
        row = []
        for member in part:
            entry = {
                'type': 'item_button',
                'item': None,
                'index': -1,
                'id': EquipmentMenu.INTERAC_EQUIPMENT
            }
            for i, eq in enumerate(equipments):
                if member == eq.body_part:
                    entry = {
                        'type': 'item_button',
                        'item': eq,
                        'index': i,
                        'id': EquipmentMenu.INTERAC_EQUIPMENT
                    }
            row.append(entry)
        entries.append(row)
    return InfoBox("Equipment",
                   EquipmentMenu,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   EQUIPMENT_MENU_WIDTH,
                   close_button=UNFINAL_ACTION)
コード例 #5
0
def create_trade_item_menu(item_button_pos, item, players):
    entries = [[{
        'name': 'Info',
        'id': ItemMenu.INFO_ITEM
    }], [{
        'name': 'Trade',
        'id': ItemMenu.TRADE_ITEM,
        'args': players
    }]]
    formatted_item_name = item.get_formatted_name()

    for row in entries:
        for entry in row:
            entry['type'] = 'button'

    item_rect = pg.Rect(item_button_pos[0] - 20, item_button_pos[1],
                        ITEM_BUTTON_SIZE[0], ITEM_BUTTON_SIZE[1])

    return InfoBox(formatted_item_name,
                   ItemMenu,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   ACTION_MENU_WIDTH,
                   el_rect_linked=item_rect,
                   close_button=UNFINAL_ACTION)
コード例 #6
0
def create_item_menu(item_button_pos, item, is_equipped=False):
    entries = [[{
        'name': 'Info',
        'id': ItemMenu.INFO_ITEM
    }], [{
        'name': 'Throw',
        'id': ItemMenu.THROW_ITEM
    }]]
    formatted_item_name = item.get_formatted_name()

    if isinstance(item, Consumable):
        entries.insert(0, [{'name': 'Use', 'id': ItemMenu.USE_ITEM}])
    elif isinstance(item, Equipment):
        if is_equipped:
            entries.insert(0, [{
                'name': 'Unequip',
                'id': ItemMenu.UNEQUIP_ITEM
            }])
        else:
            entries.insert(0, [{'name': 'Equip', 'id': ItemMenu.EQUIP_ITEM}])

    for row in entries:
        for entry in row:
            entry['type'] = 'button'

    item_rect = pg.Rect(item_button_pos[0] - 20, item_button_pos[1],
                        ITEM_BUTTON_SIZE[0], ITEM_BUTTON_SIZE[1])

    return InfoBox(formatted_item_name,
                   ItemMenu,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   ACTION_MENU_WIDTH,
                   el_rect_linked=item_rect,
                   close_button=UNFINAL_ACTION)
コード例 #7
0
def create_reward_menu(mission):
    entries = [[{
        'type': 'text',
        'text': 'Congratulations ! Objective has been completed !',
        'font': fonts['ITEM_DESC_FONT']
    }]]
    if mission.gold:
        entries.append([{
            'type':
            'text',
            'text':
            'Earned gold : ' + str(mission.gold) + ' (all characters)'
        }])
    for item in mission.items:
        entries.append([{
            'type': 'text',
            'text': 'Earned item : ' + str(item)
        }])

    return InfoBox(mission.desc,
                   "",
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   REWARD_MENU_WIDTH,
                   close_button=UNFINAL_ACTION)
コード例 #8
0
def create_item_desc_menu(item):
    item_title = str(item)

    entries = [[{
        'type': 'text',
        'text': item.desc,
        'font': fonts['ITEM_DESC_FONT'],
        'margin': (20, 0, 20, 0)
    }]]

    if isinstance(item, Equipment):
        if item.restrictions != {}:
            entries.append(
                create_item_desc_stat('RESERVED TO',
                                      item.get_formatted_restrictions()))
        if item.atk > 0:
            entries.append(create_item_desc_stat('POWER', str(item.atk)))
        if item.defense > 0:
            entries.append(create_item_desc_stat('DEFENSE', str(item.defense)))
        if item.res > 0:
            entries.append(create_item_desc_stat('MAGICAL RES', str(item.res)))
        if isinstance(item, Weapon):
            # Compute reach
            reach_txt = ""
            for nb in item.reach:
                reach_txt += str(nb) + ', '
            reach_txt = reach_txt[:len(reach_txt) - 2]
            entries.append(
                create_item_desc_stat('TYPE OF DAMAGE',
                                      str(item.attack_kind.value)))
            entries.append(create_item_desc_stat('REACH', reach_txt))
            for possible_effect in item.effects:
                entries.append(
                    create_item_desc_stat(
                        'EFFECT',
                        possible_effect['effect'].get_formatted_name() + ' (' +
                        str(possible_effect['probability']) + '%)'))
        if isinstance(item, Shield):
            entries.append(
                create_item_desc_stat('PARRY RATE',
                                      str(item.parry) + '%'))
        if isinstance(item, Weapon) or isinstance(item, Shield):
            entries.append(
                create_item_desc_stat(
                    'DURABILITY',
                    str(item.durability) + ' / ' + str(item.durability_max)))
        entries.append(create_item_desc_stat('WEIGHT', str(item.weight)))
    elif isinstance(item, Consumable):
        for eff in item.effects:
            entries.append(
                create_item_desc_stat('EFFECT', eff.get_formatted_desc()))

    return InfoBox(item_title,
                   "",
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   ITEM_INFO_MENU_WIDTH,
                   close_button=UNFINAL_ACTION)
コード例 #9
0
    def create_menu():
        entries = [[{'name': 'New game', 'id': StartMenu.NEW_GAME}], [{'name': 'Load game', 'id': StartMenu.LOAD_GAME}],
                   [{'name': 'Options', 'id': StartMenu.OPTIONS}], [{'name': 'Exit game', 'id': StartMenu.EXIT}]]

        for row in entries:
            for entry in row:
                entry['type'] = 'button'

        return InfoBox("In the name of the Five Cats", StartMenu,
                       "imgs/interface/PopUpMenu.png", entries, START_MENU_WIDTH)
コード例 #10
0
    def load_game(self):
        try:
            save = open("saves/main_save.xml", "r")

            # Test if there is a current saved game
            if save:
                tree_root = etree.parse("saves/main_save.xml").getroot()
                index = tree_root.find("level/index").text.strip()
                level_name = 'maps/level_' + index + '/'
                game_status = tree_root.find("level/phase").text.strip()
                turn_nb = 0
                if game_status != 'I':
                    turn_nb = int(tree_root.find("level/turn").text.strip())

                # Load level with current game status, foes states, and team
                self.level_id = int(index)
                level = Level(level_name, self.level_id, game_status, turn_nb,
                              tree_root.find("level/entities"))
                self.play(level)
                save.close()
                return
        except FileNotFoundError:
            # No saved game
            self.background_menus.append([self.active_menu, True])

            name = "Load Game"
            entries = [[{
                'type': 'text',
                'text': "No saved game.",
                'font': fonts['MENU_SUB_TITLE_FONT']
            }]]
            width = self.screen.get_width() // 2
            self.active_menu = InfoBox(name,
                                       "",
                                       "imgs/interface/PopUpMenu.png",
                                       entries,
                                       width,
                                       close_button=1)
コード例 #11
0
def create_skill_info_menu(skill):
    entries = [[{
        'type': 'text',
        'text': skill.desc,
        'font': fonts['ITEM_DESC_FONT'],
        'margin': (20, 0, 20, 0)
    }], [{
        'type': 'text',
        'text': '',
        'margin': (0, 0, 10, 0)
    }]]

    return InfoBox(skill.formatted_name,
                   "",
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   STATUS_INFO_MENU_WIDTH,
                   close_button=UNFINAL_ACTION)
コード例 #12
0
def create_item_sell_menu(item_button_pos, item):
    entries = [[{
        'name': 'Sell',
        'id': ItemMenu.SELL_ITEM,
        'type': 'button'
    }], [{
        'name': 'Info',
        'id': ItemMenu.INFO_ITEM,
        'type': 'button'
    }]]
    formatted_item_name = str(item)
    item_rect = pg.Rect(item_button_pos[0] - 20, item_button_pos[1],
                        ITEM_BUTTON_SIZE[0], ITEM_BUTTON_SIZE[1])

    return InfoBox(formatted_item_name,
                   ItemMenu,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   ACTION_MENU_WIDTH,
                   el_rect_linked=item_rect,
                   close_button=UNFINAL_ACTION)
コード例 #13
0
def create_inventory_menu(items, gold, price=False):
    entries = []
    row = []
    method_id = SellMenu.INTERAC_SELL if price else InventoryMenu.INTERAC_ITEM
    for i, it in enumerate(items):
        entry = {
            'type': 'item_button',
            'item': it,
            'index': i,
            'id': method_id
        }
        # Test if price should appeared
        if price and it:
            entry['price'] = it.price // 2 if it.price != 0 else 0
        row.append(entry)
        if len(row) == 2:
            entries.append(row)
            row = []
    if row:
        entries.append(row)

    # Gold at end
    entry = [{
        'type': 'text',
        'text': 'Your gold : ' + str(gold),
        'font': fonts['ITEM_DESC_FONT']
    }]
    entries.append(entry)

    title = "Shop - Selling" if price else "Inventory"
    menu_id = SellMenu if price else InventoryMenu
    title_color = ORANGE if price else WHITE
    return InfoBox(title,
                   menu_id,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   ITEM_MENU_WIDTH,
                   close_button=UNFINAL_ACTION,
                   title_color=title_color)
コード例 #14
0
def create_item_shop_menu(item_button_pos, item, price):
    entries = [[{
        'name': 'Buy',
        'id': ItemMenu.BUY_ITEM,
        'type': 'button',
        'args': [price]
    }], [{
        'name': 'Info',
        'id': ItemMenu.INFO_ITEM,
        'type': 'button'
    }]]
    formatted_item_name = item.get_formatted_name()
    item_rect = pg.Rect(item_button_pos[0] - 20, item_button_pos[1],
                        ITEM_BUTTON_SIZE[0], ITEM_BUTTON_SIZE[1])

    return InfoBox(formatted_item_name,
                   ItemMenu,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   ACTION_MENU_WIDTH,
                   el_rect_linked=item_rect,
                   close_button=UNFINAL_ACTION)
コード例 #15
0
def create_alteration_info_menu(alteration):

    turns_left = alteration.get_turns_left()
    entries = [[{
        'type': 'text',
        'text': alteration.desc,
        'font': fonts['ITEM_DESC_FONT'],
        'margin': (20, 0, 20, 0)
    }],
               [{
                   'type': 'text',
                   'text': 'Turns left : ' + str(turns_left),
                   'font': fonts['ITEM_DESC_FONT'],
                   'margin': (0, 0, 10, 0),
                   'color': ORANGE
               }]]

    return InfoBox(str(alteration),
                   "",
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   STATUS_INFO_MENU_WIDTH,
                   close_button=UNFINAL_ACTION)
コード例 #16
0
def create_foe_menu(foe):
    formatted_name = foe.get_formatted_name()

    entries = [[],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'Level :',
                   'margin': (10, 0, 0, 0)
               }, {
                   'type': 'text',
                   'text': str(foe.lvl),
                   'margin': (10, 0, 0, 0)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'STATS',
                   'font': fonts['MENU_SUB_TITLE_FONT'],
                   'margin': (10, 0, 10, 0)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'HP :'
               }, {
                   'type': 'text',
                   'text': str(foe.hp) + ' / ' + str(foe.hp_max),
                   'color': determine_hp_color(foe.hp, foe.hp_max)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'MOVE :'
               }, {
                   'type': 'text',
                   'text': str(foe.max_moves)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'ATTACK :'
               }, {
                   'type': 'text',
                   'text': str(foe.strength)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'DEFENSE :'
               }, {
                   'type': 'text',
                   'text': str(foe.defense)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'MAGICAL RES :'
               }, {
                   'type': 'text',
                   'text': str(foe.res)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'ALTERATIONS',
                   'font': fonts['MENU_SUB_TITLE_FONT'],
                   'margin': (10, 0, 10, 0)
               }]]

    alts = foe.alterations

    if not alts:
        entries.append([{'type': 'text', 'color': WHITE, 'text': 'None'}])

    for alt in alts:
        entries.append([{
            'type': 'text_button',
            'name': alt.get_formatted_name(),
            'id': StatusMenu.INFO_ALTERATION,
            'color': WHITE,
            'color_hover': TURQUOISE,
            'obj': alt
        }])

    return InfoBox(formatted_name,
                   "",
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   STATUS_MENU_WIDTH,
                   close_button=UNFINAL_ACTION)
コード例 #17
0
def create_status_menu(player):
    entries = [
        [{}, {
            'type': 'text',
            'color': GREEN,
            'text': 'Name :',
            'font': fonts['ITALIC_ITEM_FONT']
        }, {
            'type': 'text',
            'text': str(player)
        }, {}],
        [{}, {}, {
            'type': 'text',
            'color': DARK_GREEN,
            'text': 'SKILLS',
            'font': fonts['MENU_SUB_TITLE_FONT'],
            'margin': (10, 0, 10, 0)
        }],
        [{
            'type': 'text',
            'color': GREEN,
            'text': 'Class :',
            'font': fonts['ITALIC_ITEM_FONT']
        }, {
            'type': 'text',
            'text': player.get_formatted_classes()
        }],
        [{
            'type': 'text',
            'color': GREEN,
            'text': 'Race :',
            'font': fonts['ITALIC_ITEM_FONT']
        }, {
            'type': 'text',
            'text': player.get_formatted_race()
        }],
        [{
            'type': 'text',
            'color': GREEN,
            'text': 'Level :',
            'font': fonts['ITALIC_ITEM_FONT']
        },
         {
             'type': 'text',
             'text': str(player.lvl)
         }],
        [{
            'type': 'text',
            'color': GOLD,
            'text': '   XP :',
            'font': fonts['ITALIC_ITEM_FONT']
        },
         {
             'type': 'text',
             'text': str(player.xp) + ' / ' + str(player.xp_next_lvl)
         }],
        [{
            'type': 'text',
            'color': DARK_GREEN,
            'text': 'STATS',
            'font': fonts['MENU_SUB_TITLE_FONT'],
            'margin': (10, 0, 10, 0)
        }],
        [{
            'type': 'text',
            'color': WHITE,
            'text': 'HP :'
        },
         {
             'type': 'text',
             'text': str(player.hp) + ' / ' + str(player.hp_max),
             'color': determine_hp_color(player.hp, player.hp_max)
         }],
        [{
            'type': 'text',
            'color': WHITE,
            'text': 'MOVE :'
        }, {
            'type':
            'text',
            'text':
            str(player.max_moves) + player.get_formatted_stat_change('speed')
        }],
        [{
            'type': 'text',
            'color': WHITE,
            'text': 'CONSTITUTION :'
        },
         {
             'type': 'text',
             'text': str(player.constitution)
         }],
        [{
            'type': 'text',
            'color': WHITE,
            'text': 'ATTACK :'
        }, {
            'type':
            'text',
            'text':
            str(player.strength) + player.get_formatted_stat_change('strength')
        }],
        [{
            'type': 'text',
            'color': WHITE,
            'text': 'DEFENSE :'
        }, {
            'type':
            'text',
            'text':
            str(player.defense) + player.get_formatted_stat_change('defense')
        }],
        [{
            'type': 'text',
            'color': WHITE,
            'text': 'MAGICAL RES :'
        }, {
            'type':
            'text',
            'text':
            str(player.res) + player.get_formatted_stat_change('resistance')
        }],
        [{
            'type': 'text',
            'color': DARK_GREEN,
            'text': 'ALTERATIONS',
            'font': fonts['MENU_SUB_TITLE_FONT'],
            'margin': (10, 0, 10, 0)
        }]
    ]

    alts = player.alterations
    if not alts:
        entries.append([{'type': 'text', 'color': WHITE, 'text': 'None'}])
    for alt in alts:
        entries.append([{
            'type': 'text_button',
            'name': alt.get_formatted_name(),
            'id': StatusMenu.INFO_ALTERATION,
            'color': WHITE,
            'color_hover': TURQUOISE,
            'obj': alt
        }])

    # Display skills
    i = 2
    for skill in player.skills:
        skill_displayed = {
            'type': 'text_button',
            'name': skill.formatted_name,
            'id': StatusMenu.INFO_SKILL,
            'color': WHITE,
            'color_hover': TURQUOISE,
            'obj': skill
        }
        entries[i].append(skill_displayed)
        i += 1
    for j in range(i, len(entries)):
        entries[j].append({})

    return InfoBox("Status",
                   StatusMenu,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   STATUS_MENU_WIDTH,
                   close_button=UNFINAL_ACTION)
コード例 #18
0
class StartScreen:
    def __init__(self, screen):
        self.screen = screen
        self.menu_screen = self.screen.copy()

        # Start screen loop
        bg_image = pg.image.load('imgs/interface/main_menu_background.jpg').convert_alpha()
        self.background = pg.transform.scale(bg_image, screen.get_size())

        # Creating menu
        self.active_menu = StartScreen.create_menu()
        self.background_menus = []

        # Memorize if a game is currently being performed
        self.level = None

        self.levels = [0, 1]
        self.level_id = None

        # Load current saved parameters
        self.load_options()

        self.exit = False

    def load_options(self):
        # Load current move speed
        Movable.move_speed = int(self.read_options_file("move_speed"))

    @staticmethod
    def create_menu():
        entries = [[{'name': 'New game', 'id': StartMenu.NEW_GAME}], [{'name': 'Load game', 'id': StartMenu.LOAD_GAME}],
                   [{'name': 'Options', 'id': StartMenu.OPTIONS}], [{'name': 'Exit game', 'id': StartMenu.EXIT}]]

        for row in entries:
            for entry in row:
                entry['type'] = 'button'

        return InfoBox("In the name of the Five Cats", StartMenu,
                       "imgs/interface/PopUpMenu.png", entries, START_MENU_WIDTH)

    @staticmethod
    def load_parameter_entry(param, formatted_name, values, identifier):
        val = int(StartScreen.read_options_file(param))

        entry = {'name': formatted_name, 'values': values, 'id': identifier, 'current_value_ind': 0}

        for i in range(len(entry['values'])):
            if entry['values'][i]['value'] == val:
                entry['current_value_ind'] = i

        return entry

    @staticmethod
    def create_options_menu():
        entries = [[StartScreen.load_parameter_entry("move_speed", "Move speed : ",
                                                     [{'label': 'Slow', 'value': ANIMATION_SPEED // 2},
                                                      {'label': 'Normal', 'value': ANIMATION_SPEED},
                                                      {'label': 'Fast', 'value': ANIMATION_SPEED * 2}],
                                                     OptionsMenu.CHANGE_MOVE_SPEED)]]
        for row in entries:
            for entry in row:
                entry['type'] = 'parameter_button'

        return InfoBox("Options", OptionsMenu,
                       "imgs/interface/PopUpMenu.png", entries, START_MENU_WIDTH, close_button=1)

    @staticmethod
    def modify_options_file(el_to_edit, new_value):
        tree = etree.parse("saves/options.xml")
        el = tree.find(".//" + el_to_edit)
        el.text = str(new_value)
        tree.write("saves/options.xml")

    @staticmethod
    def read_options_file(el_to_read):
        tree = etree.parse("saves/options.xml").getroot()

        el = tree.find(".//" + el_to_read)
        return el.text.strip()

    def display(self):
        if self.level:
            self.screen.fill(BLACK)
            self.level.display(self.screen)
        else:
            self.screen.blit(self.background, (0, 0))
            for menu in self.background_menus:
                if menu[1]:
                    menu[0].display(self.screen)
            if self.active_menu:
                self.active_menu.display(self.screen)

    def play(self, level):
        # Modify screen
        self.screen = pg.display.set_mode((WIN_WIDTH, WIN_HEIGHT))
        self.level = level

    def update_state(self):
        if self.level:
            status = self.level.update_state()
            if status is Status.ENDED_VICTORY:
                self.level_id += 1
                if self.level_id in self.levels:
                    team = self.level.passed_players
                    for player in team:
                        # Players are fully restored between level
                        player.healed(player.hp_max)
                        # Reset player's state
                        player.new_turn()
                    self.play(StartScreen.load_level(self.level_id, team))
                else:
                    # TODO: Game win dialog?
                    self.screen = pg.display.set_mode((self.menu_screen.get_width(), self.menu_screen.get_height()))
                    self.level = None
            elif status is Status.ENDED_DEFEAT:
                self.screen = pg.display.set_mode((self.menu_screen.get_width(), self.menu_screen.get_height()))
                self.level = None

    @staticmethod
    def load_level(level, team):
        return Level('maps/level_' + str(level) + '/', team, level)

    def new_game(self):
        # Init player's team (one character at beginning)
        team = [LoadFromXMLManager.load_player("john"), LoadFromXMLManager.load_player("archer")]

        # Init the first level
        self.level_id = 0
        self.play(StartScreen.load_level(self.level_id, team))

    def load_game(self):
        try:
            save = open("saves/main_save.xml", "r")

            # Test if there is a current saved game
            if save:
                tree_root = etree.parse("saves/main_save.xml").getroot()
                index = tree_root.find("level/index").text.strip()
                level_name = 'maps/level_' + index + '/'
                game_status = tree_root.find("level/phase").text.strip()
                turn_nb = 0
                if game_status != 'I':
                    turn_nb = int(tree_root.find("level/turn").text.strip())
                team = []
                for player in tree_root.findall("team/player"):
                    name = player.find("name").text.strip()
                    level = int(player.find("level").text.strip())
                    p_class = player.find("class").text.strip()
                    race = player.find("race").text.strip()
                    gold = int(player.find("gold").text.strip())
                    exp = int(player.find("exp").text.strip())
                    hp = int(player.find("hp").text.strip())
                    strength = int(player.find("strength").text.strip())
                    defense = int(player.find("def").text.strip())
                    res = int(player.find("res").text.strip())
                    move = int(player.find("move").text.strip())
                    current_hp = int(player.find("currentHp").text.strip())
                    pos = (int(player.find("position/x").text.strip()) * TILE_SIZE,
                           int(player.find("position/y").text.strip()) * TILE_SIZE)
                    state = player.find("turnFinished").text.strip()
                    inv = []
                    for it in player.findall("inventory/item"):
                        it_name = it.find("name").text.strip()
                        item = LoadFromXMLManager.parse_item_file(it_name)
                        inv.append(item)

                    equipments = []
                    for eq in player.findall("equipments/equipment"):
                        eq_name = eq.find("name").text.strip()
                        eq = LoadFromXMLManager.parse_item_file(eq_name)
                        equipments.append(eq)

                    # -- Reading of the XML file for default character's values (i.e. sprites)
                    tree = etree.parse("data/characters.xml").getroot()
                    player_t = tree.xpath(name)[0]

                    sprite = 'imgs/dungeon_crawl/player/' + player_t.find('sprite').text.strip()
                    compl_sprite = player_t.find('complementSprite')
                    if compl_sprite is not None:
                        compl_sprite = 'imgs/dungeon_crawl/player/' + compl_sprite.text.strip()

                    p = Player(name, sprite, hp, defense, res, move, strength, [p_class], equipments, race, gold, level,
                               compl_sprite=compl_sprite)
                    p.earn_xp(exp)
                    p.items = inv
                    p.set_current_hp(current_hp)
                    p.pos = pos
                    if state == "True":
                        p.turn_finished()

                    team.append(p)

                # Load level with current game status, foes states, and team
                self.level_id = int(index)
                level = Level(level_name, team, self.level_id, game_status, turn_nb, tree_root.find("level/entities"))
                self.play(level)
                save.close()
                return
        except FileNotFoundError:
            # No saved game
            self.background_menus.append([self.active_menu, True])

            name = "Load Game"
            entries = [[{'type': 'text', 'text': "No saved game.", 'font': fonts['MENU_SUB_TITLE_FONT']}]]
            width = self.screen.get_width() // 2
            self.active_menu = InfoBox(name, "", "imgs/interface/PopUpMenu.png",
                                       entries, width, close_button=1)

    def options_menu(self):
        self.background_menus.append([self.active_menu, False])
        self.active_menu = StartScreen.create_options_menu()

    def exit_game(self):
        self.exit = True

    def main_menu_action(self, method_id, args):
        # Execute action
        if method_id is StartMenu.NEW_GAME:
            self.new_game()
        elif method_id is StartMenu.LOAD_GAME:
            self.load_game()
        elif method_id is StartMenu.OPTIONS:
            self.options_menu()
        elif method_id is StartMenu.EXIT:
            self.exit_game()
        else:
            print("Unknown action... : ", str(method_id))

    @staticmethod
    def options_menu_action(method_id, args):
        # Execute action
        if method_id is OptionsMenu.CHANGE_MOVE_SPEED:
            Movable.move_speed = args[2][0]
            StartScreen.modify_options_file("move_speed", args[2][0])
        else:
            print("Unknown action... : ", method_id)

    def execute_action(self, menu_type, action):
        if not action:
            return
        method_id = action[0]
        args = action[1]

        # Test if the action is a generic one (according to the method_id)
        # Close menu : Active menu is closed
        if method_id is GenericActions.CLOSE:
            self.active_menu = None
            if self.background_menus:
                self.active_menu = self.background_menus.pop()[0]
            return

        if menu_type is StartMenu:
            self.main_menu_action(method_id, args)
        elif menu_type is OptionsMenu:
            self.options_menu_action(method_id, args)
        else:
            print("Unknown menu... : ", str(menu_type))

    def motion(self, pos):
        if self.level is None:
            self.active_menu.motion(pos)
        else:
            self.level.motion(pos)

    def click(self, button, pos):
        if self.level is None:
            if button == 1:
                self.execute_action(self.active_menu.type, self.active_menu.click(pos))
        else:
            self.level.click(button, pos)
        return self.exit

    def button_down(self, button, pos):
        if self.level is not None:
            self.level.button_down(button, pos)
コード例 #19
0
def create_status_entity_menu(ent):
    entries = [[{
        'type': 'text',
        'text': 'LEVEL : ' + str(ent.lvl),
        'font': fonts['ITEM_DESC_FONT']
    }],
               [{
                   'type': 'text',
                   'text': 'ATTACK',
                   'font': fonts['MENU_SUB_TITLE_FONT'],
                   'color': DARK_GREEN,
                   'margin': (20, 0, 20, 0)
               }, {}, {}, {
                   'type': 'text',
                   'text': 'LOOT',
                   'font': fonts['MENU_SUB_TITLE_FONT'],
                   'color': DARK_GREEN,
                   'margin': (20, 0, 20, 0)
               } if isinstance(ent, Foe) else {}, {}],
               [{
                   'type': 'text',
                   'text': 'TYPE :'
               }, {
                   'type': 'text',
                   'text': str(ent.attack_kind.value)
               }, {}, {}, {}],
               [{
                   'type': 'text',
                   'text': 'REACH :'
               }, {
                   'type': 'text',
                   'text': ent.get_formatted_reach()
               }, {}, {}, {}], [{}, {}, {}, {}, {}], [{}, {}, {}, {}, {}],
               [{
                   'type': 'text',
                   'text': 'STATS',
                   'font': fonts['MENU_SUB_TITLE_FONT'],
                   'color': DARK_GREEN,
                   'margin': (10, 0, 10, 0)
               }, {}, {}, {
                   'type': 'text',
                   'text': 'SKILLS',
                   'font': fonts['MENU_SUB_TITLE_FONT'],
                   'color': DARK_GREEN,
                   'margin': (10, 0, 10, 0)
               }, {}],
               [{
                   'type': 'text',
                   'text': 'HP :'
               }, {
                   'type': 'text',
                   'text': str(ent.hp) + ' / ' + str(ent.hp_max),
                   'color': determine_hp_color(ent.hp, ent.hp_max)
               }, {}, {}, {}],
               [{
                   'type': 'text',
                   'text': 'MOVE :'
               }, {
                   'type': 'text',
                   'text': str(ent.max_moves)
               }, {}, {}, {}],
               [{
                   'type': 'text',
                   'text': 'ATTACK :'
               }, {
                   'type': 'text',
                   'text': str(ent.strength)
               }, {}, {}, {}],
               [{
                   'type': 'text',
                   'text': 'DEFENSE :'
               }, {
                   'type': 'text',
                   'text': str(ent.defense)
               }, {}, {}, {}],
               [{
                   'type': 'text',
                   'text': 'MAGICAL RES :'
               }, {
                   'type': 'text',
                   'text': str(ent.res)
               }, {}, {}, {}],
               [{
                   'type': 'text',
                   'text': 'ALTERATIONS',
                   'font': fonts['MENU_SUB_TITLE_FONT'],
                   'color': DARK_GREEN,
                   'margin': (10, 0, 10, 0)
               }]]

    alts = ent.alterations
    if not alts:
        entries.append([{'type': 'text', 'text': 'None'}])
    for alt in alts:
        entries.append([{
            'type': 'text_button',
            'name': alt.get_formatted_name(),
            'id': StatusMenu.INFO_ALTERATION,
            'color': WHITE,
            'color_hover': TURQUOISE,
            'obj': alt
        }])

    if isinstance(ent, Foe):
        loot = ent.potential_loot
        i = 2
        for (item, probability) in loot:
            name = str(item)
            entries[i][3] = {'type': 'text', 'text': name}
            entries[i][4] = {
                'type': 'text',
                'text': ' (' + str(probability * 100) + '%)'
            }
            i += 1

    # Display skills
    i = 7
    for skill in ent.skills:
        entries[i][3] = {'type': 'text', 'text': '> ' + skill.formatted_name}
        i += 1

    return InfoBox(str(ent),
                   StatusMenu,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   FOE_STATUS_MENU_WIDTH,
                   close_button=UNFINAL_ACTION)
コード例 #20
0
def create_trade_menu(first_player, second_player):
    # Extract data from players
    items_max = first_player.nb_items_max
    items_first = list(first_player.items)
    free_spaces = items_max - len(items_first)
    items_first += [None] * free_spaces

    items_max = first_player.nb_items_max
    items_second = list(second_player.items)
    free_spaces = items_max - len(items_second)
    items_second += [None] * free_spaces

    entries = []
    method_id = TradeMenu.INTERAC_ITEM
    # We assume that first player and second player items lists have the same size and are even
    for i in range(len(items_first) // 2):
        row = []
        for owner_i, items in enumerate([items_first, items_second]):
            for j in range(2):
                entry = {
                    'type': 'item_button',
                    'item': items[i * 2 + j],
                    'index': i,
                    'subtype': 'trade',
                    'id': method_id,
                    'args': [first_player, second_player, owner_i]
                }
                row.append(entry)
        entries.append(row)

    # Gold at end
    entry = [{
        'type':
        'text',
        'text':
        first_player.get_formatted_name() + '\'s gold : ' +
        str(first_player.gold),
        'font':
        fonts['ITEM_DESC_FONT']
    }, {
        'type':
        'text',
        'text':
        second_player.get_formatted_name() + '\'s gold : ' +
        str(second_player.gold),
        'font':
        fonts['ITEM_DESC_FONT']
    }]
    entries.append(entry)

    title = "Trade"
    menu_id = TradeMenu
    title_color = WHITE
    return InfoBox(title,
                   menu_id,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   TRADE_MENU_WIDTH,
                   close_button=UNFINAL_ACTION,
                   sep=True,
                   title_color=title_color)
コード例 #21
0
class StartScreen:
    screen_size = SCREEN_SIZE

    def __init__(self, screen):
        self.screen = screen
        self.menu_screen = self.screen.copy()

        # Start screen loop
        bg_image = pg.image.load(
            'imgs/interface/main_menu_background.jpg').convert_alpha()
        self.background = pg.transform.scale(bg_image, screen.get_size())

        # Creating menu
        self.active_menu = StartScreen.create_menu()
        self.background_menus = []

        # Memorize if a game is currently being performed
        self.level = None

        self.levels = [0, 1, 2]
        self.level_id = None

        # Load current saved parameters
        self.load_options()

        self.exit = False

    def load_options(self):
        # Load current move speed
        Movable.move_speed = int(self.read_options_file("move_speed"))
        StartScreen.screen_size = int(self.read_options_file("screen_size"))

    @staticmethod
    def create_menu():
        entries = [[{
            'name': 'New game',
            'id': StartMenu.NEW_GAME
        }], [{
            'name': 'Load game',
            'id': StartMenu.LOAD_GAME
        }], [{
            'name': 'Options',
            'id': StartMenu.OPTIONS
        }], [{
            'name': 'Exit game',
            'id': StartMenu.EXIT
        }]]

        for row in entries:
            for entry in row:
                entry['type'] = 'button'

        return InfoBox("In the name of the Five Cats", StartMenu,
                       "imgs/interface/PopUpMenu.png", entries,
                       START_MENU_WIDTH)

    @staticmethod
    def load_parameter_entry(param, formatted_name, values, identifier):
        val = int(StartScreen.read_options_file(param))

        entry = {
            'name': formatted_name,
            'values': values,
            'id': identifier,
            'current_value_ind': 0
        }

        for i in range(len(entry['values'])):
            if entry['values'][i]['value'] == val:
                entry['current_value_ind'] = i

        return entry

    @staticmethod
    def create_options_menu():
        entries = [[
            StartScreen.load_parameter_entry("move_speed", "Move speed : ",
                                             [{
                                                 'label': 'Slow',
                                                 'value': ANIMATION_SPEED // 2
                                             }, {
                                                 'label': 'Normal',
                                                 'value': ANIMATION_SPEED
                                             }, {
                                                 'label': 'Fast',
                                                 'value': ANIMATION_SPEED * 2
                                             }], OptionsMenu.CHANGE_MOVE_SPEED)
        ],
                   [
                       StartScreen.load_parameter_entry(
                           "screen_size", "Screen mode : ",
                           [{
                               'label': 'Window',
                               'value': SCREEN_SIZE // 2
                           }, {
                               'label': 'Full',
                               'value': SCREEN_SIZE
                           }], OptionsMenu.CHANGE_SCREEN_SIZE)
                   ]]
        for row in entries:
            for entry in row:
                entry['type'] = 'parameter_button'

        return InfoBox("Options",
                       OptionsMenu,
                       "imgs/interface/PopUpMenu.png",
                       entries,
                       START_MENU_WIDTH,
                       close_button=1)

    @staticmethod
    def modify_options_file(el_to_edit, new_value):
        tree = etree.parse("saves/options.xml")
        el = tree.find(".//" + el_to_edit)
        el.text = str(new_value)
        tree.write("saves/options.xml")

    @staticmethod
    def read_options_file(el_to_read):
        tree = etree.parse("saves/options.xml").getroot()

        el = tree.find(".//" + el_to_read)
        return el.text.strip()

    def display(self):
        if self.level:
            self.screen.fill(BLACK)
            self.level.display(self.screen)
        else:
            self.screen.blit(self.background, (0, 0))
            for menu in self.background_menus:
                if menu[1]:
                    menu[0].display(self.screen)
            if self.active_menu:
                self.active_menu.display(self.screen)

    def play(self, level):
        # Modify screen
        flags = pg.FULLSCREEN if StartScreen.screen_size == 2 else 0
        self.screen = pg.display.set_mode((WIN_WIDTH, WIN_HEIGHT), flags)
        self.level = level

    def update_state(self):
        if self.level:
            status = self.level.update_state()
            if status is Status.ENDED_VICTORY and (self.level_id +
                                                   1) in self.levels:
                self.level_id += 1
                team = self.level.passed_players + self.level.players
                for player in team:
                    # Players are fully restored between level
                    player.healed(player.hp_max)
                    # Reset player's state
                    player.new_turn()
                self.play(StartScreen.load_level(self.level_id, team))
            elif status is Status.ENDED_VICTORY or status is Status.ENDED_DEFEAT:
                # TODO: Game win dialog?
                self.screen = pg.display.set_mode(
                    (MAIN_WIN_WIDTH, MAIN_WIN_HEIGHT))
                self.level = None

    @staticmethod
    def load_level(level, team=None):
        if team is None:
            team = []
        return Level('maps/level_' + str(level) + '/', level, players=team)

    def new_game(self):
        # Init the first level
        self.level_id = 0
        self.play(StartScreen.load_level(self.level_id))

    def load_game(self):
        try:
            save = open("saves/main_save.xml", "r")

            # Test if there is a current saved game
            if save:
                tree_root = etree.parse("saves/main_save.xml").getroot()
                index = tree_root.find("level/index").text.strip()
                level_name = 'maps/level_' + index + '/'
                game_status = tree_root.find("level/phase").text.strip()
                turn_nb = 0
                if game_status != 'I':
                    turn_nb = int(tree_root.find("level/turn").text.strip())

                # Load level with current game status, foes states, and team
                self.level_id = int(index)
                level = Level(level_name, self.level_id, game_status, turn_nb,
                              tree_root.find("level/entities"))
                self.play(level)
                save.close()
                return
        except FileNotFoundError:
            # No saved game
            self.background_menus.append([self.active_menu, True])

            name = "Load Game"
            entries = [[{
                'type': 'text',
                'text': "No saved game.",
                'font': fonts['MENU_SUB_TITLE_FONT']
            }]]
            width = self.screen.get_width() // 2
            self.active_menu = InfoBox(name,
                                       "",
                                       "imgs/interface/PopUpMenu.png",
                                       entries,
                                       width,
                                       close_button=1)

    def options_menu(self):
        self.background_menus.append([self.active_menu, False])
        self.active_menu = StartScreen.create_options_menu()

    def exit_game(self):
        self.exit = True

    def main_menu_action(self, method_id, args):
        # Execute action
        if method_id is StartMenu.NEW_GAME:
            self.new_game()
        elif method_id is StartMenu.LOAD_GAME:
            self.load_game()
        elif method_id is StartMenu.OPTIONS:
            self.options_menu()
        elif method_id is StartMenu.EXIT:
            self.exit_game()
        else:
            print("Unknown action... : ", str(method_id))

    @staticmethod
    def options_menu_action(method_id, args):
        # Execute action
        if method_id is OptionsMenu.CHANGE_MOVE_SPEED:
            Movable.move_speed = args[2][0]
            StartScreen.modify_options_file("move_speed", args[2][0])
        elif method_id is OptionsMenu.CHANGE_SCREEN_SIZE:
            StartScreen.screen_size = args[2][0]
            StartScreen.modify_options_file("screen_size", args[2][0])
        else:
            print("Unknown action... : ", method_id)

    def execute_action(self, menu_type, action):
        if not action:
            return
        method_id = action[0]
        args = action[1]

        # Test if the action is a generic one (according to the method_id)
        # Close menu : Active menu is closed
        if method_id is GenericActions.CLOSE:
            self.active_menu = None
            if self.background_menus:
                self.active_menu = self.background_menus.pop()[0]
            return

        if menu_type is StartMenu:
            self.main_menu_action(method_id, args)
        elif menu_type is OptionsMenu:
            self.options_menu_action(method_id, args)
        else:
            print("Unknown menu... : ", str(menu_type))

    def motion(self, pos):
        if self.level is None:
            self.active_menu.motion(pos)
        else:
            self.level.motion(pos)

    def click(self, button, pos):
        if self.level is None:
            if button == 1:
                self.execute_action(self.active_menu.type,
                                    self.active_menu.click(pos))
        else:
            self.level.click(button, pos)
        return self.exit

    def button_down(self, button, pos):
        if self.level is not None:
            self.level.button_down(button, pos)
コード例 #22
0
    def load_game(self):
        try:
            save = open("saves/main_save.xml", "r")

            # Test if there is a current saved game
            if save:
                tree_root = etree.parse("saves/main_save.xml").getroot()
                level_name = tree_root.find("level/name").text.strip()
                game_status = tree_root.find("level/phase").text.strip()
                turn_nb = 0
                if game_status != 'I':
                    turn_nb = int(tree_root.find("level/turn").text.strip())
                team = []
                for player in tree_root.findall("team/player"):
                    name = player.find("name").text.strip()
                    level = int(player.find("level").text.strip())
                    p_class = player.find("class").text.strip()
                    race = player.find("race").text.strip()
                    gold = int(player.find("gold").text.strip())
                    exp = int(player.find("exp").text.strip())
                    hp = int(player.find("hp").text.strip())
                    strength = int(player.find("strength").text.strip())
                    defense = int(player.find("defense").text.strip())
                    res = int(player.find("res").text.strip())
                    move = int(player.find("move").text.strip())
                    current_hp = int(player.find("currentHp").text.strip())
                    pos = (int(player.find("position/x").text.strip()),
                           int(player.find("position/y").text.strip()))
                    state = player.find("turnFinished").text.strip()
                    inv = []
                    for it in player.findall("inventory/item"):
                        it_name = it.find("name").text.strip()
                        item = Level.parse_item_file(it_name)
                        inv.append(item)

                    equipments = []
                    for eq in player.findall("equipments/equipment"):
                        eq_name = eq.find("name").text.strip()
                        eq = Level.parse_item_file(eq_name)
                        equipments.append(eq)

                    # -- Reading of the XML file for default character's values (i.e. sprites)
                    tree = etree.parse("data/characters.xml").getroot()
                    player_t = tree.xpath(name)[0]

                    sprite = 'imgs/dungeon_crawl/player/' + player_t.find(
                        'sprite').text.strip()
                    compl_sprite = player_t.find('complementSprite')
                    if compl_sprite is not None:
                        compl_sprite = 'imgs/dungeon_crawl/player/' + compl_sprite.text.strip(
                        )

                    p = Player(name,
                               sprite,
                               hp,
                               defense,
                               res,
                               move,
                               strength, [p_class],
                               equipments,
                               race,
                               gold,
                               level,
                               compl_sprite=compl_sprite)
                    p.earn_xp(exp)
                    p.set_items(inv)
                    p.set_current_hp(current_hp)
                    p.set_pos(pos)
                    if state == "True":
                        p.turn_finished()

                    team.append(p)

                # Load level with current game status, foes states, and team
                level = Level(level_name, team, game_status, turn_nb,
                              tree_root.find("level/entities"))
                self.play(level)
                save.close()
                return
        except FileNotFoundError as err:
            pass

        # No saved game
        self.background_menus.append([self.active_menu, True])

        name = "Load Game"
        entries = [[{
            'type': 'text',
            'text': "No saved game.",
            'font': ITEM_DESC_FONT
        }]]
        width = self.screen.get_width() // 2
        self.active_menu = InfoBox(name,
                                   "",
                                   "imgs/interface/PopUpMenu.png",
                                   entries,
                                   width,
                                   close_button=1)
コード例 #23
0
def create_status_menu(player):
    entries = [[{
        'type': 'text',
        'color': GREEN,
        'text': 'Name :',
        'font': fonts['ITALIC_ITEM_FONT']
    }, {
        'type': 'text',
        'text': player.get_formatted_name()
    }],
               [{
                   'type': 'text',
                   'color': GREEN,
                   'text': 'Class :',
                   'font': fonts['ITALIC_ITEM_FONT']
               }, {
                   'type': 'text',
                   'text': player.get_formatted_classes()
               }],
               [{
                   'type': 'text',
                   'color': GREEN,
                   'text': 'Race :',
                   'font': fonts['ITALIC_ITEM_FONT']
               }, {
                   'type': 'text',
                   'text': player.get_formatted_race()
               }],
               [{
                   'type': 'text',
                   'color': GREEN,
                   'text': 'Level :',
                   'font': fonts['ITALIC_ITEM_FONT']
               }, {
                   'type': 'text',
                   'text': str(player.lvl)
               }],
               [{
                   'type': 'text',
                   'color': GOLD,
                   'text': '   XP :',
                   'font': fonts['ITALIC_ITEM_FONT']
               }, {
                   'type': 'text',
                   'text': str(player.xp) + ' / ' + str(player.xp_next_lvl)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'STATS',
                   'font': fonts['MENU_SUB_TITLE_FONT'],
                   'margin': (10, 0, 10, 0)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'HP :'
               }, {
                   'type': 'text',
                   'text': str(player.hp) + ' / ' + str(player.hp_max),
                   'color': determine_hp_color(player.hp, player.hp_max)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'MOVE :'
               }, {
                   'type': 'text',
                   'text': str(player.max_moves)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'ATTACK :'
               }, {
                   'type': 'text',
                   'text': str(player.strength)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'DEFENSE :'
               }, {
                   'type': 'text',
                   'text': str(player.defense)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'MAGICAL RES :'
               }, {
                   'type': 'text',
                   'text': str(player.res)
               }],
               [{
                   'type': 'text',
                   'color': WHITE,
                   'text': 'ALTERATIONS',
                   'font': fonts['MENU_SUB_TITLE_FONT'],
                   'margin': (10, 0, 10, 0)
               }]]

    alts = player.alterations
    if not alts:
        entries.append([{'type': 'text', 'color': WHITE, 'text': 'None'}])
    for alt in alts:
        entries.append([{
            'type': 'text_button',
            'name': alt.get_formatted_name(),
            'id': StatusMenu.INFO_ALTERATION,
            'color': WHITE,
            'color_hover': TURQUOISE,
            'obj': alt
        }])

    return InfoBox("Status",
                   StatusMenu,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   STATUS_MENU_WIDTH,
                   close_button=UNFINAL_ACTION)
コード例 #24
0
def create_player_menu(player, buildings, interact_entities, missions, foes):
    entries = [[{
        'name': 'Inventory',
        'id': CharacterMenu.INV
    }], [{
        'name': 'Equipment',
        'id': CharacterMenu.EQUIPMENT
    }], [{
        'name': 'Status',
        'id': CharacterMenu.STATUS
    }], [{
        'name': 'Wait',
        'id': CharacterMenu.WAIT
    }]]

    # Options flags
    chest_option = False
    portal_option = False
    fountain_option = False
    talk_option = False
    trade_option = False

    case_pos = (player.pos[0], player.pos[1] - TILE_SIZE)
    if (0, 0) < case_pos < (MAP_WIDTH, MAP_HEIGHT):
        for building in buildings:
            if building.pos == case_pos:
                entries.insert(0, [{
                    'name': 'Visit',
                    'id': CharacterMenu.VISIT
                }])
                break

    for ent in interact_entities:
        if abs(ent.pos[0] - player.pos[0]) + abs(ent.pos[1] -
                                                 player.pos[1]) == TILE_SIZE:
            if isinstance(ent, Player):
                if not trade_option:
                    entries.insert(0, [{
                        'name': 'Trade',
                        'id': CharacterMenu.TRADE
                    }])
                    trade_option = True
            elif isinstance(ent, Chest):
                if not ent.opened and not chest_option:
                    entries.insert(0, [{
                        'name': 'Open',
                        'id': CharacterMenu.OPEN_CHEST
                    }])
                    chest_option = True
            elif isinstance(ent, Portal):
                if not portal_option:
                    entries.insert(0, [{
                        'name': 'Use Portal',
                        'id': CharacterMenu.USE_PORTAL
                    }])
                    portal_option = True
            elif isinstance(ent, Fountain):
                if not fountain_option:
                    entries.insert(0, [{
                        'name': 'Drink',
                        'id': CharacterMenu.DRINK
                    }])
                    fountain_option = True
            elif isinstance(ent, Character):
                if not talk_option:
                    entries.insert(0, [{
                        'name': 'Talk',
                        'id': CharacterMenu.TALK
                    }])
                    talk_option = True

    # Check if player is on mission position
    for mission in missions:
        if mission.type is MissionType.POSITION:
            if mission.pos_is_valid(player.pos):
                entries.insert(0, [{'name': 'Take', 'id': CharacterMenu.TAKE}])

    # Check if player could attack something, according to weapon range
    w_range = [1] if player.get_weapon() is None else player.get_weapon().reach
    end = False
    for foe in foes:
        for reach in w_range:
            if abs(foe.pos[0] -
                   player.pos[0]) + abs(foe.pos[1] -
                                        player.pos[1]) == TILE_SIZE * reach:
                entries.insert(0, [{
                    'name': 'Attack',
                    'id': CharacterMenu.ATTACK
                }])
                end = True
                break
        if end:
            break

    for row in entries:
        for entry in row:
            entry['type'] = 'button'

    return InfoBox("Select an action",
                   CharacterMenu,
                   "imgs/interface/PopUpMenu.png",
                   entries,
                   ACTION_MENU_WIDTH,
                   el_rect_linked=player.get_rect())
コード例 #25
0
class StartScreen:
    def __init__(self, screen):
        self.screen = screen
        self.menu_screen = self.screen.copy()

        # Start screen loop
        bg_image = pg.image.load(
            'imgs/interface/main_menu_background.jpg').convert_alpha()
        self.background = pg.transform.scale(bg_image, screen.get_size())

        # Creating menu
        self.active_menu = StartScreen.create_menu()
        self.background_menus = []

        # Memorize if a game is currently being performed
        self.level = None

        # Load current saved parameters
        self.load_options()

    def load_options(self):
        # Load current move speed
        Movable.move_speed = int(self.read_options_file("move_speed"))

    @staticmethod
    def create_menu():
        entries = [[{
            'name': 'New game',
            'id': NEW_GAME_ACTION_ID
        }], [{
            'name': 'Load game',
            'id': LOAD_GAME_ACTION_ID
        }], [{
            'name': 'Options',
            'id': OPTIONS_ACTION_ID
        }], [{
            'name': 'Exit game',
            'id': EXIT_ACTION_ID
        }]]

        for row in entries:
            for entry in row:
                entry['type'] = 'button'

        return InfoBox("In the name of the Five Cats", START_MENU_ID,
                       "imgs/interface/PopUpMenu.png", entries,
                       START_MENU_WIDTH)

    @staticmethod
    def load_parameter_entry(param, formatted_name, values, id):
        val = int(StartScreen.read_options_file(param))

        entry = {
            'name': formatted_name,
            'values': values,
            'id': id,
            'current_value_ind': 0
        }

        for i in range(len(entry['values'])):
            if entry['values'][i]['value'] == val:
                entry['current_value_ind'] = i

        return entry

    @staticmethod
    def create_options_menu():
        entries = [[
            StartScreen.load_parameter_entry("move_speed", "Move speed : ",
                                             [{
                                                 'label': 'Slow',
                                                 'value': ANIMATION_SPEED // 2
                                             }, {
                                                 'label': 'Normal',
                                                 'value': ANIMATION_SPEED
                                             }, {
                                                 'label': 'Fast',
                                                 'value': ANIMATION_SPEED * 2
                                             }], CHANGE_MOVE_SPEED)
        ]]
        for row in entries:
            for entry in row:
                entry['type'] = 'parameter_button'

        return InfoBox("Options",
                       OPTIONS_MENU_ID,
                       "imgs/interface/PopUpMenu.png",
                       entries,
                       START_MENU_WIDTH,
                       close_button=1)

    @staticmethod
    def modify_options_file(el_to_edit, new_value):
        tree = etree.parse("saves/options.xml")
        el = tree.find(".//" + el_to_edit)
        el.text = str(new_value)
        tree.write("saves/options.xml")

    @staticmethod
    def read_options_file(el_to_read):
        tree = etree.parse("saves/options.xml").getroot()

        el = tree.find(".//" + el_to_read)
        return el.text.strip()

    def display(self):
        if self.level:
            self.screen.fill(BLACK)
            self.level.display(self.screen)
        else:
            self.screen.blit(self.background, (0, 0))
            for menu in self.background_menus:
                if menu[1]:
                    menu[0].display(self.screen)
            if self.active_menu:
                self.active_menu.display(self.screen)

    def play(self, level):
        # Modify screen
        self.screen = pg.display.set_mode((WIN_WIDTH, WIN_HEIGHT))
        self.level = level

    def update_state(self):
        if self.level:
            exit = self.level.update_state()
            if exit:
                self.screen = pg.display.set_mode(
                    (self.menu_screen.get_width(),
                     self.menu_screen.get_height()))
                self.level = None

    def level_is_ended(self):
        return self.level.is_ended()

    @staticmethod
    def init_player(name):
        # -- Reading of the XML file
        tree = etree.parse("data/characters.xml").getroot()
        player_t = tree.xpath(name)[0]
        player_class = player_t.find('class').text.strip()
        race = player_t.find('race').text.strip()
        lvl = player_t.find('lvl')
        if lvl is None:
            # If lvl is not informed, default value is assumes to be 1
            lvl = 1
        else:
            lvl = int(lvl.text.strip())
        defense = int(player_t.find('initDef').text.strip())
        res = int(player_t.find('initRes').text.strip())
        hp = int(player_t.find('initHP').text.strip())
        strength = int(player_t.find('initStrength').text.strip())
        move = int(player_t.find('move').text.strip())
        sprite = 'imgs/dungeon_crawl/player/' + player_t.find(
            'sprite').text.strip()
        compl_sprite = player_t.find('complementSprite')
        if compl_sprite is not None:
            compl_sprite = 'imgs/dungeon_crawl/player/' + compl_sprite.text.strip(
            )

        equipment = player_t.find('equipment')
        equipments = []
        for eq in equipment.findall('*'):
            equipments.append(Level.parse_item_file(eq.text.strip()))
        gold = int(player_t.find('gold').text.strip())

        # Creating player instance
        player = Player(name,
                        sprite,
                        hp,
                        defense,
                        res,
                        move,
                        strength, [player_class],
                        equipments,
                        race,
                        gold,
                        lvl,
                        compl_sprite=compl_sprite)

        # Up stats according to current lvl
        player.stats_up(lvl - 1)
        # Restore hp due to lvl up
        player.healed()

        inventory = player_t.find('inventory')
        for it in inventory.findall('item'):
            item = Level.parse_item_file(it.text.strip())
            player.set_item(item)

        return player

    @staticmethod
    def load_level(level, team):
        return Level('maps/level_' + level + '/', team)

    def new_game(self):
        # Init player's team (one character at beginning)
        team = [self.init_player("john"), self.init_player("archer")]

        # Init the first level
        level = StartScreen.load_level("0", team)

        self.play(level)

    def load_game(self):
        try:
            save = open("saves/main_save.xml", "r")

            # Test if there is a current saved game
            if save:
                tree_root = etree.parse("saves/main_save.xml").getroot()
                level_name = tree_root.find("level/name").text.strip()
                game_status = tree_root.find("level/phase").text.strip()
                turn_nb = 0
                if game_status != 'I':
                    turn_nb = int(tree_root.find("level/turn").text.strip())
                team = []
                for player in tree_root.findall("team/player"):
                    name = player.find("name").text.strip()
                    level = int(player.find("level").text.strip())
                    p_class = player.find("class").text.strip()
                    race = player.find("race").text.strip()
                    gold = int(player.find("gold").text.strip())
                    exp = int(player.find("exp").text.strip())
                    hp = int(player.find("hp").text.strip())
                    strength = int(player.find("strength").text.strip())
                    defense = int(player.find("defense").text.strip())
                    res = int(player.find("res").text.strip())
                    move = int(player.find("move").text.strip())
                    current_hp = int(player.find("currentHp").text.strip())
                    pos = (int(player.find("position/x").text.strip()),
                           int(player.find("position/y").text.strip()))
                    state = player.find("turnFinished").text.strip()
                    inv = []
                    for it in player.findall("inventory/item"):
                        it_name = it.find("name").text.strip()
                        item = Level.parse_item_file(it_name)
                        inv.append(item)

                    equipments = []
                    for eq in player.findall("equipments/equipment"):
                        eq_name = eq.find("name").text.strip()
                        eq = Level.parse_item_file(eq_name)
                        equipments.append(eq)

                    # -- Reading of the XML file for default character's values (i.e. sprites)
                    tree = etree.parse("data/characters.xml").getroot()
                    player_t = tree.xpath(name)[0]

                    sprite = 'imgs/dungeon_crawl/player/' + player_t.find(
                        'sprite').text.strip()
                    compl_sprite = player_t.find('complementSprite')
                    if compl_sprite is not None:
                        compl_sprite = 'imgs/dungeon_crawl/player/' + compl_sprite.text.strip(
                        )

                    p = Player(name,
                               sprite,
                               hp,
                               defense,
                               res,
                               move,
                               strength, [p_class],
                               equipments,
                               race,
                               gold,
                               level,
                               compl_sprite=compl_sprite)
                    p.earn_xp(exp)
                    p.set_items(inv)
                    p.set_current_hp(current_hp)
                    p.set_pos(pos)
                    if state == "True":
                        p.turn_finished()

                    team.append(p)

                # Load level with current game status, foes states, and team
                level = Level(level_name, team, game_status, turn_nb,
                              tree_root.find("level/entities"))
                self.play(level)
                save.close()
                return
        except FileNotFoundError as err:
            pass

        # No saved game
        self.background_menus.append([self.active_menu, True])

        name = "Load Game"
        entries = [[{
            'type': 'text',
            'text': "No saved game.",
            'font': ITEM_DESC_FONT
        }]]
        width = self.screen.get_width() // 2
        self.active_menu = InfoBox(name,
                                   "",
                                   "imgs/interface/PopUpMenu.png",
                                   entries,
                                   width,
                                   close_button=1)

    def options_menu(self):
        self.background_menus.append([self.active_menu, False])
        self.active_menu = StartScreen.create_options_menu()

    @staticmethod
    def exit_game():
        pg.quit()
        raise SystemExit

    def main_menu_action(self, method_id, args):
        # Execute action
        if method_id == NEW_GAME_ACTION_ID:
            self.new_game()
        elif method_id == LOAD_GAME_ACTION_ID:
            self.load_game()
        elif method_id == OPTIONS_ACTION_ID:
            self.options_menu()
        elif method_id == EXIT_ACTION_ID:
            self.exit_game()
        else:
            print("Unknown action... : ", method_id)

    def options_menu_action(self, method_id, args):
        # Execute action
        if method_id == CHANGE_MOVE_SPEED:
            Movable.move_speed = args[2][0]
            StartScreen.modify_options_file("move_speed", args[2][0])
        else:
            print("Unknown action... : ", method_id)

    def execute_action(self, menu_type, action):
        if not action:
            return
        method_id = action[0]
        args = action[1]

        # Test if the action is a generic one (according to the method_id)
        # Close menu : Active menu is closed
        if method_id == CLOSE_ACTION_ID:
            self.active_menu = None
            if self.background_menus:
                self.active_menu = self.background_menus.pop()[0]
            return

        if menu_type == START_MENU_ID:
            self.main_menu_action(method_id, args)
        elif menu_type == OPTIONS_MENU_ID:
            self.options_menu_action(method_id, args)
        else:
            print("Unknown menu... : ", menu_type)

    def motion(self, pos):
        if self.level is None:
            self.active_menu.motion(pos)
        else:
            self.level.motion(pos)

    def click(self, button, pos):
        if self.level is None:
            if button == 1:
                self.execute_action(self.active_menu.get_type(),
                                    self.active_menu.click(pos))
        else:
            self.level.click(button, pos)

    def button_down(self, button, pos):
        if self.level is not None:
            self.level.button_down(button, pos)
コード例 #26
0
    def load_game(self):
        try:
            save = open("saves/main_save.xml", "r")

            # Test if there is a current saved game
            if save:
                tree_root = etree.parse("saves/main_save.xml").getroot()
                index = tree_root.find("level/index").text.strip()
                level_name = 'maps/level_' + index + '/'
                game_status = tree_root.find("level/phase").text.strip()
                turn_nb = 0
                if game_status != 'I':
                    turn_nb = int(tree_root.find("level/turn").text.strip())
                team = []
                for player in tree_root.findall("team/player"):
                    name = player.find("name").text.strip()
                    level = int(player.find("level").text.strip())
                    p_class = player.find("class").text.strip()
                    race = player.find("race").text.strip()
                    gold = int(player.find("gold").text.strip())
                    exp = int(player.find("exp").text.strip())
                    hp = int(player.find("hp").text.strip())
                    strength = int(player.find("strength").text.strip())
                    defense = int(player.find("defense").text.strip())
                    res = int(player.find("resistance").text.strip())
                    current_hp = int(player.find("currentHp").text.strip())
                    pos = (int(player.find("position/x").text.strip()) *
                           TILE_SIZE,
                           int(player.find("position/y").text.strip()) *
                           TILE_SIZE)
                    state = player.find("turnFinished").text.strip()
                    inv = []
                    for it in player.findall("inventory/item"):
                        it_name = it.find("name").text.strip()
                        item = LoadFromXMLManager.parse_item_file(it_name)
                        inv.append(item)

                    equipments = []
                    for eq in player.findall("equipment/*"):
                        eq_name = eq.text.strip()
                        eq = LoadFromXMLManager.parse_item_file(eq_name)
                        equipments.append(eq)

                    skills = [
                        (LoadFromXMLManager.load_skill(skill.text.strip())
                         if skill.text.strip()
                         not in LoadFromXMLManager.skills_infos else
                         LoadFromXMLManager.skills_infos[skill.text.strip()])
                        for skill in player.findall('skills/skill/name')
                    ]

                    # -- Reading of the XML file for default character's values (i.e. sprites)
                    tree = etree.parse("data/characters.xml").getroot()
                    player_t = tree.xpath(name)[0]

                    sprite = 'imgs/' + player_t.find('sprite').text.strip()
                    compl_sprite = player_t.find('complementSprite')
                    if compl_sprite is not None:
                        compl_sprite = 'imgs/' + compl_sprite.text.strip()

                    p = Player(name,
                               sprite,
                               hp,
                               defense,
                               res,
                               strength, [p_class],
                               equipments,
                               race,
                               gold,
                               level,
                               skills,
                               compl_sprite=compl_sprite)
                    p.earn_xp(exp)
                    p.items = inv
                    p.set_current_hp(current_hp)
                    p.pos = pos
                    if state == "True":
                        p.turn_finished()

                    team.append(p)

                # Load level with current game status, foes states, and team
                self.level_id = int(index)
                level = Level(level_name, team, self.level_id, game_status,
                              turn_nb, tree_root.find("level/entities"))
                self.play(level)
                save.close()
                return
        except FileNotFoundError:
            # No saved game
            self.background_menus.append([self.active_menu, True])

            name = "Load Game"
            entries = [[{
                'type': 'text',
                'text': "No saved game.",
                'font': fonts['MENU_SUB_TITLE_FONT']
            }]]
            width = self.screen.get_width() // 2
            self.active_menu = InfoBox(name,
                                       "",
                                       "imgs/interface/PopUpMenu.png",
                                       entries,
                                       width,
                                       close_button=1)