Repository: PokemonGoF/PokemonGo-Bot

Issue:
Pokemon will now be caught from lures
### Short Description:

Pokemon will now be caught from lures
### Fixes:
- When visiting a pokestop, the bot will check for lures and catch any pokemon spawning from it.
### Important

PgoAPI should be updated to the latest version!
Instructions will be shown if an outdated version is detected.

![2016-07-26 17_31_46-c__windows_system32_cmd exe](https://cloud.githubusercontent.com/assets/1166874/17155707/94102fce-5386-11e6-9bf9-1e53afc5a8e9.png)



Discussion:
Removed the warning message and moved the api call to a new method.


Resolving patch:
diff --git a/pokemongo_bot/cell_workers/pokemon_catch_worker.py b/pokemongo_bot/cell_workers/pokemon_catch_worker.py
--- a/pokemongo_bot/cell_workers/pokemon_catch_worker.py
+++ b/pokemongo_bot/cell_workers/pokemon_catch_worker.py
@@ -20,33 +20,38 @@ def __init__(self, pokemon, bot):
         self.pokemon_list = bot.pokemon_list
         self.item_list = bot.item_list
         self.inventory = bot.inventory
+        self.spawn_point_guid = ''
+        self.response_key = ''
+        self.response_status_key = ''
 
     def work(self):
+
         encounter_id = self.pokemon['encounter_id']
-        spawnpoint_id = self.pokemon['spawnpoint_id']
-        player_latitude = self.pokemon['latitude']
-        player_longitude = self.pokemon['longitude']
-        self.api.encounter(encounter_id=encounter_id, spawnpoint_id=spawnpoint_id,
-                           player_latitude=player_latitude, player_longitude=player_longitude)
-        response_dict = self.api.call()
+
+        response_dict = self.create_encounter_api_call()
 
         if response_dict and 'responses' in response_dict:
-            if 'ENCOUNTER' in response_dict['responses']:
-                if 'status' in response_dict['responses']['ENCOUNTER']:
-                    if response_dict['responses']['ENCOUNTER']['status'] is 7:
+            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 7:
                         if self.config.initial_transfer:
                             logger.log('Pokemon Bag is full!', 'red')
                             return PokemonCatchWorker.BAG_FULL
                         else:
                             raise RuntimeError('Pokemon Bag is full!')
 
-                    if response_dict['responses']['ENCOUNTER']['status'] is 1:
+                    if response_dict['responses'][self.response_key][self.response_status_key] is 1:
                         cp = 0
                         total_IV = 0
-                        if 'wild_pokemon' in response_dict['responses']['ENCOUNTER']:
-                            pokemon = response_dict['responses']['ENCOUNTER']['wild_pokemon']
-                            catch_rate = response_dict['responses']['ENCOUNTER']['capture_probability']['capture_probability'] # 0 = pokeballs, 1 great balls, 3 ultra balls
-
+                        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']:
                                 cp = pokemon['pokemon_data']['cp']
 
@@ -91,13 +96,13 @@ def work(self):
                                 sleep(3)
 
                         if not self.should_capture_pokemon(pokemon_name, cp, pokemon_potential, response_dict):
-                            #logger.log('[x] Rule prevents capture.')
+                            # logger.log('[x] Rule prevents capture.')
                             return False
 
                         balls_stock = self.bot.pokeball_inventory()
                         while(True):
 
-                            ## pick the most simple ball from stock
+                            # pick the most simple ball from stock
                             pokeball = 1 # start from 1 - PokeBalls
 
                             current_type = pokeball
@@ -106,14 +111,14 @@ def work(self):
                                 if balls_stock[current_type] > 0: # next tier's stock > 0
                                     pokeball = current_type
 
-                            ## re-check stock again
+                            # re-check stock again
                             if balls_stock[pokeball] is 0:
                                 logger.log('Out of pokeballs, switching to farming mode...', 'red')
                                 # Begin searching for pokestops.
                                 self.config.mode = 'farm'
                                 return PokemonCatchWorker.NO_POKEBALLS
 
-                            ## Use berry to increase success chance.
+                            # Use berry to increase success chance.
                             berry_id = 701 # @ TODO: use better berries if possible
                             berries_count = self.bot.item_inventory_count(berry_id)
                             if(catch_rate[pokeball-1] < 0.5 and berries_count > 0): # and berry is in stock
@@ -125,8 +130,8 @@ def work(self):
 
                                 self.api.use_item_capture(
                                     item_id=berry_id,
-                                    encounter_id = encounter_id,
-                                    spawn_point_guid = spawnpoint_id
+                                    encounter_id=encounter_id,
+                                    spawn_point_guid=self.spawn_point_guid
                                 )
                                 response_dict = self.api.call()
                                 if response_dict and response_dict['status_code'] is 1 and 'item_capture_mult' in response_dict['responses']['USE_ITEM_CAPTURE']:
@@ -142,7 +147,7 @@ def work(self):
                                     else:
                                         logger.log('Fail to use berry. Status Code: {}'.format(response_dict['status_code']),'red')
 
-                            ## change ball to next tier if catch rate is too low
+                            # change ball to next tier if catch rate is too low
                             current_type = pokeball
                             while(current_type < 3):
                                 current_type = current_type+1
@@ -164,7 +169,7 @@ def work(self):
                             self.api.catch_pokemon(encounter_id=encounter_id,
                                                    pokeball=pokeball,
                                                    normalized_reticle_size=1.950,
-                                                   spawn_point_guid=spawnpoint_id,
+                                                   spawn_point_guid=self.spawn_point_guid,
                                                    hit_pokemon=1,
                                                    spin_modifier=1,
                                                    NormalizedHitPosition=1)
@@ -377,3 +382,26 @@ def _get_release_config_for(self, pokemon):
         if not release_config:
             release_config = {}
         return release_config
+
+    def create_encounter_api_call(self):
+
+        encounter_id = self.pokemon['encounter_id']
+        player_latitude = self.pokemon['latitude']
+        player_longitude = self.pokemon['longitude']
+
+        if 'spawnpoint_id' in self.pokemon:
+            spawnpoint_id = self.pokemon['spawnpoint_id']
+            self.spawn_point_guid = spawnpoint_id
+            self.response_key = 'ENCOUNTER'
+            self.response_status_key = 'status'
+            self.api.encounter(encounter_id=encounter_id, spawn_point_id=spawnpoint_id,
+                               player_latitude=player_latitude, player_longitude=player_longitude)
+        else:
+            fort_id = self.pokemon['fort_id']
+            self.spawn_point_guid = fort_id
+            self.response_key = 'DISK_ENCOUNTER'
+            self. response_status_key = 'result'
+            self.api.disk_encounter(encounter_id=encounter_id, fort_id=fort_id,
+                                    player_latitude=player_latitude, player_longitude=player_longitude)
+
+        return self.api.call()
diff --git a/pokemongo_bot/cell_workers/seen_fort_worker.py b/pokemongo_bot/cell_workers/seen_fort_worker.py
--- a/pokemongo_bot/cell_workers/seen_fort_worker.py
+++ b/pokemongo_bot/cell_workers/seen_fort_worker.py
@@ -6,6 +6,7 @@
 
 from pokemongo_bot import logger
 from pokemongo_bot.human_behaviour import sleep
+from pokemongo_bot.cell_workers import PokemonCatchWorker
 from utils import format_time
 
 
@@ -16,7 +17,11 @@ def __init__(self, fort, bot):
         self.bot = bot
         self.position = bot.position
         self.config = bot.config
+        self.pokemon_list = bot.pokemon_list
         self.item_list = bot.item_list
+        self.inventory = bot.inventory
+        self.pokeball_inventory = bot.pokeball_inventory
+        self.item_inventory_count = bot.item_inventory_count
         self.rest_time = 50
 
     def work(self):
@@ -34,9 +39,28 @@ def work(self):
             fort_name = fort_details['name'].encode('utf8', 'replace')
         else:
             fort_name = 'Unknown'
-        logger.log('Now at Pokestop: ' + fort_name + ' - Spinning...',
+        logger.log('Now at Pokestop: ' + fort_name,
                    'cyan')
-        sleep(2)
+        if self.config.mode != 'farm' and 'lure_info' in self.fort:
+            # Check if the lure has a pokemon active
+            if 'encounter_id' in self.fort['lure_info']:
+                logger.log("Found a lure on this pokestop! Catching pokemon...", 'cyan')
+
+                pokemon = {
+                    'encounter_id': self.fort['lure_info']['encounter_id'],
+                    'fort_id': self.fort['id'],
+                    'latitude': self.fort['latitude'],
+                    'longitude': self.fort['longitude']
+                }
+
+                self.catch_pokemon(pokemon)
+
+            else:
+                logger.log('Found a lure, but there is no pokemon present.', 'yellow')
+            sleep(2)
+
+        logger.log('Spinning ...', 'cyan')
+
         self.api.fort_search(fort_id=self.fort['id'],
                              fort_latitude=lat,
                              fort_longitude=lng,
@@ -141,6 +165,16 @@ def work(self):
         sleep(8)
         return 0
 
+    def catch_pokemon(self, pokemon):
+        worker = PokemonCatchWorker(pokemon, self)
+        return_value = worker.work()
+
+        if return_value == PokemonCatchWorker.BAG_FULL:
+            worker = InitialTransferWorker(self)
+            worker.work()
+
+        return return_value
+
     @staticmethod
     def closest_fort(current_lat, current_long, forts):
         print x


Test patch: