forked from PokemonGoF/PokemonGo-Bot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactoring the StepWalker to support 0.0 and float(inf)
- Loading branch information
Showing
3 changed files
with
166 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,108 +1,130 @@ | ||
from math import sqrt | ||
|
||
from random import uniform | ||
|
||
from pokemongo_bot.cell_workers.utils import distance | ||
from pokemongo_bot.human_behaviour import random_lat_long_delta, sleep, random_alt_delta | ||
|
||
|
||
class StepWalker(object): | ||
|
||
def __init__(self, bot, dest_lat, dest_lng, dest_alt=None, fixed_speed=False): | ||
""" | ||
StepWalker is used to handle bot position altering | ||
""" | ||
|
||
def __init__(self, bot, dest_lat, dest_lng, dest_alt=None, | ||
fixed_speed=None, add_deltas=True, | ||
stationary_deltas=False, stationary_updates=False): | ||
""" | ||
:param bot: PokemonGoBot object | ||
:param dest_lat: Latitude of final destination | ||
:param dest_lng: Longitude of final destination | ||
:param dest_alt: Altitude of final destination (meters) | ||
:param fixed_speed: Fix the speed to particular values | ||
Default: None thus a random value between walk_min and walk_max is used | ||
(Used by PolylineWalker to pass same values from the PolylineObjectHandler | ||
Use 0.0 to stay put. | ||
Use float("inf") to teleport | ||
:param add_deltas: Add random_lat_long_delta() and random_alt_delta() to lat,lng, alt Default: True | ||
:param stationary_deltas: Use the deltas in the case of speed 0.0 or small distance Default: False | ||
:param stationary_updates: Force the StepWalker to set_position even on small distance and speed 0.0 Default: False | ||
""" | ||
self.bot = bot | ||
self.api = bot.api | ||
|
||
self.initLat, self.initLng = self.bot.position[0:2] | ||
self.add_deltas = add_deltas | ||
self.stationary_deltas = stationary_deltas | ||
self.stationary_updates = stationary_updates | ||
self.init_lat, self.init_lng, self.init_alt = self.bot.position | ||
|
||
self.dist = distance( | ||
self.initLat, | ||
self.initLng, | ||
self.init_lat, | ||
self.init_lng, | ||
dest_lat, | ||
dest_lng | ||
) | ||
|
||
if dest_alt == None: | ||
if dest_alt is None: | ||
self.alt = uniform(self.bot.config.alt_min, self.bot.config.alt_max) | ||
else: | ||
self.alt = dest_alt | ||
|
||
if not fixed_speed: | ||
if fixed_speed is None: | ||
self.speed = uniform(self.bot.config.walk_min, self.bot.config.walk_max) | ||
else: | ||
# PolylineWalker uses a fixed speed! | ||
self.speed = self.bot.config.walk_min | ||
# Use this to pass custom values from 0.0 to stay put to float("inf") to teleport | ||
self.speed = fixed_speed | ||
|
||
if len(self.bot.position) == 3: | ||
self.initAlt = self.bot.position[2] | ||
else: | ||
self.initAlt = self.alt; | ||
|
||
self.destLat = dest_lat | ||
self.destLng = dest_lng | ||
self.totalDist = max(1, self.dist) | ||
self.dest_lat = dest_lat | ||
self.dest_lng = dest_lng | ||
# If distance <= speed we consider the that distance = speed | ||
# Will pe used for percentage_walked calculations | ||
self.distance = max(self.dist, self.speed) | ||
|
||
def step(self): | ||
""" | ||
Sets the bot.position to the next calculated point according to the speed and distance | ||
:return: boolean True/False reflecting if the full distance to final destination was walked in the step. | ||
""" | ||
completed_walk = False | ||
# If speed 0.0 we stay put and we don't add deltas | ||
if self.speed == 0: | ||
raise Exception("Walking speed cannot be 0, change your walking speed higher than 1!") | ||
else: | ||
self.steps = (self.dist + 0.0) / (self.speed + 0.0) | ||
|
||
if self.dist < self.speed or int(self.steps) <= 1: | ||
self.dLat = 0 | ||
self.dLng = 0 | ||
self.magnitude = 0 | ||
completed_walk = True | ||
if self.stationary_updates: | ||
return self.set_position(self.init_lat, self.init_lng, self.alt, | ||
add_deltas=self.stationary_deltas, | ||
completed_walk=completed_walk) | ||
# If speed is infinite we teleport | ||
if self.speed == float("inf"): | ||
completed_walk = True | ||
return self.set_position(self.dest_lat, self.dest_lng, self.alt, | ||
add_deltas=self.add_deltas, | ||
completed_walk=completed_walk) | ||
# If distance <= speed percentage = 1 | ||
# else the percentage_walked is between 0 and 1 | ||
percentage_walked = self.speed / self.distance | ||
if percentage_walked == 1: | ||
completed_walk = True | ||
lat = self.init_lat + (self.dest_lat - self.init_lat) * percentage_walked | ||
lng = self.init_lng + (self.dest_lng - self.init_lng ) * percentage_walked | ||
alt = self.init_alt + (self.alt - self.init_alt) * percentage_walked | ||
if self.dist >= self.speed: | ||
return self.set_position(lat, lng, alt, | ||
add_deltas=self.add_deltas, | ||
completed_walk=completed_walk) | ||
else: | ||
self.dLat = (dest_lat - self.initLat) / int(self.steps) | ||
self.dLng = (dest_lng - self.initLng) / int(self.steps) | ||
self.magnitude = self._pythagorean(self.dLat, self.dLng) | ||
self.unitAlt = (self.alt - self.initAlt) / int(self.steps) | ||
|
||
def step(self): | ||
if (self.dLat == 0 and self.dLng == 0) or self.dist < self.speed: | ||
self.api.set_position(self.destLat + random_lat_long_delta(), self.destLng + random_lat_long_delta(), self.alt) | ||
self.bot.event_manager.emit( | ||
'position_update', | ||
sender=self, | ||
level='debug', | ||
data={ | ||
'current_position': (self.destLat, self.destLng), | ||
'last_position': (self.initLat, self.initLng), | ||
'distance': '', | ||
'distance_unit': '' | ||
} | ||
) | ||
self.bot.heartbeat() | ||
return True | ||
|
||
totalDLat = (self.destLat - self.initLat) | ||
totalDLng = (self.destLng - self.initLng) | ||
magnitude = self._pythagorean(totalDLat, totalDLng) | ||
unitLat = totalDLat / magnitude | ||
unitLng = totalDLng / magnitude | ||
|
||
scaledDLat = unitLat * self.magnitude | ||
scaledDLng = unitLng * self.magnitude | ||
|
||
cLat = self.initLat + scaledDLat + random_lat_long_delta() | ||
cLng = self.initLng + scaledDLng + random_lat_long_delta() | ||
cAlt = self.initAlt + self.unitAlt + random_alt_delta() | ||
|
||
self.api.set_position(cLat, cLng, cAlt) | ||
if self.stationary_updates: | ||
return self.set_position(lat, lng, alt, | ||
add_deltas=self.stationary_deltas, | ||
completed_walk=completed_walk) | ||
else: | ||
return True | ||
|
||
def set_position(self, lat, lng, alt, add_deltas=True, completed_walk=False): | ||
""" | ||
:param lat: Latitude of the calculated position | ||
:param lng: longitude of the calculated position | ||
:param alt: Altitde of the calculated position | ||
:param add_deltas: Add random_lat_long_delta() and random_alt_delta() to lat,lng, alt Default: True | ||
:param completed_walk: boolean reflecting if the distance was fully walked or not Default: False | ||
:return: boolean True/False reflecting if the full distance to final destination was walked in the step. | ||
""" | ||
if add_deltas: | ||
lat += random_lat_long_delta() | ||
lng += random_lat_long_delta() | ||
alt += random_alt_delta() | ||
self.api.set_position(lat, lng, alt) | ||
self.bot.event_manager.emit( | ||
'position_update', | ||
sender=self, | ||
level='debug', | ||
data={ | ||
'current_position': (cLat, cLng, cAlt), | ||
'last_position': (self.initLat, self.initLng, self.initAlt), | ||
'current_position': (lat, lng, alt), | ||
'last_position': (self.init_lat, self.init_lng, self.init_alt), | ||
'distance': '', | ||
'distance_unit': '' | ||
} | ||
) | ||
self.bot.heartbeat() | ||
|
||
sleep(1) # sleep one second plus a random delta | ||
# self._work_at_position( | ||
# self.initLat, self.initLng, | ||
# alt, False) | ||
|
||
def _pythagorean(self, lat, lng): | ||
return sqrt((lat ** 2) + (lng ** 2)) | ||
if completed_walk: | ||
return True |