Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions SerialPrograms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 +1380,8 @@ file(GLOB MAIN_SOURCES
Source/PokemonLGPE/Programs/Farming/PokemonLGPE_DailyItemFarmer.h
Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp
Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h
Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_GiftReset.cpp
Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_GiftReset.h
Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp
Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h
Source/PokemonLGPE/PokemonLGPE_Panels.cpp
Expand Down
2 changes: 2 additions & 0 deletions SerialPrograms/SerialPrograms.pro
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,7 @@ SOURCES += \
Source/PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.cpp \
Source/PokemonLGPE/Programs/Farming/PokemonLGPE_DailyItemFarmer.cpp \
Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp \
Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_GiftReset.cpp \
Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp \
Source/PokemonLGPE/PokemonLGPE_Panels.cpp \
Source/PokemonLGPE/PokemonLGPE_Settings.cpp \
Expand Down Expand Up @@ -1868,6 +1869,7 @@ HEADERS += \
Source/PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.h \
Source/PokemonLGPE/Programs/Farming/PokemonLGPE_DailyItemFarmer.h \
Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h \
Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_GiftReset.h \
Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h \
Source/PokemonLGPE/PokemonLGPE_Panels.h \
Source/PokemonLGPE/PokemonLGPE_Settings.h \
Expand Down
2 changes: 2 additions & 0 deletions SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Panels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "Programs/Farming/PokemonLGPE_DailyItemFarmer.h"
#include "Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h"
#include "Programs/ShinyHunting/PokemonLGPE_GiftReset.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
Expand All @@ -31,6 +32,7 @@ std::vector<PanelEntry> PanelListFactory::make_panels() const{

ret.emplace_back("---- Shiny Hunting ----");
ret.emplace_back(make_single_switch_program<AlolanTrade_Descriptor, AlolanTrade>());
ret.emplace_back(make_single_switch_program<GiftReset_Descriptor, GiftReset>());

return ret;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ DailyItemFarmer_Descriptor::DailyItemFarmer_Descriptor()
Pokemon::STRING_POKEMON + " LGPE", "Daily Item Farmer",
"",
"Farm daily item respawns (ex. fossils) by date-skipping.",
FeedbackType::NONE,
FeedbackType::REQUIRED,
AllowCommandsWhenRunning::DISABLE_COMMANDS,
{ControllerFeature::NintendoSwitch_RightJoycon},
FasterIfTickPrecise::NOT_FASTER
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ AlolanTrade_Descriptor::AlolanTrade_Descriptor()
Pokemon::STRING_POKEMON + " LGPE", "Alolan Trade",
"",
"Shiny hunt Alolan forms by trading in-game.",
FeedbackType::NONE,
FeedbackType::REQUIRED,
AllowCommandsWhenRunning::DISABLE_COMMANDS,
{ControllerFeature::NintendoSwitch_RightJoycon},
FasterIfTickPrecise::NOT_FASTER
Expand Down Expand Up @@ -136,19 +136,18 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope&
/*
WARNING: JOYCON TEST PROGRAM. Not well tested. Bare minimum in general.

Only works with Right joycon atm. Do not update right joycon. Decline the update before running this.

Right joycon required for home button (this means no on-switch screenshots).
Also don't remap any of the buttons in the switch button mapping settings. Yet? Could use this to add Home and Screenshot.
Also don't remap any of the buttons in the switch button mapping settings.

Preconditions:
DO NOT have any Pokemon you want to keep in your boxes. Move them out to Home first.
Favoriting a Pokemon does not prevent it from being traded.
This must not be your first time doing the trade. (I've done all the trades, so I can't check first time trade behavior.)
?This must not be your first time doing the trade? (I've done all the trades, so I can't check first time trade behavior.)

Setup:
Catch the Kanto variant of the target. Put this number in NUM_TRADES.
Stand in front of trade NPC.
Save the game.
Start the program in-game.

Future additions?:
Expand Down Expand Up @@ -230,6 +229,7 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope&
env.update_stats();
send_program_notification(env, NOTIFICATION_SHINY, COLOR_YELLOW, "Shiny found!", {}, "", screen, true);
shiny_found = true;
//TODO: Favorite the shiny.
}
else {
env.log("Not shiny.");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/* LGPE Gift Reset
*
* From: https://github.com/PokemonAutomation/
*
*/

#include "CommonFramework/Exceptions/OperationFailedException.h"
#include "CommonFramework/Notifications/ProgramNotifications.h"
#include "CommonFramework/ProgramStats/StatsTracking.h"
#include "CommonFramework/VideoPipeline/VideoFeed.h"
#include "CommonTools/Async/InferenceRoutines.h"
#include "CommonTools/StartupChecks/VideoResolutionCheck.h"
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
#include "NintendoSwitch/Controllers/NintendoSwitch_Joycon.h"
#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h"
#include "Pokemon/Pokemon_Strings.h"
#include "CommonTools/VisualDetectors/BlackScreenDetector.h"
#include "PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.h"
#include "PokemonLGPE/Programs/PokemonLGPE_GameEntry.h"
#include "PokemonLGPE_GiftReset.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonLGPE{

GiftReset_Descriptor::GiftReset_Descriptor()
: SingleSwitchProgramDescriptor(
"PokemonLGPE:GiftReset",
Pokemon::STRING_POKEMON + " LGPE", "Gift Reset",
"",
"Shiny hunt gift Pokemon by resetting the game.",
FeedbackType::REQUIRED,
AllowCommandsWhenRunning::DISABLE_COMMANDS,
{ControllerFeature::NintendoSwitch_RightJoycon},
FasterIfTickPrecise::NOT_FASTER
)
{}

struct GiftReset_Descriptor::Stats : public StatsTracker{
Stats()
: resets(m_stats["Resets"])
, shinies(m_stats["Shinies"])
{
m_display_order.emplace_back("Resets");
m_display_order.emplace_back("Shinies");
}
std::atomic<uint64_t>& resets;
std::atomic<uint64_t>& shinies;
};
std::unique_ptr<StatsTracker> GiftReset_Descriptor::make_stats() const{
return std::unique_ptr<StatsTracker>(new Stats());
}

GiftReset::GiftReset()
: GO_HOME_WHEN_DONE(false)
, NOTIFICATION_SHINY(
"Shiny Found",
true, true, ImageAttachmentMode::JPG,
{"Notifs", "Showcase"}
)
, NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600))
, NOTIFICATIONS({
&NOTIFICATION_SHINY,
&NOTIFICATION_STATUS_UPDATE,
&NOTIFICATION_PROGRAM_FINISH,
})
{
PA_ADD_OPTION(GO_HOME_WHEN_DONE);
PA_ADD_OPTION(NOTIFICATIONS);
}

void GiftReset::program(SingleSwitchProgramEnvironment& env, CancellableScope& scope){
JoyconContext context(scope, env.console.controller<JoyconController>());
assert_16_9_720p_min(env.logger(), env.console);
GiftReset_Descriptor::Stats& stats = env.current_stats<GiftReset_Descriptor::Stats>();

/*
Setup:
Stand in front of trade NPC.
Start the program in-game.

Must have 500yen for magikarp.
Gift Pokemon: https://www.serebii.net/letsgopikachueevee/gift.shtml
Tested with Magikarp on a new save. Should work with most of the others.
Can always add a dropdown with target if it doesn't.
Fossils will be handled in a different program.
*/

bool shiny_found = false;
while (!shiny_found) {
//Purchase Magikarp
BlackScreenOverWatcher gift_obtained(COLOR_RED);
int ret = run_until<JoyconContext>(
env.console, context,
[](JoyconContext& context){
pbf_mash_button(context, BUTTON_A, 20000ms);
},
{gift_obtained}
);
context.wait_for_all_requests();
if (ret != 0){
env.log("Failed to receive gift Pokemon.", COLOR_RED);
OperationFailedException::fire(
ErrorReport::SEND_ERROR_REPORT,
"Failed to receive gift Pokemon.",
env.console
);
}
else {
env.log("Received gift Pokemon.");
}
send_program_status_notification(
env, NOTIFICATION_STATUS_UPDATE,
"Received gift Pokemon."
);

//Wait a bit.
pbf_wait(context, 2500ms);
context.wait_for_all_requests();

//Open menu, open party, open boxes
env.log("Opening boxes.");
pbf_press_button(context, BUTTON_X, 200ms, 500ms);
pbf_press_button(context, BUTTON_A, 200ms, 1500ms);
pbf_press_button(context, BUTTON_Y, 200ms, 2000ms);
context.wait_for_all_requests();

//Sort by order caught
env.log("Sorting by order caught.");
pbf_press_button(context, BUTTON_Y, 200ms, 1000ms);
pbf_press_button(context, BUTTON_A, 200ms, 1000ms);
pbf_press_button(context, BUTTON_A, 200ms, 1000ms);
context.wait_for_all_requests();

//Press left to go to last (most recent) Pokemon
env.log("Opening summary of most recent Pokemon.");
pbf_move_joystick(context, 0, 128, 100ms, 100ms);
context.wait_for_all_requests();

//View summary - it takes a moment to load
env.log("Viewing summary.");
pbf_press_button(context, BUTTON_A, 200ms, 1000ms);
pbf_move_joystick(context, 128, 255, 100ms, 100ms);
pbf_move_joystick(context, 128, 255, 100ms, 100ms);
pbf_press_button(context, BUTTON_A, 200ms, 100ms);
context.wait_for_all_requests();

pbf_wait(context, 5000ms);
context.wait_for_all_requests();

//Now check for shinies. Check everything that was traded.
VideoSnapshot screen = env.console.video().snapshot();
ShinySymbolDetector shiny_checker(COLOR_YELLOW);
bool check = shiny_checker.read(env.console.logger(), screen);

if (check) {
env.log("Shiny detected!");
stats.shinies++;
env.update_stats();
send_program_notification(env, NOTIFICATION_SHINY, COLOR_YELLOW, "Shiny found!", {}, "", screen, true);
shiny_found = true;
}
else {
env.log("Not shiny. Resetting game.");
send_program_status_notification(
env, NOTIFICATION_STATUS_UPDATE,
"Not shiny. Resetting game."
);

//Reset game
pbf_press_button(context, BUTTON_HOME, 200ms, 2000ms);
reset_game_from_home(env, env.console, context, 3000ms);
context.wait_for_all_requests();

stats.resets++;
env.update_stats();
}
}

if (GO_HOME_WHEN_DONE) {
pbf_press_button(context, BUTTON_HOME, 200ms, 1000ms);
}
send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH);
}


}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* LGPE Gift Reset
*
* From: https://github.com/PokemonAutomation/
*
*/

#ifndef PokemonAutomation_PokemonLGPE_GiftReset_H
#define PokemonAutomation_PokemonLGPE_GiftReset_H

#include "NintendoSwitch/Controllers/NintendoSwitch_Joycon.h"
#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h"
#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h"
#include "CommonFramework/Notifications/EventNotificationsTable.h"
#include "Common/Cpp/Options/SimpleIntegerOption.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonLGPE{

class GiftReset_Descriptor : public SingleSwitchProgramDescriptor{
public:
GiftReset_Descriptor();
struct Stats;
virtual std::unique_ptr<StatsTracker> make_stats() const override;
};

class GiftReset : public SingleSwitchProgramInstance{
public:
GiftReset();
virtual void program(SingleSwitchProgramEnvironment& env, CancellableScope& scope) override;

private:
GoHomeWhenDoneOption GO_HOME_WHEN_DONE;

EventNotificationOption NOTIFICATION_SHINY;
EventNotificationOption NOTIFICATION_STATUS_UPDATE;
EventNotificationsOption NOTIFICATIONS;
};




}
}
}
#endif