Skip to content

Commit 77b94f0

Browse files
authored
Merge pull request jekirl#190 from sftwninja/needy-farmables
Allow bot to stop catching pokemon and farm balls when inventory is depleted
2 parents 43ed881 + a585ffd commit 77b94f0

File tree

3 files changed

+73
-3
lines changed

3 files changed

+73
-3
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ optional arguments:
5252
* `BIG_EGGS_FIRST` incubate big eggs (most km) first (default: true)
5353
* `RELEASE_DUPLICATES` The bot seems to have a bad habit of hoarding pokemon. Enabling this feature (disabled by default) will have the bot automatically transfer pokemon that are duplicates. To determine which pokemon to transfer when duplicates exist, the lvl's of the pokemon are compared. A pokemon's lvl is an arbitrary and configurable parameter that can either be representative of a pokemon's CP, IV, CPxIV, or CP+IV. The bot will transfer the lowest lvl pokemon, maintaining` MIN_SIMILAR_POKEMON` of each type. To be completely confident that the bot will not transfer your high lvl pokemon, when this feature is enabled only pokemon with a lvl below `RELEASE_DUPLICATES_MAX_LVL`. If you have multiple pokemon that are close to the same lvl the bot can be configured to not transfer them by using `RELEASE_DUPLICATES_SCALER`. The value of this config is multiplied by the highest lvl pokemon of a type and only those pokemon that are less than the scaled lvl are transfered.
5454
* EXAMPlES: If you set lvl to "IV" while having two Snorlaxs, one with stats CP:14 IV:95 and the other with CP:1800 IV:30 the bot will transfer the Snorlax with CP of 1800 and keep the CP 14 Snorlax because you have indicated you only care about a pokemon's IV. It must be fully understood why this happens to avoid unwanted transfer of pokemon. If not used correctly this feature can very easily transfer a large ammount of your pokemon so please make sure you fully understand it's mechanics before attempting use!
55-
55+
* `NEEDY_ITEM_FARMING` [Experimental] will cease trying to catch pokemon and roam around to collect more pokeballs when inventory is low
56+
* `ENABLE` : `Boolean`, whether or not this feature is enabled
57+
* `POKEBALL_FARM_THRESHOLD` : `Integer`, when the observed pokeball count drops on or below this number, skip catching pokemon and begin collecting.
58+
* `POKEBALL_CONTINUE_THRESHOLD`: `Integer`, when the observed pokeball count reaches this amount, stop farming and go back to catching pokemon.
59+
* `FARM_IGNORE_POKEBALL_COUNT`: `Boolean`, Whether to include this ball in counting. Same goes for `GREATBALL`, `ULTRABALL`, and `MASTERBALL`. Masterball is ignored by default.
60+
* `FARM_OVERRIDE_STEP_SIZE`: `Integer`, When it goes into farming mode, the bot assumes this step size to potentially speed up resource gathering. _This might lead to softbans._ Setting to `-1` disables this feature. Disabled by default for safety.
61+
* If `EXPERIMENTAL` OR `CATCH_POKEMON` are false, this configuration will disable itself.
5662

5763
## Requirements
5864
* Run `pip install -r requirements.txt`

config.json.example

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@
3131
"ITEM_MAX_REVIVE": 10,
3232
"ITEM_RAZZ_BERRY": 10
3333
},
34+
"NEEDY_ITEM_FARMING": {
35+
"ENABLE": true,
36+
"POKEBALL_CONTINUE_THRESHOLD": 50,
37+
"POKEBALL_FARM_THRESHOLD": 10,
38+
"FARM_IGNORE_POKEBALL_COUNT": false,
39+
"FARM_IGNORE_GREATBALL_COUNT": false,
40+
"FARM_IGNORE_ULTRABALL_COUNT": false,
41+
"FARM_IGNORE_MASTERBALL_COUNT": true,
42+
"FARM_OVERRIDE_STEP_SIZE": -1
43+
},
3444
"POKEMON_EVOLUTION": {
3545
"PIDGEY": 12,
3646
"WEEDLE":12

pgoapi/pgoapi.py

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ def __init__(self, config, pokemon_names):
7575
self._heartbeat_number = 5
7676
self._firstRun = True
7777
self._last_egg_use_time = 0
78+
self._farm_mode_triggered = False
79+
self._orig_step_size = config.get("STEP_SIZE", 200)
7880

7981
self.pokemon_caught = 0
8082
self.player = Player({})
@@ -97,6 +99,10 @@ def __init__(self, config, pokemon_names):
9799
self.POKEMON_EVOLUTION[getattr(Enums_pb2, k)] = v
98100
self.POKEMON_EVOLUTION_FAMILY[getattr(Enums_pb2, k)] = getattr(Enums_pb2, "FAMILY_" + k)
99101

102+
self.experimental = config.get("EXPERIMENTAL", False)
103+
104+
self.STEP_SIZE = self._orig_step_size
105+
100106
self.KEEP_IV_OVER = config.get("KEEP_IV_OVER", 0) # release anything under this
101107
self.KEEP_CP_OVER = config.get("KEEP_CP_OVER", 0) # release anything under this
102108

@@ -110,8 +116,17 @@ def __init__(self, config, pokemon_names):
110116
self.USE_DISPOSABLE_INCUBATORS = config.get("EGG_INCUBATION", {}).get("USE_DISPOSABLE_INCUBATORS", False)
111117
self.INCUBATE_BIG_EGGS_FIRST = config.get("EGG_INCUBATION", {}).get("BIG_EGGS_FIRST", True)
112118

119+
self.FARM_ITEMS_ENABLED = config.get("NEEDY_ITEM_FARMING", {}).get("ENABLE", True and self.experimental) # be concious of pokeball/item limits
120+
self.POKEBALL_CONTINUE_THRESHOLD = config.get("NEEDY_ITEM_FARMING", {}).get("POKEBALL_CONTINUE_THRESHOLD", 50) # keep at least 10 pokeballs of any assortment, otherwise go farming
121+
self.POKEBALL_FARM_THRESHOLD = config.get("NEEDY_ITEM_FARMING", {}).get("POKEBALL_FARM_THRESHOLD", 10) # at this point, go collect pokeballs
122+
self.FARM_IGNORE_POKEBALL_COUNT = config.get("NEEDY_ITEM_FARMING", {}).get("FARM_IGNORE_POKEBALL_COUNT", False) # ignore pokeballs in the continue tally
123+
self.FARM_IGNORE_GREATBALL_COUNT = config.get("NEEDY_ITEM_FARMING", {}).get("FARM_IGNORE_GREATBALL_COUNT", False) # ignore greatballs in the continue tally
124+
self.FARM_IGNORE_ULTRABALL_COUNT = config.get("NEEDY_ITEM_FARMING", {}).get("FARM_IGNORE_ULTRABALL_COUNT", False) # ignore ultraballs in the continue tally
125+
self.FARM_IGNORE_MASTERBALL_COUNT = config.get("NEEDY_ITEM_FARMING", {}).get("FARM_IGNORE_MASTERBALL_COUNT", True) # ignore masterballs in the continue tally
126+
self.FARM_OVERRIDE_STEP_SIZE = config.get("NEEDY_ITEM_FARMING", {}).get("FARM_OVERRIDE_STEP_SIZE", -1) # should the step size be overriden when looking for more inventory, -1 to disable
127+
# OVERRIDE STEP SIZE could be softbannable. No data to suggest either way.
128+
113129
self.visited_forts = ExpiringDict(max_len=120, max_age_seconds=config.get("SKIP_VISITED_FORT_DURATION", 600))
114-
self.experimental = config.get("EXPERIMENTAL", False)
115130
self.spin_all_forts = config.get("SPIN_ALL_FORTS", False)
116131
self.keep_pokemon_ids = map(lambda x: getattr(Enums_pb2, x), config.get("KEEP_POKEMON_NAMES", []))
117132
self.throw_pokemon_ids = map(lambda x: getattr(Enums_pb2, x), config.get("THROW_POKEMON_NAMES", []))
@@ -123,6 +138,19 @@ def __init__(self, config, pokemon_names):
123138
self.RELEASE_DUPLICATES_SCALER = config.get("RELEAES_DUPLICATES_SCALER", 1.0) # when comparing two pokemon's lvl, multiply larger by this
124139
self.DEFINE_POKEMON_LV = config.get("DEFINE_POKEMON_LV", "CP") # define a pokemon's lvl, options are CP, IV, CP*IV, CP+IV
125140

141+
# Sanity checking
142+
self.FARM_ITEMS_ENABLED = self.FARM_ITEMS_ENABLED and self.experimental and self.should_catch_pokemon # Experimental, and we needn't do this if we're farming anyway
143+
if ( self.FARM_ITEMS_ENABLED
144+
and self.FARM_IGNORE_POKEBALL_COUNT
145+
and self.FARM_IGNORE_GREATBALL_COUNT
146+
and self.FARM_IGNORE_ULTRABALL_COUNT
147+
and self.FARM_IGNORE_MASTERBALL_COUNT ):
148+
self.FARM_ITEMS_ENABLED = False
149+
self.log.warn("FARM_ITEMS has been disabled due to all Pokeball counts being ignored.")
150+
elif self.FARM_ITEMS_ENABLED and not (self.POKEBALL_FARM_THRESHOLD < self.POKEBALL_CONTINUE_THRESHOLD):
151+
self.FARM_ITEMS_ENABLED = False
152+
self.log.warn("FARM_ITEMS has been disabled due to farming threshold being below the continue. Set 'CATCH_POKEMON' to 'false' to enable captureless traveling.")
153+
126154
def call(self):
127155
if not self._req_method_list:
128156
return False
@@ -256,6 +284,32 @@ def heartbeat(self):
256284
self.cleanup_pokemon(self.inventory.inventory_items)
257285
# Auto-use lucky-egg if applicable
258286
self.use_lucky_egg()
287+
288+
# Farm precon
289+
if self.FARM_ITEMS_ENABLED:
290+
pokeball_count = 0
291+
if not self.FARM_IGNORE_POKEBALL_COUNT:
292+
pokeball_count += self.inventory.poke_balls
293+
if not self.FARM_IGNORE_GREATBALL_COUNT:
294+
pokeball_count += self.inventory.great_balls
295+
if not self.FARM_IGNORE_ULTRABALL_COUNT:
296+
pokeball_count += self.inventory.ultra_balls
297+
if not self.FARM_IGNORE_MASTERBALL_COUNT:
298+
pokeball_count += self.inventory.master_balls
299+
if self.POKEBALL_FARM_THRESHOLD > pokeball_count and not self._farm_mode_triggered:
300+
self.should_catch_pokemon = False
301+
self._farm_mode_triggered = True
302+
self.log.info("Player only has %s Pokeballs, farming for more...", pokeball_count)
303+
if self.FARM_OVERRIDE_STEP_SIZE != -1:
304+
self.STEP_SIZE = self.FARM_OVERRIDE_STEP_SIZE
305+
self.log.info("Player has changed speed to %s", self.STEP_SIZE)
306+
elif self.POKEBALL_CONTINUE_THRESHOLD <= pokeball_count and self._farm_mode_triggered:
307+
self.should_catch_pokemon = True
308+
self._farm_mode_triggered = False
309+
self.log.info("Player has %s Pokeballs, continuing to catch more!", pokeball_count)
310+
if self.FARM_OVERRIDE_STEP_SIZE != -1:
311+
self.STEP_SIZE = self._orig_step_size
312+
self.log.info("Player has returned to normal speed of %s", self.STEP_SIZE)
259313
self._heartbeat_number += 1
260314
return res
261315

@@ -283,7 +337,7 @@ def walk_to(self, loc, waypoints=[], directly=False): # location in floats of c
283337
self.experimental and self.spin_all_forts, waypoints)
284338
catch_attempt = 0
285339
base_travel_link = "https://www.google.com/maps/dir/%s,%s/" % (self._posf[0], self._posf[1])
286-
step_size = self.config.get("STEP_SIZE", 200)
340+
step_size = self.STEP_SIZE
287341
total_distance_traveled = 0
288342
total_distance = distance_in_meters(self._posf, loc)
289343
new_loc = (loc[0], loc[1], 0)

0 commit comments

Comments
 (0)