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
def work(self, response_dict=None): encounter_id = self.pokemon['encounter_id'] if not response_dict: response_dict = self.create_encounter_api_call() if response_dict and 'responses' in response_dict: if self.response_key in response_dict['responses']: if self.response_status_key in response_dict['responses'][ self.response_key]: if response_dict['responses'][self.response_key][ self.response_status_key] is 1: cp = 0 if 'wild_pokemon' in response_dict['responses'][self.response_key] or 'pokemon_data' in \ response_dict['responses'][self.response_key]: if self.response_key == 'ENCOUNTER': pokemon = response_dict['responses'][ self.response_key]['wild_pokemon'] else: pokemon = response_dict['responses'][ self.response_key] catch_rate = response_dict['responses'][ self.response_key]['capture_probability'][ 'capture_probability'] # 0 = pokeballs, 1 great balls, 3 ultra balls if 'pokemon_data' in pokemon and 'cp' in pokemon[ 'pokemon_data']: pokemon_data = pokemon['pokemon_data'] cp = pokemon_data['cp'] individual_attack = pokemon_data.get( "individual_attack", 0) individual_stamina = pokemon_data.get( "individual_stamina", 0) individual_defense = pokemon_data.get( "individual_defense", 0) iv_display = '{}/{}/{}'.format( individual_attack, individual_defense, individual_stamina) pokemon_potential = self.pokemon_potential( pokemon_data) pokemon_num = int( pokemon_data['pokemon_id']) - 1 pokemon_name = self.pokemon_list[int( pokemon_num)]['Name'] msg = 'A wild {pokemon} appeared! [CP {cp}] [Potential {iv}] [S/A/D {iv_display}]' self.emit_event('pokemon_appeared', formatted=msg, data={ 'pokemon': pokemon_name, 'cp': cp, 'iv': pokemon_potential, 'iv_display': iv_display, }) pokemon_data['name'] = pokemon_name # Simulate app sleep(3) if not self.should_capture_pokemon( pokemon_name, cp, pokemon_potential, response_dict): return False flag_VIP = False # @TODO, use the best ball in stock to catch VIP (Very Important Pokemon: Configurable) if self.check_vip_pokemon(pokemon_name, cp, pokemon_potential): self.emit_event( 'vip_pokemon', formatted='This is a VIP pokemon. Catch!!!') flag_VIP = True items_stock = self.bot.current_inventory() berry_id = 701 # @ TODO: use better berries if possible berries_count = self.bot.item_inventory_count(berry_id) while True: # pick the most simple ball from stock pokeball = 1 # start from 1 - PokeBalls berry_used = False if flag_VIP: if (berries_count > 0 and catch_rate[pokeball - 1] < 0.9): success_percentage = '{0:.2f}'.format( catch_rate[pokeball - 1] * 100) self.emit_event( 'pokemon_catch_rate', level='debug', formatted= "Catch rate of {catch_rate} is low. Maybe will throw {berry_name} ({berry_count} left)", data={ 'catch_rate': success_percentage, 'berry_name': self.item_list[str(berry_id)], 'berry_count': berries_count }) # Out of all pokeballs! Let's don't waste berry. if items_stock[1] == 0 and items_stock[ 2] == 0 and items_stock[3] == 0: break # Use the berry to catch response_dict = self.api.use_item_capture( item_id=berry_id, encounter_id=encounter_id, spawn_point_id=self.spawn_point_guid) if response_dict and response_dict[ 'status_code'] is 1 and 'item_capture_mult' in response_dict[ 'responses'][ 'USE_ITEM_CAPTURE']: for i in range(len(catch_rate)): if 'item_capture_mult' in response_dict[ 'responses'][ 'USE_ITEM_CAPTURE']: catch_rate[i] = catch_rate[ i] * response_dict[ 'responses'][ 'USE_ITEM_CAPTURE'][ 'item_capture_mult'] success_percentage = '{0:.2f}'.format( catch_rate[pokeball - 1] * 100) berries_count = berries_count - 1 berry_used = True self.emit_event( 'threw_berry', formatted= "Threw a {berry_name}! Catch rate now: {new_catch_rate}", data={ "berry_name": self.item_list[str(berry_id)], "new_catch_rate": success_percentage }) else: if response_dict['status_code'] is 1: self.emit_event( 'softban', level='warning', formatted= 'Failed to use berry. You may be softbanned.' ) else: self.emit_event( 'threw_berry_failed', formatted= 'Unknown response when throwing berry: {status_code}.', data={ 'status_code': response_dict[ 'status_code'] }) #use the best ball to catch current_type = pokeball #debug use normal ball while current_type < 3: current_type += 1 if catch_rate[pokeball - 1] < 0.9 and items_stock[ current_type] > 0: # if current ball chance to catch is under 90%, and player has better ball - then use it pokeball = current_type # use better ball else: # If we have a lot of berries (than the great ball), we prefer use a berry first! if catch_rate[ pokeball - 1] < 0.42 and items_stock[ pokeball + 1] + 30 < berries_count: # If it's not the VIP type, we don't want to waste our ultra ball if no balls left. if items_stock[1] == 0 and items_stock[ 2] == 0: break success_percentage = '{0:.2f}'.format( catch_rate[pokeball - 1] * 100) self.emit_event( 'pokemon_catch_rate', level='debug', formatted= "Catch rate of {catch_rate} is low. Maybe will throw {berry_name} ({berry_count} left)", data={ 'catch_rate': success_percentage, 'berry_name': self.item_list[str(berry_id)], 'berry_count': berries_count - 1 }) response_dict = self.api.use_item_capture( item_id=berry_id, encounter_id=encounter_id, spawn_point_id=self.spawn_point_guid) if response_dict and response_dict[ 'status_code'] is 1 and 'item_capture_mult' in response_dict[ 'responses'][ 'USE_ITEM_CAPTURE']: for i in range(len(catch_rate)): if 'item_capture_mult' in response_dict[ 'responses'][ 'USE_ITEM_CAPTURE']: catch_rate[i] = catch_rate[ i] * response_dict[ 'responses'][ 'USE_ITEM_CAPTURE'][ 'item_capture_mult'] success_percentage = '{0:.2f}'.format( catch_rate[pokeball - 1] * 100) berries_count = berries_count - 1 berry_used = True self.emit_event( 'threw_berry', formatted= "Threw a {berry_name}! Catch rate now: {new_catch_rate}", data={ "berry_name": self.item_list[str(berry_id)], "new_catch_rate": success_percentage }) else: if response_dict['status_code'] is 1: self.emit_event( 'softban', level='warning', formatted= 'Failed to use berry. You may be softbanned.' ) else: self.emit_event( 'threw_berry_failed', formatted= 'Unknown response when throwing berry: {status_code}.', data={ 'status_code': response_dict[ 'status_code'] }) else: #We don't have many berry to waste, pick a good ball first. Save some berry for future VIP pokemon current_type = pokeball while current_type < 2: current_type += 1 if catch_rate[ pokeball - 1] < 0.35 and items_stock[ current_type] > 0: # if current ball chance to catch is under 35%, and player has better ball - then use it pokeball = current_type # use better ball #if the rate is still low and we didn't throw a berry before use berry if catch_rate[ pokeball - 1] < 0.35 and berries_count > 0 and berry_used == False: # If it's not the VIP type, we don't want to waste our ultra ball if no balls left. if items_stock[1] == 0 and items_stock[ 2] == 0: break success_percentage = '{0:.2f}'.format( catch_rate[pokeball - 1] * 100) self.emit_event( 'pokemon_catch_rate', level='debug', formatted= "Catch rate of {catch_rate} is low. Throwing {berry_name} ({berry_count} left)", data={ 'catch_rate': success_percentage, 'berry_name': self.item_list[str(berry_id)], 'berry_count': berries_count - 1 }) response_dict = self.api.use_item_capture( item_id=berry_id, encounter_id=encounter_id, spawn_point_id=self.spawn_point_guid) if response_dict and response_dict[ 'status_code'] is 1 and 'item_capture_mult' in response_dict[ 'responses'][ 'USE_ITEM_CAPTURE']: for i in range(len(catch_rate)): if 'item_capture_mult' in response_dict[ 'responses'][ 'USE_ITEM_CAPTURE']: catch_rate[i] = catch_rate[ i] * response_dict[ 'responses'][ 'USE_ITEM_CAPTURE'][ 'item_capture_mult'] success_percentage = '{0:.2f}'.format( catch_rate[pokeball - 1] * 100) berries_count = berries_count - 1 berry_used = True self.emit_event( 'threw_berry', formatted= "Threw a {berry_name}! Catch rate now: {new_catch_rate}", data={ "berry_name": self.item_list[str(berry_id)], "new_catch_rate": success_percentage }) else: if response_dict['status_code'] is 1: self.emit_event( 'softban', level='warning', formatted= 'Failed to use berry. You may be softbanned.' ) else: self.emit_event( 'threw_berry_failed', formatted= 'Unknown response when throwing berry: {status_code}.', data={ 'status_code': response_dict[ 'status_code'] }) # Re-check if berry is used, find a ball for a good capture rate current_type = pokeball while current_type < 2: current_type += 1 if catch_rate[pokeball - 1] < 0.35 and items_stock[ current_type] > 0: pokeball = current_type # use better ball # This is to avoid rare case that a berry has ben throwed <0.42 # and still picking normal pokeball (out of stock) -> error if items_stock[1] == 0 and items_stock[2] > 0: pokeball = 2 # Add this logic to avoid Pokeball = 0, Great Ball = 0, Ultra Ball = X # And this logic saves Ultra Balls if it's a weak trash pokemon if catch_rate[pokeball - 1] < 0.30 and items_stock[3] > 0: pokeball = 3 items_stock[pokeball] -= 1 success_percentage = '{0:.2f}'.format( catch_rate[pokeball - 1] * 100) self.emit_event( 'threw_pokeball', formatted= 'Used {pokeball}, with chance {success_percentage} ({count_left} left)', data={ 'pokeball': self.item_list[str(pokeball)], 'success_percentage': success_percentage, 'count_left': items_stock[pokeball] }) id_list1 = self.count_pokemon_inventory() 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=pokeball, 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) if response_dict and \ 'responses' in response_dict and \ 'CATCH_POKEMON' in response_dict['responses'] and \ 'status' in response_dict['responses']['CATCH_POKEMON']: status = response_dict['responses'][ 'CATCH_POKEMON']['status'] if status is 2: self.emit_event( 'pokemon_escaped', formatted="{pokemon} escaped.", data={'pokemon': pokemon_name}) sleep(2) continue if status is 3: self.emit_event( 'pokemon_vanished', formatted="{pokemon} vanished!", data={'pokemon': pokemon_name}) if success_percentage == 100: self.softban = True if status is 1: self.bot.metrics.captured_pokemon( pokemon_name, cp, iv_display, pokemon_potential) self.emit_event( 'pokemon_caught', formatted= 'Captured {pokemon}! [CP {cp}] [Potential {iv}] [{iv_display}] [+{exp} exp]', data={ 'pokemon': pokemon_name, 'cp': cp, 'iv': pokemon_potential, 'iv_display': iv_display, 'exp': sum(response_dict['responses'] ['CATCH_POKEMON'] ['capture_award']['xp']) }) self.bot.softban = False if (self.config.evolve_captured and (self.config.evolve_captured[0] == 'all' or pokemon_name in self.config.evolve_captured)): id_list2 = self.count_pokemon_inventory( ) # No need to capture this even for metrics, player stats includes it. pokemon_to_transfer = list( set(id_list2) - set(id_list1)) # TODO dont throw RuntimeError, do something better if len(pokemon_to_transfer) == 0: raise RuntimeError( 'Trying to evolve 0 pokemons!') response_dict = self.api.evolve_pokemon( pokemon_id=pokemon_to_transfer[0]) status = response_dict['responses'][ 'EVOLVE_POKEMON']['result'] if status == 1: self.emit_event( 'pokemon_evolved', formatted="{pokemon} evolved!", data={'pokemon': pokemon_name}) else: self.emit_event( 'pokemon_evolve_fail', formatted= "Failed to evolve {pokemon}!", data={'pokemon': pokemon_name}) break time.sleep(5)
def work(self, response_dict=None): encounter_id = self.pokemon['encounter_id'] if not response_dict: response_dict = self.create_encounter_api_call() if response_dict and 'responses' in response_dict: if self.response_key in response_dict['responses']: if self.response_status_key in response_dict['responses'][self.response_key]: if response_dict['responses'][self.response_key][self.response_status_key] is 1: cp = 0 if 'wild_pokemon' in response_dict['responses'][self.response_key] or 'pokemon_data' in \ response_dict['responses'][self.response_key]: if self.response_key == 'ENCOUNTER': pokemon = response_dict['responses'][self.response_key]['wild_pokemon'] else: pokemon = response_dict['responses'][self.response_key] catch_rate = response_dict['responses'][self.response_key]['capture_probability'][ 'capture_probability'] # 0 = pokeballs, 1 great balls, 3 ultra balls if 'pokemon_data' in pokemon and 'cp' in pokemon['pokemon_data']: pokemon_data = pokemon['pokemon_data'] cp = pokemon_data['cp'] individual_attack = pokemon_data.get("individual_attack", 0) individual_stamina = pokemon_data.get("individual_stamina", 0) individual_defense = pokemon_data.get("individual_defense", 0) iv_display = '{}/{}/{}'.format( individual_attack, individual_defense, individual_stamina ) pokemon_potential = self.pokemon_potential(pokemon_data) pokemon_num = int(pokemon_data['pokemon_id']) - 1 pokemon_name = self.pokemon_list[int(pokemon_num)]['Name'] msg = 'A wild {pokemon} appeared! [CP {cp}] [Potential {iv}] [S/A/D {iv_display}]' self.emit_event( 'pokemon_appeared', formatted=msg, data={ 'pokemon': pokemon_name, 'cp': cp, 'iv': pokemon_potential, 'iv_display': iv_display, } ) pokemon_data['name'] = pokemon_name # Simulate app sleep(3) if not self.should_capture_pokemon(pokemon_name, cp, pokemon_potential, response_dict): return False flag_VIP = False # @TODO, use the best ball in stock to catch VIP (Very Important Pokemon: Configurable) if self.check_vip_pokemon(pokemon_name, cp, pokemon_potential): self.emit_event( 'vip_pokemon', formatted='This is a VIP pokemon. Catch!!!' ) flag_VIP=True items_stock = self.bot.current_inventory() berry_id = 701 # @ TODO: use better berries if possible berries_count = self.bot.item_inventory_count(berry_id) while True: # pick the most simple ball from stock pokeball = 1 # start from 1 - PokeBalls berry_used = False if flag_VIP: if(berries_count>0 and catch_rate[pokeball-1] < 0.9): success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) self.emit_event( 'pokemon_catch_rate', level='debug', formatted="Catch rate of {catch_rate} is low. Maybe will throw {berry_name} ({berry_count} left)", data={ 'catch_rate': success_percentage, 'berry_name': self.item_list[str(berry_id)], 'berry_count': berries_count } ) # Out of all pokeballs! Let's don't waste berry. if items_stock[1] == 0 and items_stock[2] == 0 and items_stock[3] == 0: break # Use the berry to catch response_dict = self.api.use_item_capture( item_id=berry_id, encounter_id=encounter_id, spawn_point_id=self.spawn_point_guid ) if response_dict and response_dict['status_code'] is 1 and 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: for i in range(len(catch_rate)): if 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: catch_rate[i] = catch_rate[i] * response_dict['responses']['USE_ITEM_CAPTURE']['item_capture_mult'] success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) berries_count = berries_count -1 berry_used = True self.emit_event( 'threw_berry', formatted="Threw a {berry_name}! Catch rate now: {new_catch_rate}", data={ "berry_name": self.item_list[str(berry_id)], "new_catch_rate": success_percentage } ) else: if response_dict['status_code'] is 1: self.emit_event( 'softban', level='warning', formatted='Failed to use berry. You may be softbanned.' ) else: self.emit_event( 'threw_berry_failed', formatted='Unknown response when throwing berry: {status_code}.', data={ 'status_code': response_dict['status_code'] } ) #use the best ball to catch current_type = pokeball #debug use normal ball while current_type < 3: current_type += 1 if catch_rate[pokeball-1] < 0.9 and items_stock[current_type] > 0: # if current ball chance to catch is under 90%, and player has better ball - then use it pokeball = current_type # use better ball else: # If we have a lot of berries (than the great ball), we prefer use a berry first! if catch_rate[pokeball-1] < 0.42 and items_stock[pokeball+1]+30 < berries_count: # If it's not the VIP type, we don't want to waste our ultra ball if no balls left. if items_stock[1] == 0 and items_stock[2] == 0: break success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) self.emit_event( 'pokemon_catch_rate', level='debug', formatted="Catch rate of {catch_rate} is low. Maybe will throw {berry_name} ({berry_count} left)", data={ 'catch_rate': success_percentage, 'berry_name': self.item_list[str(berry_id)], 'berry_count': berries_count-1 } ) response_dict = self.api.use_item_capture(item_id=berry_id, encounter_id=encounter_id, spawn_point_id=self.spawn_point_guid ) if response_dict and response_dict['status_code'] is 1 and 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: for i in range(len(catch_rate)): if 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: catch_rate[i] = catch_rate[i] * response_dict['responses']['USE_ITEM_CAPTURE']['item_capture_mult'] success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) berries_count = berries_count -1 berry_used = True self.emit_event( 'threw_berry', formatted="Threw a {berry_name}! Catch rate now: {new_catch_rate}", data={ "berry_name": self.item_list[str(berry_id)], "new_catch_rate": success_percentage } ) else: if response_dict['status_code'] is 1: self.emit_event( 'softban', level='warning', formatted='Failed to use berry. You may be softbanned.' ) else: self.emit_event( 'threw_berry_failed', formatted='Unknown response when throwing berry: {status_code}.', data={ 'status_code': response_dict['status_code'] } ) else: #We don't have many berry to waste, pick a good ball first. Save some berry for future VIP pokemon current_type = pokeball while current_type < 2: current_type += 1 if catch_rate[pokeball-1] < 0.35 and items_stock[current_type] > 0: # if current ball chance to catch is under 35%, and player has better ball - then use it pokeball = current_type # use better ball #if the rate is still low and we didn't throw a berry before use berry if catch_rate[pokeball-1] < 0.35 and berries_count > 0 and berry_used == False: # If it's not the VIP type, we don't want to waste our ultra ball if no balls left. if items_stock[1] == 0 and items_stock[2] == 0: break success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) self.emit_event( 'pokemon_catch_rate', level='debug', formatted="Catch rate of {catch_rate} is low. Throwing {berry_name} ({berry_count} left)", data={ 'catch_rate': success_percentage, 'berry_name': self.item_list[str(berry_id)], 'berry_count': berries_count-1 } ) response_dict = self.api.use_item_capture(item_id=berry_id, encounter_id=encounter_id, spawn_point_id=self.spawn_point_guid ) if response_dict and response_dict['status_code'] is 1 and 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: for i in range(len(catch_rate)): if 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: catch_rate[i] = catch_rate[i] * response_dict['responses']['USE_ITEM_CAPTURE']['item_capture_mult'] success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) berries_count = berries_count -1 berry_used = True self.emit_event( 'threw_berry', formatted="Threw a {berry_name}! Catch rate now: {new_catch_rate}", data={ "berry_name": self.item_list[str(berry_id)], "new_catch_rate": success_percentage } ) else: if response_dict['status_code'] is 1: self.emit_event( 'softban', level='warning', formatted='Failed to use berry. You may be softbanned.' ) else: self.emit_event( 'threw_berry_failed', formatted='Unknown response when throwing berry: {status_code}.', data={ 'status_code': response_dict['status_code'] } ) # Re-check if berry is used, find a ball for a good capture rate current_type=pokeball while current_type < 2: current_type += 1 if catch_rate[pokeball-1] < 0.35 and items_stock[current_type] > 0: pokeball = current_type # use better ball # This is to avoid rare case that a berry has ben throwed <0.42 # and still picking normal pokeball (out of stock) -> error if items_stock[1] == 0 and items_stock[2] > 0: pokeball = 2 # Add this logic to avoid Pokeball = 0, Great Ball = 0, Ultra Ball = X # And this logic saves Ultra Balls if it's a weak trash pokemon if catch_rate[pokeball-1]<0.30 and items_stock[3]>0: pokeball = 3 items_stock[pokeball] -= 1 success_percentage = '{0:.2f}'.format(catch_rate[pokeball - 1] * 100) self.emit_event( 'threw_pokeball', formatted='Used {pokeball}, with chance {success_percentage} ({count_left} left)', data={ 'pokeball': self.item_list[str(pokeball)], 'success_percentage': success_percentage, 'count_left': items_stock[pokeball] } ) id_list1 = self.count_pokemon_inventory() 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=pokeball, 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 ) if response_dict and \ 'responses' in response_dict and \ 'CATCH_POKEMON' in response_dict['responses'] and \ 'status' in response_dict['responses']['CATCH_POKEMON']: status = response_dict['responses'][ 'CATCH_POKEMON']['status'] if status is 2: self.emit_event( 'pokemon_fled', formatted="{pokemon} fled.", data={'pokemon': pokemon_name} ) sleep(2) continue if status is 3: self.emit_event( 'pokemon_vanished', formatted="{pokemon} vanished!", data={'pokemon': pokemon_name} ) if success_percentage == 100: self.softban = True if status is 1: self.bot.metrics.captured_pokemon(pokemon_name, cp, iv_display, pokemon_potential) self.emit_event( 'pokemon_caught', formatted='Captured {pokemon}! [CP {cp}] [Potential {iv}] [{iv_display}] [+{exp} exp]', data={ 'pokemon': pokemon_name, 'cp': cp, 'iv': pokemon_potential, 'iv_display': iv_display, 'exp': sum(response_dict['responses']['CATCH_POKEMON']['capture_award']['xp']) } ) self.bot.softban = False if (self.config.evolve_captured and (self.config.evolve_captured[0] == 'all' or pokemon_name in self.config.evolve_captured)): id_list2 = self.count_pokemon_inventory() # No need to capture this even for metrics, player stats includes it. pokemon_to_transfer = list(set(id_list2) - set(id_list1)) # TODO dont throw RuntimeError, do something better if len(pokemon_to_transfer) == 0: raise RuntimeError( 'Trying to evolve 0 pokemons!') response_dict = self.api.evolve_pokemon(pokemon_id=pokemon_to_transfer[0]) status = response_dict['responses']['EVOLVE_POKEMON']['result'] if status == 1: self.emit_event( 'pokemon_evolved', formatted="{pokemon} evolved!", data={'pokemon': pokemon_name} ) else: self.emit_event( 'pokemon_evolve_fail', formatted="Failed to evolve {pokemon}!", data={'pokemon': pokemon_name} ) break time.sleep(5)
def work(self): encounter_id = self.pokemon['encounter_id'] response_dict = self.create_encounter_api_call() if response_dict and 'responses' in response_dict: if self.response_key in response_dict['responses']: if self.response_status_key in response_dict['responses'][self.response_key]: if response_dict['responses'][self.response_key][self.response_status_key] is 1: cp = 0 if 'wild_pokemon' in response_dict['responses'][self.response_key] or 'pokemon_data' in \ response_dict['responses'][self.response_key]: if self.response_key == 'ENCOUNTER': pokemon = response_dict['responses'][self.response_key]['wild_pokemon'] else: pokemon = response_dict['responses'][self.response_key] catch_rate = response_dict['responses'][self.response_key]['capture_probability'][ 'capture_probability'] # 0 = pokeballs, 1 great balls, 3 ultra balls if 'pokemon_data' in pokemon and 'cp' in pokemon['pokemon_data']: pokemon_data = pokemon['pokemon_data'] cp = pokemon_data['cp'] individual_attack = pokemon_data.get("individual_attack", 0) individual_stamina = pokemon_data.get("individual_stamina", 0) individual_defense = pokemon_data.get("individual_defense", 0) iv_display = '{}/{}/{}'.format( individual_attack, individual_defense, individual_stamina ) pokemon_potential = self.pokemon_potential(pokemon_data) pokemon_num = int(pokemon_data['pokemon_id']) - 1 pokemon_name = self.pokemon_list[int(pokemon_num)]['Name'] logger.log('A Wild {} appeared! [CP {}] [Potential {}]'.format( pokemon_name, cp, pokemon_potential), 'yellow') logger.log('IV [Attack/Defense/Stamina] = [{}]'.format(iv_display)) pokemon_data['name'] = pokemon_name # Simulate app sleep(3) if not self.should_capture_pokemon(pokemon_name, cp, pokemon_potential, response_dict): # logger.log('[x] Rule prevents capture.') return False flag_VIP = False # @TODO, use the best ball in stock to catch VIP (Very Important Pokemon: Configurable) if self.check_vip_pokemon(pokemon_name, cp, pokemon_potential): logger.log('[-] {} is a VIP Pokemon! [CP {}] [Potential {}] Nice! Try our best to catch it!'.format(pokemon_name, cp, pokemon_potential),'red') flag_VIP=True items_stock = self.bot.current_inventory() berry_id = 701 # @ TODO: use better berries if possible berries_count = self.bot.item_inventory_count(berry_id) while True: # pick the most simple ball from stock pokeball = 1 # start from 1 - PokeBalls berry_used = False if flag_VIP: if(berries_count > 0 and catch_rate[pokeball-1] < 0.9): success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) logger.log('Catch Rate with normal Pokeball is low ({}%). Thinking to throw a {}... ({} left!)'.format(success_percentage,self.item_list[str(berry_id)],berries_count-1)) # Out of all pokeballs! Let's don't waste berry. if items_stock[1] == 0 and items_stock[2] == 0 and items_stock[3] == 0: break # Use the berry to catch self.api.use_item_capture(item_id = berry_id,encounter_id = encounter_id,spawn_point_id = self.spawn_point_guid) response_dict = get_api_response(self.api) if response_dict and response_dict['status_code'] is 1 and 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: for i in range(len(catch_rate)): if 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: catch_rate[i] = catch_rate[i] * response_dict['responses']['USE_ITEM_CAPTURE']['item_capture_mult'] success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) berries_count = berries_count -1 berry_used = True logger.log('Threw a berry! Catch Rate with normal Pokeball has increased to {}%'.format(success_percentage)) else: if response_dict['status_code'] is 1: logger.log('Fail to use berry. Seem like you are softbanned.', 'red') else: logger.log('Fail to use berry. Status Code: {}'.format(response_dict['status_code']),'red') #use the best ball to catch current_type = pokeball #debug use normal ball while current_type < 3: current_type += 1 if catch_rate[pokeball-1] < 0.9 and items_stock[current_type] > 0: # if current ball chance to catch is under 90%, and player has better ball - then use it pokeball = current_type # use better ball else: # If we have a lot of berries (than the great ball), we prefer use a berry first! if catch_rate[pokeball-1] < 0.42 and items_stock[pokeball+1]+30 < berries_count: # If it's not the VIP type, we don't want to waste our ultra ball if no balls left. if items_stock[1] == 0 and items_stock[2] == 0: break success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) logger.log('Catch Rate with normal Pokeball is low ({}%). Thinking to throw a {}... ({} left!)'.format(success_percentage,self.item_list[str(berry_id)],berries_count-1)) self.api.use_item_capture(item_id = berry_id,encounter_id = encounter_id,spawn_point_id = self.spawn_point_guid) response_dict = get_api_response(self.api) if response_dict and response_dict['status_code'] is 1 and 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: for i in range(len(catch_rate)): if 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: catch_rate[i] = catch_rate[i] * response_dict['responses']['USE_ITEM_CAPTURE']['item_capture_mult'] success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) berries_count = berries_count -1 berry_used = True logger.log('Threw a berry! Catch Rate with normal Pokeball has increased to {}%'.format(success_percentage)) else: if response_dict['status_code'] is 1: logger.log('Fail to use berry. Seem like you are softbanned.', 'red') else: logger.log('Fail to use berry. Status Code: {}'.format(response_dict['status_code']),'red') else: #We don't have many berry to waste, pick a good ball first. Save some berry for future VIP pokemon current_type = pokeball while current_type < 2: current_type += 1 if catch_rate[pokeball-1] < 0.35 and items_stock[current_type] > 0: # if current ball chance to catch is under 35%, and player has better ball - then use it pokeball = current_type # use better ball #if the rate is still low and we didn't throw a berry before use berry if catch_rate[pokeball-1] < 0.35 and berries_count > 0 and berry_used == False: # If it's not the VIP type, we don't want to waste our ultra ball if no balls left. if items_stock[1] == 0 and items_stock[2] == 0: break success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) logger.log('Catch Rate with normal Pokeball is low ({}%). Thinking to throw a {}... ({} left!)'.format(success_percentage,self.item_list[str(berry_id)],berries_count-1)) self.api.use_item_capture(item_id = berry_id,encounter_id = encounter_id,spawn_point_id = self.spawn_point_guid) response_dict = get_api_response(self.api) if response_dict and response_dict['status_code'] is 1 and 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: for i in range(len(catch_rate)): if 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']: catch_rate[i] = catch_rate[i] * response_dict['responses']['USE_ITEM_CAPTURE']['item_capture_mult'] success_percentage = '{0:.2f}'.format(catch_rate[pokeball-1]*100) berries_count = berries_count -1 berry_used = True logger.log('Threw a berry! Catch Rate with normal Pokeball has increased to {}%'.format(success_percentage)) else: if response_dict['status_code'] is 1: logger.log('Fail to use berry. Seem like you are softbanned.', 'red') else: logger.log('Fail to use berry. Status Code: {}'.format(response_dict['status_code']),'red') # Re-check if berry is used, find a ball for a good capture rate current_type=pokeball while current_type < 2: current_type += 1 if catch_rate[pokeball-1] < 0.35 and items_stock[current_type] > 0: pokeball = current_type # use better ball # This is to avoid rare case that a berry has ben throwed <0.42 # and still picking normal pokeball (out of stock) -> error if items_stock[1] == 0 and items_stock[2] > 0: pokeball = 2 # Add this logic to avoid Pokeball = 0, Great Ball = 0, Ultra Ball = X # And this logic saves Ultra Balls if it's a weak trash pokemon if catch_rate[pokeball-1]<0.30 and items_stock[3]>0: pokeball = 3 items_stock[pokeball] -= 1 success_percentage = '{0:.2f}'.format(catch_rate[pokeball - 1] * 100) logger.log('Using {} (chance: {}%)... ({} left!)'.format( self.item_list[str(pokeball)], success_percentage, items_stock[pokeball] )) id_list1 = self.count_pokemon_inventory() reticle_size_parameter = normalized_reticle_size(self.config.catch_randomize_reticle_factor) spin_modifier_parameter = spin_modifier(self.config.catch_randomize_spin_factor) self.api.catch_pokemon(encounter_id=encounter_id, pokeball=pokeball, 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) response_dict = get_api_response(self.api) if response_dict and \ 'responses' in response_dict and \ 'CATCH_POKEMON' in response_dict['responses'] and \ 'status' in response_dict['responses']['CATCH_POKEMON']: status = response_dict['responses'][ 'CATCH_POKEMON']['status'] if status is 2: logger.log( '[-] Attempted to capture {} - failed.. trying again!'.format(pokemon_name), 'red') sleep(2) continue if status is 3: logger.log( 'Oh no! {} vanished! :('.format(pokemon_name), 'red') if success_percentage == 100: self.softban = True if status is 1: self.bot.metrics.captured_pokemon(pokemon_name, cp, iv_display, pokemon_potential) logger.log('Captured {}! [CP {}] [Potential {}] [{}] [+{} exp]'.format( pokemon_name, cp, pokemon_potential, iv_display, sum(response_dict['responses']['CATCH_POKEMON']['capture_award']['xp']) ), 'blue') self.bot.softban = False if (self.config.evolve_captured and (self.config.evolve_captured[0] == 'all' or pokemon_name in self.config.evolve_captured)): id_list2 = self.count_pokemon_inventory() # No need to capture this even for metrics, player stats includes it. pokemon_to_transfer = list(set(id_list2) - set(id_list1)) # TODO dont throw RuntimeError, do something better if len(pokemon_to_transfer) == 0: raise RuntimeError( 'Trying to evolve 0 pokemons!') self.api.evolve_pokemon(pokemon_id=pokemon_to_transfer[0]) response_dict = get_api_response(self.api) status = response_dict['responses']['EVOLVE_POKEMON']['result'] if status == 1: logger.log( '{} has been evolved!'.format(pokemon_name), 'green') else: logger.log( 'Failed to evolve {}!'.format(pokemon_name)) break time.sleep(7)