package dekk.pw.pokemate; import com.google.common.geometry.S2LatLng; import com.google.common.util.concurrent.AtomicDouble; import com.google.maps.model.DirectionsStep; import com.google.maps.model.LatLng; import dekk.pw.pokemate.tasks.Navigate; import dekk.pw.pokemate.tasks.TagPokestop; import dekk.pw.pokemate.util.Time; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.util.Random; import java.util.Timer; import java.util.TimerTask; /** * Created by TimD on 7/21/2016. */ public class Walking { private static final Logger logger = LogManager.getLogger(Walking.class); private static final double VARIANCE = Config.getRange(); private static double getSmallRandom() { return Math.random() * 0.0001 - 0.00005; } public static void setLocation(Context context) { setLocation(false, context); } private static void setLocation(boolean random, Context context) { if (random) { context.getApi().setLocation(context.getLat().get() + getSmallRandom(), context.getLng().get() + getSmallRandom(), new Random().nextInt(10)); } else { context.getApi().setLocation(context.getLat().get(), context.getLng().get(), new Random().nextInt(10)); } } public static void walk( final Context context, S2LatLng end) { // PokeStop Walking context.getWalking().set(true); S2LatLng start = S2LatLng.fromDegrees(context.getLat().get(), context.getLng().get()); S2LatLng diff = end.sub(start); double distance = start.getEarthDistance(end); long timeout = 200L; double timeRequired = distance / Config.getSpeed(); final AtomicDouble stepsRequired = new AtomicDouble(timeRequired / (timeout / 1000D)); double deltaLat = diff.latDegrees() / stepsRequired.get(); double deltaLng = diff.lngDegrees() / stepsRequired.get(); logger.debug("starting to walk"); //Schedule a timer to walk every 200 ms new Timer().scheduleAtFixedRate(new TimerTask() { @Override public void run() { context.getApi().setLocation(context.getLat().addAndGet(deltaLat), context.getLng().addAndGet(deltaLng), new Random().nextInt(10)); stepsRequired.getAndAdd(-1); if (stepsRequired.get() <= 0) { logger.debug("Setting a new destination"); context.getWalking().set(false); context.addTask(new TagPokestop(context)); context.addTask(new Navigate(context, new LatLng(context.getLat().get() - VARIANCE, context.getLng().get() - VARIANCE), new LatLng(context.getLat().get() + VARIANCE, context.getLng().get() + VARIANCE))); cancel(); } } }, 0, timeout); } public static void walk(Context context, DirectionsStep[] steps) { // Streets Walking context.getWalking().set(true); if (steps != null) { for (DirectionsStep step : steps) { logger.debug("WALKER Heading to: [" + step.endLocation.lat + ", " + step.endLocation.lng + "]"); context.getApi().setLocation(step.startLocation.lat, step.startLocation.lng, 0); context.getLat().set(step.startLocation.lat); context.getLng().set(step.startLocation.lng); S2LatLng start = S2LatLng.fromDegrees(step.startLocation.lat, step.startLocation.lng); S2LatLng end = S2LatLng.fromDegrees(step.endLocation.lat, step.endLocation.lng); S2LatLng diff = end.sub(start); double distance; distance = start.getEarthDistance(end); long timeout = 350L; double timeRequired = distance / Config.getSpeed(); int stepsRequired = (int) (timeRequired / (new Long(timeout).doubleValue() / 1000)); double deltaLat = diff.latDegrees() / stepsRequired; double deltaLng = diff.lngDegrees() / stepsRequired; int remainingSteps = stepsRequired; while (remainingSteps >= 0) { context.getLat().addAndGet(deltaLat); context.getLng().addAndGet(deltaLng); setLocation(context); try { Thread.sleep(timeout); } catch (InterruptedException e) { e.printStackTrace(); } logger.debug( "Set location: [" + context.getLat().get() + ", " + context.getLng().get() + "]"); remainingSteps--; } logger.debug( "Arrived at: [" + step.endLocation.lat + ", " + step.endLocation.lng + "]"); } }else{ logger.error("WALKING ERROR"); } context.getWalking().set(false); } }