Пример #1
0
        protected override async Task EncounterLoop(SAV8SWSH sav, CancellationToken token)
        {
            var monoffset  = GetResetOffset(Hub.Config.Encounter.EncounteringType);
            var pkoriginal = monoffset is BoxStartOffset ? await ReadBoxPokemon(0, 0, token).ConfigureAwait(false) : new PK8();

            while (!token.IsCancellationRequested)
            {
                PK8?pknew;

                Log("Looking for a Pokémon...");
                do
                {
                    await DoExtraCommands(token, Hub.Config.Encounter.EncounteringType).ConfigureAwait(false);

                    pknew = await ReadUntilPresent(monoffset, 0_050, 0_050, BoxFormatSlotSize, token).ConfigureAwait(false);
                } while (pknew is null || SearchUtil.HashByDetails(pkoriginal) == SearchUtil.HashByDetails(pknew));

                TradeExtensions <PK8> .EncounterLogs(pknew, "EncounterLogPretty_Reset.txt");

                if (await HandleEncounter(pknew, token).ConfigureAwait(false))
                {
                    return;
                }

                Log("No match, resetting the game...");
                await CloseGame(Hub.Config, token).ConfigureAwait(false);
                await StartGame(Hub.Config, token).ConfigureAwait(false);
            }
        }
Пример #2
0
        protected override async Task EncounterLoop(SAV8SWSH sav, CancellationToken token)
        {
            bool campEntered = false;

            while (!token.IsCancellationRequested)
            {
                await Click(X, 2_000, token).ConfigureAwait(false);

                if (!campEntered)
                {
                    await Click(DDOWN, 0_600, token).ConfigureAwait(false);
                    await Click(DRIGHT, 0_600, token).ConfigureAwait(false);

                    campEntered = true;
                }

                Log("Entering camp...");
                await Click(A, 12_000, token).ConfigureAwait(false);
                await Click(B, 2_000, token).ConfigureAwait(false);
                await Click(A, 0_500, token).ConfigureAwait(false);

                while (!await IsInBattle(token).ConfigureAwait(false))
                {
                    await Task.Delay(2_000).ConfigureAwait(false);
                }

                var pk = await ReadUntilPresent(WildPokemonOffset, 2_000, 0_200, BoxFormatSlotSize, token).ConfigureAwait(false);

                if (pk == null)
                {
                    Log("Invalid data detected. Restarting loop.");
                    continue;
                }
                else
                {
                    TradeExtensions <PK8> .EncounterLogs(pk, "EncounterLogPretty_SoJ.txt");

                    if (await HandleEncounter(pk, token).ConfigureAwait(false))
                    {
                        return;
                    }
                }

                Log("Fleeing from battle...");
                while (await IsInBattle(token).ConfigureAwait(false))
                {
                    await FleeToOverworld(token).ConfigureAwait(false);
                }

                while (!await IsOnOverworld(Hub.Config, token).ConfigureAwait(false))
                {
                    await Task.Delay(2_000).ConfigureAwait(false);
                }
            }
        }
Пример #3
0
        protected override async Task EncounterLoop(SAV8SWSH sav, CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                Log("Looking for a new dog...");

                // At the start of each loop, an A press is needed to exit out of a prompt.
                await Click(A, 0_100, token).ConfigureAwait(false);
                await SetStick(LEFT, 0, 30000, 1_000, token).ConfigureAwait(false);

                // Encounters Zacian/Zamazenta and clicks through all the menus.
                while (!await IsInBattle(token).ConfigureAwait(false))
                {
                    await Click(A, 0_300, token).ConfigureAwait(false);
                }

                Log("Encounter started! Checking details...");
                var pk = await ReadUntilPresent(LegendaryPokemonOffset, 2_000, 0_200, BoxFormatSlotSize, token).ConfigureAwait(false);

                if (pk == null)
                {
                    Log("Invalid data detected. Restarting loop.");
                    continue;
                }

                // Get rid of any stick stuff left over so we can flee properly.
                await ResetStick(token).ConfigureAwait(false);

                // Wait for the entire cutscene.
                await Task.Delay(15_000, token).ConfigureAwait(false);

                // Offsets are flickery so make sure we see it 3 times.
                for (int i = 0; i < 3; i++)
                {
                    await ReadUntilChanged(BattleMenuOffset, BattleMenuReady, 5_000, 0_100, true, token).ConfigureAwait(false);
                }

                TradeExtensions <PK8> .EncounterLogs(pk, "EncounterLogPretty_EncounterDog.txt");

                if (await HandleEncounter(pk, token).ConfigureAwait(false))
                {
                    return;
                }

                Log("Running away...");
                await FleeToOverworld(token).ConfigureAwait(false);

                // Extra delay to be sure we're fully out of the battle.
                await Task.Delay(0_250, token).ConfigureAwait(false);
            }
        }
Пример #4
0
        protected override async Task EncounterLoop(SAV8SWSH sav, CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                var attempts = await StepUntilEncounter(token).ConfigureAwait(false);

                if (attempts < 0) // aborted
                {
                    continue;
                }

                Log($"Encounter found after {attempts} attempts! Checking details...");

                // Reset stick while we wait for the encounter to load.
                await ResetStick(token).ConfigureAwait(false);

                var pk = await ReadUntilPresent(WildPokemonOffset, 2_000, 0_200, BoxFormatSlotSize, token).ConfigureAwait(false);

                if (pk == null)
                {
                    Log("Invalid data detected. Restarting loop.");

                    // Flee and continue looping.
                    await FleeToOverworld(token).ConfigureAwait(false);

                    continue;
                }

                // Offsets are flickery so make sure we see it 3 times.
                for (int i = 0; i < 3; i++)
                {
                    await ReadUntilChanged(BattleMenuOffset, BattleMenuReady, 5_000, 0_100, true, token).ConfigureAwait(false);
                }

                TradeExtensions <PK8> .EncounterLogs(pk, "EncounterLogPretty_EncounterLine.txt");

                if (await HandleEncounter(pk, token).ConfigureAwait(false))
                {
                    return;
                }

                Log("Running away...");
                await FleeToOverworld(token).ConfigureAwait(false);
            }
        }
Пример #5
0
        private async Task <bool> HandleEncounter(PK8 pk, bool legends, CancellationToken token)
        {
            encounterCount++;
            Log($"Encounter: {encounterCount}{Environment.NewLine}{ShowdownParsing.GetShowdownText(pk)}{Environment.NewLine}{(StopConditionSettings.HasMark(pk, out RibbonIndex mark) ? $"Mark: {mark.ToString().Replace("Mark", "")}{Environment.NewLine}" : "")}");
            TradeExtensions.EncounterLogs(pk);
            if (legends)
            {
                Counts.AddCompletedLegends();
            }
            else
            {
                Counts.AddCompletedEncounters();
            }

            if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder))
            {
                DumpPokemon(DumpSetting.DumpFolder, legends ? "legends" : "encounters", pk);
            }

            if (StopConditionSettings.EncounterFound(pk, DesiredIVs, Hub.Config.StopConditions))
            {
                Log(Hub.Config.StopConditions.CatchEncounter && (Hub.Config.Encounter.EncounteringType == EncounterMode.VerticalLine || Hub.Config.Encounter.EncounteringType == EncounterMode.HorizontalLine) ?
                    "Result found! Attempting to catch..." : $"{(!Hub.Config.StopConditions.PingOnMatch.Equals(string.Empty) ? $"<@{Hub.Config.StopConditions.PingOnMatch}>\n" : "")}Result found! Stopping routine execution; restart the bot(s) to search again.");
                if (Hub.Config.StopConditions.CaptureVideoClip)
                {
                    await Task.Delay(Hub.Config.StopConditions.ExtraTimeWaitCaptureVideo, token).ConfigureAwait(false);
                    await PressAndHold(CAPTURE, 2_000, 1_000, token).ConfigureAwait(false);
                }

                if (Hub.Config.StopConditions.CatchEncounter && (Hub.Config.Encounter.EncounteringType == EncounterMode.VerticalLine || Hub.Config.Encounter.EncounteringType == EncounterMode.HorizontalLine))
                {
                    await CatchWildPokemon(pk, token).ConfigureAwait(false);
                }

                return(true);
            }

            return(false);
        }
Пример #6
0
        private Tuple <ulong, ulong> PerformSeedSearch()
        {
            Log("Searching for a matching seed... Search may take a while.");
            SeedSearchUtil.SpecificSeedSearch(RaidInfo, out long frames, out ulong seed, out ulong threeDay, out string ivSpread);
            if (ivSpread == string.Empty)
            {
                Log($"No results found within the specified search range.");
                return(new Tuple <ulong, ulong>(0, 0));
            }

            var species  = RaidInfo.Den.IsEvent ? RaidInfo.RaidDistributionEncounter.Species : RaidInfo.RaidEncounter.Species;
            var specName = SpeciesName.GetSpeciesNameGeneration((int)species, 2, 8);
            var form     = TradeExtensions.FormOutput((int)(RaidInfo.Den.IsEvent ? RaidInfo.RaidDistributionEncounter.Species : RaidInfo.RaidEncounter.Species), (int)(RaidInfo.Den.IsEvent ? RaidInfo.RaidDistributionEncounter.AltForm : RaidInfo.RaidEncounter.AltForm), out _);
            var results  = $"\n\nDesired species: {(uint)RaidInfo.Den.Stars + 1}★ - {specName}{form}\n" +
                           $"\n{ivSpread}\n" +
                           $"\nStarting seed: {RaidInfo.Den.Seed:X16}\n" +
                           $"Target frame seed: {seed:X16}\n" +
                           $"Three day roll: {threeDay:X16}\n" +
                           $"Skips to target frame: {frames:N0}\n";

            EchoUtil.Echo(results);
            return(new Tuple <ulong, ulong>(seed, threeDay));
        }
Пример #7
0
        private async Task <PokeTradeResult> PerformLinkCodeTrade(SAV8SWSH sav, PokeTradeDetail <PK8> poke, CancellationToken token)
        {
            // Update Barrier Settings
            UpdateBarrier(poke.IsSynchronized);
            poke.TradeInitialize(this);
            Hub.Config.Stream.EndEnterCode(this);

            if (await CheckIfSoftBanned(token).ConfigureAwait(false))
            {
                await Unban(token).ConfigureAwait(false);
            }

            var pkm = poke.TradeData;

            if (pkm.Species != 0)
            {
                await SetBoxPokemon(pkm, InjectBox, InjectSlot, token, sav).ConfigureAwait(false);
            }

            if (!await IsOnOverworld(Hub.Config, token).ConfigureAwait(false))
            {
                await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                return(PokeTradeResult.RecoverStart);
            }

            while (await CheckIfSearchingForLinkTradePartner(token).ConfigureAwait(false))
            {
                Log("Still searching, reset bot position.");
                await ResetTradePosition(Hub.Config, token).ConfigureAwait(false);
            }

            Log("Opening Y-Comm Menu");
            await Click(Y, 2_000, token).ConfigureAwait(false);

            Log("Selecting Link Trade");
            await Click(A, 1_500, token).ConfigureAwait(false);

            Log("Selecting Link Trade Code");
            await Click(DDOWN, 500, token).ConfigureAwait(false);

            for (int i = 0; i < 2; i++)
            {
                await Click(A, 1_500, token).ConfigureAwait(false);
            }

            // All other languages require an extra A press at this menu.
            if (GameLang != LanguageID.English && GameLang != LanguageID.Spanish)
            {
                await Click(A, 1_500, token).ConfigureAwait(false);
            }

            // Loading Screen
            await Task.Delay(1_000, token).ConfigureAwait(false);

            if (poke.Type != PokeTradeType.Random)
            {
                Hub.Config.Stream.StartEnterCode(this);
            }
            await Task.Delay(1_000, token).ConfigureAwait(false);

            var code = poke.Code;

            Log($"Entering Link Trade Code: {code:0000 0000}...");
            await EnterTradeCode(code, Hub.Config, token).ConfigureAwait(false);

            // Wait for Barrier to trigger all bots simultaneously.
            WaitAtBarrierIfApplicable(token);
            await Click(PLUS, 1_000, token).ConfigureAwait(false);

            Hub.Config.Stream.EndEnterCode(this);

            // Confirming and return to overworld.
            var delay_count = 0;

            while (!await IsOnOverworld(Hub.Config, token).ConfigureAwait(false))
            {
                if (delay_count >= 5)
                {
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.RecoverPostLinkCode);
                }

                for (int i = 0; i < 5; i++)
                {
                    await Click(A, 0_800, token).ConfigureAwait(false);
                }
                delay_count++;
            }

            poke.TradeSearching(this);
            await Task.Delay(0_500, token).ConfigureAwait(false);

            // Wait for a Trainer...
            Log("Waiting for trainer...");
            bool partnerFound = await WaitForPokemonChanged(LinkTradePartnerPokemonOffset, Hub.Config.Trade.TradeWaitTime * 1_000, 0_200, token).ConfigureAwait(false);

            if (token.IsCancellationRequested)
            {
                return(PokeTradeResult.Aborted);
            }
            if (!partnerFound)
            {
                await ResetTradePosition(Hub.Config, token).ConfigureAwait(false);

                return(PokeTradeResult.NoTrainerFound);
            }

            // Select Pokemon
            // pkm already injected to b1s1
            await Task.Delay(5_500, token).ConfigureAwait(false); // necessary delay to get to the box properly

            var TrainerName = await GetTradePartnerName(TradeMethod.LinkTrade, token).ConfigureAwait(false);

            Log($"Found Trading Partner: {TrainerName}...");

            if (!await IsInBox(token).ConfigureAwait(false))
            {
                await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                return(PokeTradeResult.RecoverOpenBox);
            }

            // Confirm Box 1 Slot 1
            if (poke.Type == PokeTradeType.Specific || poke.Type == PokeTradeType.TradeCord || poke.Type == PokeTradeType.Giveaway)
            {
                for (int i = 0; i < 5; i++)
                {
                    await Click(A, 0_500, token).ConfigureAwait(false);
                }
            }

            poke.SendNotification(this, $"Found Trading Partner: {TrainerName}. Waiting for a Pokémon...");

            if (poke.Type == PokeTradeType.Dump)
            {
                return(await ProcessDumpTradeAsync(poke, token).ConfigureAwait(false));
            }

            // Wait for User Input...
            var pk = await ReadUntilPresent(LinkTradePartnerPokemonOffset, 25_000, 1_000, token).ConfigureAwait(false);

            var oldEC = await Connection.ReadBytesAsync(LinkTradePartnerPokemonOffset, 4, token).ConfigureAwait(false);

            if (pk == null)
            {
                await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                return(PokeTradeResult.TrainerTooSlow);
            }

            if (poke.Type == PokeTradeType.Seed)
            {
                // Immediately exit, we aren't trading anything.
                return(await EndSeedCheckTradeAsync(poke, pk, token).ConfigureAwait(false));
            }

            if (poke.Type == PokeTradeType.Random) // distribution
            {
                // Allow the trade partner to do a Ledy swap.
                var trade = Hub.Ledy.GetLedyTrade(pk, Hub.Config.Distribution.LedySpecies);
                if (trade != null)
                {
                    pkm            = trade.Receive;
                    poke.TradeData = pkm;

                    poke.SendNotification(this, "Injecting the requested Pokémon.");
                    await Click(A, 0_800, token).ConfigureAwait(false);
                    await SetBoxPokemon(pkm, InjectBox, InjectSlot, token, sav).ConfigureAwait(false);

                    await Task.Delay(2_500, token).ConfigureAwait(false);
                }

                for (int i = 0; i < 5; i++)
                {
                    await Click(A, 0_500, token).ConfigureAwait(false);
                }
            }
            else if (poke.Type == PokeTradeType.FixOT)
            {
                var clone = (PK8)pk.Clone();
                var adOT  = System.Text.RegularExpressions.Regex.Match(clone.OT_Name, @"(YT$)|(YT\w*$)|(Lab$)|(\.\w*)|(TV$)|(PKHeX)|(FB:)|(SysBot)|(AuSLove)|(ShinyMart)|(Blainette)").Value != "" ||
                            System.Text.RegularExpressions.Regex.Match(clone.Nickname, @"(YT$)|(YT\w*$)|(Lab$)|(\.\w*)|(TV$)|(PKHeX)|(FB:)|(SysBot)|(AuSLove)|(ShinyMart)|(Blainette)").Value != "";

                var extraInfo = $"\nBall: {(Ball)clone.Ball}\nShiny: {(clone.ShinyXor == 0 ? "Square" : clone.ShinyXor <= 16 ? "Star" : "No")}{(clone.FatefulEncounter ? "" : $"\nOT: {TrainerName}")}";
                var laInit    = new LegalityAnalysis(clone);
                if (laInit.Valid && adOT)
                {
                    clone.OT_Name       = clone.FatefulEncounter ? clone.OT_Name : $"{TrainerName}";
                    clone.PKRS_Infected = false;
                    clone.PKRS_Cured    = false;
                    clone.PKRS_Days     = 0;
                    clone.PKRS_Strain   = 0;
                }
                else if (!laInit.Valid)
                {
                    Log($"FixOT request has detected an invalid Pokémon from {poke.Trainer.TrainerName}: {(Species)clone.Species}");
                    if (DumpSetting.Dump)
                    {
                        DumpPokemon(DumpSetting.DumpFolder, "hacked", clone);
                    }

                    poke.SendNotification(this, $"```fix\nShown Pokémon is invalid. Attempting to regenerate... \n{laInit.Report()}```");
                    if (clone.FatefulEncounter)
                    {
                        clone.SetDefaultNickname(laInit);
                        var mg = EncounterEvent.GetAllEvents().Where(x => x.Species == clone.Species && x.Form == clone.AltForm && x.IsShiny == clone.IsShiny && x.OT_Name == clone.OT_Name).ToList();
                        if (mg.Count > 0)
                        {
                            clone = TradeExtensions.CherishHandler(mg.First());
                        }
                        else
                        {
                            clone = (PK8)AutoLegalityWrapper.GetTrainerInfo(8).GetLegal(AutoLegalityWrapper.GetTemplate(new ShowdownSet(ShowdownSet.GetShowdownText(clone) + extraInfo)), out _);
                        }
                    }
                    else
                    {
                        clone = (PK8)AutoLegalityWrapper.GetTrainerInfo(8).GetLegal(AutoLegalityWrapper.GetTemplate(new ShowdownSet(ShowdownSet.GetShowdownText(clone) + extraInfo)), out _);
                    }
                    var laRegen = new LegalityAnalysis(clone);
                    if (laRegen.Valid)
                    {
                        poke.SendNotification(this, $"```fix\nRegenerated and legalized your {(Species)clone.Species}!```");
                    }
                }
                else if (!adOT && laInit.Valid)
                {
                    poke.SendNotification(this, "```fix\nNo ad detected in Nickname or OT, and the Pokémon is legal. Exiting trade.```");
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.Aborted);
                }

                clone = (PK8)TradeExtensions.TrashBytes(clone, new LegalityAnalysis(clone));
                var la = new LegalityAnalysis(clone);
                if (!la.Valid)
                {
                    var report = la.Report();
                    Log(report);
                    poke.SendNotification(this, "This Pokémon is not legal per PKHeX's legality checks. I was unable to fix this. Exiting trade.");
                    poke.SendNotification(this, report);
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.IllegalTrade);
                }

                if (Hub.Config.Legality.ResetHOMETracker)
                {
                    clone.Tracker = 0;
                }

                poke.SendNotification(this, $"```fix\nNow confirm the trade!```");
                Log($"{(!laInit.Valid ? "Legalized" : "Fixed Nickname/OT for")} {(Species)clone.Species}!");

                bool changed = await ReadUntilChanged(LinkTradePartnerPokemonOffset, oldEC, 10_000, 0_200, false, token).ConfigureAwait(false);

                if (changed)
                {
                    Log($"{poke.Trainer.TrainerName} changed the shown Pokémon ({(Species)clone.Species})");
                    poke.SendNotification(this, $"```fix\nSend away the originally shown Pokémon, please.```");
                    changed = !await ReadUntilChanged(LinkTradePartnerPokemonOffset, oldEC, 15_000, 0_200, true, token).ConfigureAwait(false);
                }

                var pk2 = await ReadUntilPresent(LinkTradePartnerPokemonOffset, 3_000, 1_000, token).ConfigureAwait(false);

                if (changed || pk2 == null || SearchUtil.HashByDetails(pk2) != SearchUtil.HashByDetails(pk))
                {
                    Log("Trading partner did not wish to send away their ad-mon.");
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.TrainerTooSlow);
                }

                await Click(A, 0_800, token).ConfigureAwait(false);
                await SetBoxPokemon(clone, InjectBox, InjectSlot, token, sav).ConfigureAwait(false);

                pkm = clone;

                for (int i = 0; i < 5; i++)
                {
                    await Click(A, 0_500, token).ConfigureAwait(false);
                }
            }
            else if (poke.Type == PokeTradeType.Clone)
            {
                // Inject the shown Pokémon.
                var clone = (PK8)pk.Clone();

                if (Hub.Config.Discord.ReturnPK8s)
                {
                    poke.SendNotification(this, clone, "Here's what you showed me!");
                }

                var la = new LegalityAnalysis(clone);
                if (!la.Valid)
                {
                    Log($"Clone request (from {poke.Trainer.TrainerName}) has detected an invalid Pokémon: {(Species)clone.Species}.");
                    if (DumpSetting.Dump)
                    {
                        DumpPokemon(DumpSetting.DumpFolder, "hacked", clone);
                    }

                    var report = la.Report();
                    Log(report);
                    poke.SendNotification(this, "This Pokémon is not legal per PKHeX's legality checks. I am forbidden from cloning this. Exiting trade.");
                    poke.SendNotification(this, report);

                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.IllegalTrade);
                }

                if (Hub.Config.Legality.ResetHOMETracker)
                {
                    clone.Tracker = 0;
                }

                poke.SendNotification(this, $"**Cloned your {(Species)clone.Species}!**\nNow press B to cancel your offer and trade me a Pokémon you don't want.");
                Log($"Cloned a {(Species)clone.Species}. Waiting for user to change their Pokémon...");

                // Separate this out from WaitForPokemonChanged since we compare to old EC from original read.
                partnerFound = await ReadUntilChanged(LinkTradePartnerPokemonOffset, oldEC, 15_000, 0_200, false, token).ConfigureAwait(false);

                if (!partnerFound)
                {
                    poke.SendNotification(this, "**HEY CHANGE IT NOW OR I AM LEAVING!!!**");
                    // They get one more chance.
                    partnerFound = await ReadUntilChanged(LinkTradePartnerPokemonOffset, oldEC, 15_000, 0_200, false, token).ConfigureAwait(false);
                }

                var pk2 = await ReadUntilPresent(LinkTradePartnerPokemonOffset, 3_000, 1_000, token).ConfigureAwait(false);

                if (!partnerFound || pk2 == null || SearchUtil.HashByDetails(pk2) == SearchUtil.HashByDetails(pk))
                {
                    Log("Trading partner did not change their Pokémon.");
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.TrainerTooSlow);
                }

                await Click(A, 0_800, token).ConfigureAwait(false);
                await SetBoxPokemon(clone, InjectBox, InjectSlot, token, sav).ConfigureAwait(false);

                pkm = clone;

                for (int i = 0; i < 5; i++)
                {
                    await Click(A, 0_500, token).ConfigureAwait(false);
                }
            }

            await Click(A, 3_000, token).ConfigureAwait(false);

            for (int i = 0; i < 5; i++)
            {
                await Click(A, 1_500, token).ConfigureAwait(false);
            }

            delay_count = 0;
            while (!await IsInBox(token).ConfigureAwait(false))
            {
                await Click(A, 3_000, token).ConfigureAwait(false);

                delay_count++;
                if (delay_count >= 50)
                {
                    break;
                }
                if (await IsOnOverworld(Hub.Config, token).ConfigureAwait(false)) // In case we are in a Trade Evolution/PokeDex Entry and the Trade Partner quits we land on the Overworld
                {
                    break;
                }
            }

            await Task.Delay(1_000 + Util.Rand.Next(0_700, 1_000), token).ConfigureAwait(false);

            await ExitTrade(Hub.Config, false, token).ConfigureAwait(false);

            Log("Exited Trade!");

            if (token.IsCancellationRequested)
            {
                return(PokeTradeResult.Aborted);
            }

            // Trade was Successful!
            var traded = await ReadBoxPokemon(InjectBox, InjectSlot, token).ConfigureAwait(false);

            // Pokémon in b1s1 is same as the one they were supposed to receive (was never sent).
            if (poke.Type != PokeTradeType.FixOT && SearchUtil.HashByDetails(traded) == SearchUtil.HashByDetails(pkm))
            {
                Log("User did not complete the trade.");
                return(PokeTradeResult.TrainerTooSlow);
            }
            else
            {
                // As long as we got rid of our inject in b1s1, assume the trade went through.
                Log("User completed the trade.");
                poke.TradeFinished(this, traded);

                // Only log if we completed the trade.
                var counts = Hub.Counts;
                if (poke.Type == PokeTradeType.Random)
                {
                    counts.AddCompletedDistribution();
                }
                else if (poke.Type == PokeTradeType.Clone)
                {
                    counts.AddCompletedClones();
                }
                else if (poke.Type == PokeTradeType.FixOT)
                {
                    counts.AddCompletedFixOTs();
                }
                else if (poke.Type == PokeTradeType.TradeCord)
                {
                    counts.AddCompletedTradeCords();
                }
                else if (poke.Type == PokeTradeType.Giveaway)
                {
                    counts.AddCompletedGiveaways();
                }
                else
                {
                    Hub.Counts.AddCompletedTrade();
                }

                if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder))
                {
                    var subfolder = poke.Type.ToString().ToLower();
                    DumpPokemon(DumpSetting.DumpFolder, subfolder, traded); // received
                    if (poke.Type == PokeTradeType.Specific || poke.Type == PokeTradeType.Clone || poke.Type == PokeTradeType.FixOT || poke.Type == PokeTradeType.TradeCord || poke.Type == PokeTradeType.Giveaway)
                    {
                        DumpPokemon(DumpSetting.DumpFolder, "traded", pkm); // sent to partner
                    }
                }
            }

            return(PokeTradeResult.Success);
        }
Пример #8
0
        private async Task DoCurryMonEncounter(int ingrIndex, int berryIndex, int berryCount, int ingredientCount, CancellationToken token)
        {
            bool firstRun   = true;
            PK8? comparison = null;

            while (!token.IsCancellationRequested && Config.NextRoutineType == PokeRoutineType.CurryBot)
            {
                if (await IsOnOverworld(Hub.Config, token).ConfigureAwait(false))
                {
                    Log("Entering camp...");
                    await Click(X, 2_000, token).ConfigureAwait(false);
                    await Click(A, Settings.EnterCamp, token).ConfigureAwait(false);
                }

                if (!await LairStatusCheck(0xFF000000, 0x6B311300, token).ConfigureAwait(false)) // Check if camp screen.
                {
                    await Click(B, 2_000, token).ConfigureAwait(false);
                }

                await CookingCurry(ingrIndex, berryIndex, berryCount, firstRun, token).ConfigureAwait(false);

                ingredientCount--;
                berryCount -= berryCount >= 10 ? 10 : 1;
                firstRun    = false;

                Log("Checking for a camper...");
                PK8?camperMon = await GetCampPokemon(token).ConfigureAwait(false);

                if (camperMon != null && string.IsNullOrEmpty(camperMon.OT_Name) && camperMon != comparison)
                {
                    comparison = camperMon;
                    await SetStick(RIGHT, 0, 30_000, 1_000, token).ConfigureAwait(false);
                    await SetStick(RIGHT, 0, 0, 0_100, token).ConfigureAwait(false);

                    Log($"New camper found on curry #{curryCount}.");
                    TradeExtensions <PK8> .EncounterLogs(camperMon, "EncounterLogPretty_Curry.txt");

                    if (await HandleEncounter(camperMon, token).ConfigureAwait(false))
                    {
                        return;
                    }
                }
                else
                {
                    Log($"No new campers on curry #{curryCount}...");
                }

                if (!Settings.RestorePouches && (ingredientCount <= 0 || berryCount <= 0))
                {
                    Log("Ran out of ingredients to make curry. Stopping...");
                    return;
                }
                else if (Settings.RestorePouches && (ingredientCount <= 1 || berryCount <= 10))
                {
                    Log("Restoring ingredient and berry pouches...");
                    await Connection.WriteBytesAsync(BerryPouch, BerryPouchOffset, token).ConfigureAwait(false);

                    berryCount = BerryCount;
                    await Connection.WriteBytesAsync(IngredientPouch, IngredientPouchOffset, token).ConfigureAwait(false);

                    ingredientCount = IngredientCount;
                }
            }
        }