Skip to content

Commit

Permalink
[Inventory Management] Add a central class for caching/parsing invent…
Browse files Browse the repository at this point in the history
…ory & static data (#2528)

* new class to centralize inventory management

* use new inventory class in evolve_pokemon

* use new inventory to display # candy after catch
  • Loading branch information
aeckert authored and elicwhite committed Aug 9, 2016
1 parent 61b6854 commit 03d7f92
Show file tree
Hide file tree
Showing 4 changed files with 293 additions and 68 deletions.
7 changes: 6 additions & 1 deletion pokemongo_bot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@
from pokemongo_bot.websocket_remote_control import WebsocketRemoteControl
from worker_result import WorkerResult
from tree_config_builder import ConfigException, MismatchTaskApiVersion, TreeConfigBuilder
from inventory import init_inventory
from sys import platform as _platform
import struct


class PokemonGoBot(object):
@property
def position(self):
Expand Down Expand Up @@ -286,7 +289,7 @@ def _register_events(self):
self.event_manager.register_event('skip_evolve')
self.event_manager.register_event('threw_berry_failed', parameters=('status_code',))
self.event_manager.register_event('vip_pokemon')

self.event_manager.register_event('gained_candy', parameters=('quantity', 'type'))

# level up stuff
self.event_manager.register_event(
Expand Down Expand Up @@ -782,6 +785,8 @@ def get_inventory(self):
return self.latest_inventory

def update_inventory(self):
# TODO: transition to using this inventory class everywhere
init_inventory(self)
response = self.get_inventory()
self.inventory = list()
inventory_items = response.get('responses', {}).get('GET_INVENTORY', {}).get(
Expand Down
85 changes: 20 additions & 65 deletions pokemongo_bot/cell_workers/evolve_pokemon.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from pokemongo_bot import inventory
from pokemongo_bot.human_behaviour import sleep
from pokemongo_bot.item_list import Item
from pokemongo_bot.base_task import BaseTask
Expand Down Expand Up @@ -25,21 +26,16 @@ def work(self):
if not self._should_run():
return

response_dict = self.api.get_inventory()
inventory_items = response_dict.get('responses', {}).get('GET_INVENTORY', {}).get('inventory_delta', {}).get(
'inventory_items', {})

evolve_list = self._sort_and_filter(inventory_items)
evolve_list = self._sort_and_filter()

if self.evolve_all[0] != 'all':
# filter out non-listed pokemons
evolve_list = filter(lambda x: x["name"] in self.evolve_all, evolve_list)
evolve_list = filter(lambda x: x.name in self.evolve_all, evolve_list)

cache = {}
candy_list = self._get_candy_list(inventory_items)
for pokemon in evolve_list:
if self._can_evolve(pokemon, candy_list, cache):
self._execute_pokemon_evolve(pokemon, candy_list, cache)
if pokemon.can_evolve_now():
self._execute_pokemon_evolve(pokemon, cache)

def _should_run(self):
if not self.evolve_all or self.evolve_all[0] == 'none':
Expand Down Expand Up @@ -80,81 +76,40 @@ def _should_run(self):
)
return False

def _get_candy_list(self, inventory_items):
candies = {}
for item in inventory_items:
candy = item.get('inventory_item_data', {}).get('candy', {})
family_id = candy.get('family_id', 0)
amount = candy.get('candy', 0)
if family_id > 0 and amount > 0:
family = self.bot.pokemon_list[family_id - 1]['Name'] + " candies"
candies[family] = amount

return candies

def _sort_and_filter(self, inventory_items):
def _sort_and_filter(self):
pokemons = []
logic_to_function = {
'or': lambda pokemon: pokemon["cp"] >= self.evolve_above_cp or pokemon["iv"] >= self.evolve_above_iv,
'and': lambda pokemon: pokemon["cp"] >= self.evolve_above_cp and pokemon["iv"] >= self.evolve_above_iv
'or': lambda pokemon: pokemon.cp >= self.evolve_above_cp or pokemon.iv >= self.evolve_above_iv,
'and': lambda pokemon: pokemon.cp >= self.evolve_above_cp and pokemon.iv >= self.evolve_above_iv
}
for item in inventory_items:
pokemon = item.get('inventory_item_data', {}).get('pokemon_data', {})
pokemon_num = int(pokemon.get('pokemon_id', 0)) - 1
next_evol = self.bot.pokemon_list[pokemon_num].get('Next Evolution Requirements', {})
pokemon = {
'id': pokemon.get('id', 0),
'num': pokemon_num,
'name': self.bot.pokemon_list[pokemon_num]['Name'],
'cp': pokemon.get('cp', 0),
'iv': self._compute_iv(pokemon),
'candies_family': next_evol.get('Name', ""),
'candies_amount': next_evol.get('Amount', 0)
}
if pokemon["id"] > 0 and pokemon["candies_amount"] > 0 and (logic_to_function[self.cp_iv_logic](pokemon)):

for pokemon in inventory.pokemons().all():
if pokemon.id > 0 and pokemon.has_next_evolution() and (logic_to_function[self.cp_iv_logic](pokemon)):
pokemons.append(pokemon)

if self.first_evolve_by == "cp":
pokemons.sort(key=lambda x: (x['num'], x["cp"], x["iv"]), reverse=True)
pokemons.sort(key=lambda x: (x.pokemon_id, x.cp, x.iv), reverse=True)
else:
pokemons.sort(key=lambda x: (x['num'], x["iv"], x["cp"]), reverse=True)
pokemons.sort(key=lambda x: (x.pokemon_id, x.iv, x.cp), reverse=True)

return pokemons

def _can_evolve(self, pokemon, candy_list, cache):

if pokemon["name"] in cache:
return False

family = pokemon["candies_family"]
amount = pokemon["candies_amount"]
if family in candy_list and candy_list[family] >= amount:
return True
else:
cache[pokemon["name"]] = 1
return False

def _execute_pokemon_evolve(self, pokemon, candy_list, cache):
pokemon_id = pokemon["id"]
pokemon_name = pokemon["name"]
pokemon_cp = pokemon["cp"]
pokemon_iv = pokemon["iv"]

if pokemon_name in cache:
def _execute_pokemon_evolve(self, pokemon, cache):
if pokemon.name in cache:
return False

response_dict = self.api.evolve_pokemon(pokemon_id=pokemon_id)
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
'pokemon': pokemon.name,
'iv': pokemon.iv,
'cp': pokemon.cp
}
)
candy_list[pokemon["candies_family"]] -= pokemon["candies_amount"]
inventory.candies().get(pokemon.pokemon_id).consume(pokemon.evolution_cost)
sleep(self.evolve_speed)
return True
else:
Expand Down
18 changes: 16 additions & 2 deletions pokemongo_bot/cell_workers/pokemon_catch_worker.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-

import time
from pokemongo_bot import inventory
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.human_behaviour import normalized_reticle_size, sleep, spin_modifier

Expand All @@ -27,8 +28,8 @@
class Pokemon(object):

def __init__(self, pokemon_list, pokemon_data):
self.num = int(pokemon_data['pokemon_id']) - 1
self.name = pokemon_list[int(self.num)]['Name']
self.num = int(pokemon_data['pokemon_id'])
self.name = pokemon_list[int(self.num) - 1]['Name']
self.cp = pokemon_data['cp']
self.attack = pokemon_data.get('individual_attack', 0)
self.defense = pokemon_data.get('individual_defense', 0)
Expand Down Expand Up @@ -388,6 +389,19 @@ def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False):
'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
Expand Down
Loading

1 comment on commit 03d7f92

@achretien
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Transfer task should also add 1 candy for the family

Please sign in to comment.