diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..eae67698a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,2 @@ +language: csharp +solution: "NecroBot-for-Pokemon-Go.sln" \ No newline at end of file diff --git a/FeroxRev b/FeroxRev index 31f14b96c..3ff1579e7 160000 --- a/FeroxRev +++ b/FeroxRev @@ -1 +1 @@ -Subproject commit 31f14b96ce746f7a10e2a39e38743cc1323c229e +Subproject commit 3ff1579e7bdc05b1abea112112495d015a65c586 diff --git a/PoGo.NecroBot.Logic/ILogicSettings.cs b/PoGo.NecroBot.Logic/ILogicSettings.cs index cc4e70fdf..c9bb82738 100644 --- a/PoGo.NecroBot.Logic/ILogicSettings.cs +++ b/PoGo.NecroBot.Logic/ILogicSettings.cs @@ -69,6 +69,7 @@ public interface ILogicSettings bool EvolveAllPokemonWithEnoughCandy { get; } bool KeepPokemonsThatCanEvolve { get; } bool TransferDuplicatePokemon { get; } + bool TransferDuplicatePokemonOnCapture { get; } bool UseEggIncubators { get; } int UseGreatBallAboveCp { get; } int UseUltraBallAboveCp { get; } @@ -92,6 +93,10 @@ public interface ILogicSettings int GetMinStarDustForLevelUp { get; } bool UseLuckyEggConstantly { get; } bool UseIncenseConstantly { get; } + int UseBerriesMinCp { get; } + float UseBerriesMinIv { get; } + double UseBerriesBelowCatchProbability { get; } + string UseBerriesOperator { get; } int MaxTravelDistanceInMeters { get; } bool UseGpxPathing { get; } string GpxFile { get; } diff --git a/PoGo.NecroBot.Logic/Settings.cs b/PoGo.NecroBot.Logic/Settings.cs index 53dc949bf..24c669d52 100644 --- a/PoGo.NecroBot.Logic/Settings.cs +++ b/PoGo.NecroBot.Logic/Settings.cs @@ -149,12 +149,16 @@ public class GlobalSettings public int KeepMinDuplicatePokemon = 1; public float KeepMinIvPercentage = 90; public bool PrioritizeIvOverCp = false; - //luckyandincense + //lucky, incense and berries public bool UseEggIncubators = true; public bool UseLuckyEggConstantly = false; public int UseLuckyEggsMinPokemonAmount = 30; public bool UseLuckyEggsWhileEvolving = false; public bool UseIncenseConstantly = false; + public int UseBerriesMinCp = 1000; + public float UseBerriesMinIv = 90; + public double UseBerriesBelowCatchProbability = 0.20; + public string UseBerriesOperator = "and"; //snipe public bool UseSnipeOnlineLocationServer = true; public bool UseSnipeLocationServer = false; @@ -188,6 +192,7 @@ public class GlobalSettings public double UseMasterBallBelowCatchProbability = 0.05; //transfer public bool TransferDuplicatePokemon = true; + public bool TransferDuplicatePokemonOnCapture = true; //favorite public float FavoriteMinIvPercentage = 95; public bool AutoFavoritePokemon = false; @@ -527,7 +532,37 @@ public static GlobalSettings Load(string path) { settings.EvolveKeptPokemonsAtStorageUsagePercentage = Default.EvolveKeptPokemonsAtStorageUsagePercentage; } - + + if (settings.UseGreatBallBelowCatchProbability < 0) + { + settings.UseGreatBallBelowCatchProbability = Default.UseGreatBallBelowCatchProbability; + } + + if (settings.UseUltraBallBelowCatchProbability < 0) + { + settings.UseUltraBallBelowCatchProbability = Default.UseUltraBallBelowCatchProbability; + } + + if (settings.UseMasterBallBelowCatchProbability < 0) + { + settings.UseMasterBallBelowCatchProbability = Default.UseMasterBallBelowCatchProbability; + } + + if (settings.UseBerriesMinCp < 0) + { + settings.UseBerriesMinCp = Default.UseBerriesMinCp; + } + + if (settings.UseBerriesMinIv < 0) + { + settings.UseBerriesMinIv = Default.UseBerriesMinIv; + } + + if (settings.UseBerriesOperator.ToLower().Equals("and") && settings.UseBerriesOperator.ToLower().Equals("or")) + { + settings.UseBerriesOperator = Default.UseBerriesOperator; + } + settings.ProfilePath = profilePath; settings.ProfileConfigPath = profileConfigPath; settings.GeneralConfigPath = Path.Combine(Directory.GetCurrentDirectory(), "config"); @@ -668,14 +703,19 @@ public LogicSettings(GlobalSettings settings) public string LevelUpByCPorIv => _settings.LevelUpByCPorIv; public int GetMinStarDustForLevelUp => _settings.GetMinStarDustForLevelUp; public bool UseLuckyEggConstantly => _settings.UseLuckyEggConstantly; - public bool UseIncenseConstantly => _settings.UseIncenseConstantly; + public int UseBerriesMinCp => _settings.UseBerriesMinCp; + public float UseBerriesMinIv => _settings.UseBerriesMinIv; + public double UseBerriesBelowCatchProbability => _settings.UseBerriesBelowCatchProbability; + public string UseBerriesOperator => _settings.UseBerriesOperator; + public float UpgradePokemonIvMinimum => _settings.UpgradePokemonIvMinimum; public float UpgradePokemonCpMinimum => _settings.UpgradePokemonCpMinimum; public double WalkingSpeedInKilometerPerHour => _settings.WalkingSpeedInKilometerPerHour; public bool EvolveAllPokemonWithEnoughCandy => _settings.EvolveAllPokemonWithEnoughCandy; - public bool KeepPokemonsThatCanEvolve => _settings.KeepPokemonsThatCanEvolve; + public bool KeepPokemonsThatCanEvolve => _settings.KeepPokemonsThatCanEvolve; public bool TransferDuplicatePokemon => _settings.TransferDuplicatePokemon; + public bool TransferDuplicatePokemonOnCapture => _settings.TransferDuplicatePokemonOnCapture; public bool UseEggIncubators => _settings.UseEggIncubators; public int UseGreatBallAboveCp => _settings.UseGreatBallAboveCp; public int UseUltraBallAboveCp => _settings.UseUltraBallAboveCp; diff --git a/PoGo.NecroBot.Logic/Tasks/CatchIncensePokemonsTask.cs b/PoGo.NecroBot.Logic/Tasks/CatchIncensePokemonsTask.cs index 4e5ce3c53..f1596f83e 100644 --- a/PoGo.NecroBot.Logic/Tasks/CatchIncensePokemonsTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/CatchIncensePokemonsTask.cs @@ -54,7 +54,7 @@ public static async Task Execute(ISession session, CancellationToken cancellatio if (encounter.Result == IncenseEncounterResponse.Types.Result.IncenseEncounterSuccess) { - await CatchPokemonTask.Execute(session, encounter, pokemon); + await CatchPokemonTask.Execute(session, cancellationToken, encounter, pokemon); } else if (encounter.Result == IncenseEncounterResponse.Types.Result.PokemonInventoryFull) { diff --git a/PoGo.NecroBot.Logic/Tasks/CatchLurePokemonsTask.cs b/PoGo.NecroBot.Logic/Tasks/CatchLurePokemonsTask.cs index 26a6d2cbe..8a2b01d2f 100644 --- a/PoGo.NecroBot.Logic/Tasks/CatchLurePokemonsTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/CatchLurePokemonsTask.cs @@ -40,7 +40,7 @@ public static async Task Execute(ISession session, FortData currentFortData, Can if (encounter.Result == DiskEncounterResponse.Types.Result.Success) { - await CatchPokemonTask.Execute(session, encounter, null, currentFortData, encounterId); + await CatchPokemonTask.Execute(session, cancellationToken, encounter, null, currentFortData, encounterId); } else if (encounter.Result == DiskEncounterResponse.Types.Result.PokemonInventoryFull) { diff --git a/PoGo.NecroBot.Logic/Tasks/CatchNearbyPokemonsTask.cs b/PoGo.NecroBot.Logic/Tasks/CatchNearbyPokemonsTask.cs index bf30b4c75..db97753f0 100644 --- a/PoGo.NecroBot.Logic/Tasks/CatchNearbyPokemonsTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/CatchNearbyPokemonsTask.cs @@ -56,7 +56,7 @@ public static async Task Execute(ISession session, CancellationToken cancellatio if (encounter.Status == EncounterResponse.Types.Status.EncounterSuccess) { - await CatchPokemonTask.Execute(session, encounter, pokemon); + await CatchPokemonTask.Execute(session, cancellationToken, encounter, pokemon); } else if (encounter.Status == EncounterResponse.Types.Status.PokemonInventoryFull) { diff --git a/PoGo.NecroBot.Logic/Tasks/CatchPokemonTask.cs b/PoGo.NecroBot.Logic/Tasks/CatchPokemonTask.cs index a1965f94e..8f30db5f7 100644 --- a/PoGo.NecroBot.Logic/Tasks/CatchPokemonTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/CatchPokemonTask.cs @@ -12,6 +12,7 @@ using POGOProtos.Map.Fort; using POGOProtos.Map.Pokemon; using POGOProtos.Networking.Responses; +using System.Threading; #endregion @@ -19,20 +20,67 @@ namespace PoGo.NecroBot.Logic.Tasks { public static class CatchPokemonTask { - public static async Task Execute(ISession session, dynamic encounter, MapPokemon pokemon, + public static async Task Execute(ISession session, CancellationToken cancellationToken, dynamic encounter, MapPokemon pokemon, FortData currentFortData = null, ulong encounterId = 0) { + cancellationToken.ThrowIfCancellationRequested(); + + // If the encounter is null nothing will work below, so exit now + if (encounter == null) return; + + float probability = encounter?.CaptureProbability?.CaptureProbability_[0]; + + // Check for pokeballs before proceeding + var pokeball = await GetBestBall(session, encounter, probability); + if (pokeball == ItemId.ItemUnknown) return; + + //Calculate CP and IV + var pokemonCp = (encounter is EncounterResponse + ? encounter.WildPokemon?.PokemonData?.Cp + : encounter.PokemonData?.Cp); + var pokemonIv = PokemonInfo.CalculatePokemonPerfection(encounter is EncounterResponse + ? encounter.WildPokemon?.PokemonData + : encounter?.PokemonData); + + // Determine whether to use berries or not + if ((session.LogicSettings.UseBerriesOperator.ToLower().Equals("and") && + pokemonIv >= session.LogicSettings.UseBerriesMinIv && + pokemonCp >= session.LogicSettings.UseBerriesMinCp && + probability < session.LogicSettings.UseBerriesBelowCatchProbability) || + (session.LogicSettings.UseBerriesOperator.ToLower().Equals("or") && ( + pokemonIv >= session.LogicSettings.UseBerriesMinIv || + pokemonCp >= session.LogicSettings.UseBerriesMinCp || + probability < session.LogicSettings.UseBerriesBelowCatchProbability))) + { + await + UseBerry(session, + encounter is EncounterResponse || encounter is IncenseEncounterResponse + ? pokemon.EncounterId + : encounterId, + encounter is EncounterResponse || encounter is IncenseEncounterResponse + ? pokemon.SpawnPointId + : currentFortData?.Id); + } + + // Calculate distance away + var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, + session.Client.CurrentLongitude, + encounter is EncounterResponse || encounter is IncenseEncounterResponse + ? pokemon.Latitude + : currentFortData.Latitude, + encounter is EncounterResponse || encounter is IncenseEncounterResponse + ? pokemon.Longitude + : currentFortData.Longitude); + CatchPokemonResponse caughtPokemonResponse; var attemptCounter = 1; do { - if (session.LogicSettings.MaxPokeballsPerPokemon > 0 && - attemptCounter > session.LogicSettings.MaxPokeballsPerPokemon) + if ((session.LogicSettings.MaxPokeballsPerPokemon > 0 && + attemptCounter > session.LogicSettings.MaxPokeballsPerPokemon)) break; - float probability = encounter?.CaptureProbability?.CaptureProbability_[0]; - - var pokeball = await GetBestBall(session, encounter, probability); + pokeball = await GetBestBall(session, encounter, probability); if (pokeball == ItemId.ItemUnknown) { session.EventDispatcher.Send(new NoPokeballEvent @@ -46,37 +94,6 @@ public static async Task Execute(ISession session, dynamic encounter, MapPokemon return; } - var isLowProbability = probability < 0.35; - var isHighCp = encounter != null && - (encounter is EncounterResponse - ? encounter.WildPokemon?.PokemonData?.Cp - : encounter.PokemonData?.Cp) > 400; - var isHighPerfection = - PokemonInfo.CalculatePokemonPerfection(encounter is EncounterResponse - ? encounter.WildPokemon?.PokemonData - : encounter?.PokemonData) >= session.LogicSettings.KeepMinIvPercentage; - - if ((isLowProbability && isHighCp) || isHighPerfection) - { - await - UseBerry(session, - encounter is EncounterResponse || encounter is IncenseEncounterResponse - ? pokemon.EncounterId - : encounterId, - encounter is EncounterResponse || encounter is IncenseEncounterResponse - ? pokemon.SpawnPointId - : currentFortData?.Id); - } - - var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, - session.Client.CurrentLongitude, - encounter is EncounterResponse || encounter is IncenseEncounterResponse - ? pokemon.Latitude - : currentFortData.Latitude, - encounter is EncounterResponse || encounter is IncenseEncounterResponse - ? pokemon.Longitude - : currentFortData.Longitude); - caughtPokemonResponse = await session.Client.Encounter.CatchPokemon( encounter is EncounterResponse || encounter is IncenseEncounterResponse @@ -97,7 +114,6 @@ encounter is EncounterResponse || encounter is IncenseEncounterResponse Longitude = lng }; - if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess) { var totalExp = 0; @@ -128,8 +144,10 @@ encounter is EncounterResponse || encounter is IncenseEncounterResponse { evt.FamilyCandies = caughtPokemonResponse.CaptureAward.Candy.Sum(); } - } + if (session.LogicSettings.TransferDuplicatePokemonOnCapture && session.LogicSettings.TransferDuplicatePokemon) + await TransferDuplicatePokemonTask.Execute(session, cancellationToken); + } evt.CatchType = encounter is EncounterResponse ? session.Translation.GetTranslation(TranslationString.CatchTypeNormal) diff --git a/PoGo.NecroBot.Logic/Tasks/SnipePokemonTask.cs b/PoGo.NecroBot.Logic/Tasks/SnipePokemonTask.cs index 2c45f1421..4587c83ef 100644 --- a/PoGo.NecroBot.Logic/Tasks/SnipePokemonTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/SnipePokemonTask.cs @@ -278,7 +278,7 @@ await session.Client.Player.UpdatePlayerLocation(CurrentLatitude, CurrentLongitu Longitude = CurrentLongitude }); - await CatchPokemonTask.Execute(session, encounter, pokemon); + await CatchPokemonTask.Execute(session, cancellationToken, encounter, pokemon); } else if (encounter.Status == EncounterResponse.Types.Status.PokemonInventoryFull) { diff --git a/PoGo.NecroBot.Logic/Tasks/TransferDuplicatePokemonTask.cs b/PoGo.NecroBot.Logic/Tasks/TransferDuplicatePokemonTask.cs index 413be6550..c8b66aff9 100644 --- a/PoGo.NecroBot.Logic/Tasks/TransferDuplicatePokemonTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/TransferDuplicatePokemonTask.cs @@ -7,6 +7,8 @@ using PoGo.NecroBot.Logic.PoGoUtils; using PoGo.NecroBot.Logic.State; using PoGo.NecroBot.Logic.Utils; +using PoGo.NecroBot.Logic.Logging; +using PoGo.NecroBot.Logic.Common; #endregion