Example #1
0
        private async Task <bool> HandleEncounter(PK8 pk, bool legends, CancellationToken token)
        {
            encounterCount++;
            Log($"Encounter: {encounterCount}{Environment.NewLine}{ShowdownSet.GetShowdownText(pk)}{Environment.NewLine}");
            Counts.AddEncounteredSpecies(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..." : $"{Ping}Result found! Stopping routine execution; restart the bot(s) to search again.");
                if (Hub.Config.StopConditions.CaptureVideoClip)
                {
                    await Task.Delay(Hub.Config.StopConditions.ExtraTimeWaitCaptureVideo).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);
        }
Example #2
0
        protected override async Task MainLoop(CancellationToken token)
        {
            Log("Identifying trainer data of the host console.");
            await IdentifyTrainer(token).ConfigureAwait(false);

            await SetCurrentBox(0, token).ConfigureAwait(false);

            var existing = await ReadBoxPokemon(InjectBox, InjectSlot, token).ConfigureAwait(false);

            if (existing.Species != 0 && existing.ChecksumValid)
            {
                Log("Destination slot is occupied! Dumping the Pokémon found there...");
                DumpPokemon(DumpSetting.DumpFolder, "saved", existing);
            }
            Log("Clearing destination slot to start the bot.");
            await SetBoxPokemon(Blank, InjectBox, InjectSlot, token).ConfigureAwait(false);

            Log("Starting main EggBot loop.");
            Config.IterateNextRoutine();
            while (!token.IsCancellationRequested && Config.NextRoutineType == PokeRoutineType.EggFetch)
            {
                // Walk a step left, then right => check if egg was generated on this attempt.
                // Repeat until an egg is generated.

                var attempts = await StepUntilEgg(token).ConfigureAwait(false);

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

                Log($"Egg available after {attempts} attempts! Clearing destination slot.");
                await SetBoxPokemon(Blank, InjectBox, InjectSlot, token).ConfigureAwait(false);

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

                // Safe to mash B from here until we get out of all menus.
                while (!await IsOnOverworld(Hub.Config, token).ConfigureAwait(false))
                {
                    await Click(B, 0_400, token).ConfigureAwait(false);
                }

                Log("Egg received. Checking details.");
                var pk = await ReadBoxPokemon(InjectBox, InjectSlot, token).ConfigureAwait(false);

                if (pk.Species == 0)
                {
                    Log("Invalid data detected in destination slot. Restarting loop.");
                    continue;
                }

                encounterCount++;
                Log($"Encounter: {encounterCount}:{Environment.NewLine}{ShowdownSet.GetShowdownText(pk)}{Environment.NewLine}");
                Counts.AddCompletedEggs();
                Counts.AddEncounteredSpecies(pk);

                if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder))
                {
                    DumpPokemon(DumpSetting.DumpFolder, "egg", pk);
                }

                if (StopConditionSettings.EncounterFound(pk, DesiredIVs, Hub.Config.StopConditions))
                {
                    if (Hub.Config.Egg.ContinueAfterMatch)
                    {
                        Log($"{Ping}Result found! Continuing to collect more eggs.");
                        continue;
                    }
                    Log($"{Ping}Result found! Stopping routine execution; restart the bot(s) to search again.");
                    await DetachController(token).ConfigureAwait(false);

                    return;
                }
            }

            // If aborting the sequence, we might have the stick set at some position. Clear it just in case.
            await SetStick(LEFT, 0, 0, 0, CancellationToken.None).ConfigureAwait(false); // reset
        }
Example #3
0
        private async Task WalkInLine(CancellationToken token)
        {
            if (hub.Config.Encounter.CatchEncounter && !hub.Config.Encounter.StrongSpawn)
            {
                Log("Checking Poké Ball count...");
                pouchData = await Connection.ReadBytesAsync(PokeBallOffset, 116, token).ConfigureAwait(false);

                var counts = EncounterCount.GetBallCounts(pouchData);
                catchCount = counts.PossibleCatches(Ball.Master);

                if (catchCount == 0)
                {
                    Log("Insufficient Master Balls. Please obtain at least one before starting.");
                    return;
                }
            }

            while (!token.IsCancellationRequested)
            {
                if (hub.Config.Encounter.StrongSpawn)
                {
                    await StrongSpawn(token).ConfigureAwait(false);
                }

                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 ReadPokemon(WildPokemonOffset, token).ConfigureAwait(false);

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

                    // Flee and continue looping.
                    while (await IsInBattle(token).ConfigureAwait(false))
                    {
                        await FleeToOverworld(token).ConfigureAwait(false);
                    }
                    continue;
                }

                encounterCount++;
                Log($"Encounter: {encounterCount}{Environment.NewLine}{ShowdownSet.GetShowdownText(pk)}{Environment.NewLine}");
                Counts.AddCompletedEncounters();
                Counts.AddEncounteredSpecies(pk);

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

                // 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);
                }

                if (StopCondition(pk))
                {
                    if (hub.Config.CaptureVideoClip)
                    {
                        await PressAndHold(CAPTURE, 2_000, 1_000, token).ConfigureAwait(false);
                    }

                    if (hub.Config.Encounter.CatchEncounter && !hub.Config.Encounter.StrongSpawn)
                    {
                        await SetLastUsedBall(Ball.Master, token).ConfigureAwait(false);

                        Log($"Result found! Attempting to catch...");
                        await CatchWildPokemon(pk, token).ConfigureAwait(false);

                        if (!hub.Config.Encounter.InjectPokeBalls && encounterCount != 0 && encounterCount % catchCount == 0)
                        {
                            return;
                        }

                        await WalkInLine(token).ConfigureAwait(false);
                    }

                    Log($"{Ping}Result found! Stopping routine execution; restart the bot(s) to search again.");
                    return;
                }

                Log("Running away...");
                while (await IsInBattle(token).ConfigureAwait(false) && !hub.Config.Encounter.StrongSpawn)
                {
                    await FleeToOverworld(token).ConfigureAwait(false);
                }
            }
        }
Example #4
0
        protected override async Task MainLoop(CancellationToken token)
        {
            Log("Identifying trainer data of the host console.");
            await IdentifyTrainer(token).ConfigureAwait(false);

            await SetCurrentBox(0, token).ConfigureAwait(false);

            var existing = await ReadBoxPokemon(InjectBox, InjectSlot, token).ConfigureAwait(false);

            if (existing.Species != 0 && existing.ChecksumValid)
            {
                Log("Destination slot is occupied! Dumping the Pokémon found there...");
                DumpPokemon(DumpSetting.DumpFolder, "saved", existing);
            }
            Log("Clearing destination slot to start the bot.");
            await SetBoxPokemon(Blank, InjectBox, InjectSlot, token).ConfigureAwait(false);

            Log("Checking item counts...");
            var pouchData = await Connection.ReadBytesAsync(ItemTreasureAddress, 80, Config.ConnectionType, token).ConfigureAwait(false);

            var counts      = FossilCount.GetFossilCounts(pouchData);
            int reviveCount = counts.PossibleRevives(Hub.Config.Fossil.Species);

            if (reviveCount == 0)
            {
                Log("Insufficient fossil pieces. Please obtain at least one of each required fossil piece first.");
                return;
            }

            Log("Starting main FossilBot loop.");
            Config.IterateNextRoutine();
            while (!token.IsCancellationRequested && Config.NextRoutineType == PokeRoutineType.FossilBot)
            {
                if (encounterCount != 0 && encounterCount % reviveCount == 0)
                {
                    Log($"Ran out of fossils to revive {Hub.Config.Fossil.Species}.");
                    if (Hub.Config.Fossil.InjectWhenEmpty)
                    {
                        Log("Restoring original pouch data.");
                        await Connection.WriteBytesAsync(pouchData, ItemTreasureAddress, Config.ConnectionType, token).ConfigureAwait(false);

                        await Task.Delay(500, token).ConfigureAwait(false);
                    }
                    else
                    {
                        Log("Restart the game and the bot(s) or set \"Inject Fossils\" to True in the config.");
                        return;
                    }
                }

                await ReviveFossil(counts, token).ConfigureAwait(false);

                Log("Fossil revived. Checking details...");

                var pk = await ReadBoxPokemon(InjectBox, InjectSlot, token).ConfigureAwait(false);

                if (pk.Species == 0 || !pk.ChecksumValid)
                {
                    Log("Invalid data detected in destination slot. Restarting loop.");
                    continue;
                }

                encounterCount++;
                Log($"Encounter: {encounterCount}:{Environment.NewLine}{ShowdownSet.GetShowdownText(pk)}{Environment.NewLine}{Environment.NewLine}");
                if (DumpSetting.Dump)
                {
                    DumpPokemon(DumpSetting.DumpFolder, "fossil", pk);
                }

                Counts.AddCompletedFossils();
                Counts.AddEncounteredSpecies(pk);

                if (StopConditionSettings.EncounterFound(pk, DesiredIVs, Hub.Config.StopConditions))
                {
                    if (Hub.Config.StopConditions.CaptureVideoClip)
                    {
                        await Task.Delay(Hub.Config.StopConditions.ExtraTimeWaitCaptureVideo).ConfigureAwait(false);
                        await PressAndHold(CAPTURE, 2_000, 1_000, token).ConfigureAwait(false);
                    }

                    if (Hub.Config.Fossil.ContinueAfterMatch)
                    {
                        Log($"{Ping}Result found! Continuing to collect more fossils.");
                    }
                    else
                    {
                        Log($"{Ping}Result found! Stopping routine execution; restart the bot(s) to search again.");
                        await DetachController(token).ConfigureAwait(false);

                        return;
                    }
                }

                Log("Clearing destination slot.");
                await SetBoxPokemon(Blank, InjectBox, InjectSlot, token).ConfigureAwait(false);
            }
        }