-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Now track inventory when spinning a fort #3774
Changes from 13 commits
4b753af
2af365d
20bff34
e1d24ef
8732775
be193eb
e5e4e5b
472c7aa
0d5c891
5379ed5
b047d12
7edfabb
067ae45
cf6c5bf
6b8dc43
a18d1c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,6 +101,7 @@ share/ | |
# PyCharm IDE settings | ||
.idea/ | ||
*.iml | ||
out/ | ||
|
||
# Personal load details | ||
src/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,13 @@ | ||
# -*- coding: utf-8 -*- | ||
from __future__ import unicode_literals | ||
|
||
import json | ||
import json | ||
import os | ||
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 | ||
|
@@ -14,6 +16,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 | ||
|
@@ -22,12 +29,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() | ||
|
@@ -50,25 +58,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: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yesss! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should make a naming convention for these imo. I don’t like mine so if you got an idea |
||
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( | ||
|
@@ -77,7 +76,7 @@ def work(self): | |
data={ | ||
'pokestop': fort_name, | ||
'exp': experience_awarded, | ||
'items': tmp_count_items | ||
'items': items_awarded | ||
} | ||
) | ||
else: | ||
|
@@ -90,13 +89,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: | ||
|
@@ -110,7 +109,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', | ||
|
@@ -165,3 +164,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']) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,6 +106,25 @@ def captured(self, pokemon_id): | |
return False | ||
return self._data[pokemon_id]['times_captured'] > 0 | ||
|
||
class Item(object): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Didn't this just get moved below in a previous PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes someone did. Maybe for the best. But when merging conflicts I simply accepted my modified version. We need to heavily refactor this class anyway, so I didn’t take the time to move it again. |
||
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' | ||
|
@@ -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): | ||
|
@@ -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 | ||
|
@@ -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 | ||
|
@@ -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 | ||
|
||
|
@@ -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 | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicated import detected :P