Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BBQ Solo Farmer #407

Merged
merged 34 commits into from
Apr 13, 2024
Merged

Conversation

kichithewolf
Copy link
Contributor

BBQ json: PokemonAutomation/Packages#22
Setup/Instructions: PokemonAutomation/ComputerControl#177

All singleplayer quests except "Pickup 10 items" are automated. That quest will be skipped, no rerolling, it only takes up one slot. No intention of doing multiplayer at this time, I've never found a ditto block in my life.

Some quests more reliable than others, ex. hatch egg and make sandwich are solid but the catch/photo quests are more sensitive to weather-induced lag since they have to navigate the area. I tried aiming for locations that are less likely to lag but there's no avoiding it outright. "Give your Pokemon a bath" depends on what Pokemon it ends up washing, it just moves the brush in a + shape. The program will retry quests anyway, so it will eventually complete the quests. I was able to do a successful run of 100 quests a few times.

Shiny checking - there's checking for overworld encounters that should work in theory, in practice all the targets are fixed spawns so they're full odds and I have no way of really testing it.

There are still improvements that can be done, quest processing logic was written with the assumption that most quests could not be automated so could be tweaked a bit, travel 500 meters could use sound detection (I don't have the sound file for it) to check when it is complete, could probably keep track of egg/TM position, etc. This things is 10 different programs in a trenchcoat, take your time reviewing. I need a break since it's been 3 weeks.

uint64_t binomial_coefficient_u64(size_t degree, size_t index){
if (degree > 62){
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Cannot go beyond degree 62.");
double binomial_coefficient_u64(size_t degree, size_t index){
Copy link
Member

@pifopi pifopi Mar 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename the method to binomial_coefficient_double
(or binomial_coefficient ? not sure what's best)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed it to binomial_coefficient_double

m_box = ImageFloatBox(0.604, 0.572, 0.282, 0.095);
break;
case QuestPosition::FOURTH:
m_box = ImageFloatBox(0.604, 0.749, 0.282, 0.096);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the fourth intended to be bigger ? (difference is small anyway)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, it was unintentional

{OOEggs::KeepGoing, "keep-going", "Keep Going - Warning: Bonus(Red) quests will be blocked!"},
},
LockMode::LOCK_WHILE_RUNNING,
OOEggs::Stop
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to do KeepGoing ? From my experience, it seems you can "stack up" red quest, meaining even if you do not complete the current red quest, you're already working on unlocking the next red quest

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It only stacks up an additional two red quests. The bar fills green->gold->red and then stops there.

image
image

@Mysticial
Copy link
Collaborator

Given how big this change is. Let's split this up into smaller PRs that can go in incrementally. Especially the parts that are shared with existing programs so they can be tested separately. I'll comment on each file individually on what should probably be split out.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's split this binomial refactor out to a separate PR. It's shared by a zillion other things so we can test it with those first.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split out into #410.

open_map_from_overworld(info, console, context);
}
catch (...) {
//Stuck climbing on a wall? Center camera and try to backwards jump off.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of getting off the wall is interesting since we have this problem elsewhere. (platform bot has this problem)

Here you're only retrying once. But from my experience that may not be enough depending on how you get stuck. So what I'm thinking is that we could pull this out in a generic "get off the wall" function with multiple retries before finally giving up.

Here you're using the open_map_from_overworld() to determine if you've successfully jumped off the wall. And I think in most of our other cases it's the same thing.

Exactly how we want to do this I'm not sure. Could either add this retry capability to open_map_from_overworld() itself or define a new function that wraps it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's pull this file (and header) out into a separate PR. It looks self-contained enough to test and iterate on in isolation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulled out into #409.

@Mysticial
Copy link
Collaborator

Looks like you can rebase this so we can see what's left to start chipping away at.

@Mysticial
Copy link
Collaborator

Looks like we need another rebase.

namespace NintendoSwitch{
namespace PokemonSV{

class BBQOption : public GroupOption, private ConfigOption::Listener {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to inherit from ConfigOption::Listener? I don't see an override for any of its functions.

#include "PokemonSV/Options/PokemonSV_EncounterBotCommon.h"
#include "PokemonSV/Options/PokemonSV_BBQOption.h"

using namespace std;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't put this, especially in headers.

namespace PokemonSV{

//Navigate to a photo target
CameraAngle quest_photo_navi(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context, BBQOption& BBQ_OPTIONS, BBQuests& current_quest);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're not writing to BBQuests& current_quest right? If it's strictly an input parameter, take it by value since it's a primitive.

//Open the quest panel and read in the current quests.
//Currently only supports singleplayer.
//For multiplayer, we will want keep track of which quest are gold/red and scroll cursor down until all of the current player's blue quests are in.
std::vector<BBQuests> read_quests(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context, BBQOption& BBQ_OPTIONS);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can BBQOption& BBQ_OPTIONS be made const? I don't think you're changing it. But at the same time, I'm don't remember if the getters are const. (since they internally take locks)

)
, NUM_EGGS(
"<b>Hatch Quest - Number of Eggs:</b><br>Amount of eggs located in your current box.",
LockMode::LOCK_WHILE_RUNNING, 30, 0, 30
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the way you're using this, it's safe to unlock. Though I don't see any legitimate use for editing while running other than fixing an incorrect value.

, CATCH_ON_WIN(true)
, NUM_RETRIES(
"<b>Number of Retries:</b><br>Reattempt a quest this many times if it fails.",
LockMode::LOCK_WHILE_RUNNING, 1, 0, 5
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one looks safe to unlock.

//Check eggs remaining.
if (n == BBQuests::hatch_egg && eggs_hatched >= BBQ_OPTIONS.NUM_EGGS) {
console.log("Out of eggs! Quest not possible.");
if (BBQ_OPTIONS.OUT_OF_EGGS == BBQOption::OOEggs::Reroll) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you make this a switch statement so that BBQ_OPTIONS.OUT_OF_EGGS is only read once, you can unlock this config.

WallClock start = current_time();

console.log("Opening ball menu...");
while (ball_reader == "") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of duplicated code here between the Quick Ball and normal ball paths. Can you pull this out into a separate function where you just pass in the ball to use?

if (ret == 0) {
console.log("Battle menu detected.");

encounter_watcher.throw_if_no_sound();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bad indent. :)

move encounter watcher out of ret
@@ -608,6 +610,57 @@ void quest_catch_navi(const ProgramInfo& info, ConsoleHandle& console, BotBaseCo

}

void quest_catch_throw_ball(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context, Language language, std::string selected_ball) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::string selected_ball -> const std::string& selected_ball since it's not being modified and is not a primitive.

MoveSelectDetector move_select(COLOR_BLUE);

int ret_move_select = run_until(
console, context,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation

@Mysticial
Copy link
Collaborator

Last few nits. Otherwise, it's pretty much good to go.

@@ -31,7 +31,7 @@ void quest_photo(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext
void quest_catch_navi(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context, const BBQOption& BBQ_OPTIONS, BBQuests current_quest);

//Select and throw ball
void quest_catch_throw_ball(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context, Language language, std::string selected_ball);
void quest_catch_throw_ball(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context, Language language, const std::string selected_ball);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const reference, not just const. Remember that we don't want to copy non-trivial objects unless we need to.

@Mysticial Mysticial merged commit e8adb61 into PokemonAutomation:main Apr 13, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants