Пример #1
0
    def start(self):
        player = self.session.player

        # Don't start a battle if we don't even have monsters in our party yet.
        if not check_battle_legal(player):
            logger.debug("battle is not legal, won't start")
            return False

        world = self.session.client.get_state_name("WorldState")
        if not world:
            return False

        npc = world.get_entity(self.parameters.npc_slug)
        npc.load_party()

        # Lookup the environment
        env_slug = "grass"
        if 'environment' in player.game_variables:
            env_slug = player.game_variables['environment']
        env = db.lookup(env_slug, table="environment")

        # Add our players and setup combat
        logger.debug("Starting battle!")
        self.session.client.push_state("CombatState",
                                       players=(player, npc),
                                       combat_type="trainer",
                                       graphics=env['battle_graphics'])

        # Start some music!
        filename = env['battle_music']
        self.session.client.event_engine.execute_action(
            "play_music", [filename])
Пример #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"]
Пример #3
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()
Пример #4
0
    def set_flairs(self):
        """Sets the flairs of this monster if they were not already configured

        :rtype: None
        :returns: None
        """
        if len(self.flairs) > 0 or self.slug == "":
            return

        results = db.lookup(self.slug, table="monster")
        flairs = results.get("flairs")
        if flairs:
            for flair in flairs:
                flair = Flair(flair['category'], random.choice(flair['names']))
                self.flairs[flair.category] = flair
Пример #5
0
    def start(self):
        player = self.session.player

        # Don't start a battle if we don't even have monsters in our party yet.
        if not check_battle_legal(player):
            return False

        slug = self.parameters.encounter_slug
        encounters = db.database['encounter'][slug]['monsters']
        encounter = _choose_encounter(encounters, self.parameters.total_prob)

        # If a random encounter was successfully rolled, look up the monster and start the
        # battle.
        if encounter:
            logger.info("Starting random encounter!")

            npc = _create_monster_npc(encounter)

            # Lookup the environment
            env_slug = "grass"
            if 'environment' in player.game_variables:
                env_slug = player.game_variables['environment']
            env = db.lookup(env_slug, table="environment")

            # Add our players and setup combat
            # "queueing" it will mean it starts after the top of the stack is popped (or replaced)
            self.session.client.queue_state("CombatState",
                                            players=(player, npc),
                                            combat_type="monster",
                                            graphics=env['battle_graphics'])

            # stop the player
            world = self.session.client.get_state_name("WorldState")
            world.lock_controls()
            world.stop_player()

            # flash the screen
            self.session.client.push_state("FlashTransition")

            # Start some music!
            filename = env['battle_music']
            self.session.client.event_engine.execute_action(
                "play_music", [filename])
Пример #6
0
    def __init__(self,
                 npc_slug,
                 sprite_name=None,
                 combat_front=None,
                 combat_back=None):
        super().__init__()

        # load initial data from the npc database
        npc_data = db.lookup(npc_slug, table="npc")

        self.slug = npc_slug

        # This is the NPC's name to be used in dialog
        self.name = T.translate(self.slug)

        # use 'animations' passed in
        # Hold on the the string so it can be sent over the network
        self.sprite_name = sprite_name
        self.combat_front = combat_front
        self.combat_back = combat_back
        if self.sprite_name is None:
            # Try to use the sprites defined in the JSON data
            self.sprite_name = npc_data["sprite_name"]
        if self.combat_front is None:
            self.combat_front = npc_data["combat_front"]
        if self.combat_back is None:
            self.combat_back = npc_data["combat_back"]

        # general
        self.behavior = "wander"  # not used for now
        self.game_variables = {}  # Tracks the game state
        self.interactions = []  # List of ways player can interact with the Npc
        self.isplayer = False  # used for various tests, idk
        self.monsters = [
        ]  # This is a list of tuxemon the npc has. Do not modify directly
        self.inventory = {}  # The Player's inventory.
        # Variables for long-term item and monster storage
        # Keeping these seperate so other code can safely
        # assume that all values are lists
        self.monster_boxes = dict()
        self.item_boxes = dict()

        # combat related
        self.ai = None  # Whether or not this player has AI associated with it
        self.speed = 10  # To determine combat order (not related to movement!)
        self.moves = []  # list of techniques

        # pathfinding and waypoint related
        self.pathfinding = None
        self.path = []
        self.final_move_dest = [
            0, 0
        ]  # Stores the final destination sent from a client

        # This is used to 'set back' when lost, and make movement robust.
        # If entity falls off of map due to a bug, it can be returned to this value.
        # When moving to a waypoint, this is used to detect if movement has overshot
        # the destination due to speed issues or framerate jitters.
        self.path_origin = None

        # movement related
        self.move_direction = None  # Set this value to move the npc (see below)
        self.facing = "down"  # Set this value to change the facing direction
        self.moverate = CONFIG.player_walkrate  # walk by default
        self.ignore_collisions = False

        # What is "move_direction"?
        # Move direction allows other functions to move the npc in a controlled way.
        # To move the npc, change the value to one of four directions: left, right, up or down.
        # The npc will then move one tile in that direction until it is set to None.

        # TODO: move sprites into renderer so class can be used headless
        self.playerHeight = 0
        self.playerWidth = 0
        self.standing = {}  # Standing animation frames
        self.sprite = {}  # Moving animation frames
        self.moveConductor = pyganim.PygConductor()
        self.load_sprites()
        self.rect = Rect(
            self.tile_pos,
            (self.playerWidth, self.playerHeight))  # Collision rect
Пример #7
0
    def load_from_db(self, slug):
        """Loads and sets this monster's attributes from the monster.db database.
        The monster is looked up in the database by name.

        :param slug: Slug to lookup
        :type slug: str

        :rtype: None
        """

        # Look up the monster by name and set the attributes in this instance
        results = db.lookup(slug, table="monster")

        if results is None:
            logger.error("monster {} is not found".format(slug))
            raise RuntimeError

        self.slug = results["slug"]  # short English identifier
        self.name = T.translate(results["slug"])  # translated name
        self.description = T.translate("{}_description".format(
            results["slug"]))  # translated description
        self.category = T.translate(results["category"])  # translated category
        self.shape = results.get("shape", "landrace").lower()
        types = results.get("types")
        if types:
            self.type1 = results["types"][0].lower()
            if len(types) > 1:
                self.type2 = results["types"][1].lower()

        self.weight = results['weight']

        # Look up the moves that this monster can learn AND LEARN THEM.
        moveset = results.get("moveset")
        if moveset:
            for move in moveset:
                self.moveset.append(move)
                if move['level_learned'] >= self.level:
                    technique = Technique(move['technique'])
                    self.learn(technique)

        # Look up the evolutions for this monster.
        evolutions = results.get("evolutions")
        if evolutions:
            for evolution in evolutions:
                self.evolutions.append(evolution)

        # Look up the monster's sprite image paths
        self.front_battle_sprite = self.get_sprite_path(
            results['sprites']['battle1'])
        self.back_battle_sprite = self.get_sprite_path(
            results['sprites']['battle2'])
        self.menu_sprite_1 = self.get_sprite_path(results['sprites']['menu1'])
        self.menu_sprite_2 = self.get_sprite_path(results['sprites']['menu2'])

        # get sound slugs for this monster, defaulting to a generic type-based sound
        self.combat_call = results.get("sounds", {}).get(
            "combat_call", "sound_{}_call".format(self.type1))
        self.faint_call = results.get("sounds", {}).get(
            "faint_call", "sound_{}_faint".format(self.type1))

        # Load the monster AI
        # TODO: clean up AI 'core' loading and what not
        ai_result = results['ai']
        if ai_result == "SimpleAI":
            self.ai = ai.SimpleAI()
        elif ai_result == "RandomAI":
            self.ai = ai.RandomAI()