예제 #1
0
    def _execute_pokemon_evolve(self, pokemon, cache):
        if pokemon.name in cache:
            return False

        response_dict = self.api.evolve_pokemon(pokemon_id=pokemon.id)
        if response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("result", 0) == 1:
            self.emit_event(
                "pokemon_evolved",
                formatted="Successfully evolved {pokemon} with CP {cp} and IV {iv}!",
                data={"pokemon": pokemon.name, "iv": pokemon.iv, "cp": pokemon.cp, "ncp": "?", "dps": "?", "xp": "?"},
            )
            awarded_candies = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("candy_awarded", 0)
            inventory.candies().get(pokemon.pokemon_id).consume(pokemon.evolution_cost - awarded_candies)
            inventory.pokemons().remove(pokemon.id)
            pokemon = Pokemon(
                response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("evolved_pokemon_data", {})
            )
            inventory.pokemons().add(pokemon)
            sleep(self.evolve_speed)
            return True
        else:
            # cache pokemons we can't evolve. Less server calls
            cache[pokemon.name] = 1
            sleep(0.7)
            return False
예제 #2
0
    def transfer_pokemon(self, pokemon):
        if self.config_transfer and (not self.bot.config.test):
            response_dict = self.bot.api.release_pokemon(pokemon_id=pokemon.id)
        else:
            response_dict = {"responses": {"RELEASE_POKEMON": {"candy_awarded": 0}}}

        if not response_dict:
            return False

        self.emit_event("pokemon_release",
                        formatted="Exchanged {pokemon} [IV {iv}] [CP {cp}] [NCP {ncp}] [DPS {dps}]",
                        data={"pokemon": pokemon.name,
                              "iv": pokemon.iv,
                              "cp": pokemon.cp,
                              "ncp": round(pokemon.ncp, 2),
                              "dps": round(pokemon.dps, 2)})

        if self.config_transfer and (not self.bot.config.test):
            candy = response_dict.get("responses", {}).get("RELEASE_POKEMON", {}).get("candy_awarded", 0)

            inventory.candies().get(pokemon.pokemon_id).add(candy)
            inventory.pokemons().remove(pokemon.id)

            action_delay(self.transfer_wait_min, self.transfer_wait_max)

        return True
예제 #3
0
    def _get_award(self):
        response_dict = self.bot.api.get_buddy_walked()
        result = response_dict.get('responses', {}).get('GET_BUDDY_WALKED', {})
        success = result.get('success', False)
        family_id = result.get('family_candy_id', 0)
        candy_awarded = result.get('candy_earned_count', 0)

        if success and family_id != 0:
            candy = inventory.candies().get(family_id)
            candy.add(candy_awarded)
            self.candy_awarded += candy_awarded

            msg = "{candy} {family} candy earned. You now have {quantity} candy!"
            if self.candy_limit != 0 and len(self.buddy_list) > 1:
                msg += " (Candy limit: {candy_earned}/{candy_limit})"
            if candy_awarded == 0:
                msg += " Probably reached candy daily limit"
            self.emit_event(
                'buddy_candy_earned',
                formatted=msg,
                data={
                    'candy': candy_awarded,
                    'family': inventory.candies().get(family_id).type,
                    'quantity': candy.quantity,
                    'candy_earned': self.candy_awarded,
                    'candy_limit': self.candy_limit
                }
            )
            return True
        else:
            self.emit_event(
                'buddy_candy_fail',
                formatted='Error trying to get candy from buddy.'
            )
            return False
예제 #4
0
    def _execute_pokemon_evolve(self, pokemon, cache):
        if pokemon.name in cache:
            return False

        response_dict = self.api.evolve_pokemon(pokemon_id=pokemon.id)
        if response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('result', 0) == 1:
            self.emit_event(
                'pokemon_evolved',
                formatted="Successfully evolved {pokemon} with CP {cp} and IV {iv}!",
                data={
                    'pokemon': pokemon.name,
                    'iv': pokemon.iv,
                    'cp': pokemon.cp,
                    'ncp': '?',
                    'dps': '?',
                    'xp': '?'
                }
            )
            awarded_candies = response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('candy_awarded', 0)
            inventory.candies().get(pokemon.pokemon_id).consume(pokemon.evolution_cost - awarded_candies)
            inventory.pokemons().remove(pokemon.id)
            pokemon = Pokemon(response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('evolved_pokemon_data', {}))
            inventory.pokemons().add(pokemon)
            sleep(self.evolve_speed)
            return True
        else:
            # cache pokemons we can't evolve. Less server calls
            cache[pokemon.name] = 1
            sleep(0.7)
            return False
예제 #5
0
    def _get_award(self):
        response_dict = self.bot.api.get_buddy_walked()
        result = response_dict.get('responses', {}).get('GET_BUDDY_WALKED', {})
        success = result.get('success', False)
        family_id = result.get('family_candy_id', 0)
        candy_awarded = result.get('candy_earned_count', 0)

        if success and family_id != 0:
            candy = inventory.candies().get(family_id)
            candy.add(candy_awarded)
            self.candy_awarded += candy_awarded

            msg = "{candy} {family} candy earned. You now have {quantity} candy!"
            if self.candy_limit != 0 and len(self.buddy_list) > 1:
                msg += " (Candy limit: {candy_earned}/{candy_limit})"
            if candy_awarded == 0:
                msg += " Probably reached candy daily limit"
            self.emit_event(
                'buddy_candy_earned',
                formatted=msg,
                data={
                    'candy': candy_awarded,
                    'family': inventory.candies().get(family_id).type,
                    'quantity': candy.quantity,
                    'candy_earned': self.candy_awarded,
                    'candy_limit': self.candy_limit
                }
            )
            return True
        else:
            self.emit_event(
                'buddy_candy_fail',
                formatted='Error trying to get candy from buddy.'
            )
            return False
예제 #6
0
    def release_pokemon(self, pokemon):
        """

        :type pokemon: Pokemon
        """
        try:
            if self.bot.config.test:
                candy_awarded = 1
            else:
                response_dict = self.bot.api.release_pokemon(
                    pokemon_id=pokemon.id)
                candy_awarded = response_dict['responses']['RELEASE_POKEMON'][
                    'candy_awarded']
        except KeyError:
            return

        # We could refresh here too, but adding 1 saves a inventory request
        candy = inventory.candies().get(pokemon.pokemon_id)
        candy.add(candy_awarded)
        inventory.pokemons().remove(pokemon.id)
        self.bot.metrics.released_pokemon()
        self.emit_event(
            'pokemon_release',
            formatted='Exchanged {pokemon} [CP {cp}] [IV {iv}] for candy.',
            data={
                'pokemon': pokemon.name,
                'cp': pokemon.cp,
                'iv': pokemon.iv,
                'ncp': pokemon.cp_percent,
                'dps': pokemon.moveset.dps
            })
        action_delay(self.transfer_wait_min, self.transfer_wait_max)
예제 #7
0
    def work(self):
        if not self._should_run():
            return

        filtered_list, filtered_dict = self._sort_and_filter()

        pokemon_to_be_evolved = 0
        pokemon_ids = []
        for pokemon in filtered_list:
            if pokemon.pokemon_id not in pokemon_ids:
                pokemon_ids.append(pokemon.pokemon_id)
                candy = inventory.candies().get(pokemon.pokemon_id)
                pokemon_to_be_evolved = pokemon_to_be_evolved + min(
                    candy.quantity / (pokemon.evolution_cost - 1),
                    filtered_dict[pokemon.pokemon_id])

        self._log_update_if_should(pokemon_to_be_evolved,
                                   self.min_pokemon_to_be_evolved)

        has_minimum_to_evolve = pokemon_to_be_evolved >= self.min_pokemon_to_be_evolved
        if has_minimum_to_evolve:
            if self.use_lucky_egg:
                self._use_lucky_egg()
            cache = {}
            for pokemon in filtered_list:
                if pokemon.can_evolve_now():
                    self._execute_pokemon_evolve(pokemon, cache)
예제 #8
0
    def get_worth_pokemons(self, pokemons, closest_first=False):
        if self.config_hunt_all:
            worth_pokemons = pokemons
        else:
            worth_pokemons = []

            # worth_pokemons += [p for p in pokemons if not inventory.pokedex().seen(p["pokemon_id"])]

            if self.config_hunt_vip:
                worth_pokemons += [
                    p for p in pokemons if p["name"] in self.bot.config.vips
                ]

            if self.config_target_family_of_vip or self.config_treat_family_of_vip_as_vip:
                worth_pokemons += [
                    p for p in pokemons
                    if (p not in worth_pokemons) and self._is_family_of_vip(p)
                ]

            if self.config_hunt_pokedex:
                worth_pokemons += [
                    p for p in pokemons
                    if (p not in worth_pokemons) and self._is_needed_pokedex(p)
                ]

        if closest_first:
            worth_pokemons.sort(key=lambda p: p["distance"])
        else:
            worth_pokemons.sort(key=lambda p: inventory.candies().get(p[
                "pokemon_id"]).quantity)

        return worth_pokemons
예제 #9
0
    def get_buddy_walked(self, pokemon):
        if not self.bot.config.test:
            response_dict = self.bot.api.get_buddy_walked()
        else:
            response_dict = {"responses": {"GET_BUDDY_WALKED": {"success": True, "family_candy_id": 0, "candy_earned_count": 0}}}

        if not response_dict:
            return False

        success = response_dict.get("responses", {}).get("GET_BUDDY_WALKED", {}).get("success", False)

        if not success:
            return False

        family_candy_id = response_dict.get("responses", {}).get("GET_BUDDY_WALKED", {}).get("family_candy_id", 0)
        candy_earned_count = response_dict.get("responses", {}).get("GET_BUDDY_WALKED", {}).get("candy_earned_count", 0)
        candy = inventory.candies().get(family_candy_id)

        if not self.bot.config.test:
            candy.add(candy_earned_count)

        self.emit_event("buddy_reward",
                        formatted="Buddy {pokemon} rewards {family} candies [+{candy_earned} candies] [{candy} candies]",
                        data={"pokemon": pokemon.name,
                              "family": candy.type,
                              "candy_earned": candy_earned_count,
                              "candy": candy.quantity})

        if not self.bot.config.test:
            action_delay(self.config_action_wait_min, self.config_action_wait_max)

        return True
예제 #10
0
    def upgrade_pokemon(self, pokemon):
        level = int(pokemon.level * 2) - 1
        candy = inventory.candies().get(pokemon.pokemon_id)

        for i in range(level, 80):
            upgrade_cost = self.pokemon_upgrade_cost[i - 1]
            upgrade_candy_cost = upgrade_cost[0]
            upgrade_stardust_cost = upgrade_cost[1]

            if self.config_upgrade and (not self.bot.config.test):
                response_dict = self.bot.api.upgrade_pokemon(
                    pokemon_id=pokemon.unique_id)
            else:
                response_dict = {
                    "responses": {
                        "UPGRADE_POKEMON": {
                            "result": SUCCESS
                        }
                    }
                }

            if not response_dict:
                return False

            result = response_dict.get("responses",
                                       {}).get("UPGRADE_POKEMON",
                                               {}).get("result", 0)

            if result != SUCCESS:
                return False

            upgrade = response_dict.get("responses", {}).get(
                "UPGRADE_POKEMON", {}).get("upgraded_pokemon", {})

            if self.config_upgrade and (not self.bot.config.test):
                candy.consume(upgrade_candy_cost)
                self.stardust_count -= upgrade_stardust_cost

            self.emit_event(
                "pokemon_upgraded",
                formatted=
                "Upgraded {pokemon} [IV {iv}] [CP {cp}] [{candy} candies] [{stardust} stardust]",
                data={
                    "pokemon": pokemon.name,
                    "iv": pokemon.iv,
                    "cp": pokemon.cp,
                    "candy": candy.quantity,
                    "stardust": self.stardust_count
                })

            if self.config_upgrade and (not self.bot.config.test):
                inventory.pokemons().remove(pokemon.unique_id)

                new_pokemon = inventory.Pokemon(upgrade)
                inventory.pokemons().add(new_pokemon)

                action_delay(self.config_transfer_wait_min,
                             self.config_transfer_wait_max)

        return True
예제 #11
0
    def release_pokemon(self, pokemon):
        """

        :type pokemon: Pokemon
        """
        try:
            if self.bot.config.test:
                candy_awarded = 1
            else:
                response_dict = self.bot.api.release_pokemon(pokemon_id=pokemon.id)
                candy_awarded = response_dict['responses']['RELEASE_POKEMON']['candy_awarded']
        except KeyError:
            return

        # We could refresh here too, but adding 1 saves a inventory request
        candy = inventory.candies().get(pokemon.pokemon_id)
        candy.add(candy_awarded)
        inventory.pokemons().remove(pokemon.id)
        self.bot.metrics.released_pokemon()
        self.emit_event(
            'pokemon_release',
            formatted='Exchanged {pokemon} [CP {cp}] [IV {iv}] for candy.',
            data={
                'pokemon': pokemon.name,
                'cp': pokemon.cp,
                'iv': pokemon.iv,
                'ncp': pokemon.cp_percent,
                'dps': pokemon.moveset.dps
            }
        )
        action_delay(self.bot.config.action_wait_min, self.bot.config.action_wait_max)
예제 #12
0
    def save_web_inventory(self):
        web_inventory = os.path.join(_base_dir, "web", "inventory-%s.json" % self.bot.config.username)

        with open(web_inventory, "r") as infile:
            ii = json.load(infile)

        ii = [x for x in ii if not x.get("inventory_item_data", {}).get("pokedex_entry", None)]
        ii = [x for x in ii if not x.get("inventory_item_data", {}).get("candy", None)]
        ii = [x for x in ii if not x.get("inventory_item_data", {}).get("item", None)]
        ii = [x for x in ii if not x.get("inventory_item_data", {}).get("pokemon_data", None)]

        for pokedex in inventory.pokedex().all():
            ii.append({"inventory_item_data": {"pokedex_entry": pokedex}})

        for family_id, candy in inventory.candies()._data.items():
            ii.append({"inventory_item_data": {"candy": {"family_id": family_id, "candy": candy.quantity}}})

        for item_id, item in inventory.items()._data.items():
            ii.append({"inventory_item_data": {"item": {"item_id": item_id, "count": item.count}}})

        for pokemon in inventory.pokemons().all():
            ii.append({"inventory_item_data": {"pokemon_data": pokemon._data}})

        with open(web_inventory, "w") as outfile:
            json.dump(ii, outfile)
예제 #13
0
    def release_pokemon(self, pokemon):
        """

        :type pokemon: Pokemon
        """
        try:
            if self.bot.config.test:
                candy_awarded = 1
            else:
                request = self.bot.api.create_request()
                request.release_pokemon(pokemon_id=pokemon.unique_id)
                response_dict = request.call()
                
                candy_awarded = response_dict['responses'][
                    'RELEASE_POKEMON']['candy_awarded']
        except KeyError:
            return

        # We could refresh here too, but adding 1 saves a inventory request
        candy = inventory.candies().get(pokemon.pokemon_id)
        candy.add(candy_awarded)
        inventory.pokemons().remove(pokemon.unique_id)
        self.bot.metrics.released_pokemon()
        self.emit_event(
            'pokemon_release',
            data={
                'pokemon': pokemon.name,
                'iv': pokemon.iv,
                'cp': pokemon.cp,
                'ivcp': pokemon.ivcp,
                'candy': candy.quantity,
                'candy_type': candy.type
            },
            formatted="Released {} (CP: {}, IV: {}, IVCP: {:.2f}) You now have"
                      " {} {} candies".format(pokemon.name, pokemon.cp,
                                              pokemon.iv, pokemon.ivcp,
                                              candy.quantity, candy.type)
        )
        with self.bot.database as conn:
            c = conn.cursor()
            c.execute(
                "SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='transfer_log'")

        result = c.fetchone()

        while True:
            if result[0] == 1:
                conn.execute('''INSERT INTO transfer_log (pokemon, iv, cp) VALUES (?, ?, ?)''',
                             (pokemon.name, pokemon.iv, pokemon.cp))
                break
            else:
                self.emit_event(
                    'transfer_log',
                    sender=self,
                    level='info',
                    formatted="transfer_log table not found, skipping log"
                )
                break
        action_delay(self.transfer_wait_min, self.transfer_wait_max)
예제 #14
0
    def _execute_pokemon_evolve(self, pokemon, cache):
        if pokemon.name in cache:
            return False

        response_dict = self.bot.api.evolve_pokemon(pokemon_id=pokemon.unique_id)
        if response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('result', 0) == 1:
            xp = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("experience_awarded", 0)
            evolution = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("evolved_pokemon_data", {})
            awarded_candies = response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('candy_awarded', 0)
            candy = inventory.candies().get(pokemon.pokemon_id)

            candy.consume(pokemon.evolution_cost - awarded_candies)

            self.emit_event(
                'pokemon_evolved',
                formatted="*Evolved {}* (IV {}) (CP {}) ({} candies) (+{} xp)".format(pokemon.name, pokemon.iv, pokemon.cp, candy.quantity, xp),
                data={
                    'pokemon': pokemon.name,
                    'iv': pokemon.iv,
                    'cp': pokemon.cp,
                    'candy': candy.quantity,
                    'xp': xp,
                }
            )

            inventory.pokemons().remove(pokemon.unique_id)
            new_pokemon = inventory.Pokemon(evolution)
            inventory.pokemons().add(new_pokemon)
            inventory.player().exp += xp

            action_delay(self.min_evolve_speed, self.max_evolve_speed)
            evolve_result = True
        else:
            # cache pokemons we can't evolve. Less server calls
            cache[pokemon.name] = 1
            sleep(0.7)
            evolve_result = False

        with self.bot.database as conn:
            c = conn.cursor()
            c.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='evolve_log'")

        result = c.fetchone()

        while True:
            if result[0] == 1:
                conn.execute('''INSERT INTO evolve_log (pokemon, iv, cp) VALUES (?, ?, ?)''', (pokemon.name, pokemon.iv, pokemon.cp))
                break
            else:
                self.emit_event(
                    'evolve_log',
                    sender=self,
                    level='info',
                    formatted="evolve_log table not found, skipping log"
                )
                break

        return evolve_result
예제 #15
0
    def release_pokemon(self, pokemon):
        """

        :type pokemon: Pokemon
        """
        try:
            if self.bot.config.test:
                candy_awarded = 1
            else:
                request = self.bot.api.create_request()
                request.release_pokemon(pokemon_id=pokemon.unique_id)
                response_dict = request.call()

                candy_awarded = response_dict['responses']['RELEASE_POKEMON'][
                    'candy_awarded']
        except KeyError:
            return

        # We could refresh here too, but adding 1 saves a inventory request
        candy = inventory.candies().get(pokemon.pokemon_id)
        candy.add(candy_awarded)
        inventory.pokemons().remove(pokemon.unique_id)
        self.bot.metrics.released_pokemon()
        self.emit_event(
            'pokemon_release',
            data={
                'pokemon': pokemon.name,
                'iv': pokemon.iv,
                'cp': pokemon.cp,
                'ivcp': pokemon.ivcp,
                'candy': candy.quantity,
                'candy_type': candy.type
            },
            formatted="Released {} (CP: {}, IV: {}, IVCP: {:.2f}) You now have"
            " {} {} candies".format(pokemon.name, pokemon.cp, pokemon.iv,
                                    pokemon.ivcp, candy.quantity, candy.type))
        with self.bot.database as conn:
            c = conn.cursor()
            c.execute(
                "SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='transfer_log'"
            )

        result = c.fetchone()

        while True:
            if result[0] == 1:
                conn.execute(
                    '''INSERT INTO transfer_log (pokemon, iv, cp) VALUES (?, ?, ?)''',
                    (pokemon.name, pokemon.iv, pokemon.cp))
                break
            else:
                self.emit_event(
                    'transfer_log',
                    sender=self,
                    level='info',
                    formatted="transfer_log table not found, skipping log")
                break
        action_delay(self.transfer_wait_min, self.transfer_wait_max)
예제 #16
0
    def _execute_pokemon_evolve(self, pokemon, cache):
        if pokemon.name in cache:
            return False

        response_dict = self.api.evolve_pokemon(pokemon_id=pokemon.unique_id)
        if response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('result', 0) == 1:
            xp = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("experience_awarded", 0)
            evolution = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("evolved_pokemon_data", {})
            awarded_candies = response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('candy_awarded', 0)
            candy = inventory.candies().get(pokemon.pokemon_id)

            candy.consume(pokemon.evolution_cost - awarded_candies)

            self.emit_event(
                'pokemon_evolved',
                formatted="*Evolved {}* (IV {}) (CP {}) ({} candies) (+{} xp)".format(pokemon.name, pokemon.iv, pokemon.cp, candy.quantity, xp),
                data={
                    'pokemon': pokemon.name,
                    'iv': pokemon.iv,
                    'cp': pokemon.cp,
                    'candy': candy.quantity,
                    'xp': xp,
                }
            )

            inventory.pokemons().remove(pokemon.unique_id)
            new_pokemon = inventory.Pokemon(evolution)
            inventory.pokemons().add(new_pokemon)
            inventory.player().exp += xp

            action_delay(self.min_evolve_speed, self.max_evolve_speed)
            evolve_result = True
        else:
            # cache pokemons we can't evolve. Less server calls
            cache[pokemon.name] = 1
            sleep(0.7)
            evolve_result = False

        with self.bot.database as conn:
            c = conn.cursor()
            c.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='evolve_log'")

        result = c.fetchone()

        while True:
            if result[0] == 1:
                conn.execute('''INSERT INTO evolve_log (pokemon, iv, cp) VALUES (?, ?, ?)''', (pokemon.name, pokemon.iv, pokemon.cp))
                break
            else:
                self.emit_event(
                    'evolve_log',
                    sender=self,
                    level='info',
                    formatted="evolve_log table not found, skipping log"
                )
                break

        return evolve_result
예제 #17
0
    def get_nearby_pokemons(self):
        radius = self.config_max_distance

        pokemons = [
            p for p in self.bot.cell["nearby_pokemons"]
            if self.get_distance(self.bot.start_position, p) <= radius
        ]

        if 'wild_pokemons' in self.bot.cell:
            for pokemon in self.bot.cell['wild_pokemons']:
                if pokemon['encounter_id'] in map(
                        lambda pokemon: pokemon['encounter_id'], pokemons):
                    # Already added this Pokemon
                    continue
                if self.get_distance(self.bot.start_position,
                                     pokemon) <= radius:
                    pokemons.append(pokemon)

        if 'catchable_pokemons' in self.bot.cell:
            for pokemon in self.bot.cell['catchable_pokemons']:
                if pokemon['encounter_id'] in map(
                        lambda pokemon: pokemon['encounter_id'], pokemons):
                    # Already added this Pokemon
                    continue
                if self.get_distance(self.bot.start_position,
                                     pokemon) <= radius:
                    pokemons.append(pokemon)

        for pokemon in pokemons:
            if "pokemon_data" in pokemon:
                pokemon["pokemon_id"] = pokemon["pokemon_data"]["pokemon_id"]
                pokemon["name"] = inventory.pokemons().name_for(
                    pokemon["pokemon_id"])

            if "name" not in pokemon and "pokemon_id" not in pokemon:
                self.logger.warning("Strange result? %s" % pokemon)
                # Skip this one!
                continue

            pokemon["distance"] = self.get_distance(self.bot.position, pokemon)

            if "name" not in pokemon:
                pokemon["name"] = inventory.pokemons().name_for(
                    pokemon["pokemon_id"])
            if "pokemon_id" not in pokemon:
                pokemon["pokemon_id"] = inventory.pokemons().id_for(
                    pokemon["name"])

            pokemon["candies"] = inventory.candies().get(
                pokemon["pokemon_id"]).quantity
            # Pokemon also has a fort_id of the PokeStop the Pokemon is hiding at.
            # We should set our first destination at that Pokestop.

        pokemons.sort(key=lambda p: p["distance"])

        return pokemons
예제 #18
0
    def transfer_pokemon(self, pokemon):
        if self.config_transfer and (not self.bot.config.test):
            response_dict = self.bot.api.release_pokemon(
                pokemon_id=pokemon.unique_id)
        else:
            response_dict = {
                "responses": {
                    "RELEASE_POKEMON": {
                        "candy_awarded": 0
                    }
                }
            }

        if not response_dict:
            return False

        candy_awarded = response_dict.get("responses",
                                          {}).get("RELEASE_POKEMON",
                                                  {}).get("candy_awarded", 0)
        candy = inventory.candies().get(pokemon.pokemon_id)

        if self.config_transfer and (not self.bot.config.test):
            candy.add(candy_awarded)

        self.emit_event(
            "pokemon_release",
            formatted=
            "Exchanged {pokemon} [IV {iv}] [CP {cp}] [{candy} candies]",
            data={
                "pokemon": pokemon.name,
                "iv": pokemon.iv,
                "cp": pokemon.cp,
                "candy": candy.quantity
            })

        if self.config_transfer and (not self.bot.config.test):
            inventory.pokemons().remove(pokemon.unique_id)

            with self.bot.database as db:
                cursor = db.cursor()
                cursor.execute(
                    "SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='transfer_log'"
                )

                db_result = cursor.fetchone()

                if db_result[0] == 1:
                    db.execute(
                        "INSERT INTO transfer_log (pokemon, iv, cp) VALUES (?, ?, ?)",
                        (pokemon.name, pokemon.iv, pokemon.cp))

            action_delay(self.config_action_wait_min,
                         self.config_action_wait_max)

        return True
예제 #19
0
    def evolve_pokemon(self, pokemon):
        while pokemon.unique_id in self.evolution_map:
            pokemon = self.evolution_map[pokemon.unique_id]

        if self.config_evolve and (not self.bot.config.test):
            response_dict = self.bot.api.evolve_pokemon(pokemon_id=pokemon.unique_id)
        else:
            response_dict = {"responses": {"EVOLVE_POKEMON": {"result": SUCCESS}}}

        if not response_dict:
            return False

        result = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("result", 0)

        if result != SUCCESS:
            return False

        xp = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("experience_awarded", 0)
        candy_awarded = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("candy_awarded", 0)
        candy = inventory.candies().get(pokemon.pokemon_id)
        evolution = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("evolved_pokemon_data", {})

        if self.config_evolve and (not self.bot.config.test):
            candy.consume(pokemon.evolution_cost - candy_awarded)
            inventory.player().exp += xp

        self.emit_event("pokemon_evolved",
                        formatted="Evolved {pokemon} [IV {iv}] [CP {cp}] [{candy} candies] [+{xp} xp]",
                        data={"pokemon": pokemon.name,
                              "iv": pokemon.iv,
                              "cp": pokemon.cp,
                              "candy": candy.quantity,
                              "xp": xp})

        if self.config_evolve and (not self.bot.config.test):
            new_pokemon = inventory.Pokemon(evolution)

            self.evolution_map[pokemon.unique_id] = new_pokemon

            inventory.pokemons().remove(pokemon.unique_id)
            inventory.pokemons().add(new_pokemon)

            with self.bot.database as db:
                cursor = db.cursor()
                cursor.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='evolve_log'")

                db_result = cursor.fetchone()

                if db_result[0] == 1:
                    db.execute("INSERT INTO evolve_log (pokemon, iv, cp) VALUES (?, ?, ?)", (pokemon.name, pokemon.iv, pokemon.cp))

            sleep(self.config_evolve_time, 0.1)

        return True
예제 #20
0
    def evolve_pokemon(self, pokemon):
        while pokemon.unique_id in self.evolution_map:
            pokemon = self.evolution_map[pokemon.unique_id]

        if self.config_evolve and (not self.bot.config.test):
            response_dict = self.bot.api.evolve_pokemon(pokemon_id=pokemon.unique_id)
        else:
            response_dict = {"responses": {"EVOLVE_POKEMON": {"result": SUCCESS}}}

        if not response_dict:
            return False

        result = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("result", 0)

        if result != SUCCESS:
            return False

        xp = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("experience_awarded", 0)
        candy_awarded = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("candy_awarded", 0)
        candy = inventory.candies().get(pokemon.pokemon_id)
        evolution = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("evolved_pokemon_data", {})

        if self.config_evolve and (not self.bot.config.test):
            candy.consume(pokemon.evolution_cost - candy_awarded)
            inventory.player().exp += xp

        self.emit_event("pokemon_evolved",
                        formatted="Evolved {pokemon} [IV {iv}] [CP {cp}] [{candy} candies] [+{xp} xp]",
                        data={"pokemon": pokemon.name,
                              "iv": pokemon.iv,
                              "cp": pokemon.cp,
                              "candy": candy.quantity,
                              "xp": xp})

        if self.config_evolve and (not self.bot.config.test):
            new_pokemon = inventory.Pokemon(evolution)

            self.evolution_map[pokemon.unique_id] = new_pokemon

            inventory.pokemons().remove(pokemon.unique_id)
            inventory.pokemons().add(new_pokemon)

            with self.bot.database as db:
                cursor = db.cursor()
                cursor.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='evolve_log'")

                db_result = cursor.fetchone()

                if db_result[0] == 1:
                    db.execute("INSERT INTO evolve_log (pokemon, iv, cp) VALUES (?, ?, ?)", (pokemon.name, pokemon.iv, pokemon.cp))

            sleep(self.config_evolve_time, 0.1)

        return True
예제 #21
0
    def get_buddy_walked(self, pokemon):
        if not self.bot.config.test:
            response_dict = self.bot.api.get_buddy_walked()
        else:
            response_dict = {
                "responses": {
                    "GET_BUDDY_WALKED": {
                        "success": True,
                        "family_candy_id": 0,
                        "candy_earned_count": 0
                    }
                }
            }

        if not response_dict:
            return False

        success = response_dict.get("responses",
                                    {}).get("GET_BUDDY_WALKED",
                                            {}).get("success", False)

        if not success:
            return False

        candy_earned_count = response_dict.get("responses", {}).get(
            "GET_BUDDY_WALKED", {}).get("candy_earned_count", 0)

        if candy_earned_count == 0:
            return

        family_candy_id = self.get_family_id(pokemon)
        candy = inventory.candies().get(family_candy_id)

        if not self.bot.config.test:
            candy.add(candy_earned_count)

        self.emit_event(
            "buddy_reward",
            formatted=
            "Buddy {pokemon} rewards {family} candies [+{candy_earned} candies] [{candy} candies]",
            data={
                "pokemon": pokemon.name,
                "family": candy.type,
                "candy_earned": candy_earned_count,
                "candy": candy.quantity
            })

        if not self.bot.config.test:
            action_delay(self.config_action_wait_min,
                         self.config_action_wait_max)

        return True
예제 #22
0
    def save_web_inventory(self):
        web_inventory = os.path.join(
            _base_dir, "web", "inventory-%s.json" % self.bot.config.username)

        with open(web_inventory, "r") as infile:
            ii = json.load(infile)

        ii = [
            x for x in ii
            if not x.get("inventory_item_data", {}).get("pokedex_entry", None)
        ]
        ii = [
            x for x in ii
            if not x.get("inventory_item_data", {}).get("candy", None)
        ]
        ii = [
            x for x in ii
            if not x.get("inventory_item_data", {}).get("item", None)
        ]
        ii = [
            x for x in ii
            if not x.get("inventory_item_data", {}).get("pokemon_data", None)
        ]

        for pokedex in inventory.pokedex().all():
            ii.append({"inventory_item_data": {"pokedex_entry": pokedex}})

        for family_id, candy in inventory.candies()._data.items():
            ii.append({
                "inventory_item_data": {
                    "candy": {
                        "family_id": family_id,
                        "candy": candy.quantity
                    }
                }
            })

        for item_id, item in inventory.items()._data.items():
            ii.append({
                "inventory_item_data": {
                    "item": {
                        "item_id": item_id,
                        "count": item.count
                    }
                }
            })

        for pokemon in inventory.pokemons().all():
            ii.append({"inventory_item_data": {"pokemon_data": pokemon._data}})

        with open(web_inventory, "w") as outfile:
            json.dump(ii, outfile)
예제 #23
0
    def get_nearby_pokemons(self):
        radius = self.config_max_distance

        pokemons = [p for p in self.bot.cell["nearby_pokemons"] if self.get_distance(self.bot.start_position, p) <= radius]

        for pokemon in pokemons:
            pokemon["distance"] = self.get_distance(self.bot.position, p)
            pokemon["name"] = inventory.pokemons().name_for(pokemon["pokemon_id"])
            pokemon["candies"] = inventory.candies().get(pokemon["pokemon_id"]).quantity

        pokemons.sort(key=lambda p: p["distance"])

        return pokemons
예제 #24
0
    def _pokemon_matches_config(self, config, pokemon, default_logic='and'):
        pokemon_config = config.get(pokemon.name, config.get('any'))

        if not pokemon_config:
            return False

        catch_results = {
            'ncp': False,
            'cp': False,
            'iv': False,
        }

        candies = inventory.candies().get(pokemon.pokemon_id).quantity
        threshold = pokemon_config.get('candy_threshold', -1)
        if (threshold > 0 and candies >= threshold):
            self.emit_event(
                'ignore_candy_above_thresold',
                level='info',
                formatted=
                'Amount of candies for {name} is {amount}, greater than threshold {threshold}',
                data={
                    'name': pokemon.name,
                    'amount': candies,
                    'threshold': threshold
                })
            return False

        if pokemon_config.get('never_catch', False):
            return False

        if pokemon_config.get('always_catch', False):
            return True

        catch_ncp = pokemon_config.get('catch_above_ncp', 0.8)
        if pokemon.cp_percent > catch_ncp:
            catch_results['ncp'] = True

        catch_cp = pokemon_config.get('catch_above_cp', 1200)
        if pokemon.cp > catch_cp:
            catch_results['cp'] = True

        catch_iv = pokemon_config.get('catch_above_iv', 0.8)
        if pokemon.iv > catch_iv:
            catch_results['iv'] = True

        # check if encountered pokemon is our locked pokemon
        if self.bot.capture_locked and self.bot.capture_locked != pokemon.pokemon_id:
            return False

        return LOGIC_TO_FUNCTION[pokemon_config.get(
            'logic', default_logic)](*catch_results.values())
예제 #25
0
    def _execute_pokemon_evolve(self, pokemon, cache):
        if pokemon.name in cache:
            return False

        response_dict = self.api.evolve_pokemon(pokemon_id=pokemon.id)
        if response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('result', 0) == 1:
            self.emit_event(
                'pokemon_evolved',
                formatted="Successfully evolved {pokemon} with CP {cp} and IV {iv}!",
                data={
                    'pokemon': pokemon.name,
                    'iv': pokemon.iv,
                    'cp': pokemon.cp
                }
            )
            inventory.candies().get(pokemon.pokemon_id).consume(pokemon.evolution_cost)
            sleep(self.evolve_speed)
            return True
        else:
            # cache pokemons we can't evolve. Less server calls
            cache[pokemon.name] = 1
            sleep(0.7)
            return False
예제 #26
0
    def upgrade_pokemon(self, pokemon):
        upgrade_level = min(self.config_upgrade_level, inventory.player().level + 1.5, 40)
        candy = inventory.candies().get(pokemon.pokemon_id)

        for i in range(int(pokemon.level * 2), int(upgrade_level * 2)):
            upgrade_cost = self.pokemon_upgrade_cost[i - 2]
            upgrade_candy_cost = upgrade_cost[0]
            upgrade_stardust_cost = upgrade_cost[1]

            if self.config_upgrade and (not self.bot.config.test):
                request = self.bot.api.create_request()
                request.upgrade_pokemon(pokemon_id=pokemon.unique_id)
                response_dict = request.call()
            else:
                response_dict = {"responses": {"UPGRADE_POKEMON": {"result": SUCCESS}}}

            if not response_dict:
                return False

            result = response_dict.get("responses", {}).get("UPGRADE_POKEMON", {}).get("result", 0)

            if result != SUCCESS:
                return False

            upgrade = response_dict.get("responses", {}).get("UPGRADE_POKEMON", {}).get("upgraded_pokemon", {})

            if self.config_upgrade and (not self.bot.config.test):
                candy.consume(upgrade_candy_cost)
                self.bot.stardust -= upgrade_stardust_cost

            new_pokemon = inventory.Pokemon(upgrade)
            self.emit_event("pokemon_upgraded",
                            formatted="Upgraded {pokemon} [IV {iv}] [CP {cp} -> {new_cp}] [{candy} candies] [{stardust} stardust]",
                            data={"pokemon": pokemon.name,
                                  "iv": pokemon.iv,
                                  "cp": pokemon.cp,
                                  "new_cp": new_pokemon.cp,
                                  "candy": candy.quantity,
                                  "stardust": self.bot.stardust})

            if self.config_upgrade and (not self.bot.config.test):
                inventory.pokemons().remove(pokemon.unique_id)

                new_pokemon = inventory.Pokemon(upgrade)
                inventory.pokemons().add(new_pokemon)
                pokemon = new_pokemon

                action_delay(self.config_action_wait_min, self.config_action_wait_max)

        return True
    def _pokemon_matches_config(self, config, pokemon, default_logic='and'):
        pokemon_config = config.get(pokemon.name, config.get('any'))

        if not pokemon_config:
            return False

        catch_results = {
            'ncp': False,
            'cp': False,
            'iv': False,
        }

        candies = inventory.candies().get(pokemon.pokemon_id).quantity
        threshold = pokemon_config.get('candy_threshold', -1)
        if (threshold > 0 and candies >= threshold):
            self.emit_event(
                'ignore_candy_above_thresold',
                level='info',
                formatted='Amount of candies for {name} is {amount}, greater than threshold {threshold}',
                data={
                    'name': pokemon.name,
                    'amount': candies,
                    'threshold': threshold
                }
            )
            return False

        if pokemon_config.get('never_catch', False):
            return False

        if pokemon_config.get('always_catch', False):
            return True

        catch_ncp = pokemon_config.get('catch_above_ncp', 0.8)
        if pokemon.cp_percent > catch_ncp:
            catch_results['ncp'] = True

        catch_cp = pokemon_config.get('catch_above_cp', 1200)
        if pokemon.cp > catch_cp:
            catch_results['cp'] = True

        catch_iv = pokemon_config.get('catch_above_iv', 0.8)
        if pokemon.iv > catch_iv:
            catch_results['iv'] = True

        # check if encountered pokemon is our locked pokemon
        if self.bot.capture_locked and self.bot.capture_locked != pokemon.pokemon_id:
            return False

        return LOGIC_TO_FUNCTION[pokemon_config.get('logic', default_logic)](*catch_results.values())
예제 #28
0
    def evolve_pokemon(self, pokemon):
        if self.config_evolve and (not self.bot.config.test):
            response_dict = self.bot.api.evolve_pokemon(pokemon_id=pokemon.id)
        else:
            response_dict = {"responses": {"EVOLVE_POKEMON": {"result": 1}}}

        if not response_dict:
            return False

        result = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("result", 0)

        if result != SUCCESS:
            return False

        xp = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("experience_awarded", 0)
        candy = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("candy_awarded", 0)
        evolution = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("evolved_pokemon_data", {})

        self.emit_event("pokemon_evolved",
                        formatted="Evolved {pokemon} [IV {iv}] [CP {cp}] [NCP {ncp}] [DPS {dps}] [+{xp} xp]",
                        data={"pokemon": pokemon.name,
                              "iv": pokemon.iv,
                              "cp": pokemon.cp,
                              "ncp": round(pokemon.ncp, 2),
                              "dps": round(pokemon.dps, 2),
                              "xp": xp})

        if self.config_evolve and (not self.bot.config.test):
            inventory.candies().get(pokemon.pokemon_id).consume(pokemon.evolution_cost - candy)
            inventory.pokemons().remove(pokemon.id)

            new_pokemon = inventory.Pokemon(evolution)
            inventory.pokemons().add(new_pokemon)

            sleep(self.config_evolve_time)

        return True
예제 #29
0
    def get_nearby_pokemons(self):
        radius = self.config_max_distance

        pokemons = [p for p in self.bot.cell["nearby_pokemons"] if self.get_distance(self.bot.start_position, p) <= radius]

        for pokemon in pokemons:
            pokemon["distance"] = self.get_distance(self.bot.position, pokemon)
            pokemon["name"] = inventory.pokemons().name_for(pokemon["pokemon_id"])
            pokemon["candies"] = inventory.candies().get(pokemon["pokemon_id"]).quantity
            # Pokemon also has a fort_id of the PokeStop the Pokemon is hiding at.
            # We should set our first destination at that Pokestop.

        pokemons.sort(key=lambda p: p["distance"])

        return pokemons
예제 #30
0
    def get_worth_pokemons(self, pokemons):
        if self.config_hunt_all:
            worth_pokemons = pokemons
        else:
            worth_pokemons = []

            if self.config_hunt_vip:
                worth_pokemons += [p for p in pokemons if p["name"] in self.bot.config.vips]

            if self.config_hunt_pokedex:
                worth_pokemons += [p for p in pokemons if (p not in worth_pokemons) and self._is_needed_pokedex(p)]

        worth_pokemons.sort(key=lambda p: inventory.candies().get(p["pokemon_id"]).quantity)

        return worth_pokemons
예제 #31
0
    def get_worth_pokemons(self, pokemons):
        if self.config_hunt_all:
            worth_pokemons = pokemons
        else:
            worth_pokemons = []

            if self.config_hunt_vip:
                worth_pokemons += [p for p in pokemons if p["name"] in self.bot.config.vips]

            if self.config_hunt_pokedex:
                worth_pokemons += [p for p in pokemons if (p not in worth_pokemons) and any(not inventory.pokedex().seen(fid) for fid in self.get_family_ids(p))]

        worth_pokemons.sort(key=lambda p: inventory.candies().get(p["pokemon_id"]).quantity)

        return worth_pokemons
예제 #32
0
    def get_nearby_pokemons(self):
        radius = self.config_max_distance

        pokemons = [p for p in self.bot.cell["nearby_pokemons"] if self.get_distance(self.bot.start_position, p) <= radius]

        if 'wild_pokemons' in self.bot.cell:
            for pokemon in self.bot.cell['wild_pokemons']:
                if pokemon['encounter_id'] in map(lambda pokemon: pokemon['encounter_id'], pokemons):
                    # Already added this Pokemon
                    continue
                if self.get_distance(self.bot.start_position, pokemon) <= radius:
                    pokemons.append(pokemon)
        
        if 'catchable_pokemons' in self.bot.cell:
            for pokemon in self.bot.cell['catchable_pokemons']:
                if pokemon['encounter_id'] in map(lambda pokemon: pokemon['encounter_id'], pokemons):
                    # Already added this Pokemon
                    continue
                if self.get_distance(self.bot.start_position, pokemon) <= radius:
                    pokemons.append(pokemon)

        for pokemon in pokemons:
            if "pokemon_data" in pokemon:
                pokemon["pokemon_id"] = pokemon["pokemon_data"]["pokemon_id"]
                pokemon["name"] = inventory.pokemons().name_for(pokemon["pokemon_id"])

            if "name" not in pokemon and "pokemon_id" not in pokemon:
                self.logger.warning("Strange result? %s" % pokemon)
                # Skip this one!
                continue

            pokemon["distance"] = self.get_distance(self.bot.position, pokemon)
            
            if "name" not in pokemon:
                pokemon["name"] = inventory.pokemons().name_for(pokemon["pokemon_id"])
            if "pokemon_id" not in pokemon:
                pokemon["pokemon_id"] = inventory.pokemons().id_for(pokemon["name"])

            pokemon["candies"] = inventory.candies().get(pokemon["pokemon_id"]).quantity
            # Pokemon also has a fort_id of the PokeStop the Pokemon is hiding at.
            # We should set our first destination at that Pokestop.

        pokemons.sort(key=lambda p: p["distance"])

        return pokemons
예제 #33
0
    def get_nearby_pokemons(self):
        radius = self.config_max_distance

        pokemons = [
            p for p in self.bot.cell["nearby_pokemons"]
            if self.get_distance(self.bot.start_position, p) <= radius
        ]

        for pokemon in pokemons:
            pokemon["distance"] = self.get_distance(self.bot.position, p)
            pokemon["name"] = inventory.pokemons().name_for(
                pokemon["pokemon_id"])
            pokemon["candies"] = inventory.candies().get(
                pokemon["pokemon_id"]).quantity

        pokemons.sort(key=lambda p: p["distance"])

        return pokemons
예제 #34
0
    def showtop(self, chatid, num, order):
        if not num.isnumeric():
            num = 10
        else:
            num = int(num)

        if order not in ["cp", "iv"]:
            order = "iv"

        pkmns = sorted(inventory.pokemons().all(),
                       key=lambda p: getattr(p, order),
                       reverse=True)[:num]

        outMsg = "\n".join([
            "*{}* (_CP:_ {}) (_IV:_ {}) (Candy:{})".format(
                p.name, p.cp, p.iv,
                inventory.candies().get(p.pokemon_id).quantity) for p in pkmns
        ])
        self.sendMessage(chat_id=chatid, parse_mode='Markdown', text=outMsg)
예제 #35
0
    def get_top(self, num, order):
        if not num.isnumeric():
            num = 10
        else:
            num = int(num)

        if order not in ["cp", "iv", "dated"]:
            order = "iv"
        pkmns = sorted(inventory.pokemons().all(),
                       key=lambda p: getattr(p, order),
                       reverse=True)[:num]
        res = []
        for p in pkmns:
            res.append([
                p.name, p.cp, p.iv,
                inventory.candies().get(p.pokemon_id).quantity
            ])

        return res
예제 #36
0
    def get_top(self, num, order):
        if not num.isnumeric():
            num = 10
        else:
            num = int(num)

        if order not in ["cp", "iv", "dated"]:
            order = "iv"
        pkmns = sorted(inventory.pokemons().all(), key=lambda p: getattr(p, order), reverse=True)[:num]
        res = []
        for p in pkmns:
            res.append([
                p.name,
                p.cp,
                p.iv,
                inventory.candies().get(p.pokemon_id).quantity
            ])

        return res
예제 #37
0
    def work(self):
        if not self._should_run():
            return

        filtered_list, filtered_dict = self._sort_and_filter()

        pokemon_to_be_evolved = 0
        pokemon_ids = []
        for pokemon in filtered_list:
            if pokemon.pokemon_id not in pokemon_ids:
                pokemon_ids.append(pokemon.pokemon_id)
                candy = inventory.candies().get(pokemon.pokemon_id)
                pokemon_to_be_evolved = pokemon_to_be_evolved + min(candy.quantity / (pokemon.evolution_cost - 1), filtered_dict[pokemon.pokemon_id])

        if pokemon_to_be_evolved >= self.min_pokemon_to_be_evolved:
            if self.use_lucky_egg:
                self._use_lucky_egg()
            cache = {}
            for pokemon in filtered_list:
                if pokemon.can_evolve_now():
                    self._execute_pokemon_evolve(pokemon, cache)
예제 #38
0
    def get_worth_pokemons(self, pokemons):
        if self.config_hunt_all:
            worth_pokemons = pokemons
        else:
            worth_pokemons = []

            if self.config_hunt_vip:
                worth_pokemons += [
                    p for p in pokemons if p["name"] in self.bot.config.vips
                ]

            if self.config_hunt_pokedex:
                worth_pokemons += [
                    p for p in pokemons
                    if (p not in worth_pokemons) and self._is_needed_pokedex(p)
                ]

        worth_pokemons.sort(
            key=lambda p: inventory.candies().get(p["pokemon_id"]).quantity)

        return worth_pokemons
예제 #39
0
    def _is_needed_pokedex(self, pokemon):
        candies = inventory.candies().get(pokemon["pokemon_id"]).quantity
        if candies > 150:
            # We have enough candies, pass on hunting this Pokemon
            return False

        # get family ids, gets ALL ids, also for previous evo!
        # We could see a Ivysaur on the map, and need a Bulbasaur
        # Then we have no need for a Ivysaur. If we see a Bulbasaur and need
        # a Ivysaur, then we DO need this pokemon.
        got_current_evo = False
        ids = []
        for fid in self.get_family_ids(pokemon):
            if got_current_evo:
                ids += [fid]
            else:
                if fid == pokemon["pokemon_id"]:
                    ids += [fid]
                    got_current_evo = True
        # Check if we need this, or a next EVO in the Pokedex
        if any(not inventory.pokedex().seen(fid) for fid in ids):
            return True
예제 #40
0
    def _is_needed_pokedex(self, pokemon):
        candies = inventory.candies().get(pokemon["pokemon_id"]).quantity
        if candies > 150:
            # We have enough candies, pass on hunting this Pokemon
            return False

        # get family ids, gets ALL ids, also for previous evo!
        # We could see a Ivysaur on the map, and need a Bulbasaur
        # Then we have no need for a Ivysaur. If we see a Bulbasaur and need
        # a Ivysaur, then we DO need this pokemon.
        got_current_evo = False
        ids = []
        for fid in self.get_family_ids(pokemon):
            if got_current_evo:
                ids += [fid]
            else:
                if fid == pokemon["pokemon_id"]:
                    ids += [fid]
                    got_current_evo = True
        # Check if we need this, or a next EVO in the Pokedex
        if any(not inventory.pokedex().seen(fid) for fid in ids):
            return True
예제 #41
0
    def get_worth_pokemons(self, pokemons, closest_first=False):
        if self.config_hunt_all:
            worth_pokemons = pokemons
        else:
            worth_pokemons = []

            # worth_pokemons += [p for p in pokemons if not inventory.pokedex().seen(p["pokemon_id"])]

            if self.config_hunt_vip:
                worth_pokemons += [p for p in pokemons if p["name"] in self.bot.config.vips]

            if self.config_target_family_of_vip or self.config_treat_family_of_vip_as_vip:
                worth_pokemons += [p for p in pokemons if (p not in worth_pokemons) and self._is_family_of_vip(p)]

            if self.config_hunt_pokedex:
                worth_pokemons += [p for p in pokemons if (p not in worth_pokemons) and self._is_needed_pokedex(p)]

        if closest_first:
            worth_pokemons.sort(key=lambda p: p["distance"])
        else:
            worth_pokemons.sort(key=lambda p: inventory.candies().get(p["pokemon_id"]).quantity)

        return worth_pokemons
예제 #42
0
    def transfer_pokemon(self, pokemon):
        if self.config_transfer and (not self.bot.config.test):
            response_dict = self.bot.api.release_pokemon(pokemon_id=pokemon.unique_id)
        else:
            response_dict = {"responses": {"RELEASE_POKEMON": {"candy_awarded": 0}}}

        if not response_dict:
            return False

        candy_awarded = response_dict.get("responses", {}).get("RELEASE_POKEMON", {}).get("candy_awarded", 0)
        candy = inventory.candies().get(pokemon.pokemon_id)

        if self.config_transfer and (not self.bot.config.test):
            candy.add(candy_awarded)

        self.emit_event("pokemon_release",
                        formatted="Exchanged {pokemon} [IV {iv}] [CP {cp}] [{candy} candies]",
                        data={"pokemon": pokemon.name,
                              "iv": pokemon.iv,
                              "cp": pokemon.cp,
                              "candy": candy.quantity})

        if self.config_transfer and (not self.bot.config.test):
            inventory.pokemons().remove(pokemon.unique_id)

            with self.bot.database as db:
                cursor = db.cursor()
                cursor.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='transfer_log'")

                db_result = cursor.fetchone()

                if db_result[0] == 1:
                    db.execute("INSERT INTO transfer_log (pokemon, iv, cp) VALUES (?, ?, ?)", (pokemon.name, pokemon.iv, pokemon.cp))

            action_delay(self.config_action_wait_min, self.config_action_wait_max)

        return True
예제 #43
0
    def transfer_pokemon(self, pokemons):
        error_codes = {
            0: 'UNSET',
            1: 'SUCCESS',
            2: 'POKEMON_DEPLOYED',
            3: 'FAILED',
            4: 'ERROR_POKEMON_IS_EGG',
            5: 'ERROR_POKEMON_IS_BUDDY'
        }
        if self.config_bulktransfer_enabled and len(pokemons) > 1:
            while len(pokemons) > 0:
                action_delay(self.config_action_wait_min, self.config_action_wait_max)
                pokemon_ids = []
                count = 0
                transfered = []
                while len(pokemons) > 0 and count < self.config_max_bulktransfer:
                    pokemon = pokemons.pop()
                    transfered.append(pokemon)
                    pokemon_ids.append(pokemon.unique_id)
                    count = count + 1
                try:
                    if self.config_transfer:
                        response_dict = self.bot.api.release_pokemon(pokemon_ids=pokemon_ids)
                        result = response_dict['responses']['RELEASE_POKEMON']['result']
                        if result != 1:
                            self.logger.error(u'Error while transfer pokemon: {}'.format(error_codes[result]))
                            return False
                except Exception:
                    return False
                
                for pokemon in transfered:
                    candy = inventory.candies().get(pokemon.pokemon_id)

                    if self.config_transfer and (not self.bot.config.test):
                        candy.add(1)
                        
                    self.emit_event("pokemon_release",
                                    formatted="Exchanged {pokemon} [IV {iv}] [CP {cp}] [{candy} candies]",
                                    data={"pokemon": pokemon.name,
                                          "iv": pokemon.iv,
                                          "cp": pokemon.cp,
                                          "candy": candy.quantity})

                    if self.config_transfer:
                        inventory.pokemons().remove(pokemon.unique_id)

                        with self.bot.database as db:
                            cursor = db.cursor()
                            cursor.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='transfer_log'")

                            db_result = cursor.fetchone()

                            if db_result[0] == 1:
                                db.execute("INSERT INTO transfer_log (pokemon, iv, cp) VALUES (?, ?, ?)", (pokemon.name, pokemon.iv, pokemon.cp))

        else:
            for pokemon in pokemons:
                if self.config_transfer and (not self.bot.config.test):
                    response_dict = self.bot.api.release_pokemon(pokemon_id=pokemon.unique_id)
                else:
                    response_dict = {"responses": {"RELEASE_POKEMON": {"candy_awarded": 0}}}

                if not response_dict:
                    return False

                candy_awarded = response_dict.get("responses", {}).get("RELEASE_POKEMON", {}).get("candy_awarded", 0)
                candy = inventory.candies().get(pokemon.pokemon_id)

                if self.config_transfer and (not self.bot.config.test):
                    candy.add(candy_awarded)

                self.emit_event("pokemon_release",
                                formatted="Exchanged {pokemon} [IV {iv}] [CP {cp}] [{candy} candies]",
                                data={"pokemon": pokemon.name,
                                      "iv": pokemon.iv,
                                      "cp": pokemon.cp,
                                      "candy": candy.quantity})

                if self.config_transfer and (not self.bot.config.test):
                    inventory.pokemons().remove(pokemon.unique_id)

                    with self.bot.database as db:
                        cursor = db.cursor()
                        cursor.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='transfer_log'")

                        db_result = cursor.fetchone()

                        if db_result[0] == 1:
                            db.execute("INSERT INTO transfer_log (pokemon, iv, cp) VALUES (?, ?, ?)", (pokemon.name, pokemon.iv, pokemon.cp))

                    action_delay(self.config_action_wait_min, self.config_action_wait_max)

        return True
예제 #44
0
    def get_evolution_plan(self, family_id, family_list, keep, try_evolve, try_upgrade):
        candies = inventory.candies().get(family_id).quantity
        family_name = inventory.Pokemons().name_for(family_id)

        # All the rest is crap, for now
        crap = list(family_list)
        crap = [p for p in crap if p not in keep]
        crap = [p for p in crap if not p.in_fort and not p.is_favorite and not (p.unique_id == self.buddyid)]
        crap.sort(key=lambda p: (p.iv, p.cp), reverse=True)

        # We will gain a candy whether we choose to transfer or evolve these Pokemon
        candies += len(crap)

        evolve = []

        for pokemon in try_evolve:
            pokemon_id = pokemon.pokemon_id
            needed_evolution_item = inventory.pokemons().evolution_item_for(pokemon_id)
            if needed_evolution_item is not None:
                # We need a special Item to evolve this Pokemon!
                item = inventory.items().get(needed_evolution_item)
                needed = inventory.pokemons().evolution_items_needed_for(pokemon_id)
                if item.count < needed:
                    self.logger.info("To evolve a {} we need {} of {}. We have {}".format(pokemon.name, needed, item.name, item.count))
                    continue

            if self.config_evolve_to_final:
                pokemon_id = pokemon.pokemon_id
                while inventory.pokemons().has_next_evolution(pokemon_id):
                    candies -= inventory.pokemons().evolution_cost_for(pokemon_id)
                    pokemon_id = inventory.pokemons().next_evolution_ids_for(pokemon_id)[0]
            else:
                candies -= pokemon.evolution_cost

            if candies < 0:
                continue

            if self.config_evolve_to_final:
                pokemon_id = pokemon.pokemon_id

                while inventory.pokemons().has_next_evolution(pokemon_id):
                    candies += 1
                    evolve.append(pokemon)
                    pokemon_id = inventory.pokemons().next_evolution_ids_for(pokemon_id)[0]
            else:
                candies += 1
                evolve.append(pokemon)

        upgrade = []
        upgrade_level = min(self.config_upgrade_level, inventory.player().level + 1.5, 40)

        for pokemon in try_upgrade:
            if pokemon.level >= upgrade_level:
                continue

            full_upgrade_candy_cost = 0
            full_upgrade_stardust_cost = 0

            for i in range(int(pokemon.level * 2), int(upgrade_level * 2)):
                upgrade_cost = self.pokemon_upgrade_cost[i - 2]
                full_upgrade_candy_cost += upgrade_cost[0]
                full_upgrade_stardust_cost += upgrade_cost[1]

            candies -= full_upgrade_candy_cost
            self.ongoing_stardust_count -= full_upgrade_stardust_cost

            if (candies < 0) or (self.ongoing_stardust_count < 0):
                continue

            upgrade.append(pokemon)

        if (not self.config_evolve_for_xp) or (family_name in self.config_evolve_for_xp_blacklist):
            xp = []
            transfer = crap
        elif self.config_evolve_for_xp_whitelist and (family_name not in self.config_evolve_for_xp_whitelist):
            xp = []
            transfer = crap
        else:
            # Compute how many crap we should keep if we want to batch evolve them for xp
            lowest_evolution_cost = inventory.pokemons().evolution_cost_for(family_id)

            # transfer + keep_for_xp = len(crap)
            # leftover_candies = candies - len(crap) + transfer * 1
            # keep_for_xp = (leftover_candies - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - len(crap) + transfer - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - keep_for_xp - 1) / (lowest_evolution_cost - 1)

            if (candies > 0) and lowest_evolution_cost:
                keep_for_xp = int((candies - 1) / lowest_evolution_cost)
            else:
                keep_for_xp = 0

            xp = [p for p in crap if p.has_next_evolution() and p.evolution_cost == lowest_evolution_cost][:keep_for_xp]
            transfer = [p for p in crap if p not in xp]

        return (transfer, evolve, upgrade, xp)
예제 #45
0
    def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False):
        # settings that may be exposed at some point
        """

        :type pokemon: Pokemon
        """
        berry_id = ITEM_RAZZBERRY
        maximum_ball = ITEM_ULTRABALL if is_vip else ITEM_GREATBALL
        ideal_catch_rate_before_throw = self.vip_berry_threshold if is_vip else self.berry_threshold

        berry_count = self.inventory.get(ITEM_RAZZBERRY).count
        ball_count = {}
        for ball_id in [ITEM_POKEBALL, ITEM_GREATBALL, ITEM_ULTRABALL]:
            ball_count[ball_id] = self.inventory.get(ball_id).count

        # use `min_ultraball_to_keep` from config if is not None
        min_ultraball_to_keep = ball_count[ITEM_ULTRABALL]
        if self.min_ultraball_to_keep is not None:
            if self.min_ultraball_to_keep >= 0 and self.min_ultraball_to_keep < min_ultraball_to_keep:
                min_ultraball_to_keep = self.min_ultraball_to_keep

        used_berry = False
        while True:

            # find lowest available ball
            current_ball = ITEM_POKEBALL
            while ball_count[current_ball] == 0 and current_ball < maximum_ball:
                current_ball += 1
            if ball_count[current_ball] == 0:
                self.emit_event('no_pokeballs', formatted='No usable pokeballs found!')

                # use untraball if there is no other balls with constraint to `min_ultraball_to_keep`
                if maximum_ball != ITEM_ULTRABALL and ball_count[ITEM_ULTRABALL] > min_ultraball_to_keep:
                    maximum_ball = ITEM_ULTRABALL
                    continue
                else:
                    return WorkerResult.ERROR

            # check future ball count
            num_next_balls = 0
            next_ball = current_ball
            while next_ball < maximum_ball:
                next_ball += 1
                num_next_balls += ball_count[next_ball]

            # check if we've got berries to spare
            berries_to_spare = berry_count > 0 if is_vip else berry_count > num_next_balls + 30

            # use a berry if we are under our ideal rate and have berries to spare
            changed_ball = False
            if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and berries_to_spare and not used_berry:
                new_catch_rate_by_ball = self._use_berry(berry_id, berry_count, encounter_id, catch_rate_by_ball, current_ball)
                if new_catch_rate_by_ball != catch_rate_by_ball:
                    catch_rate_by_ball = new_catch_rate_by_ball
                    self.inventory.get(ITEM_RAZZBERRY).remove(1)
                    berry_count -= 1
                    used_berry = True

            # pick the best ball to catch with
            best_ball = current_ball
            while best_ball < maximum_ball:
                best_ball += 1
                if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and ball_count[best_ball] > 0:
                    # if current ball chance to catch is under our ideal rate, and player has better ball - then use it
                    current_ball = best_ball
                    changed_ball = True

            # if the rate is still low and we didn't throw a berry before, throw one
            if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and berry_count > 0 and not used_berry:
                new_catch_rate_by_ball = self._use_berry(berry_id, berry_count, encounter_id, catch_rate_by_ball, current_ball)
                if new_catch_rate_by_ball != catch_rate_by_ball:
                    catch_rate_by_ball = new_catch_rate_by_ball
                    self.inventory.get(ITEM_RAZZBERRY).remove(1)
                    berry_count -= 1
                    used_berry = True

            # If we change ball then wait to simulate user selecting it
            if changed_ball:
                action_delay(self.catchsim_changeball_wait_min, self.catchsim_changeball_wait_max)

            # Randomize the quality of the throw
            # Default structure
            throw_parameters = {'normalized_reticle_size': 1.950,
                                'spin_modifier': 1.0,
                                'normalized_hit_position': 1.0,
                                'throw_type_label': 'Excellent'}
            self.generate_spin_parameter(throw_parameters)
            self.generate_throw_quality_parameters(throw_parameters)

            # try to catch pokemon!
            ball_count[current_ball] -= 1
            self.inventory.get(current_ball).remove(1)
            # Take some time to throw the ball from config options
            action_delay(self.catchsim_catch_wait_min, self.catchsim_catch_wait_max)
            self.emit_event(
                'threw_pokeball',
                formatted='{throw_type}{spin_label} throw! Used {ball_name}, with chance {success_percentage} ({count_left} left)',
                data={
                    'throw_type': throw_parameters['throw_type_label'],
                    'spin_label': throw_parameters['spin_label'],
                    'ball_name': self.inventory.get(current_ball).name,
                    'success_percentage': self._pct(catch_rate_by_ball[current_ball]),
                    'count_left': ball_count[current_ball]
                }
            )

            hit_pokemon = 1
            if random() >= self.catch_throw_parameters_hit_rate and not is_vip:
                hit_pokemon = 0

            response_dict = self.api.catch_pokemon(
                encounter_id=encounter_id,
                pokeball=current_ball,
                normalized_reticle_size=throw_parameters['normalized_reticle_size'],
                spawn_point_id=self.spawn_point_guid,
                hit_pokemon=hit_pokemon,
                spin_modifier=throw_parameters['spin_modifier'],
                normalized_hit_position=throw_parameters['normalized_hit_position']
            )

            try:
                catch_pokemon_status = response_dict['responses']['CATCH_POKEMON']['status']
            except KeyError:
                break

            # retry failed pokemon
            if catch_pokemon_status == CATCH_STATUS_FAILED:
                self.emit_event(
                    'pokemon_capture_failed',
                    formatted='{pokemon} capture failed.. trying again!',
                    data={'pokemon': pokemon.name}
                )
                used_berry = False

                # sleep according to flee_count and flee_duration config settings
                # randomly chooses a number of times to 'show' wobble animation between 1 and flee_count
                # multiplies this by flee_duration to get total sleep
                if self.catchsim_flee_count:
                    sleep((randrange(self.catchsim_flee_count)+1) * self.catchsim_flee_duration)

                continue

            # abandon if pokemon vanished
            elif catch_pokemon_status == CATCH_STATUS_VANISHED:
                self.emit_event(
                    'pokemon_vanished',
                    formatted='{pokemon} vanished!',
                    data={
                        'pokemon': pokemon.name,
                        'encounter_id': self.pokemon['encounter_id'],
                        'latitude': self.pokemon['latitude'],
                        'longitude': self.pokemon['longitude'],
                        'pokemon_id': pokemon.pokemon_id
                    }
                )
                if self._pct(catch_rate_by_ball[current_ball]) == 100:
                    self.bot.softban = True

            # pokemon caught!
            elif catch_pokemon_status == CATCH_STATUS_SUCCESS:
                pokemon.unique_id = response_dict['responses']['CATCH_POKEMON']['captured_pokemon_id']
                self.bot.metrics.captured_pokemon(pokemon.name, pokemon.cp, pokemon.iv_display, pokemon.iv)

                try:
                    inventory.pokemons().add(pokemon)
                    self.emit_event(
                        'pokemon_caught',
                        formatted='Captured {pokemon}! [CP {cp}] [NCP {ncp}] [Potential {iv}] [{iv_display}] [+{exp} exp]',
                        data={
                            'pokemon': pokemon.name,
                            'ncp': round(pokemon.cp_percent, 2),
                            'cp': pokemon.cp,
                            'iv': pokemon.iv,
                            'iv_display': pokemon.iv_display,
                            'exp': sum(response_dict['responses']['CATCH_POKEMON']['capture_award']['xp']),
                            'encounter_id': self.pokemon['encounter_id'],
                            'latitude': self.pokemon['latitude'],
                            'longitude': self.pokemon['longitude'],
                            'pokemon_id': pokemon.pokemon_id
                        }

                    )
                    with self.bot.database as conn:
                        c = conn.cursor()
                        c.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='catch_log'")
                    result = c.fetchone()

                    while True:
                        if result[0] == 1:
                            conn.execute('''INSERT INTO catch_log (pokemon, cp, iv, encounter_id, pokemon_id) VALUES (?, ?, ?, ?, ?)''', (pokemon.name, pokemon.cp, pokemon.iv, str(encounter_id), pokemon.pokemon_id))
                        break
                    else:
                        self.emit_event(
                            'catch_log',
                            sender=self,
                            level='info',
                            formatted="catch_log table not found, skipping log"
                        )
                        break
                    user_data_caught = os.path.join(_base_dir, 'data', 'caught-%s.json' % self.bot.config.username)
                    with open(user_data_caught, 'ab') as outfile:
                        outfile.write(str(datetime.now()))
                        json.dump({
                            'pokemon': pokemon.name,
                            'cp': pokemon.cp,
                            'iv': pokemon.iv,
                            'encounter_id': self.pokemon['encounter_id'],
                            'pokemon_id': pokemon.pokemon_id
                        }, outfile)
                        outfile.write('\n')

                except IOError as e:
                    self.logger.info('[x] Error while opening location file: %s' % e)

                candy = inventory.candies().get(pokemon.pokemon_id)
                candy.add(self.get_candy_gained_count(response_dict))

                self.emit_event(
                    'gained_candy',
                    formatted='You now have {quantity} {type} candy!',
                    data = {
                        'quantity': candy.quantity,
                        'type': candy.type,
                    },
                )

                self.bot.softban = False

            elif catch_pokemon_status == CATCH_STATUS_MISSED:
                self.emit_event(
                    'pokemon_capture_failed',
                    formatted='Pokeball thrown to {pokemon} missed.. trying again!',
                    data={'pokemon': pokemon.name}
                )
                # Take some time to throw the ball from config options
                action_delay(self.catchsim_catch_wait_min, self.catchsim_catch_wait_max)
                continue

            break
예제 #46
0
    def _pokemon_matches_config(self, config, pokemon, default_logic='and'):
        pokemon_config = config.get(pokemon.name, config.get('any'))

        if not pokemon_config:
            return False


        catch_results = {
            'ncp': False,
            'cp': False,
            'iv': False,
            'fa': True,
            'ca': True
        }

        catch_logic = pokemon_config.get('logic', default_logic)

        candies = inventory.candies().get(pokemon.pokemon_id).quantity
        threshold = pokemon_config.get('candy_threshold', -1)
        if threshold > 0 and candies >= threshold: # Got enough candies
            return False

        if pokemon_config.get('never_catch', False):
            return False

        if pokemon_config.get('always_catch', False):
            return True

        if pokemon_config.get('catch_above_ncp',-1) >= 0:
            if pokemon.cp_percent >= pokemon_config.get('catch_above_ncp'):
                catch_results['ncp'] = True

        if pokemon_config.get('catch_above_cp',-1) >= 0:
            if pokemon.cp >= pokemon_config.get('catch_above_cp'):
                catch_results['cp'] = True
                
        if pokemon_config.get('catch_below_cp',-1) >= 0:
            if pokemon.cp <= pokemon_config.get('catch_below_cp'):
                catch_results['cp'] = True

        if pokemon_config.get('catch_above_iv',-1) >= 0:
            if pokemon.iv > pokemon_config.get('catch_above_iv', pokemon.iv):
                catch_results['iv'] = True

        catch_results['fa'] = ( len(pokemon_config.get('fast_attack', [])) == 0 or unicode(pokemon.fast_attack) in map(lambda x: unicode(x), pokemon_config.get('fast_attack', [])))
        catch_results['ca'] = ( len(pokemon_config.get('charged_attack', [])) == 0 or unicode(pokemon.charged_attack) in map(lambda x: unicode(x), pokemon_config.get('charged_attack', [])))

        self.bot.logger.debug("Our comparison results: FA: {}, CA: {}, CP: {}, NCP: {}, IV: {}".format(catch_results['fa'], catch_results['ca'], catch_results['cp'],  catch_results['ncp'], catch_results['iv']))

        # check if encountered pokemon is our locked pokemon
        if self.bot.capture_locked and self.bot.capture_locked != pokemon.pokemon_id:
            self.bot.logger.debug("Pokemon locked!")
            return False

        # build catch results
        cr = {
            'ncp': False,
            'cp': False,
            'iv': False
        }
        if catch_logic == 'and':
            cr['ncp'] = True,
            cr['cp'] = True,
            cr['iv'] = True
        elif catch_logic == 'andor':
            cr['ncp'] = True,
            cr['cp'] = True
        elif catch_logic == 'orand':
            cr['cp'] = True,
            cr['iv'] = True    
        
        if pokemon_config.get('catch_above_ncp',-1) >= 0: cr['ncp'] = catch_results['ncp']
        if pokemon_config.get('catch_above_cp',-1) >= 0: cr['cp'] = catch_results['cp']
        if pokemon_config.get('catch_below_cp',-1) >= 0: cr['cp'] = catch_results['cp']
        if pokemon_config.get('catch_above_iv',-1) >= 0: cr['iv'] = catch_results['iv']
        
        if DEBUG_ON:
            print "Debug information for match rules..."
            print "catch_results ncp = {}".format(catch_results['ncp'])
            print "catch_results cp = {}".format(catch_results['cp'])
            print "catch_results iv = {}".format(catch_results['iv'])
            print "cr = {}".format(cr)
            print "catch_above_ncp = {}".format(pokemon_config.get('catch_above_ncp'))
            print "catch_above_cp iv = {}".format(pokemon_config.get('catch_above_cp'))
            print "catch_below_cp iv = {}".format(pokemon_config.get('catch_below_cp'))
            print "catch_above_iv iv = {}".format(pokemon_config.get('catch_above_iv'))
            print "Pokemon {}".format(pokemon.name)
            print "pokemon ncp = {}".format(pokemon.cp_percent)
            print "pokemon cp = {}".format(pokemon.cp)
            print "pokemon iv = {}".format(pokemon.iv)
            print "catch logic = {}".format(catch_logic)

        if LOGIC_TO_FUNCTION[catch_logic](*cr.values()):
            return catch_results['fa'] and catch_results['ca']
        else:
            return False
    def get_evolution_plan(self, family_id, family_list, keep, try_evolve, try_upgrade):
        candies = inventory.candies().get(family_id).quantity

        # All the rest is crap, for now
        crap = list(family_list)
        crap = [p for p in crap if p not in keep]
        crap = [p for p in crap if not p.in_fort and not p.is_favorite]
        crap.sort(key=lambda p: (p.iv, p.cp), reverse=True)

        # We will gain a candy whether we choose to transfer or evolve these Pokemon
        candies += len(crap)

        evolve = []

        for pokemon in try_evolve:
            candies -= pokemon.evolution_cost

            if candies < 0:
                continue

            candies += 1
            evolve.append(pokemon)

        upgrade = []
        upgrade_level = min(self.config_upgrade_level, inventory.player().level * 2)

        for pokemon in try_upgrade:
            level = int(pokemon.level * 2) - 1

            if level >= upgrade_level:
                continue

            full_upgrade_candy_cost = 0
            full_upgrade_stardust_cost = 0

            for i in range(level, upgrade_level):
                upgrade_cost = self.pokemon_upgrade_cost[i - 1]
                full_upgrade_candy_cost += upgrade_cost[0]
                full_upgrade_stardust_cost += upgrade_cost[1]

            candies -= full_upgrade_candy_cost
            self.ongoing_stardust_count -= full_upgrade_stardust_cost

            if (candies < 0) or (self.ongoing_stardust_count < 0):
                continue

            upgrade.append(pokemon)

        if self.config_evolve_for_xp:
            # Compute how many crap we should keep if we want to batch evolve them for xp
            lowest_evolution_cost = inventory.pokemons().evolution_cost_for(family_id)

            # transfer + keep_for_xp = len(crap)
            # leftover_candies = candies - len(crap) + transfer * 1
            # keep_for_xp = (leftover_candies - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - len(crap) + transfer - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - keep_for_xp - 1) / (lowest_evolution_cost - 1)

            if (candies > 0) and lowest_evolution_cost:
                keep_for_xp = int((candies - 1) / lowest_evolution_cost)
            else:
                keep_for_xp = 0

            xp = [p for p in crap if p.has_next_evolution() and p.evolution_cost == lowest_evolution_cost][:keep_for_xp]

            # If not much to evolve, better keep the candies
            if len(xp) < math.ceil(self.max_pokemon_storage * 0.02):
                xp = []

            transfer = [p for p in crap if p not in xp]
        else:
            xp = []
            transfer = crap

        return (transfer, evolve, upgrade, xp)
예제 #48
0
    def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False):
        # settings that may be exposed at some point
        berry_id = ITEM_RAZZBERRY
        maximum_ball = ITEM_ULTRABALL if is_vip else ITEM_GREATBALL
        ideal_catch_rate_before_throw = 0.9 if is_vip else 0.35

        berry_count = self.bot.item_inventory_count(berry_id)
        items_stock = self.bot.current_inventory()

        while True:

            # find lowest available ball
            current_ball = ITEM_POKEBALL
            while items_stock[current_ball] == 0 and current_ball < maximum_ball:
                current_ball += 1
            if items_stock[current_ball] == 0:
                self.emit_event('no_pokeballs', formatted='No usable pokeballs found!')
                break

            # check future ball count
            num_next_balls = 0
            next_ball = current_ball
            while next_ball < maximum_ball:
                next_ball += 1
                num_next_balls += items_stock[next_ball]

            # check if we've got berries to spare
            berries_to_spare = berry_count > 0 if is_vip else berry_count > num_next_balls + 30

            # use a berry if we are under our ideal rate and have berries to spare
            used_berry = False
            if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and berries_to_spare:
                catch_rate_by_ball = self._use_berry(berry_id, berry_count, encounter_id, catch_rate_by_ball, current_ball)
                berry_count -= 1
                used_berry = True

            # pick the best ball to catch with
            best_ball = current_ball
            while best_ball < maximum_ball:
                best_ball += 1
                if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and items_stock[best_ball] > 0:
                    # if current ball chance to catch is under our ideal rate, and player has better ball - then use it
                    current_ball = best_ball

            # if the rate is still low and we didn't throw a berry before, throw one
            if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and berry_count > 0 and not used_berry:
                catch_rate_by_ball = self._use_berry(berry_id, berry_count, encounter_id, catch_rate_by_ball, current_ball)
                berry_count -= 1

            # get current pokemon list before catch
            pokemon_before_catch = self._get_current_pokemon_ids()

            # try to catch pokemon!
            items_stock[current_ball] -= 1
            self.emit_event(
                'threw_pokeball',
                formatted='Used {ball_name}, with chance {success_percentage} ({count_left} left)',
                data={
                    'ball_name': self.item_list[str(current_ball)],
                    'success_percentage': self._pct(catch_rate_by_ball[current_ball]),
                    'count_left': items_stock[current_ball]
                }
            )

            reticle_size_parameter = normalized_reticle_size(self.config.catch_randomize_reticle_factor)
            spin_modifier_parameter = spin_modifier(self.config.catch_randomize_spin_factor)

            response_dict = self.api.catch_pokemon(
                encounter_id=encounter_id,
                pokeball=current_ball,
                normalized_reticle_size=reticle_size_parameter,
                spawn_point_id=self.spawn_point_guid,
                hit_pokemon=1,
                spin_modifier=spin_modifier_parameter,
                normalized_hit_position=1
            )

            try:
                catch_pokemon_status = response_dict['responses']['CATCH_POKEMON']['status']
            except KeyError:
                break

            # retry failed pokemon
            if catch_pokemon_status == CATCH_STATUS_FAILED:
                self.emit_event(
                    'pokemon_capture_failed',
                    formatted='{pokemon} capture failed.. trying again!',
                    data={'pokemon': pokemon.name}
                )
                sleep(2)
                continue

            # abandon if pokemon vanished
            elif catch_pokemon_status == CATCH_STATUS_VANISHED:
                self.emit_event(
                    'pokemon_vanished',
                    formatted='{pokemon} vanished!',
                    data={'pokemon': pokemon.name}
                )
                if self._pct(catch_rate_by_ball[current_ball]) == 100:
                    self.bot.softban = True

            # pokemon caught!
            elif catch_pokemon_status == CATCH_STATUS_SUCCESS:
                self.bot.metrics.captured_pokemon(pokemon.name, pokemon.cp, pokemon.iv_display, pokemon.iv)
                self.emit_event(
                    'pokemon_caught',
                    formatted='Captured {pokemon}! [CP {cp}] [Potential {iv}] [{iv_display}] [+{exp} exp]',
                    data={
                        'pokemon': pokemon.name,
                        'cp': pokemon.cp,
                        'iv': pokemon.iv,
                        'iv_display': pokemon.iv_display,
                        'exp': sum(response_dict['responses']['CATCH_POKEMON']['capture_award']['xp'])
                    }
                )

                # We could refresh here too, but adding 3 saves a inventory request
                candy = inventory.candies().get(pokemon.num)
                candy.add(3)
                self.emit_event(
                    'gained_candy',
                    formatted='You now have {quantity} {type} candy!',
                    data = {
                        'quantity': candy.quantity,
                        'type': candy.type,
                    },
                )

                self.bot.softban = False

                # evolve pokemon if necessary
                if self.config.evolve_captured and (self.config.evolve_captured[0] == 'all' or pokemon.name in self.config.evolve_captured):
                    pokemon_after_catch = self._get_current_pokemon_ids()
                    pokemon_to_evolve = list(set(pokemon_after_catch) - set(pokemon_before_catch))

                    if len(pokemon_to_evolve) == 0:
                        break

                    self._do_evolve(pokemon, pokemon_to_evolve[0])

            break
예제 #49
0
    def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False):
        # settings that may be exposed at some point
        """

        :type pokemon: Pokemon
        """
        berry_id = ITEM_RAZZBERRY
        maximum_ball = ITEM_ULTRABALL if is_vip else ITEM_GREATBALL
        ideal_catch_rate_before_throw = 0.9 if is_vip else 0.35

        berry_count = self.inventory.get(ITEM_RAZZBERRY).count
        ball_count = {}
        for ball_id in [ITEM_POKEBALL, ITEM_GREATBALL, ITEM_ULTRABALL]:
            ball_count[ball_id] = self.inventory.get(ball_id).count

        # use `min_ultraball_to_keep` from config if is not None
        min_ultraball_to_keep = ball_count[ITEM_ULTRABALL]
        if self.config.min_ultraball_to_keep is not None:
            if self.config.min_ultraball_to_keep >= 0 and self.config.min_ultraball_to_keep < min_ultraball_to_keep:
                min_ultraball_to_keep = self.config.min_ultraball_to_keep

        while True:

            # find lowest available ball
            current_ball = ITEM_POKEBALL
            while ball_count[current_ball] == 0 and current_ball < maximum_ball:
                current_ball += 1
            if ball_count[current_ball] == 0:
                self.emit_event('no_pokeballs', formatted='No usable pokeballs found!')

                # use untraball if there is no other balls with constraint to `min_ultraball_to_keep`
                if maximum_ball != ITEM_ULTRABALL and ball_count[ITEM_ULTRABALL] > min_ultraball_to_keep:
                    maximum_ball = ITEM_ULTRABALL
                    continue
                else:
                    break

            # check future ball count
            num_next_balls = 0
            next_ball = current_ball
            while next_ball < maximum_ball:
                next_ball += 1
                num_next_balls += ball_count[next_ball]

            # check if we've got berries to spare
            berries_to_spare = berry_count > 0 if is_vip else berry_count > num_next_balls + 30

            # use a berry if we are under our ideal rate and have berries to spare
            used_berry = False
            if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and berries_to_spare:
                new_catch_rate_by_ball = self._use_berry(berry_id, berry_count, encounter_id, catch_rate_by_ball, current_ball)
                if new_catch_rate_by_ball != catch_rate_by_ball:
                    catch_rate_by_ball = new_catch_rate_by_ball
                    self.inventory.get(ITEM_RAZZBERRY).remove(1)
                    berry_count -= 1
                    used_berry = True

            # pick the best ball to catch with
            best_ball = current_ball
            while best_ball < maximum_ball:
                best_ball += 1
                if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and ball_count[best_ball] > 0:
                    # if current ball chance to catch is under our ideal rate, and player has better ball - then use it
                    current_ball = best_ball

            # if the rate is still low and we didn't throw a berry before, throw one
            if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and berry_count > 0 and not used_berry:
                new_catch_rate_by_ball = self._use_berry(berry_id, berry_count, encounter_id, catch_rate_by_ball, current_ball)
                if new_catch_rate_by_ball != catch_rate_by_ball:
                    catch_rate_by_ball = new_catch_rate_by_ball
                    self.inventory.get(ITEM_RAZZBERRY).remove(1)
                    berry_count -= 1

            # Randomize the quality of the throw
            # Default structure
            throw_parameters = {'normalized_reticle_size': 1.950,
                                'spin_modifier': 1.0,
                                'normalized_hit_position': 1.0,
                                'throw_type_label': 'Excellent'}
            self.generate_spin_parameter(throw_parameters)
            self.generate_throw_quality_parameters(throw_parameters)

            # try to catch pokemon!
            # TODO : Log which type of throw we selected
            ball_count[current_ball] -= 1
            self.inventory.get(current_ball).remove(1)
            self.emit_event(
                'threw_pokeball',
                formatted='Used {ball_name}, with chance {success_percentage} ({count_left} left)',
                data={
                    'ball_name': self.inventory.get(current_ball).name,
                    'success_percentage': self._pct(catch_rate_by_ball[current_ball]),
                    'count_left': ball_count[current_ball]
                }
            )

            response_dict = self.api.catch_pokemon(
                encounter_id=encounter_id,
                pokeball=current_ball,
                normalized_reticle_size=throw_parameters['normalized_reticle_size'],
                spawn_point_id=self.spawn_point_guid,
                hit_pokemon=1,
                spin_modifier=throw_parameters['spin_modifier'],
                normalized_hit_position=throw_parameters['normalized_hit_position']
            )

            try:
                catch_pokemon_status = response_dict['responses']['CATCH_POKEMON']['status']
            except KeyError:
                break

            # retry failed pokemon
            if catch_pokemon_status == CATCH_STATUS_FAILED:
                self.emit_event(
                    'pokemon_capture_failed',
                    formatted='{pokemon} capture failed.. trying again!',
                    data={'pokemon': pokemon.name}
                )
                sleep(2)
                continue

            # abandon if pokemon vanished
            elif catch_pokemon_status == CATCH_STATUS_VANISHED:
                self.emit_event(
                    'pokemon_vanished',
                    formatted='{pokemon} vanished!',
                    data={
                        'pokemon': pokemon.name,
                        'encounter_id': self.pokemon['encounter_id'],
                        'latitude': self.pokemon['latitude'],
                        'longitude': self.pokemon['longitude'],
                        'pokemon_id': pokemon.pokemon_id
                    }
                )
                if self._pct(catch_rate_by_ball[current_ball]) == 100:
                    self.bot.softban = True

            # pokemon caught!
            elif catch_pokemon_status == CATCH_STATUS_SUCCESS:
                pokemon.id = response_dict['responses']['CATCH_POKEMON']['captured_pokemon_id']
                self.bot.metrics.captured_pokemon(pokemon.name, pokemon.cp, pokemon.iv_display, pokemon.iv)
                inventory.pokemons().add(pokemon)
                self.emit_event(
                    'pokemon_caught',
                    formatted='Captured {pokemon}! [CP {cp}] [Potential {iv}] [{iv_display}] [+{exp} exp]',
                    data={
                        'pokemon': pokemon.name,
                        'cp': pokemon.cp,
                        'iv': pokemon.iv,
                        'iv_display': pokemon.iv_display,
                        'exp': sum(response_dict['responses']['CATCH_POKEMON']['capture_award']['xp']),
                        'encounter_id': self.pokemon['encounter_id'],
                        'latitude': self.pokemon['latitude'],
                        'longitude': self.pokemon['longitude'],
                        'pokemon_id': pokemon.pokemon_id
                    }
                )

                # We could refresh here too, but adding 3 saves a inventory request
                candy = inventory.candies(True).get(pokemon.pokemon_id)
                self.emit_event(
                    'gained_candy',
                    formatted='You now have {quantity} {type} candy!',
                    data = {
                        'quantity': candy.quantity,
                        'type': candy.type,
                    },
                )

                self.bot.softban = False

            break
예제 #50
0
 def _check_candy_limit_absolute(self, pokemon):
     return self.candy_limit_absolute != 0 and inventory.candies().get(pokemon.family_id).quantity >= self.candy_limit_absolute
예제 #51
0
    def get_evolution_plan(self, family_id, family_list, keep, try_evolve, try_upgrade):
        candies = inventory.candies().get(family_id).quantity
        family_name = inventory.Pokemons().name_for(family_id)

        # All the rest is crap, for now
        crap = list(family_list)
        crap = [p for p in crap if p not in keep]
        crap = [p for p in crap if not p.in_fort and not p.is_favorite and not (p.unique_id == self.buddyid)]
        crap.sort(key=lambda p: (p.iv, p.cp), reverse=True)

        # We will gain a candy whether we choose to transfer or evolve these Pokemon
        candies += len(crap)

        evolve = []

        for pokemon in try_evolve:
            if self.config_evolve_to_final:
                pokemon_id = pokemon.pokemon_id

                while inventory.pokemons().has_next_evolution(pokemon_id):
                    candies -= inventory.pokemons().evolution_cost_for(pokemon_id)
                    pokemon_id = inventory.pokemons().next_evolution_ids_for(pokemon_id)[0]
            else:
                candies -= pokemon.evolution_cost

            if candies < 0:
                continue

            if self.config_evolve_to_final:
                pokemon_id = pokemon.pokemon_id

                while inventory.pokemons().has_next_evolution(pokemon_id):
                    candies += 1
                    evolve.append(pokemon)
                    pokemon_id = inventory.pokemons().next_evolution_ids_for(pokemon_id)[0]
            else:
                candies += 1
                evolve.append(pokemon)

        upgrade = []
        upgrade_level = min(self.config_upgrade_level, inventory.player().level + 1.5, 40)

        for pokemon in try_upgrade:
            if pokemon.level >= upgrade_level:
                continue

            full_upgrade_candy_cost = 0
            full_upgrade_stardust_cost = 0

            for i in range(int(pokemon.level * 2), int(upgrade_level * 2)):
                upgrade_cost = self.pokemon_upgrade_cost[i - 2]
                full_upgrade_candy_cost += upgrade_cost[0]
                full_upgrade_stardust_cost += upgrade_cost[1]

            candies -= full_upgrade_candy_cost
            self.ongoing_stardust_count -= full_upgrade_stardust_cost

            if (candies < 0) or (self.ongoing_stardust_count < 0):
                continue

            upgrade.append(pokemon)

        if (not self.config_evolve_for_xp) or (family_name in self.config_evolve_for_xp_blacklist):
            xp = []
            transfer = crap
        elif self.config_evolve_for_xp_whitelist and (family_name not in self.config_evolve_for_xp_whitelist):
            xp = []
            transfer = crap
        else:
            # Compute how many crap we should keep if we want to batch evolve them for xp
            lowest_evolution_cost = inventory.pokemons().evolution_cost_for(family_id)

            # transfer + keep_for_xp = len(crap)
            # leftover_candies = candies - len(crap) + transfer * 1
            # keep_for_xp = (leftover_candies - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - len(crap) + transfer - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - keep_for_xp - 1) / (lowest_evolution_cost - 1)

            if (candies > 0) and lowest_evolution_cost:
                keep_for_xp = int((candies - 1) / lowest_evolution_cost)
            else:
                keep_for_xp = 0

            xp = [p for p in crap if p.has_next_evolution() and p.evolution_cost == lowest_evolution_cost][:keep_for_xp]
            transfer = [p for p in crap if p not in xp]

        return (transfer, evolve, upgrade, xp)
예제 #52
0
    def _pokemon_matches_config(self, config, pokemon, default_logic='and'):
        pokemon_config = config.get(pokemon.name, config.get('any'))

        if not pokemon_config:
            return False

        catch_results = {
            'ncp': False,
            'cp': False,
            'iv': False,
            'fa': True,
            'ca': True
        }

        catch_logic = pokemon_config.get('logic', default_logic)

        candies = inventory.candies().get(pokemon.pokemon_id).quantity
        threshold = pokemon_config.get('candy_threshold', -1)
        if threshold > 0 and candies >= threshold:  # Got enough candies
            return False

        if pokemon_config.get('never_catch', False):
            return False

        if pokemon_config.get('always_catch', False):
            return True

        if pokemon_config.get('catch_above_ncp', -1) >= 0:
            if pokemon.cp_percent >= pokemon_config.get('catch_above_ncp'):
                catch_results['ncp'] = True

        if pokemon_config.get('catch_above_cp', -1) >= 0:
            if pokemon.cp >= pokemon_config.get('catch_above_cp'):
                catch_results['cp'] = True

        if pokemon_config.get('catch_below_cp', -1) >= 0:
            if pokemon.cp <= pokemon_config.get('catch_below_cp'):
                catch_results['cp'] = True

        if pokemon_config.get('catch_above_iv', -1) >= 0:
            if pokemon.iv > pokemon_config.get('catch_above_iv', pokemon.iv):
                catch_results['iv'] = True

        catch_results['fa'] = (len(pokemon_config.get('fast_attack', [])) == 0
                               or unicode(pokemon.fast_attack) in map(
                                   lambda x: unicode(x),
                                   pokemon_config.get('fast_attack', [])))
        catch_results['ca'] = (len(pokemon_config.get('charged_attack', []))
                               == 0 or unicode(pokemon.charged_attack) in map(
                                   lambda x: unicode(x),
                                   pokemon_config.get('charged_attack', [])))

        self.bot.logger.debug(
            "Our comparison results: FA: {}, CA: {}, CP: {}, NCP: {}, IV: {}".
            format(catch_results['fa'], catch_results['ca'],
                   catch_results['cp'], catch_results['ncp'],
                   catch_results['iv']))

        # check if encountered pokemon is our locked pokemon
        if self.bot.capture_locked and self.bot.capture_locked != pokemon.pokemon_id:
            self.bot.logger.debug("Pokemon locked!")
            return False

        # build catch results
        cr = {'ncp': False, 'cp': False, 'iv': False}
        if catch_logic == 'and':
            cr['ncp'] = True,
            cr['cp'] = True,
            cr['iv'] = True
        elif catch_logic == 'andor':
            cr['ncp'] = True,
            cr['cp'] = True
        elif catch_logic == 'orand':
            cr['cp'] = True,
            cr['iv'] = True

        if pokemon_config.get('catch_above_ncp', -1) >= 0:
            cr['ncp'] = catch_results['ncp']
        if pokemon_config.get('catch_above_cp', -1) >= 0:
            cr['cp'] = catch_results['cp']
        if pokemon_config.get('catch_below_cp', -1) >= 0:
            cr['cp'] = catch_results['cp']
        if pokemon_config.get('catch_above_iv', -1) >= 0:
            cr['iv'] = catch_results['iv']

        if DEBUG_ON:
            print "Debug information for match rules..."
            print "catch_results ncp = {}".format(catch_results['ncp'])
            print "catch_results cp = {}".format(catch_results['cp'])
            print "catch_results iv = {}".format(catch_results['iv'])
            print "cr = {}".format(cr)
            print "catch_above_ncp = {}".format(
                pokemon_config.get('catch_above_ncp'))
            print "catch_above_cp iv = {}".format(
                pokemon_config.get('catch_above_cp'))
            print "catch_below_cp iv = {}".format(
                pokemon_config.get('catch_below_cp'))
            print "catch_above_iv iv = {}".format(
                pokemon_config.get('catch_above_iv'))
            print "Pokemon {}".format(pokemon.name)
            print "pokemon ncp = {}".format(pokemon.cp_percent)
            print "pokemon cp = {}".format(pokemon.cp)
            print "pokemon iv = {}".format(pokemon.iv)
            print "catch logic = {}".format(catch_logic)

        if LOGIC_TO_FUNCTION[catch_logic](*cr.values()):
            return catch_results['fa'] and catch_results['ca']
        else:
            return False
    def showtop(self, chatid, num, order):
        if not num.isnumeric():
            num = 10
        else:
            num = int(num)

        if order not in ["cp", "iv"]:
            order = "iv"

        pkmns = sorted(inventory.pokemons().all(), key=lambda p: getattr(p, order), reverse=True)[:num]

        outMsg = "\n".join(["<b>{}</b> \nCP: {} \nIV: {} \nCandy: {}\n".format(p.name, p.cp, p.iv, inventory.candies().get(p.pokemon_id).quantity) for p in pkmns])
        self.sendMessage(chat_id=chatid, parse_mode='HTML', text=outMsg)

        return
예제 #54
0
    def get_evolution_plan(self, family_id, family, evolve_best, keep_best):
        candies = inventory.candies().get(family_id).quantity

        # All the rest is crap, for now
        crap = family[:]
        crap = [p for p in crap if p not in evolve_best]
        crap = [p for p in crap if p not in keep_best]
        crap.sort(key=lambda p: p.iv * p.ncp, reverse=True)

        candies += len(crap)

        # Let's see if we can evolve our best pokemons
        can_evolve_best = []

        for pokemon in evolve_best:
            if not pokemon.has_next_evolution():
                continue

            candies -= pokemon.evolution_cost

            if candies < 0:
                continue

            can_evolve_best.append(pokemon)

            # Not sure if the evo keep the same id
            next_pid = pokemon.next_evolution_ids[0]
            next_evo = copy.copy(pokemon)
            next_evo.pokemon_id = next_pid
            next_evo.static = inventory.pokemons().data_for(next_pid)
            next_evo.name = inventory.pokemons().name_for(next_pid)
            evolve_best.append(next_evo)

        if self.config_evolve_for_xp:
            # Compute how many crap we should keep if we want to batch evolve them for xp
            junior_evolution_cost = inventory.pokemons().evolution_cost_for(family_id)

            # transfer + keep_for_evo = len(crap)
            # leftover_candies = candies - len(crap) + transfer * 1
            # keep_for_evo = leftover_candies / junior_evolution_cost
            #
            # keep_for_evo = (candies - len(crap) + transfer) / junior_evolution_cost
            # keep_for_evo = (candies - keep_for_evo) / junior_evolution_cost

            if (candies > 0) and junior_evolution_cost:
                keep_for_evo = int(candies / (junior_evolution_cost + 1))
            else:
                keep_for_evo = 0

            evo_crap = [p for p in crap if p.has_next_evolution() and p.evolution_cost == junior_evolution_cost][:keep_for_evo]

            # If not much to evolve, better keep the candies
            if len(evo_crap) < math.ceil(self.max_pokemon_storage * 0.01):
                evo_crap = []

            transfer = [p for p in crap if p not in evo_crap]
        else:
            evo_crap = []
            transfer = crap

        return (transfer, can_evolve_best, evo_crap)
예제 #55
0
    def _do_catch(self,
                  pokemon,
                  encounter_id,
                  catch_rate_by_ball,
                  is_vip=False):
        # settings that may be exposed at some point
        """

        :type pokemon: Pokemon
        """
        berry_count = self.inventory.get(ITEM_RAZZBERRY).count
        ball_count = {}
        for ball_id in [ITEM_POKEBALL, ITEM_GREATBALL, ITEM_ULTRABALL]:
            ball_count[ball_id] = self.inventory.get(ball_id).count

        # use `min_ultraball_to_keep` from config if is not None
        min_ultraball_to_keep = ball_count[ITEM_ULTRABALL]
        if self.min_ultraball_to_keep is not None and self.min_ultraball_to_keep >= 0:
            min_ultraball_to_keep = self.min_ultraball_to_keep

        berry_id = ITEM_RAZZBERRY
        maximum_ball = ITEM_GREATBALL if ball_count[
            ITEM_ULTRABALL] < min_ultraball_to_keep else ITEM_ULTRABALL
        ideal_catch_rate_before_throw = self.vip_berry_threshold if is_vip else self.berry_threshold

        used_berry = False
        original_catch_rate_by_ball = catch_rate_by_ball
        while True:

            # find lowest available ball
            current_ball = ITEM_POKEBALL
            while ball_count[current_ball] == 0 and current_ball < maximum_ball:
                current_ball += 1
            if ball_count[current_ball] == 0:
                self.emit_event('no_pokeballs',
                                formatted='No pokeballs left! Fleeing...')
                return WorkerResult.ERROR

            # check future ball count
            num_next_balls = 0
            next_ball = current_ball
            while next_ball < maximum_ball:
                next_ball += 1
                num_next_balls += ball_count[next_ball]

            # check if we've got berries to spare
            berries_to_spare = berry_count > 0 if is_vip else berry_count > num_next_balls + 30

            # use a berry if we are under our ideal rate and have berries to spare
            changed_ball = False
            if catch_rate_by_ball[
                    current_ball] < ideal_catch_rate_before_throw and berries_to_spare and not used_berry:
                new_catch_rate_by_ball = self._use_berry(
                    berry_id, berry_count, encounter_id, catch_rate_by_ball,
                    current_ball)
                if new_catch_rate_by_ball != catch_rate_by_ball:
                    catch_rate_by_ball = new_catch_rate_by_ball
                    self.inventory.get(ITEM_RAZZBERRY).remove(1)
                    berry_count -= 1
                    used_berry = True

            # pick the best ball to catch with
            best_ball = current_ball
            while best_ball < maximum_ball:
                best_ball += 1
                if catch_rate_by_ball[
                        current_ball] < ideal_catch_rate_before_throw and ball_count[
                            best_ball] > 0:
                    # if current ball chance to catch is under our ideal rate, and player has better ball - then use it
                    current_ball = best_ball
                    changed_ball = True

            # if the rate is still low and we didn't throw a berry before, throw one
            if catch_rate_by_ball[
                    current_ball] < ideal_catch_rate_before_throw and berry_count > 0 and not used_berry:
                new_catch_rate_by_ball = self._use_berry(
                    berry_id, berry_count, encounter_id, catch_rate_by_ball,
                    current_ball)
                if new_catch_rate_by_ball != catch_rate_by_ball:
                    catch_rate_by_ball = new_catch_rate_by_ball
                    self.inventory.get(ITEM_RAZZBERRY).remove(1)
                    berry_count -= 1
                    used_berry = True

            # If we change ball then wait to simulate user selecting it
            if changed_ball:
                action_delay(self.catchsim_changeball_wait_min,
                             self.catchsim_changeball_wait_max)

            # Randomize the quality of the throw
            # Default structure
            throw_parameters = {
                'normalized_reticle_size': 1.950,
                'spin_modifier': 1.0,
                'normalized_hit_position': 1.0,
                'throw_type_label': 'Excellent'
            }
            self.generate_spin_parameter(throw_parameters)
            self.generate_throw_quality_parameters(throw_parameters)

            # try to catch pokemon!
            ball_count[current_ball] -= 1
            self.inventory.get(current_ball).remove(1)
            # Take some time to throw the ball from config options
            action_delay(self.catchsim_catch_wait_min,
                         self.catchsim_catch_wait_max)
            self.emit_event(
                'threw_pokeball',
                formatted=
                '{throw_type}{spin_label} throw! Used {ball_name}, with chance {success_percentage} ({count_left} left)',
                data={
                    'throw_type':
                    throw_parameters['throw_type_label'],
                    'spin_label':
                    throw_parameters['spin_label'],
                    'ball_name':
                    self.inventory.get(current_ball).name,
                    'success_percentage':
                    self._pct(catch_rate_by_ball[current_ball]),
                    'count_left':
                    ball_count[current_ball]
                })

            hit_pokemon = 1
            if random() >= self.catch_throw_parameters_hit_rate and not is_vip:
                hit_pokemon = 0

            response_dict = self.bot.api.catch_pokemon(
                encounter_id=encounter_id,
                pokeball=current_ball,
                normalized_reticle_size=throw_parameters[
                    'normalized_reticle_size'],
                spawn_point_id=self.spawn_point_guid,
                hit_pokemon=hit_pokemon,
                spin_modifier=throw_parameters['spin_modifier'],
                normalized_hit_position=throw_parameters[
                    'normalized_hit_position'])

            try:
                catch_pokemon_status = response_dict['responses'][
                    'CATCH_POKEMON']['status']
            except KeyError:
                break

            # retry failed pokemon
            if catch_pokemon_status == CATCH_STATUS_FAILED:
                self.emit_event(
                    'pokemon_capture_failed',
                    formatted='{pokemon} capture failed.. trying again!',
                    data={'pokemon': pokemon.name})
                used_berry = False
                catch_rate_by_ball = original_catch_rate_by_ball

                # sleep according to flee_count and flee_duration config settings
                # randomly chooses a number of times to 'show' wobble animation between 1 and flee_count
                # multiplies this by flee_duration to get total sleep
                if self.catchsim_flee_count:
                    sleep((randrange(self.catchsim_flee_count) + 1) *
                          self.catchsim_flee_duration)

                continue

            # abandon if pokemon vanished
            elif catch_pokemon_status == CATCH_STATUS_VANISHED:
                #insert into DB
                with self.bot.database as conn:
                    c = conn.cursor()
                    c.execute(
                        "SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='vanish_log'"
                    )
                result = c.fetchone()

                while True:
                    if result[0] == 1:
                        conn.execute(
                            '''INSERT INTO vanish_log (pokemon, cp, iv, encounter_id, pokemon_id) VALUES (?, ?, ?, ?, ?)''',
                            (pokemon.name, pokemon.cp, pokemon.iv,
                             str(encounter_id), pokemon.pokemon_id))
                    break
                else:
                    self.emit_event(
                        'vanish_log',
                        sender=self,
                        level='info',
                        formatted="vanish_log table not found, skipping log")
                    break

                self.emit_event('pokemon_vanished',
                                formatted='{} vanished!'.format(pokemon.name),
                                data={
                                    'pokemon': pokemon.name,
                                    'encounter_id':
                                    self.pokemon['encounter_id'],
                                    'latitude': self.pokemon['latitude'],
                                    'longitude': self.pokemon['longitude'],
                                    'pokemon_id': pokemon.pokemon_id
                                })

                with self.bot.database as conn:
                    c = conn.cursor()
                    c.execute(
                        "SELECT DISTINCT COUNT(encounter_id) FROM vanish_log WHERE dated > (SELECT dated FROM catch_log WHERE dated IN (SELECT MAX(dated) FROM catch_log))"
                    )

                result = c.fetchone()
                self.consecutive_vanishes_so_far = result[0]

                if self.rest_completed == False and self.consecutive_vanishes_so_far >= self.consecutive_vanish_limit:
                    self.start_rest()

                if self._pct(catch_rate_by_ball[current_ball]) == 100:
                    self.bot.softban = True

            # pokemon caught!
            elif catch_pokemon_status == CATCH_STATUS_SUCCESS:
                if self.rest_completed == True:
                    self.rest_completed = False
                pokemon.unique_id = response_dict['responses'][
                    'CATCH_POKEMON']['captured_pokemon_id']
                self.bot.metrics.captured_pokemon(pokemon.name, pokemon.cp,
                                                  pokemon.iv_display,
                                                  pokemon.iv)

                awards = response_dict['responses']['CATCH_POKEMON'][
                    'capture_award']
                exp_gain, candy_gain, stardust_gain = self.extract_award(
                    awards)
                with self.bot.database as conn:
                    c = conn.cursor()
                    c.execute(
                        "SELECT DISTINCT COUNT(encounter_id) FROM catch_log WHERE dated >= datetime('now','-1 day')"
                    )

                result = c.fetchone()

                if is_vip:
                    self.emit_event(
                        'pokemon_vip_caught',
                        formatted=
                        'Vip Captured {pokemon}! (CP: {cp} IV: {iv} {iv_display} NCP: {ncp}) Catch Limit: ({caught_last_24_hour}/{daily_catch_limit}) +{exp} exp +{stardust} stardust',
                        data={
                            'pokemon': pokemon.name,
                            'ncp': str(round(pokemon.cp_percent, 2)),
                            'cp': str(int(pokemon.cp)),
                            'iv': str(pokemon.iv),
                            'iv_display': str(pokemon.iv_display),
                            'exp': str(exp_gain),
                            'stardust': stardust_gain,
                            'encounter_id': str(self.pokemon['encounter_id']),
                            'latitude': str(self.pokemon['latitude']),
                            'longitude': str(self.pokemon['longitude']),
                            'pokemon_id': str(pokemon.pokemon_id),
                            'caught_last_24_hour': str(result[0]),
                            'daily_catch_limit': str(self.daily_catch_limit)
                        })

                else:
                    self.emit_event(
                        'pokemon_caught',
                        formatted=
                        'Captured {pokemon}! (CP: {cp} IV: {iv} {iv_display} NCP: {ncp}) Catch Limit: ({caught_last_24_hour}/{daily_catch_limit}) +{exp} exp +{stardust} stardust',
                        data={
                            'pokemon': pokemon.name,
                            'ncp': str(round(pokemon.cp_percent, 2)),
                            'cp': str(int(pokemon.cp)),
                            'iv': str(pokemon.iv),
                            'iv_display': str(pokemon.iv_display),
                            'exp': str(exp_gain),
                            'stardust': stardust_gain,
                            'encounter_id': str(self.pokemon['encounter_id']),
                            'latitude': str(self.pokemon['latitude']),
                            'longitude': str(self.pokemon['longitude']),
                            'pokemon_id': str(pokemon.pokemon_id),
                            'caught_last_24_hour': str(result[0]),
                            'daily_catch_limit': str(self.daily_catch_limit)
                        })

                inventory.pokemons().add(pokemon)
                inventory.player().exp += exp_gain
                self.bot.stardust += stardust_gain
                candy = inventory.candies().get(pokemon.pokemon_id)
                candy.add(candy_gain)

                self.emit_event(
                    'gained_candy',
                    formatted='You now have {quantity} {type} candy!',
                    data={
                        'quantity': candy.quantity,
                        'type': candy.type,
                    },
                )

                self.bot.softban = False

                try:
                    with self.bot.database as conn:
                        c = conn.cursor()
                        c.execute(
                            "SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='catch_log'"
                        )
                    result = c.fetchone()

                    while True:
                        if result[0] == 1:
                            conn.execute(
                                '''INSERT INTO catch_log (pokemon, cp, iv, encounter_id, pokemon_id) VALUES (?, ?, ?, ?, ?)''',
                                (pokemon.name, pokemon.cp, pokemon.iv,
                                 str(encounter_id), pokemon.pokemon_id))
                        break
                    else:
                        self.emit_event(
                            'catch_log',
                            sender=self,
                            level='info',
                            formatted="catch_log table not found, skipping log"
                        )
                        break
                    user_data_caught = os.path.join(
                        _base_dir, 'data',
                        'caught-%s.json' % self.bot.config.username)
                    with open(user_data_caught, 'ab') as outfile:
                        json.dump(
                            OrderedDict({
                                'datetime':
                                str(datetime.now()),
                                'pokemon':
                                pokemon.name,
                                'cp':
                                pokemon.cp,
                                'iv':
                                pokemon.iv,
                                'encounter_id':
                                self.pokemon['encounter_id'],
                                'pokemon_id':
                                pokemon.pokemon_id,
                                'latitude':
                                self.pokemon['latitude'],
                                'longitude':
                                self.pokemon['longitude']
                            }), outfile)
                        outfile.write('\n')

                    # if it is a new pokemon to our dex, simulate app animation delay
                    if exp_gain >= 500:
                        sleep(
                            randrange(self.catchsim_newtodex_wait_min,
                                      self.catchsim_newtodex_wait_max))

                except IOError as e:
                    self.logger.info(
                        '[x] Error while opening location file: %s' % e)

            elif catch_pokemon_status == CATCH_STATUS_MISSED:
                self.emit_event(
                    'pokemon_capture_failed',
                    formatted=
                    'Pokeball thrown to {pokemon} missed.. trying again!',
                    data={'pokemon': pokemon.name})
                # Take some time to throw the ball from config options
                action_delay(self.catchsim_catch_wait_min,
                             self.catchsim_catch_wait_max)
                continue

            break
예제 #56
0
    def get_evolution_plan(self, family_id, family_list, keep, try_evolve,
                           try_upgrade):
        candies = inventory.candies().get(family_id).quantity

        # All the rest is crap, for now
        crap = list(family_list)
        crap = [p for p in crap if p not in keep]
        crap = [p for p in crap if not p.in_fort and not p.is_favorite]
        crap.sort(key=lambda p: (p.iv, p.cp), reverse=True)

        # We will gain a candy whether we choose to transfer or evolve these Pokemon
        candies += len(crap)

        evolve = []

        for pokemon in try_evolve:
            candies -= pokemon.evolution_cost

            if candies < 0:
                continue

            candies += 1
            evolve.append(pokemon)

        upgrade = []
        upgrade_level = min(self.config_upgrade_level,
                            inventory.player().level * 2)

        for pokemon in try_upgrade:
            level = int(pokemon.level * 2) - 1

            if level >= upgrade_level:
                continue

            full_upgrade_candy_cost = 0
            full_upgrade_stardust_cost = 0

            for i in range(level, upgrade_level):
                upgrade_cost = self.pokemon_upgrade_cost[i - 1]
                full_upgrade_candy_cost += upgrade_cost[0]
                full_upgrade_stardust_cost += upgrade_cost[1]

            candies -= full_upgrade_candy_cost
            self.ongoing_stardust_count -= full_upgrade_stardust_cost

            if (candies < 0) or (self.ongoing_stardust_count < 0):
                continue

            upgrade.append(pokemon)

        if self.config_evolve_for_xp:
            # Compute how many crap we should keep if we want to batch evolve them for xp
            lowest_evolution_cost = inventory.pokemons().evolution_cost_for(
                family_id)

            # transfer + keep_for_xp = len(crap)
            # leftover_candies = candies - len(crap) + transfer * 1
            # keep_for_xp = (leftover_candies - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - len(crap) + transfer - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - keep_for_xp - 1) / (lowest_evolution_cost - 1)

            if (candies > 0) and lowest_evolution_cost:
                keep_for_xp = int((candies - 1) / lowest_evolution_cost)
            else:
                keep_for_xp = 0

            xp = [
                p for p in crap if p.has_next_evolution()
                and p.evolution_cost == lowest_evolution_cost
            ][:keep_for_xp]

            # If not much to evolve, better keep the candies
            if len(xp) < math.ceil(self.max_pokemon_storage * 0.02):
                xp = []

            transfer = [p for p in crap if p not in xp]
        else:
            xp = []
            transfer = crap

        return (transfer, evolve, upgrade, xp)