Skip to content

Commit

Permalink
Now track inventory when spinning a fort (#3774)
Browse files Browse the repository at this point in the history
* Ignoring compiled test python file of PyCharm

* Now spinning fort keeps track of cached inventory

* Now the pokemon_catch_worker keeps track of cached  ITEMS (and only items, not pokemon) inventory

* Minor improvements of the new inventory

* Fixed key error

* Minor improvements of the new inventory

* Fixed attribute non existent

* Removed duplicated import
  • Loading branch information
BriceSD authored and TheSavior committed Aug 13, 2016
1 parent 6ffc8c0 commit dbf26d5
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 43 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ share/
# PyCharm IDE settings
.idea/
*.iml
out/

# Personal load details
src/
Expand Down
3 changes: 2 additions & 1 deletion pokemongo_bot/cell_workers/move_to_fort.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from pokemongo_bot import inventory
from pokemongo_bot.constants import Constants
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.worker_result import WorkerResult
Expand All @@ -18,7 +19,7 @@ def initialize(self):
self.ignore_item_count = self.config.get("ignore_item_count", False)

def should_run(self):
has_space_for_loot = self.bot.has_space_for_loot()
has_space_for_loot = inventory.Items.has_space_for_loot()
if not has_space_for_loot and not self.ignore_item_count:
self.emit_event(
'inventory_full',
Expand Down
2 changes: 1 addition & 1 deletion pokemongo_bot/cell_workers/recycle_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def should_run(self):
:return: True if the recycling process should be run; otherwise, False.
:rtype: bool
"""
if inventory.items().get_space_left() < (DEFAULT_MIN_EMPTY_SPACE if self.min_empty_space is None else self.min_empty_space):
if inventory.Items.get_space_left() < (DEFAULT_MIN_EMPTY_SPACE if self.min_empty_space is None else self.min_empty_space):
return True
return False

Expand Down
62 changes: 42 additions & 20 deletions pokemongo_bot/cell_workers/spin_fort.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import time

from pgoapi.utilities import f2i
from pokemongo_bot import inventory

from pokemongo_bot.constants import Constants
from pokemongo_bot.human_behaviour import sleep
Expand All @@ -14,6 +15,11 @@
from pokemongo_bot.base_dir import _base_dir
from utils import distance, format_time, fort_details

SPIN_REQUEST_RESULT_SUCCESS = 1
SPIN_REQUEST_RESULT_OUT_OF_RANGE = 2
SPIN_REQUEST_RESULT_IN_COOLDOWN_PERIOD = 3
SPIN_REQUEST_RESULT_INVENTORY_FULL = 4


class SpinFort(BaseTask):
SUPPORTED_TASK_API_VERSION = 1
Expand All @@ -22,12 +28,13 @@ def initialize(self):
self.ignore_item_count = self.config.get("ignore_item_count", False)

def should_run(self):
if not self.bot.has_space_for_loot() and not self.ignore_item_count:
has_space_for_loot = inventory.Items.has_space_for_loot()
if not has_space_for_loot and not self.ignore_item_count:
self.emit_event(
'inventory_full',
formatted="Inventory is full. You might want to change your config to recycle more items if this message appears consistently."
)
return self.ignore_item_count or self.bot.has_space_for_loot()
return self.ignore_item_count or has_space_for_loot

def work(self):
forts = self.get_forts_in_range()
Expand All @@ -50,25 +57,16 @@ def work(self):
player_latitude=f2i(self.bot.position[0]),
player_longitude=f2i(self.bot.position[1])
)
if 'responses' in response_dict and \
'FORT_SEARCH' in response_dict['responses']:
if 'responses' in response_dict and 'FORT_SEARCH' in response_dict['responses']:

spin_details = response_dict['responses']['FORT_SEARCH']
spin_result = spin_details.get('result', -1)
if spin_result == 1:
if spin_result == SPIN_REQUEST_RESULT_SUCCESS:
self.bot.softban = False
experience_awarded = spin_details.get('experience_awarded', 0)
items_awarded = spin_details.get('items_awarded', {})
if items_awarded:
self.bot.latest_inventory = None
tmp_count_items = {}
for item in items_awarded:
item_id = item['item_id']
item_name = self.bot.item_list[str(item_id)]
if not item_name in tmp_count_items:
tmp_count_items[item_name] = item['item_count']
else:
tmp_count_items[item_name] += item['item_count']


items_awarded = self.get_items_awarded_from_fort_spinned(response_dict)

if experience_awarded or items_awarded:
self.emit_event(
Expand All @@ -77,7 +75,7 @@ def work(self):
data={
'pokestop': fort_name,
'exp': experience_awarded,
'items': tmp_count_items
'items': items_awarded
}
)
else:
Expand All @@ -90,13 +88,13 @@ def work(self):
'cooldown_complete_timestamp_ms')
self.bot.fort_timeouts.update({fort["id"]: pokestop_cooldown})
self.bot.recent_forts = self.bot.recent_forts[1:] + [fort['id']]
elif spin_result == 2:
elif spin_result == SPIN_REQUEST_RESULT_OUT_OF_RANGE:
self.emit_event(
'pokestop_out_of_range',
formatted="Pokestop {pokestop} out of range.",
data={'pokestop': fort_name}
)
elif spin_result == 3:
elif spin_result == SPIN_REQUEST_RESULT_IN_COOLDOWN_PERIOD:
pokestop_cooldown = spin_details.get(
'cooldown_complete_timestamp_ms')
if pokestop_cooldown:
Expand All @@ -110,7 +108,7 @@ def work(self):
formatted="Pokestop {pokestop} on cooldown. Time left: {minutes_left}.",
data={'pokestop': fort_name, 'minutes_left': minutes_left}
)
elif spin_result == 4:
elif spin_result == SPIN_REQUEST_RESULT_INVENTORY_FULL:
if not self.ignore_item_count:
self.emit_event(
'inventory_full',
Expand Down Expand Up @@ -165,3 +163,27 @@ def get_forts_in_range(self):
) <= Constants.MAX_DISTANCE_FORT_IS_REACHABLE, forts)

return forts

def get_items_awarded_from_fort_spinned(self, response_dict):
items_awarded = response_dict['responses']['FORT_SEARCH'].get('items_awarded', {})
if items_awarded:
tmp_count_items = {}
for item_awarded in items_awarded:

item_awarded_id = item_awarded['item_id']
item_awarded_name = inventory.Items.name_for(item_awarded_id)
item_awarded_count = item_awarded['item_count']

if not item_awarded_name in tmp_count_items:
tmp_count_items[item_awarded_name] = item_awarded_count
else:
tmp_count_items[item_awarded_name] += item_awarded_count

self._update_inventory(item_awarded)

return tmp_count_items

# TODO : Refactor this class, hide the inventory update right after the api call
def _update_inventory(self, item_awarded):
inventory.items().get(item_awarded['item_id']).add(item_awarded['item_count'])

60 changes: 39 additions & 21 deletions pokemongo_bot/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,25 @@ def captured(self, pokemon_id):
return False
return self._data[pokemon_id]['times_captured'] > 0

class Item(object):
def __init__(self, item_id, item_count):
self.id = item_id
self.name = Items.name_for(self.id)
self.count = item_count

def remove(self, amount):
if self.count < amount:
raise Exception('Tried to remove more {} than you have'.format(self.name))
self.count -= amount

def add(self, amount):
if amount < 0:
raise Exception('Must add positive amount of {}'.format(self.name))
self.count += amount

def __str__(self):
return self.name + " : " + str(self.count)


class Items(_BaseInventoryComponent):
TYPE = 'item'
Expand Down Expand Up @@ -140,11 +159,23 @@ def get_space_used(cls):
def get_space_left(cls):
"""
Compute the space left in item inventory.
:return: The space left in item inventory.
:return: The space left in item inventory. 0 if the player has more item than his item inventory can carry.
:rtype: int
"""
_inventory.retrieve_item_inventory_size()
return _inventory.item_inventory_size - cls.get_space_used()
space_left = _inventory.item_inventory_size - cls.get_space_used()
# Space left should never be negative. Returning 0 if the computed value is negative.
return space_left if space_left >= 0 else 0

@classmethod
def has_space_for_loot(cls):
"""
Returns a value indicating whether or not the item inventory has enough space to loot a fort
:return: True if the item inventory has enough space; otherwise, False.
:rtype: bool
"""
max_number_of_items_looted_at_stop = 5
return cls.get_space_left() >= max_number_of_items_looted_at_stop


class Pokemons(_BaseInventoryComponent):
Expand Down Expand Up @@ -479,23 +510,6 @@ def add(self, amount):
self.quantity += amount


class Item(object):
def __init__(self, item_id, item_count):
self.id = item_id
self.name = Items.name_for(self.id)
self.count = item_count

def remove(self, amount):
if self.count < amount:
raise Exception('Tried to remove more {} than you have'.format(self.name))
self.count -= amount

def add(self, amount):
if amount < 0:
raise Exception('Must add positive amount of {}'.format(self.name))
self.count += amount


class Egg(object):
def __init__(self, data):
self._data = data
Expand Down Expand Up @@ -1004,6 +1018,7 @@ def refresh(self):
user_web_inventory = os.path.join(_base_dir, 'web', 'inventory-%s.json' % (self.bot.config.username))
with open(user_web_inventory, 'w') as outfile:
json.dump(inventory, outfile)

def retrieve_item_inventory_size(self):
"""
Retrieves the item inventory size
Expand Down Expand Up @@ -1087,12 +1102,10 @@ def init_inventory(bot):
def refresh_inventory():
_inventory.refresh()


def get_item_inventory_size():
_inventory.retrieve_item_inventory_size()
return _inventory.item_inventory_size


def pokedex():
return _inventory.pokedex

Expand All @@ -1110,6 +1123,11 @@ def pokemons(refresh=False):


def items():
"""
Access to the cached item inventory
:return: Instance of the cached item inventory
:rtype: Items
"""
return _inventory.items


Expand Down

0 comments on commit dbf26d5

Please sign in to comment.