Beispiel #1
0
    def add_monster_into_play(self, player, monster):
        """

        :param player:
        :param monster:
        :return:
        """
        # TODO: refactor some into the combat animations
        self.animate_monster_release(player, monster)
        self.build_hud(self._layout[player]['hud'][0], monster)
        self.monsters_in_play[player].append(monster)

        # TODO: not hardcode
        if player is self.players[0]:
            self.alert(
                T.format('combat_call_tuxemon',
                         {"name": monster.name.upper()}))
        elif self.is_trainer_battle:
            self.alert(
                T.format('combat_opponent_call_tuxemon', {
                    "name": monster.name.upper(),
                    "user": player.name.upper(),
                }))
        else:
            self.alert(
                T.format('combat_wild_appeared',
                         {"name": monster.name.upper()}))
Beispiel #2
0
    def load(self, slug):
        """Loads and sets this technique's attributes from the technique
        database. The technique is looked up in the database by slug.

        :param slug: The slug of the technique to look up in the database.

        :type slug: String

        :rtype: None
        """

        results = db.lookup(slug, table="technique")
        self.slug = results["slug"]  # a short English identifier
        self.name = T.translate(self.slug)  # locale-specific string

        self.sort = results['sort']

        # technique use notifications (translated!)
        # NOTE: should be `self.use_tech`, but Technique and Item have overlapping checks
        self.use_item = T.maybe_translate(results.get("use_tech"))
        self.use_success = T.maybe_translate(results.get("use_success"))
        self.use_failure = T.maybe_translate(results.get("use_failure"))

        self.category = results["category"]
        self.icon = results["icon"]
        self._combat_counter = 0
        self._life_counter = 0

        if results.get('types'):
            self.type1 = results["types"][0]
            if len(results['types']) > 1:
                self.type2 = results["types"][1]
            else:
                self.type2 = None
        else:
            self.type1 = self.type2 = None

        self.power = results.get("power")
        self.is_fast = results.get("is_fast")
        self.recharge_length = results.get("recharge")
        self.is_area = results.get("is_area")
        self.range = results.get("range")
        self.accuracy = results.get("accuracy")
        self.potency = results.get("potency")
        self.effect = results["effects"]
        self.target = process_targets(results["target"])

        # Load the animation sprites that will be used for this technique
        self.animation = results["animation"]
        if self.animation:
            self.images = []
            animation_dir = prepare.fetch("animations", "technique")
            directory = sorted(os.listdir(animation_dir))
            for image in directory:
                if self.animation and image.startswith(self.animation):
                    self.images.append(
                        os.path.join("animations/technique", image))

        # Load the sound effect for this technique
        self.sfx = results["sfx"]
Beispiel #3
0
    def host_game(self):

        # check if server is already hosting a game
        if self.game.server.listening:
            self.game.pop_state(self)
            open_dialog(local_session,
                        [T.translate('multiplayer_already_hosting')])

        # not hosting, so start the process
        elif not self.game.isclient:
            # Configure this game to host
            self.game.ishost = True
            self.game.server.server.listen()
            self.game.server.listening = True

            # Enable the game, so we can connect to self
            self.game.client.enable_join_multiplayer = True
            self.game.client.client.listen()
            self.game.client.listening = True

            # connect to self
            while not self.game.client.client.registered:
                self.game.client.client.autodiscover(autoregister=False)
                for game in self.game.client.client.discovered_servers:
                    self.game.client.client.register(game)

            # close this menu
            self.game.pop_state(self)

            # inform player that hosting is ready
            open_dialog(local_session,
                        [T.translate('multiplayer_hosting_ready')])
Beispiel #4
0
def pygame_init():
    """ Eventually refactor out of prepare
    """
    global JOYSTICKS
    global FONTS
    global MUSIC
    global SFX
    global GFX
    global SCREEN
    global SCREEN_RECT

    import pygame as pg

    # Configure locale
    from tuxemon.core.locale import T
    T.collect_languages(CONFIG.recompile_translations)

    # Configure databases
    from tuxemon.core.db import db
    db.load()

    logger.debug("pygame init")
    pg.init()
    pg.display.set_caption(CONFIG.window_caption)

    fullscreen = pg.FULLSCREEN if CONFIG.fullscreen else 0
    flags = pg.HWSURFACE | pg.DOUBLEBUF | fullscreen

    SCREEN = pg.display.set_mode(SCREEN_SIZE, flags)
    SCREEN_RECT = SCREEN.get_rect()

    # Disable the mouse cursor visibility
    pg.mouse.set_visible(not CONFIG.hide_mouse)

    # Set up any gamepads that we detect
    # The following event types will be generated by the joysticks:
    # JOYAXISMOTION JOYBALLMOTION JOYBUTTONDOWN JOYBUTTONUP JOYHATMOTION
    JOYSTICKS = list()
    pg.joystick.init()
    devices = [pg.joystick.Joystick(x) for x in range(pg.joystick.get_count())]

    # Initialize the individual joysticks themselves.
    for joystick in devices:
        name = joystick.get_name()
        print("Found joystick: \"{}\"".format(name))
        blacklisted = any(i.match(name) for i in joystick_blacklist)
        if blacklisted:
            print("Ignoring joystick: \"{}\"".format(name))
        else:
            print("Configuring joystick: \"{}\"".format(name))
            joystick.init()
            JOYSTICKS.append(joystick)

    from tuxemon.core.platform import android
    # Map the appropriate android keys if we're on android
    if android:
        android.init()
        android.map_key(android.KEYCODE_MENU, pg.K_ESCAPE)
Beispiel #5
0
    def prompt_for_name(self, menu_item):
        self.monster = menu_item.game_object

        self.session.client.push_state(
            state_name="InputMenu",
            prompt=T.translate("input_monster_name"),
            callback=self.set_monster_name,
            escape_key_exits=False,
            initial=T.translate(self.monster.slug))
Beispiel #6
0
    def load(self, slug):
        """Loads and sets this items's attributes from the item.db database. The item is looked up
        in the database by slug.

        :param slug: The item slug to look up in the monster.item database.

        :type slug: String

        :rtype: None
        :returns: None

        **Examples:**

        >>> potion = Item()
        >>> potion.load('potion')    # Load an item by slug.
        >>> pprint.pprint(potion.__dict__)
        {
            'description': u'Heals a monster by 50 HP.',
            'effects': [u'heal'],
            'slug': 'potion',
            'name': u'potion',
            'sprite': u'resources/gfx/items/potion.png',
            'surface': <Surface(66x90x32 SW)>,
            'surface_size_original': (66, 90),
            'type': u'Consumable'
        }
        """

        try:
            results = db.lookup(slug, table="item")
        except KeyError:
            logger.error(msg="Failed to find item with slug {}".format(slug))
            return

        self.slug = results["slug"]  # short English identifier
        self.name = T.translate(self.slug)  # translated name
        self.description = T.translate("{}_description".format(
            self.slug))  # will be locale string

        # item use notifications (translated!)
        self.use_item = T.translate(results["use_item"])
        self.use_success = T.translate(results["use_success"])
        self.use_failure = T.translate(results["use_failure"])

        # misc attributes (not translated!)
        self.sort = results['sort']
        assert self.sort
        self.type = results["type"]
        self.sprite = results["sprite"]
        self.usable_in = results["usable_in"]
        self.target = process_targets(results["target"])
        self.effects = self.parse_effects(results.get("effects", []))
        self.conditions = self.parse_conditions(results.get("conditions", []))
        self.surface = graphics.load_and_scale(self.sprite)
        self.surface_size_original = self.surface.get_size()
Beispiel #7
0
 def add(menuitem):
     monster = menuitem.game_object
     if monster.current_hp == 0:
         tools.open_dialog(local_session, [T.format("combat_fainted", parameters={"name": monster.name})])
     elif monster in self.active_monsters:
         tools.open_dialog(local_session, [T.format("combat_isactive", parameters={"name": monster.name})])
         msg = T.translate("combat_replacement_is_fainted")
         tools.open_dialog(local_session, [msg])
     else:
         self.add_monster_into_play(player, monster)
         self.client.pop_state()
Beispiel #8
0
        def ask_confirmation():
            # open menu to confirm the save
            menu = self.client.push_state("Menu")
            menu.shrink_to_items = True

            # add choices
            yes = MenuItem(self.shadow_text(T.translate('save_overwrite')),
                           None, None, positive_answer)
            no = MenuItem(self.shadow_text(T.translate('save_keep')), None,
                          None, negative_answer)

            menu.add(yes)
            menu.add(no)
Beispiel #9
0
    def ask_player_for_monster(self, player):
        """ Open dialog to allow player to choose a TXMN to enter into play

        :param player:
        :return:
        """
        def add(menuitem):
            monster = menuitem.game_object
            if monster.current_hp == 0:
                tools.open_dialog(local_session, [
                    T.format("combat_fainted",
                             parameters={"name": monster.name})
                ])
            elif monster in self.active_monsters:
                tools.open_dialog(local_session, [
                    T.format("combat_isactive",
                             parameters={"name": monster.name})
                ])
                msg = T.translate("combat_replacement_is_fainted")
                tools.open_dialog(local_session, [msg])
            else:
                self.add_monster_into_play(player, monster)
                self.client.pop_state()

        state = self.client.push_state("MonsterMenuState")
        # must use a partial because alert relies on a text box that may not exist
        # until after the state hs been startup
        state.task(partial(state.alert, T.translate("combat_replacement")), 0)
        state.on_menu_selection = add
        state.escape_key_exits = False
Beispiel #10
0
 def save(self):
     logger.info("Saving!")
     try:
         save_data = save.get_save_data(local_session, )
         save.save(
             save_data,
             self.selected_index + 1,
         )
         save.slot_number = self.selected_index
     except Exception as e:
         raise
         logger.error("Unable to save game!!")
         logger.error(e)
         open_dialog(local_session, [T.translate('save_failure')])
     else:
         open_dialog(local_session, [T.translate('save_success')])
Beispiel #11
0
 def render_empty_slot(self, rect):
     slot_image = pygame.Surface(rect.size, pygame.SRCALPHA)
     rect = rect.move(0, rect.height // 2 - 10)
     text.draw_text(slot_image,
                    T.translate('empty_slot'),
                    rect,
                    font=self.font)
     return slot_image
Beispiel #12
0
        def swap_it(menuitem):
            monster = menuitem.game_object

            if monster in self.client.get_state_by_name('CombatState').active_monsters:
                tools.open_dialog(local_session, [T.format('combat_isactive', {"name": monster.name})])
                return
            elif monster.current_hp < 1:
                tools.open_dialog(local_session, [T.format('combat_fainted', {"name": monster.name})])
                return
            combat_state = self.client.get_state_by_name("CombatState")
            swap = Technique("swap")
            swap.combat_state = combat_state
            player = local_session.player
            target = monster
            combat_state.enqueue_action(player, swap, target)
            self.client.pop_state()  # close technique menu
            self.client.pop_state()  # close the monster action menu
Beispiel #13
0
    def on_menu_selection(self, menu_item):
        """ Called when player has selected something from the inventory

        Currently, opens a new menu depending on the state context

        :param menu_item:
        :return:
        """
        item = menu_item.game_object
        state = self.determine_state_called_from()

        if not any(menu_item.game_object.validate(m) for m in local_session.player.monsters):
            msg = T.format('item_no_available_target', {'name': item.name})
            tools.open_dialog(local_session, [msg])
        elif state not in item.usable_in:
            msg = T.format('item_cannot_use_here', {'name': item.name})
            tools.open_dialog(local_session, [msg])
        else:
            self.open_confirm_use_menu(item)
Beispiel #14
0
    def initialize_items(self):
        menu_items_map = (('menu_fight', self.open_technique_menu),
                          ('menu_monster', self.open_swap_menu),
                          ('menu_item', self.open_item_menu), ('menu_run',
                                                               self.run))

        for key, callback in menu_items_map:
            label = T.translate(key).upper()
            image = self.shadow_text(label)
            yield MenuItem(image, label, None, callback)
Beispiel #15
0
 def initialize_items(self):
     servers = self.game.client.server_list
     if servers:
         for server in servers:
             label = self.shadow_text(server)
             yield MenuItem(label, None, None, None)
     else:
         label = self.shadow_text(T.translate('multiplayer_no_servers'))
         item = MenuItem(label, None, None, None)
         item.enabled = False
         yield item
Beispiel #16
0
        def choose_target(menu_item):
            # open menu to choose target of technique
            technique = menu_item.game_object
            if technique.next_use > 0:
                params = {"move": technique.name, "name": self.monster.name}
                tools.open_dialog(local_session, [T.format('combat_recharging', params)])
                return

            combat_state = self.client.get_state_by_name("CombatState")
            state = self.client.push_state("CombatTargetMenuState", player=combat_state.players[0],
                                           user=self.monster, action=technique)
            state.on_menu_selection = partial(enqueue_technique, technique)
Beispiel #17
0
 def new_game():
     # load the starting map
     state = self.client.replace_state("WorldState")
     map_name = prepare.fetch("maps", prepare.CONFIG.starting_map)
     state.change_map(map_name)
     self.client.push_state(
         state_name="InputMenu",
         prompt=T.translate("input_name"),
         callback=set_player_name,
         escape_key_exits=False,
     )
     self.client.push_state("FadeInTransition")
Beispiel #18
0
def show_item_result_as_dialog(session, item, result):
    """ Show generic dialog if item was used or not

    :param tuxemon.core.session.Session session: Session
    :param tuxemon.core.item.item.Item item: Item
    :param dict result:
    :return: None
    """
    msg_type = 'use_success' if result['success'] else 'use_failure'
    template = getattr(item, msg_type)
    if template:
        message = T.translate(template)
        open_dialog(session, [message])
Beispiel #19
0
        def open_choice_menu():
            # open the menu for use/cancel
            menu = self.client.push_state("Menu")
            menu.shrink_to_items = True

            menu_items_map = (('item_confirm_use', confirm),
                              ('item_confirm_cancel', cancel))

            # add our options to the menu
            for key, callback in menu_items_map:
                label = T.translate(key).upper()
                image = self.shadow_text(label)
                item = MenuItem(image, label, None, callback)
                menu.add(item)
Beispiel #20
0
    def animate_party_status(self):
        """ Animate monsters that need to be fainted

        * Animation to remove monster is handled here
        TODO: check for faint status, not HP

        :rtype: None
        """
        for player, party in self.monsters_in_play.items():
            for monster in party:
                if fainted(monster):
                    self.alert(T.format('combat_fainted', {"name": monster.name}))
                    self.animate_monster_faint(monster)
                    self.suppress_phase_change(3)
Beispiel #21
0
 def initialize_items(self):
     empty_image = None
     rect = self.client.screen.get_rect()
     slot_rect = Rect(0, 0, rect.width * 0.80, rect.height // 6)
     for i in range(self.number_of_slots):
         # Check to see if a save exists for the current slot
         if os.path.exists(prepare.SAVE_PATH + str(i + 1) + ".save"):
             image = self.render_slot(slot_rect, i + 1)
             item = MenuItem(image, T.translate('menu_save'), None, None)
             self.add(item)
         else:
             if not empty_image:
                 empty_image = self.render_empty_slot(slot_rect)
             item = MenuItem(empty_image, "SAVE", None, None)
             self.add(item)
Beispiel #22
0
        def enqueue_item(item, menu_item):
            target = menu_item.game_object
            # is the item valid to use?
            if not item.validate(target):
                msg = T.format('cannot_use_item_monster', {'name': item.name})
                tools.open_dialog(local_session, [msg])
                return

            # enqueue the item
            combat_state = self.client.get_state_by_name("CombatState")
            # TODO: don't hardcode to player0
            combat_state.enqueue_action(combat_state.players[0], item, target)

            # close all the open menus
            self.client.pop_state()  # close target chooser
            self.client.pop_state()  # close the monster action menu
Beispiel #23
0
    def render_slot(self, rect, slot_num):
        slot_image = pygame.Surface(rect.size, pygame.SRCALPHA)

        # Try and load the save game and draw details about the save
        save_data = save.load(slot_num)
        if "screenshot" in save_data:
            screenshot = b64decode(save_data["screenshot"])
            size = save_data["screenshot_width"], save_data[
                "screenshot_height"]
            thumb_image = pygame.image.fromstring(screenshot, size,
                                                  "RGB").convert()
            thumb_rect = thumb_image.get_rect().fit(rect)
            thumb_image = pygame.transform.smoothscale(thumb_image,
                                                       thumb_rect.size)
        else:
            thumb_rect = rect.copy()
            thumb_rect.width /= 5.0
            thumb_image = pygame.Surface(thumb_rect.size)
            thumb_image.fill((255, 255, 255))

        if "error" in save_data:
            red = (255, 0, 0)
            pygame.draw.line(thumb_image, red, [0, 0], thumb_rect.size, 3)
            pygame.draw.line(thumb_image, red, [0, thumb_rect.height],
                             [thumb_rect.width, 0], 3)

        # Draw the screenshot
        slot_image.blit(thumb_image, (rect.width * .20, 0))

        # Draw the slot text
        rect = rect.move(0, rect.height // 2 - 10)
        text.draw_text(slot_image,
                       T.translate('slot') + " " + str(slot_num),
                       rect,
                       font=self.font)

        x = int(rect.width * .5)
        text.draw_text(slot_image,
                       save_data['player_name'], (x, 0, 500, 500),
                       font=self.font)
        if "error" not in save_data:
            text.draw_text(slot_image,
                           save_data['time'], (x, 50, 500, 500),
                           font=self.font)

        return slot_image
Beispiel #24
0
    def show_monster_action_menu(self, monster):
        """ Show the main window for choosing player actions

        :param monster: Monster to choose an action for
        :type monster: tuxemon.core.monster.Monster

        :returns: None
        """
        message = T.format('combat_monster_choice', {"name": monster.name})
        self.alert(message)
        x, y, w, h = self.client.screen.get_rect()
        rect = Rect(0, 0, w // 2.5, h // 4)
        rect.bottomright = w, h

        state = self.client.push_state("MainCombatMenuState", columns=2)
        state.monster = monster
        state.rect = rect
    def start(self):
        def set_variable(var_value):
            player.game_variables[self.parameters.variable] = var_value
            self.session.client.pop_state()

        # perform text substitutions
        choices = replace_text(self.session, self.parameters.choices)
        player = get_npc(self.session, "player")

        # make menu options for each string between the colons
        var_list = choices.split(":")
        var_menu = list()

        for val in var_list:
            text = T.translate(val)
            var_menu.append((text, text, partial(set_variable, val)))

        self.open_choice_dialog(self.session, var_menu)
Beispiel #26
0
    def startup(self, *args, **kwargs):
        # If there is a save, then move the cursor to "Load game" first
        index = get_index_of_latest_save()
        kwargs['selected_index'] = 0 if index is None else 1
        super(StartState, self).startup(*args, **kwargs)

        def change_state(state, **change_state_kwargs):
            return partial(self.client.push_state, state,
                           **change_state_kwargs)

        def set_player_name(text):
            local_session.player.name = text

        def new_game():
            # load the starting map
            state = self.client.replace_state("WorldState")
            map_name = prepare.fetch("maps", prepare.CONFIG.starting_map)
            state.change_map(map_name)
            self.client.push_state(
                state_name="InputMenu",
                prompt=T.translate("input_name"),
                callback=set_player_name,
                escape_key_exits=False,
            )
            self.client.push_state("FadeInTransition")

        def options():
            pass

        def exit_game():
            self.client.exit = True

        menu_items_map = (
            ('menu_new_game', new_game),
            ('menu_load', change_state("LoadMenuState")),
            ('menu_options', options),
            ('exit', exit_game),
        )

        for key, callback in menu_items_map:
            label = T.translate(key).upper()
            image = self.shadow_text(label)
            item = MenuItem(image, label, None, callback)
            self.add(item)
Beispiel #27
0
    def run(self):
        """ Cause player to run from the battle

        TODO: only works for player0

        :return: None
        """

        # TODO: only works for player0
        self.client.pop_state(self)
        combat_state = self.client.get_state_by_name("CombatState")

        if combat_state.is_trainer_battle:
            def open_menu():
                combat_state.task(
                    partial(combat_state.show_monster_action_menu, self.monster),
                    1
                )
            combat_state.alert(T.translate("combat_can't_run_from_trainer"), open_menu)
        else:
            combat_state.trigger_player_run(combat_state.players[0])
Beispiel #28
0
    def animate_parties_in(self):
        # TODO: break out functions here for each
        left_trainer, right_trainer = self.players
        right_monster = right_trainer.monsters[0]

        surface = pygame.display.get_surface()
        x, y, w, h = surface.get_rect()

        # TODO: not hardcode this
        player, opponent = self.players
        player_home = self._layout[player]['home'][0]
        opp_home = self._layout[opponent]['home'][0]

        y_mod = scale(50)
        duration = 3

        back_island = self.load_sprite('gfx/ui/combat/' +
                                       self.graphics['island_back'],
                                       bottom=opp_home.bottom + y_mod,
                                       right=0)

        if self.is_trainer_battle:
            enemy = self.load_sprite(
                'gfx/sprites/player/' + opponent.sprite_name + '_front.png',
                bottom=back_island.rect.bottom - scale(12),
                centerx=back_island.rect.centerx)
            self._monster_sprite_map[opponent] = enemy
        else:
            enemy = right_monster.get_sprite("front",
                                             bottom=back_island.rect.bottom -
                                             scale(12),
                                             centerx=back_island.rect.centerx)
            self._monster_sprite_map[right_monster] = enemy
            self.monsters_in_play[opponent].append(right_monster)

        self.sprites.add(enemy)
        self.build_hud(self._layout[opponent]['hud'][0], right_monster)

        if self.is_trainer_battle:
            self.alert(
                T.format('combat_trainer_appeared',
                         {"name": opponent.name.upper()}))
        else:
            self.alert(
                T.format('combat_wild_appeared',
                         {"name": right_monster.name.upper()}))

        front_island = self.load_sprite('gfx/ui/combat/' +
                                        self.graphics['island_front'],
                                        bottom=player_home.bottom - y_mod,
                                        left=w)

        trainer1 = self.load_sprite(
            'gfx/sprites/player/' + player.sprite_name + '_back.png',
            bottom=front_island.rect.centery + scale(6),
            centerx=front_island.rect.centerx)
        self._monster_sprite_map[left_trainer] = trainer1

        def flip():
            enemy.image = pygame.transform.flip(enemy.image, 1, 0)
            trainer1.image = pygame.transform.flip(trainer1.image, 1, 0)

        flip()  # flip images to opposite
        self.task(flip, 1.5)  # flip the images to proper direction

        if not self.is_trainer_battle:  # the combat call is handled by fill_battlefield_positions for trainer battles
            self.task(audio.load_sound(right_monster.combat_call).play,
                      1.5)  # play combat call when it turns back

        animate = partial(self.animate,
                          transition='out_quad',
                          duration=duration)

        # top trainer
        animate(enemy.rect, back_island.rect, centerx=opp_home.centerx)
        animate(enemy.rect,
                back_island.rect,
                y=-y_mod,
                transition='out_back',
                relative=True)

        # bottom trainer
        animate(trainer1.rect, front_island.rect, centerx=player_home.centerx)
        animate(trainer1.rect,
                front_island.rect,
                y=y_mod,
                transition='out_back',
                relative=True)
Beispiel #29
0
 def join_by_ip(self):
     self.game.push_state("InputMenu",
                          prompt=T.translate("multiplayer_join_prompt"))
Beispiel #30
0
def add_menu_items(state, items):
    for key, callback in items:
        label = T.translate(key).upper()

        state.build_item(label, callback)