Skip to content
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

CampFort improvements #5310

Merged
merged 1 commit into from
Sep 9, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 47 additions & 33 deletions pokemongo_bot/cell_workers/camp_fort.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@

import math
import time
from geopy.distance import great_circle

from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.cell_workers.utils import distance, coord2merc, merc2coord
from pokemongo_bot.cell_workers.utils import coord2merc, merc2coord
from pokemongo_bot.constants import Constants
from pokemongo_bot.human_behaviour import random_lat_long_delta, random_alt_delta
from pokemongo_bot.walkers.polyline_walker import PolylineWalker
from pokemongo_bot.worker_result import WorkerResult
from pokemongo_bot.item_list import Item
from pokemongo_bot import inventory

LOG_TIME_INTERVAL = 60
NO_LURED_TIME_MALUS = 5
NO_BALLS_MOVING_TIME = 5 * 60


class CampFort(BaseTask):
SUPPORTED_TASK_API_VERSION = 1
Expand All @@ -24,8 +28,8 @@ def initialize(self):
self.destination = None
self.stay_until = 0
self.move_until = 0
self.last_position_update = 0
self.walker = None
self.no_log_until = 0

self.config_max_distance = self.config.get("max_distance", 2000)
self.config_min_forts_count = self.config.get("min_forts_count", 2)
Expand All @@ -37,23 +41,11 @@ def work(self):
if not self.enabled:
return WorkerResult.SUCCESS

self.announced_out_of_balls = False
now = time.time()

if now < self.move_until:
return WorkerResult.SUCCESS

# Let's make sure we have balls before we sit at a lure!
# See also catch_pokemon.py
if sum([inventory.items().get(ball.value).count for ball in
[Item.ITEM_POKE_BALL, Item.ITEM_GREAT_BALL, Item.ITEM_ULTRA_BALL]]) <= 0:
self.logger.info('No pokeballs left, refuse to sit at lure!')
# Move away from lures for a time
self.destination = None
self.stay_until = 0
self.move_until = now + self.config_moving_time
return WorkerResult.SUCCESS

if 0 < self.stay_until < now:
self.destination = None
self.stay_until = 0
Expand All @@ -62,42 +54,59 @@ def work(self):
if self.config_moving_time > 0:
return WorkerResult.SUCCESS

forts = self.get_forts()
# Let's make sure we have balls before we sit at a lure!
# See also catch_pokemon.py
if self.get_pokeball_count() <= 0:
self.logger.info("No pokeballs left, refuse to sit at lure!")
# Move away from lures for a time
self.destination = None
self.stay_until = 0
self.move_until = now + max(self.config_moving_time, NO_BALLS_MOVING_TIME)

return WorkerResult.SUCCESS

if self.destination is None:
forts = self.get_forts()
forts_clusters = self.get_forts_clusters(forts)

if len(forts_clusters) > 0:
self.destination = forts_clusters[0]
self.walker = PolylineWalker(self.bot, self.destination[0], self.destination[1])
self.logger.info("New destination at %s meters: %s forts, %s lured.", int(self.destination[4]), self.destination[3], self.destination[2])
self.logger.info("New destination at %s meters: %s forts, %s lured", round(self.destination[4], 2), self.destination[3], self.destination[2])
self.no_log_until = now + LOG_TIME_INTERVAL
else:
# forts = [f for f in forts if f.get("cooldown_complete_timestamp_ms", 0) < now * 1000]
# fort = min(forts, key=lambda f: self.dist(self.bot.position, f))
# self.destination = (fort["latitude"], fort["longitude"])
return WorkerResult.SUCCESS

if (now - self.last_position_update) < 1:
return WorkerResult.RUNNING
else:
self.last_position_update = now
if self.stay_until >= now:
cluster = self.get_current_cluster()

circle = (self.destination[0], self.destination[1], Constants.MAX_DISTANCE_FORT_IS_REACHABLE)
cluster = self.get_cluster(forts, circle)
if self.no_log_until < now:
self.logger.info("Staying at destination: %s forts, %s lured", cluster[3], cluster[2])
self.no_log_until = now + LOG_TIME_INTERVAL

if cluster[2] == 0:
self.stay_until -= NO_LURED_TIME_MALUS

if self.stay_until >= now:
self.walker.step(speed=0)
elif self.walker.step():
self.logger.info("Arrived at destination: %s forts, %s lured.", cluster[3], cluster[2])
cluster = self.get_current_cluster()
self.logger.info("Arrived at destination: %s forts, %s lured", cluster[3], cluster[2])
self.stay_until = now + self.config_camping_time
elif self.no_log_until < now:
cluster = self.get_current_cluster()
self.logger.info("Moving to destination at %s meters: %s forts, %s lured", round(cluster[4], 2), cluster[3], cluster[2])
self.no_log_until = now + LOG_TIME_INTERVAL

return WorkerResult.RUNNING

def get_pokeball_count(self):
return sum([inventory.items().get(ball.value).count for ball in [Item.ITEM_POKE_BALL, Item.ITEM_GREAT_BALL, Item.ITEM_ULTRA_BALL]])

def get_forts(self):
radius = self.config_max_distance + Constants.MAX_DISTANCE_FORT_IS_REACHABLE

forts = [f for f in self.bot.cell["forts"] if ("latitude" in f) and ("type" in f)]
forts = [f for f in forts if self.dist(self.bot.start_position, f) <= radius]
forts = [f for f in forts if self.get_distance(self.bot.start_position, f) <= radius]

return forts

Expand Down Expand Up @@ -187,15 +196,20 @@ def get_enclosing_circles(self, fort1, fort2, radius):
return c1, c2

def get_cluster(self, forts, circle):
forts_in_circle = [f for f in forts if self.dist(circle, f) <= circle[2]]
forts_in_circle = [f for f in forts if self.get_distance(circle, f) <= circle[2]]
count = len(forts_in_circle)
lured = len([f for f in forts_in_circle if "active_fort_modifier" in f])
dst = distance(self.bot.position[0], self.bot.position[1], circle[0], circle[1])
dst = great_circle(self.bot.position, circle).meters

return (circle[0], circle[1], lured, count, dst)

def get_cluster_key(self, cluster):
return (cluster[2], cluster[3], -cluster[4])

def dist(self, location, fort):
return distance(location[0], location[1], fort["latitude"], fort["longitude"])
def get_current_cluster(self):
forts = self.get_forts()
circle = (self.destination[0], self.destination[1], Constants.MAX_DISTANCE_FORT_IS_REACHABLE)
return self.get_cluster(forts, circle)

def get_distance(self, location, fort):
return great_circle(location, (fort["latitude"], fort["longitude"])).meters