Merge pull request #1067 from blackms/Beta-Build

Brian [2016-08-20 01:54:02]
Merge pull request #1067 from blackms/Beta-Build

Ported new Navigation system from Necro
Filename
PokemonGo.RocketBot.Logic/Common/Translations.cs
PokemonGo.RocketBot.Logic/Event/HumanWalkingEvent.cs
PokemonGo.RocketBot.Logic/ILogicSettings.cs
PokemonGo.RocketBot.Logic/Navigation.cs
PokemonGo.RocketBot.Logic/PokemonGo.RocketBot.Logic.csproj
PokemonGo.RocketBot.Logic/Settings.cs
PokemonGo.RocketBot.Logic/State/FarmState.cs
PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsGPXTask.cs
PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
PokemonGo.RocketBot.Window/ConsoleEventListener.cs
PokemonGo.RocketBot.Window/Forms/MainForm.cs
PokemonGo.RocketBot.Window/Forms/MainForm.designer.cs
diff --git a/PokemonGo.RocketBot.Logic/Common/Translations.cs b/PokemonGo.RocketBot.Logic/Common/Translations.cs
index 5a90885..a21f457 100644
--- a/PokemonGo.RocketBot.Logic/Common/Translations.cs
+++ b/PokemonGo.RocketBot.Logic/Common/Translations.cs
@@ -26,6 +26,7 @@ namespace PokemonGo.RocketBot.Logic.Common

     public enum TranslationString
     {
+        HumanWalkingVariant,
         Pokeball,
         GreatPokeball,
         UltraPokeball,
@@ -151,6 +152,7 @@ namespace PokemonGo.RocketBot.Logic.Common
         DisplayHighestMove1Header,
         DisplayHighestMove2Header,
         DisplayHighestCandy,
+        // ReSharper disable once InconsistentNaming
         IPBannedError,
         NoEggsAvailable,
         UseLuckyEggActive,
@@ -207,6 +209,7 @@ namespace PokemonGo.RocketBot.Logic.Common
         private readonly List<KeyValuePair<TranslationString, string>> _translationStrings = new List
             <KeyValuePair<TranslationString, string>>
         {
+            new KeyValuePair<TranslationString, string>(TranslationString.HumanWalkingVariant, "Walking Speed: Has been changed, {0:n2} Km/h to {1:n2} Km/h"),
             new KeyValuePair<TranslationString, string>(TranslationString.Pokeball, "PokeBall"),
             new KeyValuePair<TranslationString, string>(TranslationString.GreatPokeball, "GreatBall"),
             new KeyValuePair<TranslationString, string>(TranslationString.UltraPokeball, "UltraBall"),
diff --git a/PokemonGo.RocketBot.Logic/Event/HumanWalkingEvent.cs b/PokemonGo.RocketBot.Logic/Event/HumanWalkingEvent.cs
new file mode 100644
index 0000000..3a9e013
--- /dev/null
+++ b/PokemonGo.RocketBot.Logic/Event/HumanWalkingEvent.cs
@@ -0,0 +1,9 @@
+namespace PokemonGo.RocketBot.Logic.Event
+{
+    public class HumanWalkingEvent : IEvent
+    {
+        public double OldWalkingSpeed;
+        public double CurrentWalkingSpeed;
+    }
+}
+
diff --git a/PokemonGo.RocketBot.Logic/ILogicSettings.cs b/PokemonGo.RocketBot.Logic/ILogicSettings.cs
index 279aa39..c979758 100644
--- a/PokemonGo.RocketBot.Logic/ILogicSettings.cs
+++ b/PokemonGo.RocketBot.Logic/ILogicSettings.cs
@@ -71,6 +71,7 @@ namespace PokemonGo.RocketBot.Logic

     public interface ILogicSettings
     {
+        string GoogleAPIKey { get; }
         bool UseWebsocket { get; }
         bool CatchPokemon { get; }
         bool TransferWeakPokemon { get; }
@@ -84,6 +85,9 @@ namespace PokemonGo.RocketBot.Logic
         string KeepMinOperator { get; }
         double WalkingSpeedInKilometerPerHour { get; }
         double WalkingSpeedOffSetInKilometerPerHour { get; }
+        bool UseWalkingSpeedVariant { get; }
+        double WalkingSpeedVariant { get; }
+        bool ShowVariantWalking { get; }
         bool FastSoftBanBypass { get; }
         bool EvolveAllPokemonWithEnoughCandy { get; }
         bool KeepPokemonsThatCanEvolve { get; }
diff --git a/PokemonGo.RocketBot.Logic/Navigation.cs b/PokemonGo.RocketBot.Logic/Navigation.cs
index 7c30efc..e002987 100644
--- a/PokemonGo.RocketBot.Logic/Navigation.cs
+++ b/PokemonGo.RocketBot.Logic/Navigation.cs
@@ -1,13 +1,20 @@
 #region using directives

 using System;
+using System.Collections.Generic;
+using System.Diagnostics;
 using System.Globalization;
+using System.IO;
+using System.Net;
 using System.Threading;
 using System.Threading.Tasks;
 using GeoCoordinatePortable;
+using Newtonsoft.Json.Linq;
 using PokemonGo.RocketAPI;
 using PokemonGo.RocketBot.Logic.Utils;
 using POGOProtos.Networking.Responses;
+using PokemonGo.RocketBot.Logic.Event;
+using PokemonGo.RocketBot.Logic.State;

 #endregion

@@ -17,6 +24,11 @@ namespace PokemonGo.RocketBot.Logic

     public class Navigation
     {
+        private double _currentWalkingSpeed;
+        private DateTime _lastMajorVariantWalkingSpeed;
+        private DateTime _nextMajorVariantWalkingSpeed;
+        private readonly Random _randWalking = new Random();
+
         private const double SpeedDownTo = 10 / 3.6;
         private readonly Client _client;

@@ -25,58 +37,186 @@ namespace PokemonGo.RocketBot.Logic
             _client = client;
         }

-        public async Task<PlayerUpdateResponse> Move(GeoCoordinate targetLocation,
-            double walkingSpeedInKilometersPerHour, double walkingSpeedOffSetInKilometersPerHour,
-            Func<Task<bool>> functionExecutedWhileWalking,
-            CancellationToken cancellationToken, bool disableHumanLikeWalking)
+        private double MajorWalkingSpeedVariant(ISession session)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-            if (!disableHumanLikeWalking)
+            if (_lastMajorVariantWalkingSpeed == DateTime.MinValue && _nextMajorVariantWalkingSpeed == DateTime.MinValue)
             {
-                var sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude);
+                var minutes = _randWalking.NextDouble() * (2 - 6) + 2;
+                _lastMajorVariantWalkingSpeed = DateTime.Now;
+                _nextMajorVariantWalkingSpeed = _lastMajorVariantWalkingSpeed.AddMinutes(minutes);
+                _currentWalkingSpeed = session.LogicSettings.WalkingSpeedInKilometerPerHour;
+            }
+            else if (_nextMajorVariantWalkingSpeed.Ticks < DateTime.Now.Ticks)
+            {
+                var oldWalkingSpeed = _currentWalkingSpeed;

-                var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
-                var nextWaypointDistance = getspeedInMetersPerSecond(walkingSpeedInKilometersPerHour,
-                    walkingSpeedOffSetInKilometersPerHour);
-                ;
-                var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
+                var randomMin = session.LogicSettings.WalkingSpeedInKilometerPerHour - session.LogicSettings.WalkingSpeedVariant;
+                var randomMax = session.LogicSettings.WalkingSpeedInKilometerPerHour + session.LogicSettings.WalkingSpeedVariant;
+                _currentWalkingSpeed = _randWalking.NextDouble() * (randomMax - randomMin) + randomMin;

-                //Initial walking
-                var requestSendDateTime = DateTime.Now;
-                var result =
-                    await
-                        _client.Player.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude,
-                            waypoint.Altitude);
+                var minutes = _randWalking.NextDouble() * (2 - 6) + 2;
+                _lastMajorVariantWalkingSpeed = DateTime.Now;
+                _nextMajorVariantWalkingSpeed = _lastMajorVariantWalkingSpeed.AddMinutes(minutes);

-                UpdatePositionEvent?.Invoke(waypoint.Latitude, waypoint.Longitude);
+                session.EventDispatcher.Send(new HumanWalkingEvent
+                {
+                    OldWalkingSpeed = oldWalkingSpeed,
+                    CurrentWalkingSpeed = _currentWalkingSpeed
+                });
+            }

-                do
+            return _currentWalkingSpeed / 3.6;
+        }
+
+        private double MinorWalkingSpeedVariant(ISession session)
+        {
+            if (_randWalking.Next(1, 10) > 5) //Random change or no variant speed
+            {
+                var oldWalkingSpeed = _currentWalkingSpeed;
+
+                if (_randWalking.Next(1, 10) > 5) //Random change upper or lower variant speed
                 {
-                    var speedInMetersPerSecond = getspeedInMetersPerSecond(walkingSpeedInKilometersPerHour,
-                        walkingSpeedOffSetInKilometersPerHour);
-                    cancellationToken.ThrowIfCancellationRequested();
+                    var randomMax = session.LogicSettings.WalkingSpeedInKilometerPerHour + session.LogicSettings.WalkingSpeedVariant + 0.5;
+
+                    _currentWalkingSpeed += _randWalking.NextDouble() * (0.01 - 0.09) + 0.01;
+                    if (_currentWalkingSpeed > randomMax)
+                        _currentWalkingSpeed = randomMax;
+                }
+                else
+                {
+                    var randomMin = session.LogicSettings.WalkingSpeedInKilometerPerHour - session.LogicSettings.WalkingSpeedVariant - 0.5;
+
+                    _currentWalkingSpeed -= _randWalking.NextDouble() * (0.01 - 0.09) + 0.01;
+                    if (_currentWalkingSpeed < randomMin)
+                        _currentWalkingSpeed = randomMin;
+                }
+
+                if (Math.Abs(oldWalkingSpeed - _currentWalkingSpeed) > 0)
+                {
+                    session.EventDispatcher.Send(new HumanWalkingEvent
+                    {
+                        OldWalkingSpeed = oldWalkingSpeed,
+                        CurrentWalkingSpeed = _currentWalkingSpeed
+                    });
+                }
+            }

-                    var millisecondsUntilGetUpdatePlayerLocationResponse =
-                        (DateTime.Now - requestSendDateTime).TotalMilliseconds;
+            return _currentWalkingSpeed / 3.6;
+        }

-                    sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude);
-                    var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
+        private List<List<double>> Route(ISession session, GeoCoordinate start, GeoCoordinate dest)
+        {
+            List<List<double>> result = new List<List<double>>();

-                    if (currentDistanceToTarget < 40)
+            try
+            {
+                WebRequest web = WebRequest.Create(
+                    $"https://maps.googleapis.com/maps/api/directions/json?origin={start.Latitude},{start.Longitude}&destination={dest.Latitude},{dest.Longitude}&mode=walking&units=metric&key={session.LogicSettings.GoogleAPIKey}");
+                web.Credentials = CredentialCache.DefaultCredentials;
+
+                string strResponse;
+                using (WebResponse response = web.GetResponse())
+                {
+                    using (Stream stream = response.GetResponseStream())
                     {
-                        if (speedInMetersPerSecond > SpeedDownTo)
-                        {
-                            //Logger.Write("We are within 40 meters of the target. Speeding down to 10 km/h to not pass the target.", LogLevel.Info);
-                            speedInMetersPerSecond = SpeedDownTo;
-                        }
+                        Debug.Assert(stream != null, "stream != null");
+                        using (StreamReader reader = new StreamReader(stream))
+                            strResponse = reader.ReadToEnd();
                     }
+                }
+
+                JObject parseObject = JObject.Parse(strResponse);
+                result = Points(parseObject["routes"][0]["overview_polyline"]["points"].ToString(), 1e5);
+            }
+            catch (WebException e)
+            {
+                session.EventDispatcher.Send(new WarnEvent
+                {
+                    Message = $"Web Exception: {e.Message}"
+                });
+            }
+            catch (NullReferenceException e)
+            {
+                session.EventDispatcher.Send(new WarnEvent
+                {
+                    Message = $"Routing Error: {e.Message}"
+                });
+            }
+
+            return result;
+        }
+
+        public static List<List<double>> Points(string overview, double precision)
+        {
+            if (string.IsNullOrEmpty(overview))
+                throw new ArgumentNullException("Points");
+
+            bool polyline = false;
+            int index = 0, lat = 0, lng = 0;
+            char[] polylineChars = overview.ToCharArray();
+            List<List<double>> result = new List<List<double>>();
+
+            while (index < polylineChars.Length)
+            {
+                int sum = 0, shifter = 0, nextBits;
+                List<double> coordinates = new List<double>();
+
+                do
+                {
+                    nextBits = polylineChars[index++] - 63;
+                    sum |= (nextBits & 0x1f) << shifter;
+                    shifter += 5;
+                } while (nextBits >= 0x20 && index < polylineChars.Length);

-                    nextWaypointDistance = Math.Min(currentDistanceToTarget,
-                        millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
-                    nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
-                    waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
+                if (index >= polylineChars.Length && (!polyline || nextBits >= 0x20))
+                    break;

-                    requestSendDateTime = DateTime.Now;
+                if (!polyline)
+                    lat += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);
+                else
+                {
+                    lng += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);
+                    coordinates.Add(lng / precision);
+                    coordinates.Add(lat / precision);
+                    result.Add(coordinates);
+                }
+
+                polyline = !polyline;
+            }
+
+            return result;
+        }
+
+        public async Task<PlayerUpdateResponse> Move(GeoCoordinate targetLocation, Func<Task<bool>> functionExecutedWhileWalking,
+            ISession session,
+            CancellationToken cancellationToken)
+        {
+            cancellationToken.ThrowIfCancellationRequested();
+            if (!session.LogicSettings.DisableHumanWalking)
+            {
+                PlayerUpdateResponse result = null;
+                List<GeoCoordinate> points = new List<GeoCoordinate>();
+                var route = Route(session,
+                    new GeoCoordinate(
+                        _client.CurrentLatitude,
+                        _client.CurrentLongitude,
+                        _client.CurrentAltitude),
+                    targetLocation);
+
+                foreach (var item in route)
+                    points.Add(new GeoCoordinate(item.ToArray()[1], item.ToArray()[0]));
+
+                for (int i = 0; i < points.Count; i++)
+                {
+                    var speedInMetersPerSecond = session.LogicSettings.UseWalkingSpeedVariant ? MajorWalkingSpeedVariant(session) :
+                    session.LogicSettings.WalkingSpeedInKilometerPerHour / 3.6;
+                    var sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude);
+
+                    var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, points.ToArray()[i]);
+                    var nextWaypointDistance = speedInMetersPerSecond;
+                    var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
+
+                    var requestSendDateTime = DateTime.Now;
                     result =
                         await
                             _client.Player.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude,
@@ -84,10 +224,47 @@ namespace PokemonGo.RocketBot.Logic

                     UpdatePositionEvent?.Invoke(waypoint.Latitude, waypoint.Longitude);

+                    var realDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
+                    if (realDistanceToTarget < 30)
+                        break;

-                    if (functionExecutedWhileWalking != null)
-                        await functionExecutedWhileWalking(); // look for pokemon
-                } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30);
+                    do
+                    {
+                        cancellationToken.ThrowIfCancellationRequested();
+
+                        var millisecondsUntilGetUpdatePlayerLocationResponse =
+                            (DateTime.Now - requestSendDateTime).TotalMilliseconds;
+
+                        sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude);
+                        var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, points.ToArray()[i]);
+
+                        var realDistanceToTargetSpeedDown = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
+                        if (realDistanceToTargetSpeedDown < 40)
+                            if (speedInMetersPerSecond > SpeedDownTo)
+                                speedInMetersPerSecond = SpeedDownTo;
+
+                        if (session.LogicSettings.UseWalkingSpeedVariant)
+                            speedInMetersPerSecond = MinorWalkingSpeedVariant(session);
+
+                        nextWaypointDistance = Math.Min(currentDistanceToTarget,
+                            millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
+                        nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, points.ToArray()[i]);
+                        waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
+
+                        requestSendDateTime = DateTime.Now;
+                        result =
+                            await
+                                _client.Player.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude,
+                                    waypoint.Altitude);
+
+                        UpdatePositionEvent?.Invoke(waypoint.Latitude, waypoint.Longitude);
+
+                        if (functionExecutedWhileWalking != null)
+                            await functionExecutedWhileWalking(); // look for pokemon
+                    } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, points.ToArray()[i]) >= 2);
+
+                    UpdatePositionEvent?.Invoke(points.ToArray()[i].Latitude, points.ToArray()[i].Longitude);
+                }

                 return result;
             }
@@ -102,34 +279,25 @@ namespace PokemonGo.RocketBot.Logic
                 var waypoint = LocationUtils.CreateWaypoint(curLocation, nextWaypointDistance, nextWaypointBearing);
                 var sentTime = DateTime.Now;

-                var result =
-                    await
-                        _client.Player.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude,
-                            waypoint.Altitude);
+                PlayerUpdateResponse result;
                 UpdatePositionEvent?.Invoke(waypoint.Latitude, waypoint.Longitude);

                 do
                 {
                     cancellationToken.ThrowIfCancellationRequested();

-                    var millisecondsUntilGetUpdatePlayerLocationResponse =
-                        (DateTime.Now - sentTime).TotalMilliseconds;
-
                     curLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude);
-                    var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(curLocation, targetLocation);
+                    LocationUtils.CalculateDistanceInMeters(curLocation, targetLocation);

                     dist = LocationUtils.CalculateDistanceInMeters(curLocation, targetLocation);
+
                     if (dist >= 100)
-                    {
                         nextWaypointDistance = dist * 70 / 100;
-                    }
                     else
-                    {
                         nextWaypointDistance = dist;
-                    }
+
                     nextWaypointBearing = LocationUtils.DegreeBearing(curLocation, targetLocation);
                     waypoint = LocationUtils.CreateWaypoint(curLocation, nextWaypointDistance, nextWaypointBearing);
-                    sentTime = DateTime.Now;
                     result =
                         await
                             _client.Player.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude,
@@ -157,7 +325,8 @@ namespace PokemonGo.RocketBot.Logic
         }

         public async Task<PlayerUpdateResponse> HumanPathWalking(GpxReader.Trkpt trk,
-            double walkingSpeedInKilometersPerHour, Func<Task<bool>> functionExecutedWhileWalking,
+            Func<Task<bool>> functionExecutedWhileWalking,
+            ISession session,
             CancellationToken cancellationToken)
         {
             cancellationToken.ThrowIfCancellationRequested();
@@ -166,20 +335,14 @@ namespace PokemonGo.RocketBot.Logic

             var targetLocation = new GeoCoordinate(Convert.ToDouble(trk.Lat, CultureInfo.InvariantCulture),
                 Convert.ToDouble(trk.Lon, CultureInfo.InvariantCulture));
-
-            var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6;
-
+            var speedInMetersPerSecond = session.LogicSettings.UseWalkingSpeedVariant ? MajorWalkingSpeedVariant(session) :
+                    session.LogicSettings.WalkingSpeedInKilometerPerHour / 3.6;
             var sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude);
             LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
-            // Logger.Write($"Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget/speedInMetersPerSecond:0.##} seconds!", LogLevel.Info);
-
             var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
             var nextWaypointDistance = speedInMetersPerSecond;
             var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing,
                 Convert.ToDouble(trk.Ele, CultureInfo.InvariantCulture));
-
-            //Initial walking
-
             var requestSendDateTime = DateTime.Now;
             var result =
                 await
@@ -206,6 +369,9 @@ namespace PokemonGo.RocketBot.Logic
                 //    }
                 //}

+                if (session.LogicSettings.UseWalkingSpeedVariant)
+                    speedInMetersPerSecond = MinorWalkingSpeedVariant(session);
+
                 nextWaypointDistance = Math.Min(currentDistanceToTarget,
                     millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
                 nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
@@ -226,18 +392,6 @@ namespace PokemonGo.RocketBot.Logic
             return result;
         }

-        public double getspeedInMetersPerSecond(double SpeedInKilometersPerHour, double SpeedOffSetInKilometersPerHour)
-        {
-            var random = new Random();
-            double offset;
-            if (random.Next(0, 2) == 1)
-                offset = random.NextDouble() * SpeedOffSetInKilometersPerHour;
-            else
-                offset = -random.NextDouble() * SpeedOffSetInKilometersPerHour;
-
-            return (SpeedInKilometersPerHour + offset) / 3.6;
-        }
-
         public event UpdatePositionDelegate UpdatePositionEvent;
     }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Logic/PokemonGo.RocketBot.Logic.csproj b/PokemonGo.RocketBot.Logic/PokemonGo.RocketBot.Logic.csproj
index 77c08a2..4e780b9 100644
--- a/PokemonGo.RocketBot.Logic/PokemonGo.RocketBot.Logic.csproj
+++ b/PokemonGo.RocketBot.Logic/PokemonGo.RocketBot.Logic.csproj
@@ -110,6 +110,7 @@
     <Compile Include="Event\FortTargetEvent.cs" />
     <Compile Include="Event\FortFailedEvent.cs" />
     <Compile Include="Event\FortUsedEvent.cs" />
+    <Compile Include="Event\HumanWalkingEvent.cs" />
     <Compile Include="Event\InventoryListEvent.cs" />
     <Compile Include="Event\ItemRecycledEvent.cs" />
     <Compile Include="Event\LootPokestopEvent.cs" />
diff --git a/PokemonGo.RocketBot.Logic/Settings.cs b/PokemonGo.RocketBot.Logic/Settings.cs
index e7fac0b..d29b185 100644
--- a/PokemonGo.RocketBot.Logic/Settings.cs
+++ b/PokemonGo.RocketBot.Logic/Settings.cs
@@ -1,26 +1,24 @@
-
 #region using directives

-using Newtonsoft.Json;
-using Newtonsoft.Json.Converters;
-using PokemonGo.RocketBot.Logic.Common;
-using PokemonGo.RocketBot.Logic.Logging;
-using PokemonGo.RocketBot.Logic.State;
-using PokemonGo.RocketBot.Logic.Utils;
-using POGOProtos.Enums;
-using POGOProtos.Inventory.Item;
-using PokemonGo.RocketAPI;
-using PokemonGo.RocketAPI.Enums;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.IO;
 using System.Linq;
 using System.Net;
-using System.Net.Http;
 using System.Reflection;
 using System.Security.Cryptography;
 using System.Threading;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using PokemonGo.RocketAPI;
+using PokemonGo.RocketAPI.Enums;
+using PokemonGo.RocketBot.Logic.Common;
+using PokemonGo.RocketBot.Logic.Logging;
+using PokemonGo.RocketBot.Logic.State;
+using PokemonGo.RocketBot.Logic.Utils;
+using POGOProtos.Enums;
+using POGOProtos.Inventory.Item;

 #endregion

@@ -28,14 +26,14 @@ namespace PokemonGo.RocketBot.Logic
 {
     public class AuthSettings
     {
-        [JsonIgnore]
-        private string _filePath;
+        [JsonIgnore] private string _filePath;

         public AuthType AuthType;
         public string GoogleUsername;
         public string GooglePassword;
         public string PtcUsername;
         public string PtcPassword;
+        public string GoogleApiKey;
         public bool UseProxy;
         public string UseProxyHost;
         public string UseProxyPort;
@@ -43,34 +41,22 @@ namespace PokemonGo.RocketBot.Logic
         public string UseProxyUsername;
         public string UseProxyPassword;
         // device data
-        [DefaultValue("random")]
-        public string DevicePackageName;
-        [DefaultValue("8525f5d8201f78b5")]
-        public string DeviceId;
-        [DefaultValue("msm8996")]
-        public string AndroidBoardName;
-        [DefaultValue("1.0.0.0000")]
-        public string AndroidBootloader;
-        [DefaultValue("HTC")]
-        public string DeviceBrand;
-        [DefaultValue("HTC 10")]
-        public string DeviceModel;
-        [DefaultValue("pmewl_00531")]
-        public string DeviceModelIdentifier;
-        [DefaultValue("qcom")]
-        public string DeviceModelBoot;
-        [DefaultValue("HTC")]
-        public string HardwareManufacturer;
-        [DefaultValue("HTC 10")]
-        public string HardwareModel;
-        [DefaultValue("pmewl_00531")]
-        public string FirmwareBrand;
-        [DefaultValue("release-keys")]
-        public string FirmwareTags;
-        [DefaultValue("user")]
-        public string FirmwareType;
-        [DefaultValue("htc/pmewl_00531/htc_pmewl:6.0.1/MMB29M/770927.1:user/release-keys")]
-        public string FirmwareFingerprint;
+        [DefaultValue("random")] public string DevicePackageName;
+        [DefaultValue("8525f5d8201f78b5")] public string DeviceId;
+        [DefaultValue("msm8996")] public string AndroidBoardName;
+        [DefaultValue("1.0.0.0000")] public string AndroidBootloader;
+        [DefaultValue("HTC")] public string DeviceBrand;
+        [DefaultValue("HTC 10")] public string DeviceModel;
+        [DefaultValue("pmewl_00531")] public string DeviceModelIdentifier;
+        [DefaultValue("qcom")] public string DeviceModelBoot;
+        [DefaultValue("HTC")] public string HardwareManufacturer;
+        [DefaultValue("HTC 10")] public string HardwareModel;
+        [DefaultValue("pmewl_00531")] public string FirmwareBrand;
+        [DefaultValue("release-keys")] public string FirmwareTags;
+        [DefaultValue("user")] public string FirmwareType;
+
+        [DefaultValue("htc/pmewl_00531/htc_pmewl:6.0.1/MMB29M/770927.1:user/release-keys")] public string
+            FirmwareFingerprint;

         public AuthSettings()
         {
@@ -102,27 +88,29 @@ namespace PokemonGo.RocketBot.Logic
                     var input = File.ReadAllText(_filePath);

                     var settings = new JsonSerializerSettings();
-                    settings.Converters.Add(new StringEnumConverter { CamelCaseText = true });
+                    settings.Converters.Add(new StringEnumConverter {CamelCaseText = true});
                     JsonConvert.PopulateObject(input, this, settings);
                 }
                 // Do some post-load logic to determine what device info to be using - if 'custom' is set we just take what's in the file without question
-                if (!this.DevicePackageName.Equals("random", StringComparison.InvariantCultureIgnoreCase) && !this.DevicePackageName.Equals("custom", StringComparison.InvariantCultureIgnoreCase))
+                if (!DevicePackageName.Equals("random", StringComparison.InvariantCultureIgnoreCase) &&
+                    !DevicePackageName.Equals("custom", StringComparison.InvariantCultureIgnoreCase))
                 {
                     // User requested a specific device package, check to see if it exists and if so, set it up - otherwise fall-back to random package
-                    string keepDevId = this.DeviceId;
-                    SetDevInfoByKey(this.DevicePackageName);
-                    this.DeviceId = keepDevId;
+                    string keepDevId = DeviceId;
+                    SetDevInfoByKey();
+                    DeviceId = keepDevId;
                 }
-                if (this.DevicePackageName.Equals("random", StringComparison.InvariantCultureIgnoreCase))
+                if (DevicePackageName.Equals("random", StringComparison.InvariantCultureIgnoreCase))
                 {
                     // Random is set, so pick a random device package and set it up - it will get saved to disk below and re-used in subsequent sessions
                     Random rnd = new Random();
                     int rndIdx = rnd.Next(0, DeviceInfoHelper.DeviceInfoSets.Keys.Count - 1);
-                    this.DevicePackageName = DeviceInfoHelper.DeviceInfoSets.Keys.ToArray()[rndIdx];
-                    SetDevInfoByKey(this.DevicePackageName);
+                    DevicePackageName = DeviceInfoHelper.DeviceInfoSets.Keys.ToArray()[rndIdx];
+                    SetDevInfoByKey();
                 }
-                if (string.IsNullOrEmpty(this.DeviceId) || this.DeviceId == "8525f5d8201f78b5")
-                    this.DeviceId = this.RandomString(16, "0123456789abcdef"); // changed to random hex as full alphabet letters could have been flagged
+                if (string.IsNullOrEmpty(DeviceId) || DeviceId == "8525f5d8201f78b5")
+                    DeviceId = RandomString(16, "0123456789abcdef");
+                        // changed to random hex as full alphabet letters could have been flagged

                 // Jurann: Note that some device IDs I saw when adding devices had smaller numbers, only 12 or 14 chars instead of 16 - probably not important but noted here anyway

@@ -158,7 +146,7 @@ namespace PokemonGo.RocketBot.Logic
             {
                 DefaultValueHandling = DefaultValueHandling.Include,
                 Formatting = Formatting.Indented,
-                Converters = new JsonConverter[] { new StringEnumConverter { CamelCaseText = true } }
+                Converters = new JsonConverter[] {new StringEnumConverter {CamelCaseText = true}}
             };

             var output = JsonConvert.SerializeObject(this, jsonSerializeSettings);
@@ -180,21 +168,23 @@ namespace PokemonGo.RocketBot.Logic
             }
         }

-        public void checkProxy()
+        public void CheckProxy()
         {
             using (var tempWebClient = new NecroWebClient())
             {
-                string unproxiedIP = WebClientExtensions.DownloadString(tempWebClient, new Uri("https://api.ipify.org/?format=text"));
+                string unproxiedIp = WebClientExtensions.DownloadString(tempWebClient,
+                    new Uri("https://api.ipify.org/?format=text"));
                 if (UseProxy)
                 {
-                    tempWebClient.Proxy = this.InitProxy();
-                    string proxiedIPres = WebClientExtensions.DownloadString(tempWebClient, new Uri("https://api.ipify.org/?format=text"));
-                    string proxiedIP = proxiedIPres == null ? "INVALID PROXY" : proxiedIPres;
+                    tempWebClient.Proxy = InitProxy();
+                    string proxiedIPres = WebClientExtensions.DownloadString(tempWebClient,
+                        new Uri("https://api.ipify.org/?format=text"));
+                    string proxiedIp = proxiedIPres == null ? "INVALID PROXY" : proxiedIPres;
                     Logger.Write(
-                       $"Your IP is: {unproxiedIP} / Proxy IP is: {proxiedIP}",
-                       LogLevel.Info, (unproxiedIP == proxiedIP) ? ConsoleColor.Red : ConsoleColor.Green);
+                        $"Your IP is: {unproxiedIp} / Proxy IP is: {proxiedIp}",
+                        LogLevel.Info, (unproxiedIp == proxiedIp) ? ConsoleColor.Red : ConsoleColor.Green);

-                    if (unproxiedIP == proxiedIP || proxiedIPres == null)
+                    if (unproxiedIp == proxiedIp || proxiedIPres == null)
                     {
                         Logger.Write("Press any key to exit so you can fix your proxy settings...",
                             LogLevel.Info, ConsoleColor.Red);
@@ -205,24 +195,24 @@ namespace PokemonGo.RocketBot.Logic
                 else
                 {
                     Logger.Write(
-                       $"Your IP is: {unproxiedIP}",
-                       LogLevel.Info, ConsoleColor.Red);
+                        $"Your IP is: {unproxiedIp}",
+                        LogLevel.Info, ConsoleColor.Red);
                 }
             }
         }

         private string RandomString(int length, string alphabet = "abcdefghijklmnopqrstuvwxyz0123456789")
         {
-            var outOfRange = Byte.MaxValue + 1 - (Byte.MaxValue + 1) % alphabet.Length;
+            var outOfRange = Byte.MaxValue + 1 - (Byte.MaxValue + 1)%alphabet.Length;

             return string.Concat(
                 Enumerable
                     .Repeat(0, Int32.MaxValue)
-                    .Select(e => this.RandomByte())
+                    .Select(e => RandomByte())
                     .Where(randomByte => randomByte < outOfRange)
                     .Take(length)
-                    .Select(randomByte => alphabet[randomByte % alphabet.Length])
-            );
+                    .Select(randomByte => alphabet[randomByte%alphabet.Length])
+                );
         }

         private byte RandomByte()
@@ -235,27 +225,31 @@ namespace PokemonGo.RocketBot.Logic
             }
         }

-        private void SetDevInfoByKey(string devKey)
+        private void SetDevInfoByKey()
         {
-            if (DeviceInfoHelper.DeviceInfoSets.ContainsKey(this.DevicePackageName))
+            if (DeviceInfoHelper.DeviceInfoSets.ContainsKey(DevicePackageName))
             {
-                this.AndroidBoardName = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["AndroidBoardName"];
-                this.AndroidBootloader = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["AndroidBootloader"];
-                this.DeviceBrand = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["DeviceBrand"];
-                this.DeviceId = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["DeviceId"];
-                this.DeviceModel = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["DeviceModel"];
-                this.DeviceModelBoot = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["DeviceModelBoot"];
-                this.DeviceModelIdentifier = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["DeviceModelIdentifier"];
-                this.FirmwareBrand = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["FirmwareBrand"];
-                this.FirmwareFingerprint = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["FirmwareFingerprint"];
-                this.FirmwareTags = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["FirmwareTags"];
-                this.FirmwareType = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["FirmwareType"];
-                this.HardwareManufacturer = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["HardwareManufacturer"];
-                this.HardwareModel = DeviceInfoHelper.DeviceInfoSets[this.DevicePackageName]["HardwareModel"];
+                AndroidBoardName = DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["AndroidBoardName"];
+                AndroidBootloader = DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["AndroidBootloader"];
+                DeviceBrand = DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["DeviceBrand"];
+                DeviceId = DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["DeviceId"];
+                DeviceModel = DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["DeviceModel"];
+                DeviceModelBoot = DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["DeviceModelBoot"];
+                DeviceModelIdentifier =
+                    DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["DeviceModelIdentifier"];
+                FirmwareBrand = DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["FirmwareBrand"];
+                FirmwareFingerprint =
+                    DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["FirmwareFingerprint"];
+                FirmwareTags = DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["FirmwareTags"];
+                FirmwareType = DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["FirmwareType"];
+                HardwareManufacturer =
+                    DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["HardwareManufacturer"];
+                HardwareModel = DeviceInfoHelper.DeviceInfoSets[DevicePackageName]["HardwareModel"];
             }
             else
             {
-                throw new ArgumentException("Invalid device info package! Check your auth.config file and make sure a valid DevicePackageName is set. For simple use set it to 'random'. If you have a custom device, then set it to 'custom'.");
+                throw new ArgumentException(
+                    "Invalid device info package! Check your auth.config file and make sure a valid DevicePackageName is set. For simple use set it to 'random'. If you have a custom device, then set it to 'custom'.");
             }
         }

@@ -263,7 +257,7 @@ namespace PokemonGo.RocketBot.Logic
         {
             if (!UseProxy) return null;

-            WebProxy prox = new WebProxy(new System.Uri($"http://{UseProxyHost}:{UseProxyPort}"), false, null);
+            WebProxy prox = new WebProxy(new Uri($"http://{UseProxyHost}:{UseProxyPort}"), false, null);

             if (UseProxyAuthentication)
                 prox.Credentials = new NetworkCredential(UseProxyUsername, UseProxyPassword);
@@ -274,261 +268,154 @@ namespace PokemonGo.RocketBot.Logic

     public class GlobalSettings
     {
-        [JsonIgnore]
-        public AuthSettings Auth = new AuthSettings();
-        [JsonIgnore]
-        public string GeneralConfigPath;
-        [JsonIgnore]
-        public string ProfileConfigPath;
-        [JsonIgnore]
-        public string ProfilePath;
-
-        [JsonIgnore]
-        public bool isGui;
-
-        [DefaultValue("en")]
-        public string TranslationLanguageCode;
+        [JsonIgnore] public AuthSettings Auth = new AuthSettings();
+        [JsonIgnore] public string GeneralConfigPath;
+        [JsonIgnore] public string ProfileConfigPath;
+        [JsonIgnore] public string ProfilePath;
+
+        [JsonIgnore] public bool IsGui;
+
+        [DefaultValue("en")] public string TranslationLanguageCode;
         //autoupdate
-        [DefaultValue(true)]
-        public bool AutoUpdate;
-        [DefaultValue(true)]
-        public bool TransferConfigAndAuthOnUpdate;
+        [DefaultValue(true)] public bool AutoUpdate;
+        [DefaultValue(true)] public bool TransferConfigAndAuthOnUpdate;
         //websockets
-        [DefaultValue(false)]
-        public bool UseWebsocket;
-        [DefaultValue(14251)]
-        public int WebSocketPort;
+        [DefaultValue(false)] public bool UseWebsocket;
+        [DefaultValue(14251)] public int WebSocketPort;
         //pressakeyshit
-        [DefaultValue(false)]
-        public bool StartupWelcomeDelay;
+        [DefaultValue(false)] public bool StartupWelcomeDelay;
         //Telegram
-        [DefaultValue(false)]
-        public bool UseTelegramAPI;
-        [DefaultValue(null)]
-        public string TelegramAPIKey;
+        [DefaultValue(false)] public bool UseTelegramApi;
+        [DefaultValue(null)] public string TelegramApiKey;

         //console options
-        [DefaultValue(10)]
-        public int AmountOfPokemonToDisplayOnStart;
-        [DefaultValue(true)]
-        public bool DetailedCountsBeforeRecycling;
+        [DefaultValue(10)] public int AmountOfPokemonToDisplayOnStart;
+        [DefaultValue(true)] public bool DetailedCountsBeforeRecycling;

-        [DefaultValue(3)]
-        public int MaxBerriesToUsePerPokemon;
+        [DefaultValue(3)] public int MaxBerriesToUsePerPokemon;
         //pokemon
-        [DefaultValue(true)]
-        public bool CatchPokemon;
+        [DefaultValue(true)] public bool CatchPokemon;
         //powerup
-        [DefaultValue(false)]
-        public bool AutomaticallyLevelUpPokemon;
-        [DefaultValue(true)]
-        public bool OnlyUpgradeFavorites;
-
-        [DefaultValue((true))]
-        public bool UseLevelUpList;
-        [DefaultValue(5)]
-        public int AmountOfTimesToUpgradeLoop;
-        [DefaultValue(5000)]
-        public int GetMinStarDustForLevelUp;
-        [DefaultValue("iv")]
-        public string LevelUpByCPorIv;
-        [DefaultValue(1000)]
-        public float UpgradePokemonCpMinimum;
-        [DefaultValue(95)]
-        public float UpgradePokemonIvMinimum;
-        [DefaultValue("and")]
-        public string UpgradePokemonMinimumStatsOperator;
+        [DefaultValue(false)] public bool AutomaticallyLevelUpPokemon;
+        [DefaultValue(true)] public bool OnlyUpgradeFavorites;
+
+        [DefaultValue((true))] public bool UseLevelUpList;
+        [DefaultValue(5)] public int AmountOfTimesToUpgradeLoop;
+        [DefaultValue(5000)] public int GetMinStarDustForLevelUp;
+        [DefaultValue("iv")] public string LevelUpByCPorIv;
+        [DefaultValue(1000)] public float UpgradePokemonCpMinimum;
+        [DefaultValue(95)] public float UpgradePokemonIvMinimum;
+        [DefaultValue("and")] public string UpgradePokemonMinimumStatsOperator;
         //position
-        [DefaultValue(false)]
-        public bool DisableHumanWalking;
-        [DefaultValue(40.785091)]
-        public double DefaultLatitude;
-        [DefaultValue(-73.968285)]
-        public double DefaultLongitude;
-        [DefaultValue(19.0)]
-        public double WalkingSpeedInKilometerPerHour;
-        [DefaultValue(2)]
-        public double WalkingSpeedOffSetInKilometerPerHour;
-        [DefaultValue(10)]
+        [DefaultValue(false)] public bool DisableHumanWalking;
+        [DefaultValue(40.785091)] public double DefaultLatitude;
+        [DefaultValue(-73.968285)] public double DefaultLongitude;
+        [DefaultValue(19.0)] public double WalkingSpeedInKilometerPerHour;
+        [DefaultValue(2)] public double WalkingSpeedOffSetInKilometerPerHour;
+        [DefaultValue(true)] public bool UseWalkingSpeedVariant;
+        [DefaultValue(1.2)] public double WalkingSpeedVariant;
+        [DefaultValue(true)] public bool ShowVariantWalking;
+
+
         public int MaxSpawnLocationOffset;
         //softban related
-        [DefaultValue(false)]
-        public bool FastSoftBanBypass;
+        [DefaultValue(false)] public bool FastSoftBanBypass;
         //delays
-        [DefaultValue(500)]
-        public int DelayBetweenPlayerActions;
-        [DefaultValue(100)]
-        public int DelayBetweenPokemonCatch;
+        [DefaultValue(500)] public int DelayBetweenPlayerActions;
+        [DefaultValue(100)] public int DelayBetweenPokemonCatch;
         //dump stats
-        [DefaultValue(false)]
-        public bool DumpPokemonStats;
+        [DefaultValue(false)] public bool DumpPokemonStats;
         //evolve
-        [DefaultValue(95)]
-        public float EvolveAboveIvValue;
-        [DefaultValue(false)]
-        public bool EvolveAllPokemonAboveIv;
-        [DefaultValue(true)]
-        public bool EvolveAllPokemonWithEnoughCandy;
-        [DefaultValue(90.0)]
-        public double EvolveKeptPokemonsAtStorageUsagePercentage;
-        [DefaultValue(false)]
-        public bool KeepPokemonsThatCanEvolve;
+        [DefaultValue(95)] public float EvolveAboveIvValue;
+        [DefaultValue(false)] public bool EvolveAllPokemonAboveIv;
+        [DefaultValue(true)] public bool EvolveAllPokemonWithEnoughCandy;
+        [DefaultValue(90.0)] public double EvolveKeptPokemonsAtStorageUsagePercentage;
+        [DefaultValue(false)] public bool KeepPokemonsThatCanEvolve;
         //keeping
-        [DefaultValue(1250)]
-        public int KeepMinCp;
-        [DefaultValue(90)]
-        public float KeepMinIvPercentage;
-        [DefaultValue(6)]
-        public int KeepMinLvl;
-        [DefaultValue("or")]
-        public string KeepMinOperator;
-        [DefaultValue(false)]
-        public bool UseKeepMinLvl;
-        [DefaultValue(false)]
-        public bool PrioritizeIvOverCp;
-        [DefaultValue(0)]
-        public int KeepMinDuplicatePokemon;
+        [DefaultValue(1250)] public int KeepMinCp;
+        [DefaultValue(90)] public float KeepMinIvPercentage;
+        [DefaultValue(6)] public int KeepMinLvl;
+        [DefaultValue("or")] public string KeepMinOperator;
+        [DefaultValue(false)] public bool UseKeepMinLvl;
+        [DefaultValue(false)] public bool PrioritizeIvOverCp;
+        [DefaultValue(0)] public int KeepMinDuplicatePokemon;
         //gpx
-        [DefaultValue(false)]
-        public bool UseGpxPathing;
-        [DefaultValue("GPXPath.GPX")]
-        public string GpxFile;
+        [DefaultValue(false)] public bool UseGpxPathing;
+        [DefaultValue("GPXPath.GPX")] public string GpxFile;
         //recycle
-        [DefaultValue(true)]
-        public bool VerboseRecycling;
-        [DefaultValue(90.0)]
-        public double RecycleInventoryAtUsagePercentage;
-        [DefaultValue(false)]
-        public bool RandomizeRecycle;
-        [DefaultValue(5)]
-        public int RandomRecycleValue;
-        [DefaultValue(false)]
-        public bool DelayBetweenRecycleActions;
+        [DefaultValue(true)] public bool VerboseRecycling;
+        [DefaultValue(90.0)] public double RecycleInventoryAtUsagePercentage;
+        [DefaultValue(false)] public bool RandomizeRecycle;
+        [DefaultValue(5)] public int RandomRecycleValue;
+        [DefaultValue(false)] public bool DelayBetweenRecycleActions;
         //lucky, incense and berries
-        [DefaultValue(true)]
-        public bool UseEggIncubators;
-        [DefaultValue(false)]
-        public bool UseLuckyEggConstantly;
-        [DefaultValue(30)]
-        public int UseLuckyEggsMinPokemonAmount;
-        [DefaultValue(false)]
-        public bool UseLuckyEggsWhileEvolving;
-        [DefaultValue(false)]
-        public bool UseIncenseConstantly;
-        [DefaultValue(1000)]
-        public int UseBerriesMinCp;
-        [DefaultValue(90)]
-        public float UseBerriesMinIv;
-        [DefaultValue(0.20)]
-        public double UseBerriesBelowCatchProbability;
-        [DefaultValue("or")]
-        public string UseBerriesOperator;
+        [DefaultValue(true)] public bool UseEggIncubators;
+        [DefaultValue(false)] public bool UseLuckyEggConstantly;
+        [DefaultValue(30)] public int UseLuckyEggsMinPokemonAmount;
+        [DefaultValue(false)] public bool UseLuckyEggsWhileEvolving;
+        [DefaultValue(false)] public bool UseIncenseConstantly;
+        [DefaultValue(1000)] public int UseBerriesMinCp;
+        [DefaultValue(90)] public float UseBerriesMinIv;
+        [DefaultValue(0.20)] public double UseBerriesBelowCatchProbability;
+        [DefaultValue("or")] public string UseBerriesOperator;
         //snipe
-        [DefaultValue(false)]
-        public bool UseSnipeLocationServer;
-        [DefaultValue("localhost")]
-        public string SnipeLocationServer;
-        [DefaultValue(16969)]
-        public int SnipeLocationServerPort;
-        [DefaultValue(true)]
-        public bool GetSniperInfoFromPokezz;
-        [DefaultValue(true)]
-        public bool GetOnlyVerifiedSniperInfoFromPokezz;
-        [DefaultValue(true)]
-        public bool GetSniperInfoFromPokeSnipers;
-        [DefaultValue(true)]
-        public bool GetSniperInfoFromPokeWatchers;
-        [DefaultValue(true)]
-        public bool SnipeWithSkiplagged;
-        [DefaultValue(20)]
-        public int MinPokeballsToSnipe;
-        [DefaultValue(0)]
-        public int MinPokeballsWhileSnipe;
-        [DefaultValue(60000)]
-        public int MinDelayBetweenSnipes;
-        [DefaultValue(0.005)]
-        public double SnipingScanOffset;
-        [DefaultValue(false)]
-        public bool SnipeAtPokestops;
-        [DefaultValue(false)]
-        public bool SnipeIgnoreUnknownIv;
-        [DefaultValue(false)]
-        public bool UseTransferIvForSnipe;
-        [DefaultValue(false)]
-        public bool SnipePokemonNotInPokedex;
+        [DefaultValue(false)] public bool UseSnipeLocationServer;
+        [DefaultValue("localhost")] public string SnipeLocationServer;
+        [DefaultValue(16969)] public int SnipeLocationServerPort;
+        [DefaultValue(true)] public bool GetSniperInfoFromPokezz;
+        [DefaultValue(true)] public bool GetOnlyVerifiedSniperInfoFromPokezz;
+        [DefaultValue(true)] public bool GetSniperInfoFromPokeSnipers;
+        [DefaultValue(true)] public bool GetSniperInfoFromPokeWatchers;
+        [DefaultValue(true)] public bool SnipeWithSkiplagged;
+        [DefaultValue(20)] public int MinPokeballsToSnipe;
+        [DefaultValue(0)] public int MinPokeballsWhileSnipe;
+        [DefaultValue(60000)] public int MinDelayBetweenSnipes;
+        [DefaultValue(0.005)] public double SnipingScanOffset;
+        [DefaultValue(false)] public bool SnipeAtPokestops;
+        [DefaultValue(false)] public bool SnipeIgnoreUnknownIv;
+        [DefaultValue(false)] public bool UseTransferIvForSnipe;
+        [DefaultValue(false)] public bool SnipePokemonNotInPokedex;
         //rename
-        [DefaultValue(false)]
-        public bool RenamePokemon;
-        [DefaultValue(true)]
-        public bool RenameOnlyAboveIv;
-        [DefaultValue("{1}_{0}")]
-        public string RenameTemplate;
+        [DefaultValue(false)] public bool RenamePokemon;
+        [DefaultValue(true)] public bool RenameOnlyAboveIv;
+        [DefaultValue("{1}_{0}")] public string RenameTemplate;
         //amounts
-        [DefaultValue(6)]
-        public int MaxPokeballsPerPokemon;
-        [DefaultValue(1000)]
-        public int MaxTravelDistanceInMeters;
-        [DefaultValue(120)]
-        public int TotalAmountOfPokeballsToKeep;
-        [DefaultValue(80)]
-        public int TotalAmountOfPotionsToKeep;
-        [DefaultValue(60)]
-        public int TotalAmountOfRevivesToKeep;
-        [DefaultValue(50)]
-        public int TotalAmountOfBerriesToKeep;
+        [DefaultValue(6)] public int MaxPokeballsPerPokemon;
+        [DefaultValue(1000)] public int MaxTravelDistanceInMeters;
+        [DefaultValue(120)] public int TotalAmountOfPokeballsToKeep;
+        [DefaultValue(80)] public int TotalAmountOfPotionsToKeep;
+        [DefaultValue(60)] public int TotalAmountOfRevivesToKeep;
+        [DefaultValue(50)] public int TotalAmountOfBerriesToKeep;
         //balls
-        [DefaultValue(1000)]
-        public int UseGreatBallAboveCp;
-        [DefaultValue(1250)]
-        public int UseUltraBallAboveCp;
-        [DefaultValue(1500)]
-        public int UseMasterBallAboveCp;
-        [DefaultValue(85.0)]
-        public double UseGreatBallAboveIv;
-        [DefaultValue(95.0)]
-        public double UseUltraBallAboveIv;
-        [DefaultValue(0.2)]
-        public double UseGreatBallBelowCatchProbability;
-        [DefaultValue(0.1)]
-        public double UseUltraBallBelowCatchProbability;
-        [DefaultValue(0.05)]
-        public double UseMasterBallBelowCatchProbability;
+        [DefaultValue(1000)] public int UseGreatBallAboveCp;
+        [DefaultValue(1250)] public int UseUltraBallAboveCp;
+        [DefaultValue(1500)] public int UseMasterBallAboveCp;
+        [DefaultValue(85.0)] public double UseGreatBallAboveIv;
+        [DefaultValue(95.0)] public double UseUltraBallAboveIv;
+        [DefaultValue(0.2)] public double UseGreatBallBelowCatchProbability;
+        [DefaultValue(0.1)] public double UseUltraBallBelowCatchProbability;
+        [DefaultValue(0.05)] public double UseMasterBallBelowCatchProbability;
         //customizable catch
-        [DefaultValue(false)]
-        public bool EnableHumanizedThrows;
-        [DefaultValue(40)]
-        public int NiceThrowChance;
-        [DefaultValue(30)]
-        public int GreatThrowChance;
-        [DefaultValue(10)]
-        public int ExcellentThrowChance;
-        [DefaultValue(90)]
-        public int CurveThrowChance;
-        [DefaultValue(90.00)]
-        public double ForceGreatThrowOverIv;
-        [DefaultValue(95.00)]
-        public double ForceExcellentThrowOverIv;
-        [DefaultValue(1000)]
-        public int ForceGreatThrowOverCp;
-        [DefaultValue(1500)]
-        public int ForceExcellentThrowOverCp;
+        [DefaultValue(false)] public bool EnableHumanizedThrows;
+        [DefaultValue(40)] public int NiceThrowChance;
+        [DefaultValue(30)] public int GreatThrowChance;
+        [DefaultValue(10)] public int ExcellentThrowChance;
+        [DefaultValue(90)] public int CurveThrowChance;
+        [DefaultValue(90.00)] public double ForceGreatThrowOverIv;
+        [DefaultValue(95.00)] public double ForceExcellentThrowOverIv;
+        [DefaultValue(1000)] public int ForceGreatThrowOverCp;
+        [DefaultValue(1500)] public int ForceExcellentThrowOverCp;
         //transfer
-        [DefaultValue(false)]
-        public bool TransferWeakPokemon;
-        [DefaultValue(true)]
-        public bool TransferDuplicatePokemon;
-        [DefaultValue(true)]
-        public bool TransferDuplicatePokemonOnCapture;
+        [DefaultValue(false)] public bool TransferWeakPokemon;
+        [DefaultValue(true)] public bool TransferDuplicatePokemon;
+        [DefaultValue(true)] public bool TransferDuplicatePokemonOnCapture;
         //favorite
-        [DefaultValue(95)]
-        public float FavoriteMinIvPercentage;
-        [DefaultValue(false)]
-        public bool AutoFavoritePokemon;
+        [DefaultValue(95)] public float FavoriteMinIvPercentage;
+        [DefaultValue(false)] public bool AutoFavoritePokemon;
         //notcatch
-        [DefaultValue(false)]
-        public bool UsePokemonToNotCatchFilter;
-        [DefaultValue(false)]
-        public bool UsePokemonSniperFilterOnly;
+        [DefaultValue(false)] public bool UsePokemonToNotCatchFilter;
+        [DefaultValue(false)] public bool UsePokemonSniperFilterOnly;
+
         public List<KeyValuePair<ItemId, int>> ItemRecycleFilter = new List<KeyValuePair<ItemId, int>>
         {
             new KeyValuePair<ItemId, int>(ItemId.ItemUnknown, 0),
@@ -628,6 +515,7 @@ namespace PokemonGo.RocketBot.Logic
             //PokemonId.Goldeen,
             //PokemonId.Staryu
         };
+
         public List<PokemonId> PokemonsToLevelUp = new List<PokemonId>
         {
             //criteria: most common
@@ -639,6 +527,7 @@ namespace PokemonGo.RocketBot.Logic
             PokemonId.Zubat,
             PokemonId.Doduo
         };
+
         public List<PokemonId> PokemonsToIgnore = new List<PokemonId>
         {
             //criteria: most common
@@ -778,8 +667,10 @@ namespace PokemonGo.RocketBot.Logic

         public static GlobalSettings Load(string path, bool boolSkipSave = false)
         {
-            GlobalSettings settings = null;
-            bool isGui = (AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(a => a.FullName.Contains("PoGo.NecroBot.GUI")) != null);
+            GlobalSettings settings;
+            bool isGui =
+                (AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(a => a.FullName.Contains("PoGo.NecroBot.GUI")) !=
+                 null);
             var profilePath = Path.Combine(Directory.GetCurrentDirectory(), path);
             var profileConfigPath = Path.Combine(profilePath, "config");
             var configFile = Path.Combine(profileConfigPath, "config.json");
@@ -790,7 +681,7 @@ namespace PokemonGo.RocketBot.Logic
                 try
                 {
                     //if the file exists, load the settings
-                    string input = "";
+                    string input;
                     int count = 0;
                     while (true)
                     {
@@ -809,10 +700,10 @@ namespace PokemonGo.RocketBot.Logic
                             count++;
                             Thread.Sleep(1000);
                         }
-                    };
+                    }

                     var jsonSettings = new JsonSerializerSettings();
-                    jsonSettings.Converters.Add(new StringEnumConverter { CamelCaseText = true });
+                    jsonSettings.Converters.Add(new StringEnumConverter {CamelCaseText = true});
                     jsonSettings.ObjectCreationHandling = ObjectCreationHandling.Replace;
                     jsonSettings.DefaultValueHandling = DefaultValueHandling.Populate;

@@ -848,7 +739,7 @@ namespace PokemonGo.RocketBot.Logic
             settings.ProfilePath = profilePath;
             settings.ProfileConfigPath = profileConfigPath;
             settings.GeneralConfigPath = Path.Combine(Directory.GetCurrentDirectory(), "config");
-            settings.isGui = isGui;
+            settings.IsGui = isGui;

             if (!boolSkipSave || !settings.AutoUpdate)
             {
@@ -859,9 +750,9 @@ namespace PokemonGo.RocketBot.Logic
             return shouldExit ? null : settings;
         }

-        public void checkProxy()
+        public void CheckProxy()
         {
-            Auth.checkProxy();
+            Auth.CheckProxy();
         }

         public static bool PromptForSetup(ITranslation translator)
@@ -870,18 +761,22 @@ namespace PokemonGo.RocketBot.Logic

             while (true)
             {
-                string strInput = Console.ReadLine().ToLower();
-
-                switch (strInput)
+                var readLine = Console.ReadLine();
+                if (readLine != null)
                 {
-                    case "y":
-                        return true;
-                    case "n":
-                        Logger.Write(translator.GetTranslation(TranslationString.FirstStartAutoGenSettings));
-                        return false;
-                    default:
-                        Logger.Write(translator.GetTranslation(TranslationString.PromptError, "Y", "N"), LogLevel.Error);
-                        continue;
+                    string strInput = readLine.ToLower();
+
+                    switch (strInput)
+                    {
+                        case "y":
+                            return true;
+                        case "n":
+                            Logger.Write(translator.GetTranslation(TranslationString.FirstStartAutoGenSettings));
+                            return false;
+                        default:
+                            Logger.Write(translator.GetTranslation(TranslationString.PromptError, "Y", "N"), LogLevel.Error);
+                            continue;
+                    }
                 }
             }
         }
@@ -908,6 +803,7 @@ namespace PokemonGo.RocketBot.Logic
             bool boolBreak = false;
             while (!boolBreak)
             {
+                // ReSharper disable once PossibleNullReferenceException
                 strInput = Console.ReadLine().ToLower();

                 switch (strInput)
@@ -943,6 +839,7 @@ namespace PokemonGo.RocketBot.Logic

             while (true)
             {
+                // ReSharper disable once PossibleNullReferenceException
                 strInput = Console.ReadLine().ToLower();

                 switch (strInput)
@@ -956,7 +853,9 @@ namespace PokemonGo.RocketBot.Logic
                         Logger.Write(translator.GetTranslation(TranslationString.FirstStartSetupTypeConfirm, "PTC"));
                         return;
                     default:
-                        Logger.Write(translator.GetTranslation(TranslationString.FirstStartSetupTypePromptError, "google", "ptc"), LogLevel.Error);
+                        Logger.Write(
+                            translator.GetTranslation(TranslationString.FirstStartSetupTypePromptError, "google", "ptc"),
+                            LogLevel.Error);
                         break;
                 }
             }
@@ -989,11 +888,13 @@ namespace PokemonGo.RocketBot.Logic

         private static void SetupConfig(ITranslation translator, GlobalSettings settings)
         {
-            Logger.Write(translator.GetTranslation(TranslationString.FirstStartDefaultLocationPrompt, "Y", "N"), LogLevel.None);
+            Logger.Write(translator.GetTranslation(TranslationString.FirstStartDefaultLocationPrompt, "Y", "N"),
+                LogLevel.None);

             bool boolBreak = false;
             while (!boolBreak)
             {
+                // ReSharper disable once PossibleNullReferenceException
                 string strInput = Console.ReadLine().ToLower();

                 switch (strInput)
@@ -1017,6 +918,7 @@ namespace PokemonGo.RocketBot.Logic
             {
                 try
                 {
+                    // ReSharper disable once AssignNullToNotNullAttribute
                     double dblInput = double.Parse(Console.ReadLine());
                     settings.DefaultLatitude = dblInput;
                     Logger.Write(translator.GetTranslation(TranslationString.FirstStartSetupDefaultLatConfirm, dblInput));
@@ -1024,8 +926,8 @@ namespace PokemonGo.RocketBot.Logic
                 }
                 catch (FormatException)
                 {
-                    Logger.Write(translator.GetTranslation(TranslationString.FirstStartSetupDefaultLocationError, settings.DefaultLatitude, LogLevel.Error));
-                    continue;
+                    Logger.Write(translator.GetTranslation(TranslationString.FirstStartSetupDefaultLocationError,
+                        settings.DefaultLatitude, LogLevel.Error));
                 }
             }

@@ -1034,6 +936,7 @@ namespace PokemonGo.RocketBot.Logic
             {
                 try
                 {
+                    // ReSharper disable once AssignNullToNotNullAttribute
                     double dblInput = double.Parse(Console.ReadLine());
                     settings.DefaultLongitude = dblInput;
                     Logger.Write(translator.GetTranslation(TranslationString.FirstStartSetupDefaultLongConfirm, dblInput));
@@ -1041,8 +944,8 @@ namespace PokemonGo.RocketBot.Logic
                 }
                 catch (FormatException)
                 {
-                    Logger.Write(translator.GetTranslation(TranslationString.FirstStartSetupDefaultLocationError, settings.DefaultLongitude, LogLevel.Error));
-                    continue;
+                    Logger.Write(translator.GetTranslation(TranslationString.FirstStartSetupDefaultLocationError,
+                        settings.DefaultLongitude, LogLevel.Error));
                 }
             }
         }
@@ -1059,7 +962,7 @@ namespace PokemonGo.RocketBot.Logic
             {
                 DefaultValueHandling = DefaultValueHandling.Include,
                 Formatting = Formatting.Indented,
-                Converters = new JsonConverter[] { new StringEnumConverter { CamelCaseText = true } }
+                Converters = new JsonConverter[] {new StringEnumConverter {CamelCaseText = true}}
             };

             var output = JsonConvert.SerializeObject(this, jsonSerializeSettings);
@@ -1130,8 +1033,13 @@ namespace PokemonGo.RocketBot.Logic
         public string GoogleRefreshToken
         {
             get { return null; }
-            set { GoogleRefreshToken = null; }
+            set
+            {
+                if (value == null) throw new ArgumentNullException(nameof(value));
+                GoogleRefreshToken = null;
+            }
         }
+
         AuthType ISettings.AuthType
         {
             get { return _settings.Auth.AuthType; }
@@ -1176,66 +1084,79 @@ namespace PokemonGo.RocketBot.Logic
             get { return _settings.Auth.DevicePackageName; }
             set { _settings.Auth.DevicePackageName = value; }
         }
+
         string ISettings.DeviceId
         {
             get { return _settings.Auth.DeviceId; }
             set { _settings.Auth.DeviceId = value; }
         }
+
         string ISettings.AndroidBoardName
         {
             get { return _settings.Auth.AndroidBoardName; }
             set { _settings.Auth.AndroidBoardName = value; }
         }
+
         string ISettings.AndroidBootloader
         {
             get { return _settings.Auth.AndroidBootloader; }
             set { _settings.Auth.AndroidBootloader = value; }
         }
+
         string ISettings.DeviceBrand
         {
             get { return _settings.Auth.DeviceBrand; }
             set { _settings.Auth.DeviceBrand = value; }
         }
+
         string ISettings.DeviceModel
         {
             get { return _settings.Auth.DeviceModel; }
             set { _settings.Auth.DeviceModel = value; }
         }
+
         string ISettings.DeviceModelIdentifier
         {
             get { return _settings.Auth.DeviceModelIdentifier; }
             set { _settings.Auth.DeviceModelIdentifier = value; }
         }
+
         string ISettings.DeviceModelBoot
         {
             get { return _settings.Auth.DeviceModelBoot; }
             set { _settings.Auth.DeviceModelBoot = value; }
         }
+
         string ISettings.HardwareManufacturer
         {
             get { return _settings.Auth.HardwareManufacturer; }
             set { _settings.Auth.HardwareManufacturer = value; }
         }
+
         string ISettings.HardwareModel
         {
             get { return _settings.Auth.HardwareModel; }
             set { _settings.Auth.HardwareModel = value; }
         }
+
         string ISettings.FirmwareBrand
         {
             get { return _settings.Auth.FirmwareBrand; }
             set { _settings.Auth.FirmwareBrand = value; }
         }
+
         string ISettings.FirmwareTags
         {
             get { return _settings.Auth.FirmwareTags; }
             set { _settings.Auth.FirmwareTags = value; }
         }
+
         string ISettings.FirmwareType
         {
             get { return _settings.Auth.FirmwareType; }
             set { _settings.Auth.FirmwareType = value; }
         }
+
         string ISettings.FirmwareFingerprint
         {
             get { return _settings.Auth.FirmwareFingerprint; }
@@ -1248,7 +1169,7 @@ namespace PokemonGo.RocketBot.Logic
         {
             get
             {
-                return _settings.DefaultLatitude + _rand.NextDouble() * ((double)_settings.MaxSpawnLocationOffset / 111111);
+                return _settings.DefaultLatitude + _rand.NextDouble()*((double) _settings.MaxSpawnLocationOffset/111111);
             }

             set { _settings.DefaultLatitude = value; }
@@ -1259,8 +1180,8 @@ namespace PokemonGo.RocketBot.Logic
             get
             {
                 return _settings.DefaultLongitude +
-                       _rand.NextDouble() *
-                       ((double)_settings.MaxSpawnLocationOffset / 111111 / Math.Cos(_settings.DefaultLatitude));
+                       _rand.NextDouble()*
+                       ((double) _settings.MaxSpawnLocationOffset/111111/Math.Cos(_settings.DefaultLatitude));
             }

             set { _settings.DefaultLongitude = value; }
@@ -1272,8 +1193,9 @@ namespace PokemonGo.RocketBot.Logic
             {
                 return
                     LocationUtils.getElevation(_settings.DefaultLatitude, _settings.DefaultLongitude) +
-                    _rand.NextDouble() *
-                    ((double)5 / Math.Cos(LocationUtils.getElevation(_settings.DefaultLatitude, _settings.DefaultLongitude)));
+                    _rand.NextDouble()*
+                    (5/
+                     Math.Cos(LocationUtils.getElevation(_settings.DefaultLatitude, _settings.DefaultLongitude)));
             }


@@ -1291,6 +1213,7 @@ namespace PokemonGo.RocketBot.Logic
             _settings = settings;
         }

+        public string GoogleAPIKey => _settings.Auth.GoogleApiKey;
         public string ProfilePath => _settings.ProfilePath;
         public string ProfileConfigPath => _settings.ProfileConfigPath;
         public string GeneralConfigPath => _settings.GeneralConfigPath;
@@ -1323,6 +1246,9 @@ namespace PokemonGo.RocketBot.Logic
         public string UpgradePokemonMinimumStatsOperator => _settings.UpgradePokemonMinimumStatsOperator;
         public double WalkingSpeedInKilometerPerHour => _settings.WalkingSpeedInKilometerPerHour;
         public double WalkingSpeedOffSetInKilometerPerHour => _settings.WalkingSpeedOffSetInKilometerPerHour;
+        public bool UseWalkingSpeedVariant => _settings.UseWalkingSpeedVariant;
+        public double WalkingSpeedVariant => _settings.WalkingSpeedVariant;
+        public bool ShowVariantWalking => _settings.ShowVariantWalking;
         public bool FastSoftBanBypass => _settings.FastSoftBanBypass;
         public bool EvolveAllPokemonWithEnoughCandy => _settings.EvolveAllPokemonWithEnoughCandy;
         public bool KeepPokemonsThatCanEvolve => _settings.KeepPokemonsThatCanEvolve;
@@ -1370,7 +1296,10 @@ namespace PokemonGo.RocketBot.Logic
         public bool DetailedCountsBeforeRecycling => _settings.DetailedCountsBeforeRecycling;
         public bool VerboseRecycling => _settings.VerboseRecycling;
         public double RecycleInventoryAtUsagePercentage => _settings.RecycleInventoryAtUsagePercentage;
-        public double EvolveKeptPokemonsAtStorageUsagePercentage => _settings.EvolveKeptPokemonsAtStorageUsagePercentage;
+
+        public double EvolveKeptPokemonsAtStorageUsagePercentage => _settings.EvolveKeptPokemonsAtStorageUsagePercentage
+            ;
+
         public ICollection<KeyValuePair<ItemId, int>> ItemRecycleFilter => _settings.ItemRecycleFilter;
         public ICollection<PokemonId> PokemonsToEvolve => _settings.PokemonsToEvolve;
         public ICollection<PokemonId> PokemonsToLevelUp => _settings.PokemonsToLevelUp;
@@ -1382,8 +1311,8 @@ namespace PokemonGo.RocketBot.Logic
         public bool StartupWelcomeDelay => _settings.StartupWelcomeDelay;
         public bool SnipeAtPokestops => _settings.SnipeAtPokestops;

-        public bool UseTelegramAPI => _settings.UseTelegramAPI;
-        public string TelegramAPIKey => _settings.TelegramAPIKey;
+        public bool UseTelegramAPI => _settings.UseTelegramApi;
+        public string TelegramAPIKey => _settings.TelegramApiKey;

         public int MinPokeballsToSnipe => _settings.MinPokeballsToSnipe;
         public int MinPokeballsWhileSnipe => _settings.MinPokeballsWhileSnipe;
@@ -1411,4 +1340,4 @@ namespace PokemonGo.RocketBot.Logic
         public int TotalAmountOfRevivesToKeep => _settings.TotalAmountOfRevivesToKeep;
         public int TotalAmountOfBerriesToKeep => _settings.TotalAmountOfBerriesToKeep;
     }
-}
+}
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Logic/State/FarmState.cs b/PokemonGo.RocketBot.Logic/State/FarmState.cs
index ee8dbe2..46a0408 100644
--- a/PokemonGo.RocketBot.Logic/State/FarmState.cs
+++ b/PokemonGo.RocketBot.Logic/State/FarmState.cs
@@ -20,7 +20,7 @@ namespace PokemonGo.RocketBot.Logic.State

             if (session.LogicSettings.UseEggIncubators)
             {
-                UseIncubatorsTask.Execute(session, cancellationToken);
+                await UseIncubatorsTask.Execute(session, cancellationToken);
             }

             if (session.LogicSettings.TransferDuplicatePokemon)
@@ -30,24 +30,24 @@ namespace PokemonGo.RocketBot.Logic.State

             if (session.LogicSettings.UseLuckyEggConstantly)
             {
-                UseLuckyEggConstantlyTask.Execute(session, cancellationToken);
+                await UseLuckyEggConstantlyTask.Execute(session, cancellationToken);
             }

             if (session.LogicSettings.UseIncenseConstantly)
             {
-                UseIncenseConstantlyTask.Execute(session, cancellationToken);
+                await UseIncenseConstantlyTask.Execute(session, cancellationToken);
             }

             await GetPokeDexCount.Execute(session, cancellationToken);

             if (session.LogicSettings.RenamePokemon)
             {
-                RenamePokemonTask.Execute(session, cancellationToken);
+                await RenamePokemonTask.Execute(session, cancellationToken);
             }

             if (session.LogicSettings.AutoFavoritePokemon)
             {
-                FavoritePokemonTask.Execute(session, cancellationToken);
+                await FavoritePokemonTask.Execute(session, cancellationToken);
             }

             await RecycleItemsTask.Execute(session, cancellationToken);
diff --git a/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsGPXTask.cs b/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsGPXTask.cs
index 55b3c6e..98aa270 100644
--- a/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsGPXTask.cs
+++ b/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsGPXTask.cs
@@ -166,7 +166,6 @@ namespace PokemonGo.RocketBot.Logic.Tasks

                         await session.Navigation.HumanPathWalking(
                             trackPoints.ElementAt(curTrkPt),
-                            session.LogicSettings.WalkingSpeedInKilometerPerHour,
                             async () =>
                             {
                                 await CatchNearbyPokemonsTask.Execute(session, cancellationToken);
@@ -175,8 +174,8 @@ namespace PokemonGo.RocketBot.Logic.Tasks
                                 await UseNearbyPokestopsTask.Execute(session, cancellationToken);
                                 return true;
                             },
-                            cancellationToken
-                            );
+                            session,
+                            cancellationToken);

                         await eggWalker.ApplyDistance(distance, cancellationToken);
                     } //end trkpts
diff --git a/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs b/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
index 254fac1..1c1a832 100644
--- a/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
+++ b/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
@@ -42,9 +42,14 @@ namespace PokemonGo.RocketBot.Logic.Tasks
                     session.Translation.GetTranslation(TranslationString.FarmPokestopsOutsideRadius, distanceFromStart),
                     LogLevel.Warning);

-                await session.Navigation.Move(
-                    new GeoCoordinate(session.Settings.DefaultLatitude, session.Settings.DefaultLongitude, LocationUtils.getElevation(session.Settings.DefaultLatitude, session.Settings.DefaultLongitude)),
-                    session.LogicSettings.WalkingSpeedInKilometerPerHour, session.LogicSettings.WalkingSpeedOffSetInKilometerPerHour, null, cancellationToken, session.LogicSettings.DisableHumanWalking);
+                await session.Navigation.Move(new GeoCoordinate(
+                    session.Settings.DefaultLatitude,
+                    session.Settings.DefaultLongitude,
+                    LocationUtils.getElevation(session.Settings.DefaultLatitude,
+                    session.Settings.DefaultLongitude)),
+                    null,
+                    session,
+                    cancellationToken);
             }

             var pokestopList = await GetPokeStops(session);
@@ -77,16 +82,18 @@ namespace PokemonGo.RocketBot.Logic.Tasks

                 session.EventDispatcher.Send(new FortTargetEvent { Name = fortInfo.Name, Distance = distance });

-                await session.Navigation.Move(new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude, LocationUtils.getElevation(pokeStop.Latitude, pokeStop.Longitude)),
-                session.LogicSettings.WalkingSpeedInKilometerPerHour, session.LogicSettings.WalkingSpeedOffSetInKilometerPerHour,
-                async () =>
-                {
-                    // Catch normal map Pokemon
-                    await CatchNearbyPokemonsTask.Execute(session, cancellationToken);
-                    //Catch Incense Pokemon
-                    await CatchIncensePokemonsTask.Execute(session, cancellationToken);
-                    return true;
-                }, cancellationToken, session.LogicSettings.DisableHumanWalking);
+                await session.Navigation.Move(new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude,
+                        LocationUtils.getElevation(pokeStop.Latitude, pokeStop.Longitude)),
+                    async () =>
+                    {
+                        // Catch normal map Pokemon
+                        await CatchNearbyPokemonsTask.Execute(session, cancellationToken);
+                        //Catch Incense Pokemon
+                        await CatchIncensePokemonsTask.Execute(session, cancellationToken);
+                        return true;
+                    },
+                    session,
+                    cancellationToken);

                 //Catch Lure Pokemon
                 if (pokeStop.LureInfo != null)
diff --git a/PokemonGo.RocketBot.Window/ConsoleEventListener.cs b/PokemonGo.RocketBot.Window/ConsoleEventListener.cs
index ac85971..8b5eb11 100644
--- a/PokemonGo.RocketBot.Window/ConsoleEventListener.cs
+++ b/PokemonGo.RocketBot.Window/ConsoleEventListener.cs
@@ -18,6 +18,16 @@ namespace PokemonGo.RocketBot.Window
     [SuppressMessage("ReSharper", "UnusedParameter.Local")]
     internal class ConsoleEventListener
     {
+        private static void HandleEvent(HumanWalkingEvent humanWalkingEvent, ISession session)
+        {
+            if (session.LogicSettings.ShowVariantWalking)
+                Logger.Write(
+                    session.Translation.GetTranslation(TranslationString.HumanWalkingVariant,
+                    humanWalkingEvent.OldWalkingSpeed,
+                    humanWalkingEvent.CurrentWalkingSpeed),
+                    LogLevel.Info, ConsoleColor.DarkCyan);
+        }
+
         private static void HandleEvent(ProfileEvent profileEvent, ISession session)
         {
             Logger.Write(session.Translation.GetTranslation(TranslationString.EventProfileLogin,
diff --git a/PokemonGo.RocketBot.Window/Forms/MainForm.cs b/PokemonGo.RocketBot.Window/Forms/MainForm.cs
index 34364e6..d57676a 100644
--- a/PokemonGo.RocketBot.Window/Forms/MainForm.cs
+++ b/PokemonGo.RocketBot.Window/Forms/MainForm.cs
@@ -149,11 +149,13 @@ namespace PokemonGo.RocketBot.Window.Forms
             }
             else
             {
-                _settings = new GlobalSettings();
-                _settings.ProfilePath = profilePath;
-                _settings.ProfileConfigPath = profileConfigPath;
-                _settings.GeneralConfigPath = Path.Combine(Directory.GetCurrentDirectory(), "config");
-                _settings.TranslationLanguageCode = strCulture;
+                _settings = new GlobalSettings
+                {
+                    ProfilePath = profilePath,
+                    ProfileConfigPath = profileConfigPath,
+                    GeneralConfigPath = Path.Combine(Directory.GetCurrentDirectory(), "config"),
+                    TranslationLanguageCode = strCulture
+                };
                 BoolNeedsSetup = true;
             }

@@ -170,7 +172,7 @@ namespace PokemonGo.RocketBot.Window.Forms
             _machine = new StateMachine();
             var stats = new Statistics();

-            var strVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(3);
+            // var strVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(3); NOT USED ATM

             //Status bar
             stats.DirtyEvent +=
@@ -228,14 +230,14 @@ namespace PokemonGo.RocketBot.Window.Forms

         private async Task StartBot()
         {
-            _machine.AsyncStart(new VersionCheckState(), _session);
+            await _machine.AsyncStart(new VersionCheckState(), _session);

-            if (_settings.UseTelegramAPI)
+            if (_settings.UseTelegramApi)
             {
-                _session.Telegram = new TelegramService(_settings.TelegramAPIKey, _session);
+                _session.Telegram = new TelegramService(_settings.TelegramApiKey, _session);
             }

-            _settings.checkProxy();
+            _settings.CheckProxy();

             QuitEvent.WaitOne();
         }
@@ -249,16 +251,17 @@ namespace PokemonGo.RocketBot.Window.Forms
                 _playerOverlay.Markers.Clear();
                 _playerOverlay.Routes.Clear();
                 _playerLocations.Clear();
-                var routePoint =
+                /*var routePoint =
                     (from pokeStop in pokeStops
                         where pokeStop != null
                         select new PointLatLng(pokeStop.Latitude, pokeStop.Longitude)).ToList();

+                // Temporary removed it since the route is calculated on the fly with gmap api's
                 var route = new GMapRoute(routePoint, "Walking Path")
                 {
                     Stroke = new Pen(Color.FromArgb(128, 0, 179, 253), 4)
                 };
-                _pokestopsOverlay.Routes.Add(route);
+                _pokestopsOverlay.Routes.Add(route);*/

                 foreach (var pokeStop in pokeStops)
                 {
@@ -430,9 +433,9 @@ namespace PokemonGo.RocketBot.Window.Forms

         #region EVENTS

-        private void btnRefresh_Click(object sender, EventArgs e)
+        private async void btnRefresh_Click(object sender, EventArgs e)
         {
-            ReloadPokemonList();
+            await ReloadPokemonList();
         }

         private void startStopBotToolStripMenuItem_Click(object sender, EventArgs e)
@@ -467,6 +470,7 @@ namespace PokemonGo.RocketBot.Window.Forms
             {
                 var pokemon = rowObject as PokemonObject;

+                // ReSharper disable once PossibleNullReferenceException
                 var key = pokemon.PokemonId.ToString();
                 if (!olvPokemonList.SmallImageList.Images.ContainsKey(key))
                 {
@@ -482,11 +486,13 @@ namespace PokemonGo.RocketBot.Window.Forms
                 if (olvPokemonList.Objects
                     .Cast<PokemonObject>()
                     .Select(i => i.PokemonId)
+                    // ReSharper disable once PossibleNullReferenceException
                     .Count(p => p == pok.PokemonId) > 1)
                     e.Item.BackColor = Color.LightGreen;

                 foreach (OLVListSubItem sub in e.Item.SubItems)
                 {
+                    // ReSharper disable once PossibleNullReferenceException
                     if (sub.Text.Equals("Evolve") && !pok.CanEvolve)
                     {
                         sub.CellPadding = new Rectangle(100, 100, 0, 0);
@@ -499,12 +505,9 @@ namespace PokemonGo.RocketBot.Window.Forms
                 e.Cancel = false;
                 cmsPokemonList.Items.Clear();

-                var pokemons = olvPokemonList.SelectedObjects.Cast<PokemonObject>().Select(o => o.PokemonData);
+                var pokemons = olvPokemonList.SelectedObjects.Cast<PokemonObject>().Select(o => o.PokemonData).ToList();
                 var canAllEvolve =
-                    olvPokemonList.SelectedObjects.Cast<PokemonObject>()
-                        .Select(o => o)
-                        .Where(o => o.CanEvolve == false)
-                        .Count() == 0;
+                    olvPokemonList.SelectedObjects.Cast<PokemonObject>().Select(o => o).All(o => o.CanEvolve);
                 var count = pokemons.Count();

                 if (count < 1)
@@ -516,12 +519,11 @@ namespace PokemonGo.RocketBot.Window.Forms

                 var item = new ToolStripMenuItem();
                 var separator = new ToolStripSeparator();
-                item.Text = "Transfer " + count + " pokemon";
+                item.Text = $"Transfer {count} pokemon";
                 item.Click += delegate { TransferPokemon(pokemons); };
                 cmsPokemonList.Items.Add(item);

-                item = new ToolStripMenuItem();
-                item.Text = "Rename";
+                item = new ToolStripMenuItem {Text = @"Rename"};
                 item.Click += delegate
                 {
                     using (var form = count == 1 ? new NicknamePokemonForm(pokemonObject) : new NicknamePokemonForm())
@@ -536,46 +538,38 @@ namespace PokemonGo.RocketBot.Window.Forms

                 if (canAllEvolve)
                 {
-                    item = new ToolStripMenuItem();
-                    item.Text = "Evolve " + count + " pokemon";
+                    item = new ToolStripMenuItem {Text = $"Evolve {count} pokemon"};
                     item.Click += delegate { EvolvePokemon(pokemons); };
                     cmsPokemonList.Items.Add(item);
                 }

-                if (count == 1)
-                {
-                    item = new ToolStripMenuItem();
-                    item.Text = "PowerUp";
-                    item.Click += delegate { PowerUpPokemon(pokemons); };
-                    cmsPokemonList.Items.Add(item);
-                    cmsPokemonList.Items.Add(separator);
+                if (count != 1) return;
+                item = new ToolStripMenuItem {Text = @"PowerUp"};
+                item.Click += delegate { PowerUpPokemon(pokemons); };
+                cmsPokemonList.Items.Add(item);
+                cmsPokemonList.Items.Add(separator);

-                    item = new ToolStripMenuItem();
-                    item.Text = "Transfer Clean Up (Keep highest IV)";
-                    item.Click += delegate { CleanUpTransferPokemon(pokemonObject, "IV"); };
-                    cmsPokemonList.Items.Add(item);
+                item = new ToolStripMenuItem {Text = @"Transfer Clean Up (Keep highest IV)"};
+                item.Click += delegate { CleanUpTransferPokemon(pokemonObject, "IV"); };
+                cmsPokemonList.Items.Add(item);

-                    item = new ToolStripMenuItem();
-                    item.Text = "Transfer Clean Up (Keep highest CP)";
-                    item.Click += delegate { CleanUpTransferPokemon(pokemonObject, "CP"); };
-                    cmsPokemonList.Items.Add(item);
+                item = new ToolStripMenuItem {Text = @"Transfer Clean Up (Keep highest CP)"};
+                item.Click += delegate { CleanUpTransferPokemon(pokemonObject, "CP"); };
+                cmsPokemonList.Items.Add(item);

-                    item = new ToolStripMenuItem();
-                    item.Text = "Evolve Clean Up (Highest IV)";
-                    item.Click += delegate { CleanUpEvolvePokemon(pokemonObject, "IV"); };
-                    cmsPokemonList.Items.Add(item);
+                item = new ToolStripMenuItem {Text = @"Evolve Clean Up (Highest IV)"};
+                item.Click += delegate { CleanUpEvolvePokemon(pokemonObject, "IV"); };
+                cmsPokemonList.Items.Add(item);

-                    item = new ToolStripMenuItem();
-                    item.Text = "Evolve Clean Up (Highest CP)";
-                    item.Click += delegate { CleanUpEvolvePokemon(pokemonObject, "CP"); };
-                    cmsPokemonList.Items.Add(item);
+                item = new ToolStripMenuItem {Text = @"Evolve Clean Up (Highest CP)"};
+                item.Click += delegate { CleanUpEvolvePokemon(pokemonObject, "CP"); };
+                cmsPokemonList.Items.Add(item);

-                    cmsPokemonList.Items.Add(separator);
-                }
+                cmsPokemonList.Items.Add(separator);
             };
         }

-        private void olvPokemonList_ButtonClick(object sender, CellClickEventArgs e)
+        private async void olvPokemonList_ButtonClick(object sender, CellClickEventArgs e)
         {
             try
             {
@@ -583,21 +577,24 @@ namespace PokemonGo.RocketBot.Window.Forms
                 var cName = olvPokemonList.AllColumns[e.ColumnIndex].AspectToStringFormat;
                 if (cName.Equals("Transfer"))
                 {
+                    // ReSharper disable once PossibleNullReferenceException
                     TransferPokemon(new List<PokemonData> {pokemon.PokemonData});
                 }
                 else if (cName.Equals("Power Up"))
                 {
+                    // ReSharper disable once PossibleNullReferenceException
                     PowerUpPokemon(new List<PokemonData> {pokemon.PokemonData});
                 }
                 else if (cName.Equals("Evolve"))
                 {
+                    // ReSharper disable once PossibleNullReferenceException
                     EvolvePokemon(new List<PokemonData> {pokemon.PokemonData});
                 }
             }
             catch (Exception ex)
             {
                 Logger.Write(ex.ToString(), LogLevel.Error);
-                ReloadPokemonList();
+                await ReloadPokemonList();
             }
         }

@@ -618,7 +615,7 @@ namespace PokemonGo.RocketBot.Window.Forms
                     Logger.Write($"{pokemon.PokemonId} could not be transferred", LogLevel.Error);
                 }
             }
-            ReloadPokemonList();
+            await ReloadPokemonList();
         }

         private async void PowerUpPokemon(IEnumerable<PokemonData> pokemons)
@@ -636,7 +633,7 @@ namespace PokemonGo.RocketBot.Window.Forms
                     Logger.Write($"{pokemon.PokemonId} could not be upgraded");
                 }
             }
-            ReloadPokemonList();
+            await ReloadPokemonList();
         }

         private async void EvolvePokemon(IEnumerable<PokemonData> pokemons)
@@ -655,25 +652,25 @@ namespace PokemonGo.RocketBot.Window.Forms
                     Logger.Write($"{pokemon.PokemonId} could not be evolved");
                 }
             }
-            ReloadPokemonList();
+            await ReloadPokemonList();
         }

-        private void CleanUpTransferPokemon(PokemonObject pokemon, string type)
+        private async void CleanUpTransferPokemon(PokemonObject pokemon, string type)
         {
-            var ET = pokemon.EvolveTimes;
+            var et = pokemon.EvolveTimes;
             var pokemonCount =
-                olvPokemonList.Objects.Cast<PokemonObject>()
-                    .Where(p => p.PokemonId == pokemon.PokemonId)
-                    .Count();
+                olvPokemonList.Objects
+                    .Cast<PokemonObject>()
+                    .Count(p => p.PokemonId == pokemon.PokemonId);

-            if (pokemonCount < ET)
+            if (pokemonCount < et)
             {
-                ReloadPokemonList();
+                await ReloadPokemonList();
                 return;
             }

-            if (ET == 0)
-                ET = 1;
+            if (et == 0)
+                et = 1;

             if (type.Equals("IV"))
             {
@@ -682,8 +679,8 @@ namespace PokemonGo.RocketBot.Window.Forms
                         .Where(p => p.PokemonId == pokemon.PokemonId)
                         .Select(p => p.PokemonData)
                         .OrderBy(p => p.Cp)
-                        .OrderBy(PokemonInfo.CalculatePokemonPerfection)
-                        .Take(pokemonCount - ET);
+                        .ThenBy(PokemonInfo.CalculatePokemonPerfection)
+                        .Take(pokemonCount - et);

                 TransferPokemon(pokemons);
             }
@@ -694,20 +691,20 @@ namespace PokemonGo.RocketBot.Window.Forms
                         .Where(p => p.PokemonId == pokemon.PokemonId)
                         .Select(p => p.PokemonData)
                         .OrderBy(PokemonInfo.CalculatePokemonPerfection)
-                        .OrderBy(p => p.Cp)
-                        .Take(pokemonCount - ET);
+                        .ThenBy(p => p.Cp)
+                        .Take(pokemonCount - et);

                 TransferPokemon(pokemons);
             }
         }

-        private void CleanUpEvolvePokemon(PokemonObject pokemon, string type)
+        private async void CleanUpEvolvePokemon(PokemonObject pokemon, string type)
         {
-            var ET = pokemon.EvolveTimes;
+            var et = pokemon.EvolveTimes;

-            if (ET < 1)
+            if (et < 1)
             {
-                ReloadPokemonList();
+                await ReloadPokemonList();
                 return;
             }

@@ -718,8 +715,8 @@ namespace PokemonGo.RocketBot.Window.Forms
                         .Where(p => p.PokemonId == pokemon.PokemonId)
                         .Select(p => p.PokemonData)
                         .OrderByDescending(p => p.Cp)
-                        .OrderByDescending(PokemonInfo.CalculatePokemonPerfection)
-                        .Take(ET);
+                        .ThenByDescending(PokemonInfo.CalculatePokemonPerfection)
+                        .Take(et);

                 EvolvePokemon(pokemons);
             }
@@ -730,8 +727,8 @@ namespace PokemonGo.RocketBot.Window.Forms
                         .Where(p => p.PokemonId == pokemon.PokemonId)
                         .Select(p => p.PokemonData)
                         .OrderByDescending(PokemonInfo.CalculatePokemonPerfection)
-                        .OrderByDescending(p => p.Cp)
-                        .Take(ET);
+                        .ThenByDescending(p => p.Cp)
+                        .Take(et);

                 EvolvePokemon(pokemons);
             }
@@ -740,7 +737,8 @@ namespace PokemonGo.RocketBot.Window.Forms
         public async void NicknamePokemon(IEnumerable<PokemonData> pokemons, string nickname)
         {
             SetState(false);
-            foreach (var pokemon in pokemons)
+            var pokemonDatas = pokemons as IList<PokemonData> ?? pokemons.ToList();
+            foreach (var pokemon in pokemonDatas)
             {
                 var newName = new StringBuilder(nickname);
                 newName.Replace("{Name}", Convert.ToString(pokemon.PokemonId));
@@ -753,7 +751,7 @@ namespace PokemonGo.RocketBot.Window.Forms
                 if (nickname.Length > 12)
                 {
                     Logger.Write($"\"{newName}\" is too long, please choose another name");
-                    if (pokemons.Count() == 1)
+                    if (pokemonDatas.Count() == 1)
                     {
                         SetState(true);
                         return;
@@ -788,26 +786,16 @@ namespace PokemonGo.RocketBot.Window.Forms
                 var itemTemplates = await _session.Client.Download.GetItemTemplates();
                 var inventory = await _session.Inventory.GetCachedInventory();
                 var profile = await _session.Client.Player.GetPlayer();
-                var appliedItems = new Dictionary<ItemId, DateTime>();
                 var inventoryAppliedItems =
                     await _session.Inventory.GetAppliedItems();

-                foreach (var aItems in inventoryAppliedItems)
-                {
-                    if (aItems != null && aItems.Item != null)
-                    {
-                        foreach (var item in aItems.Item)
-                        {
-                            appliedItems.Add(item.ItemId, Utils.FromUnixTimeUtc(item.ExpireMs));
-                        }
-                    }
-                }
+                var appliedItems = inventoryAppliedItems.Where(aItems => aItems?.Item != null).SelectMany(aItems => aItems.Item).ToDictionary(item => item.ItemId, item => Utils.FromUnixTimeUtc(item.ExpireMs));

                 PokemonObject.Initilize(itemTemplates);

                 var pokemons =
                     inventory.InventoryDelta.InventoryItems.Select(i => i?.InventoryItemData?.PokemonData)
-                        .Where(p => p != null && p?.PokemonId > 0)
+                        .Where(p => p != null && p.PokemonId > 0)
                         .OrderByDescending(PokemonInfo.CalculatePokemonPerfection)
                         .ThenByDescending(key => key.Cp)
                         .OrderBy(key => key.PokemonId);
@@ -832,13 +820,12 @@ namespace PokemonGo.RocketBot.Window.Forms
                 var pokemoncount =
                     inventory.InventoryDelta.InventoryItems
                         .Select(i => i.InventoryItemData?.PokemonData)
-                        .Count(p => p != null && p?.PokemonId > 0);
+                        .Count(p => p != null && p.PokemonId > 0);
                 var eggcount =
                     inventory.InventoryDelta.InventoryItems
                         .Select(i => i.InventoryItemData?.PokemonData)
-                        .Count(p => p != null && p?.IsEgg == true);
-                lblPokemonList.Text = pokemoncount + eggcount + " / " + profile.PlayerData.MaxPokemonStorage + " (" +
-                                      pokemoncount + " pokemon, " + eggcount + " eggs)";
+                        .Count(p => p != null && p.IsEgg);
+                lblPokemonList.Text = $"{pokemoncount + eggcount} / {profile.PlayerData.MaxPokemonStorage} ({pokemoncount} pokemon, {eggcount} eggs)";

                 var items =
                     inventory.InventoryDelta.InventoryItems
@@ -861,7 +848,7 @@ namespace PokemonGo.RocketBot.Window.Forms
                     flpItems.Controls.Add(box);
                 }

-                lblInventory.Text = itemscount + " / " + profile.PlayerData.MaxItemStorage;
+                lblInventory.Text = itemscount + @" / " + profile.PlayerData.MaxItemStorage;
             }
             catch (ArgumentNullException)
             {
@@ -885,10 +872,11 @@ namespace PokemonGo.RocketBot.Window.Forms
             using (var form = new ItemForm(item))
             {
                 var result = form.ShowDialog();
-                if (result == DialogResult.OK)
+                if (result != DialogResult.OK) return;
+                SetState(false);
+                switch (item.ItemId)
                 {
-                    SetState(false);
-                    if (item.ItemId == ItemId.ItemLuckyEgg)
+                    case ItemId.ItemLuckyEgg:
                     {
                         if (_session.Client == null)
                         {
@@ -897,25 +885,31 @@ namespace PokemonGo.RocketBot.Window.Forms
                             return;
                         }
                         var response = await _session.Client.Inventory.UseItemXpBoost();
-                        if (response.Result == UseItemXpBoostResponse.Types.Result.Success)
-                        {
-                            Logger.Write($"Using a Lucky Egg");
-                            Logger.Write($"Lucky Egg valid until: {DateTime.Now.AddMinutes(30)}");
-                        }
-                        else if (response.Result == UseItemXpBoostResponse.Types.Result.ErrorXpBoostAlreadyActive)
-                        {
-                            Logger.Write($"A Lucky Egg is already active!", LogLevel.Warning);
-                        }
-                        else if (response.Result == UseItemXpBoostResponse.Types.Result.ErrorLocationUnset)
-                        {
-                            Logger.Write($"Bot must be running first!", LogLevel.Error);
-                        }
-                        else
+                        switch (response.Result)
                         {
-                            Logger.Write($"Failed using a Lucky Egg!", LogLevel.Error);
+                            case UseItemXpBoostResponse.Types.Result.Success:
+                                Logger.Write($"Using a Lucky Egg");
+                                Logger.Write($"Lucky Egg valid until: {DateTime.Now.AddMinutes(30)}");
+                                break;
+                            case UseItemXpBoostResponse.Types.Result.ErrorXpBoostAlreadyActive:
+                                Logger.Write($"A Lucky Egg is already active!", LogLevel.Warning);
+                                break;
+                            case UseItemXpBoostResponse.Types.Result.ErrorLocationUnset:
+                                Logger.Write($"Bot must be running first!", LogLevel.Error);
+                                break;
+                            case UseItemXpBoostResponse.Types.Result.Unset:
+                                break;
+                            case UseItemXpBoostResponse.Types.Result.ErrorInvalidItemType:
+                                break;
+                            case UseItemXpBoostResponse.Types.Result.ErrorNoItemsRemaining:
+                                break;
+                            default:
+                                Logger.Write($"Failed using a Lucky Egg!", LogLevel.Error);
+                                break;
                         }
                     }
-                    else if (item.ItemId == ItemId.ItemIncenseOrdinary)
+                        break;
+                    case ItemId.ItemIncenseOrdinary:
                     {
                         if (_session.Client == null)
                         {
@@ -924,24 +918,84 @@ namespace PokemonGo.RocketBot.Window.Forms
                             return;
                         }
                         var response = await _session.Client.Inventory.UseIncense(ItemId.ItemIncenseOrdinary);
-                        if (response.Result == UseIncenseResponse.Types.Result.Success)
+                        switch (response.Result)
                         {
-                            Logger.Write($"Incense valid until: {DateTime.Now.AddMinutes(30)}");
-                        }
-                        else if (response.Result == UseIncenseResponse.Types.Result.IncenseAlreadyActive)
-                        {
-                            Logger.Write($"An incense is already active!", LogLevel.Warning);
-                        }
-                        else if (response.Result == UseIncenseResponse.Types.Result.LocationUnset)
-                        {
-                            Logger.Write($"Bot must be running first!", LogLevel.Error);
-                        }
-                        else
-                        {
-                            Logger.Write($"Failed using an incense!", LogLevel.Error);
+                            case UseIncenseResponse.Types.Result.Success:
+                                Logger.Write($"Incense valid until: {DateTime.Now.AddMinutes(30)}");
+                                break;
+                            case UseIncenseResponse.Types.Result.IncenseAlreadyActive:
+                                Logger.Write($"An incense is already active!", LogLevel.Warning);
+                                break;
+                            case UseIncenseResponse.Types.Result.LocationUnset:
+                                Logger.Write($"Bot must be running first!", LogLevel.Error);
+                                break;
+                            case UseIncenseResponse.Types.Result.Unknown:
+                                break;
+                            case UseIncenseResponse.Types.Result.NoneInInventory:
+                                break;
+                            default:
+                                Logger.Write($"Failed using an incense!", LogLevel.Error);
+                                break;
                         }
                     }
-                    else
+                        break;
+                    case ItemId.ItemUnknown:
+                        break;
+                    case ItemId.ItemPokeBall:
+                        break;
+                    case ItemId.ItemGreatBall:
+                        break;
+                    case ItemId.ItemUltraBall:
+                        break;
+                    case ItemId.ItemMasterBall:
+                        break;
+                    case ItemId.ItemPotion:
+                        break;
+                    case ItemId.ItemSuperPotion:
+                        break;
+                    case ItemId.ItemHyperPotion:
+                        break;
+                    case ItemId.ItemMaxPotion:
+                        break;
+                    case ItemId.ItemRevive:
+                        break;
+                    case ItemId.ItemMaxRevive:
+                        break;
+                    case ItemId.ItemIncenseSpicy:
+                        break;
+                    case ItemId.ItemIncenseCool:
+                        break;
+                    case ItemId.ItemIncenseFloral:
+                        break;
+                    case ItemId.ItemTroyDisk:
+                        break;
+                    case ItemId.ItemXAttack:
+                        break;
+                    case ItemId.ItemXDefense:
+                        break;
+                    case ItemId.ItemXMiracle:
+                        break;
+                    case ItemId.ItemRazzBerry:
+                        break;
+                    case ItemId.ItemBlukBerry:
+                        break;
+                    case ItemId.ItemNanabBerry:
+                        break;
+                    case ItemId.ItemWeparBerry:
+                        break;
+                    case ItemId.ItemPinapBerry:
+                        break;
+                    case ItemId.ItemSpecialCamera:
+                        break;
+                    case ItemId.ItemIncubatorBasicUnlimited:
+                        break;
+                    case ItemId.ItemIncubatorBasic:
+                        break;
+                    case ItemId.ItemPokemonStorageUpgrade:
+                        break;
+                    case ItemId.ItemItemStorageUpgrade:
+                        break;
+                    default:
                     {
                         var response =
                             await
@@ -959,8 +1013,9 @@ namespace PokemonGo.RocketBot.Window.Forms
                                 LogLevel.Error);
                         }
                     }
-                    ReloadPokemonList();
+                        break;
                 }
+                await ReloadPokemonList();
             }
         }

@@ -972,5 +1027,10 @@ namespace PokemonGo.RocketBot.Window.Forms
         }

         #endregion POKEMON LIST
+
+        private void gMapControl1_Load(object sender, EventArgs e)
+        {
+
+        }
     }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Window/Forms/MainForm.designer.cs b/PokemonGo.RocketBot.Window/Forms/MainForm.designer.cs
index e256ed5..39ee085 100644
--- a/PokemonGo.RocketBot.Window/Forms/MainForm.designer.cs
+++ b/PokemonGo.RocketBot.Window/Forms/MainForm.designer.cs
@@ -53,11 +53,11 @@ namespace PokemonGo.RocketBot.Window.Forms
             this.pkmnEvolveTimes = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
             this.pkmnNickname = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
             this.pkmnLevel = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
+            this.pkmnMove1 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
+            this.pkmnMove2 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
             this.pkmnTransferButton = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
             this.pkmnPowerUpButton = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
             this.pkmnEvolveButton = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
-            this.pkmnMove1 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
-            this.pkmnMove2 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
             this.cmsPokemonList = new System.Windows.Forms.ContextMenuStrip(this.components);
             this.largePokemonImageList = new System.Windows.Forms.ImageList(this.components);
             this.smallPokemonImageList = new System.Windows.Forms.ImageList(this.components);
@@ -178,6 +178,7 @@ namespace PokemonGo.RocketBot.Window.Forms
             this.gMapControl1.Size = new System.Drawing.Size(605, 239);
             this.gMapControl1.TabIndex = 23;
             this.gMapControl1.Zoom = 0D;
+            this.gMapControl1.Load += new System.EventHandler(this.gMapControl1_Load);
             //
             // olvPokemonList
             //
@@ -304,6 +305,16 @@ namespace PokemonGo.RocketBot.Window.Forms
             this.pkmnLevel.Text = "Lv";
             this.pkmnLevel.Width = 50;
             //
+            // pkmnMove1
+            //
+            this.pkmnMove1.AspectName = "Move1";
+            this.pkmnMove1.Text = "Move1";
+            //
+            // pkmnMove2
+            //
+            this.pkmnMove2.AspectName = "Move2";
+            this.pkmnMove2.Text = "Move2";
+            //
             // pkmnTransferButton
             //
             this.pkmnTransferButton.AspectName = "Id";
@@ -328,16 +339,6 @@ namespace PokemonGo.RocketBot.Window.Forms
             this.pkmnEvolveButton.IsButton = true;
             this.pkmnEvolveButton.Text = "";
             //
-            // pkmnMove1
-            //
-            this.pkmnMove1.AspectName = "Move1";
-            this.pkmnMove1.Text = "Move1";
-            //
-            // pkmnMove2
-            //
-            this.pkmnMove2.AspectName = "Move2";
-            this.pkmnMove2.Text = "Move2";
-            //
             // cmsPokemonList
             //
             this.cmsPokemonList.Name = "cmsPokemonList";
You may download the files in Public Git.