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/Source/PokemonLZA/PokemonLZA_Panels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "Programs/ShinyHunting/PokemonLZA_AutoFossil.h"
#include "Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.h"
#include "Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.h"
#include "Programs/ShinyHunting/PokemonLZA_ShuttleRun.h"

// Non-Shiny Hunting
#include "Programs/NonShinyHunting/PokemonLZA_StatsReset.h"
Expand Down Expand Up @@ -85,6 +86,7 @@ std::vector<PanelEntry> PanelListFactory::make_panels() const{
}
if (PreloadSettings::instance().DEVELOPER_MODE){
ret.emplace_back(make_single_switch_program<BeldumHunter_Descriptor, BeldumHunter>());
ret.emplace_back(make_single_switch_program<ShinyHunt_ShuttleRun_Descriptor, ShinyHunt_ShuttleRun>());
}

// ret.emplace_back("---- Non-Shiny Hunting ----");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/* Shiny Hunt - Shuttle Run
*
* From: https://github.com/PokemonAutomation/
*
*/

#include "CommonFramework/Exceptions/OperationFailedException.h"
#include "CommonFramework/ProgramStats/StatsTracking.h"
#include "CommonFramework/Notifications/ProgramNotifications.h"
#include "CommonFramework/VideoPipeline/VideoOverlay.h"
#include "CommonTools/Async/InferenceRoutines.h"
#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h"
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h"
#include "Pokemon/Pokemon_Strings.h"
#include "PokemonLA/Inference/Sounds/PokemonLA_ShinySoundDetector.h"
#include "PokemonLZA/Programs/PokemonLZA_BasicNavigation.h"
#include "PokemonLZA_ShuttleRun.h"

namespace PokemonAutomation {
namespace NintendoSwitch {
namespace PokemonLZA {

using namespace Pokemon;


ShinyHunt_ShuttleRun_Descriptor::ShinyHunt_ShuttleRun_Descriptor()
: SingleSwitchProgramDescriptor(
"PokemonLZA:ShinyHunt-ShuttleRun", STRING_POKEMON + " LZA",
"Shuttle Run",
"Programs/PokemonLZA/ShinyHunt-ShuttleRun.html",
"Shiny hunt by repeatedly running back and forth between two points",
ProgramControllerClass::StandardController_NoRestrictions, FeedbackType::REQUIRED,
AllowCommandsWhenRunning::DISABLE_COMMANDS, {}
)
{}
class ShinyHunt_ShuttleRun_Descriptor::Stats : public StatsTracker{
public:
Stats()
: resets(m_stats["Rounds"])
, shinies(m_stats["Shiny Sounds"])
, errors(m_stats["Errors"])
{
m_display_order.emplace_back("Rounds");
m_display_order.emplace_back("Shiny Sounds");
m_display_order.emplace_back("Errors", HIDDEN_IF_ZERO);
}

std::atomic<uint64_t>& resets;
std::atomic<uint64_t>& shinies;
std::atomic<uint64_t>& errors;
};
std::unique_ptr<StatsTracker> ShinyHunt_ShuttleRun_Descriptor::make_stats() const{
return std::unique_ptr<StatsTracker>(new Stats());
}


ShinyHunt_ShuttleRun::ShinyHunt_ShuttleRun()
: DURATION("<b>Duration:</b><br>Run the program this long.", LockMode::UNLOCK_WHILE_RUNNING, "5 h")
, ROUTE("<b>Hunt Route:</b>",
{
{Routes::KLEFKI, "klefki", "Sewers: Klefki"},
{Routes::KLEFKI_INKAY_GOOMY, "klefki_inkay_goomy", "Sewers: Klefki+Inkay+Goomy"},
{Routes::LITWICK, "litwick", "Sewers: Litwick"},
{Routes::SKRELP, "skrelp", "Sewers: Skrelp"},
// {Routes::SCRAGGY, "scraggy", "Sewers: Scraggy"},
},
LockMode::LOCK_WHILE_RUNNING,
Routes::KLEFKI)
, SHINY_DETECTED("Shiny Detected", "", "1000 ms", ShinySoundDetectedAction::NOTIFY_ON_FIRST_ONLY)
, NOTIFICATION_STATUS("Status Update", true, false, std::chrono::seconds(3600))
, NOTIFICATIONS({
&NOTIFICATION_STATUS,
&NOTIFICATION_PROGRAM_FINISH,
&NOTIFICATION_ERROR_RECOVERABLE,
&NOTIFICATION_ERROR_FATAL,
})
{
PA_ADD_STATIC(SHINY_REQUIRES_AUDIO);
PA_ADD_OPTION(DURATION);
PA_ADD_OPTION(ROUTE);
PA_ADD_OPTION(SHINY_DETECTED);
PA_ADD_OPTION(NOTIFICATIONS);
}

namespace {

void fly_back(ConsoleHandle& console, ProControllerContext& context) {
pbf_press_button(context, BUTTON_PLUS, 240ms, 80ms); // open map
context.wait_for_all_requests();
pbf_wait(context, 500ms);
pbf_press_button(context, BUTTON_Y, 100ms, 100ms); // select fly point
pbf_mash_button(context, BUTTON_A, 1000ms);
wait_until_overworld(console, context, 10s);
}

void route_klefki(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
context.wait_for_all_requests();
ssf_press_button(context, BUTTON_B, 0ms, 500ms, 0ms);
pbf_move_left_joystick(context, 128, 0, 4900ms, 0ms);
pbf_move_left_joystick(context, 0, 128, 1000ms, 0ms);
pbf_press_button(context, BUTTON_L, 100ms, 500ms);
fly_back(env.console, context);
}

void route_klefki_inkay_goomy(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
context.wait_for_all_requests();
ssf_press_button(context, BUTTON_B, 0ms, 500ms, 0ms);
pbf_move_left_joystick(context, 128, 0, 8500ms, 0ms);
pbf_move_left_joystick(context, 255, 128, 1300ms, 0ms);
pbf_press_button(context, BUTTON_L, 100ms, 500ms);
fly_back(env.console, context);
}

void route_litwick(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
context.wait_for_all_requests();
ssf_press_button(context, BUTTON_B, 0ms, 500ms, 0ms);
pbf_move_left_joystick(context, 128, 0, 5000ms, 0ms);
pbf_move_left_joystick(context, 128, 255, 5500ms, 0ms);
pbf_wait(context, 500ms);
}

void route_skrelp(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
context.wait_for_all_requests();
ssf_press_button(context, BUTTON_B, 0ms, 500ms, 0ms);
pbf_move_left_joystick(context, 128, 255, 5000ms, 0ms);
pbf_move_left_joystick(context, 128, 0, 5500ms, 0ms);
pbf_wait(context, 500ms);
}

void route_scraggy(SingleSwitchProgramEnvironment& env, ProControllerContext& context){

}
} // namespace

void ShinyHunt_ShuttleRun::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
ShinyHunt_ShuttleRun_Descriptor::Stats& stats =
env.current_stats<ShinyHunt_ShuttleRun_Descriptor::Stats>();
ShinySoundHandler shiny_sound_handler(SHINY_DETECTED);
PokemonLA::ShinySoundDetector shiny_detector(env.console, [&](float error_coefficient) -> bool {
// Warning: This callback will be run from a different thread than this function.
stats.shinies++;
env.update_stats();
env.console.overlay().add_log("Shiny Sound Detected!", COLOR_YELLOW);
return shiny_sound_handler.on_shiny_sound(
env, env.console,
stats.shinies,
error_coefficient
);
});
std::function<void(SingleSwitchProgramEnvironment&, ProControllerContext&)> loop;
switch (ROUTE) {
case Routes::KLEFKI:
loop = route_klefki;
break;
case Routes::KLEFKI_INKAY_GOOMY:
loop = route_klefki_inkay_goomy;
break;
case Routes::LITWICK:
loop = route_litwick;
break;
case Routes::SKRELP:
loop = route_skrelp;
break;
case Routes::SCRAGGY:
loop = route_scraggy;
break;
default:
OperationFailedException::fire(
ErrorReport::SEND_ERROR_REPORT,
"route not implemented",
env.console
);
}
WallClock start_time = current_time();
pbf_press_button(context, BUTTON_L, 100ms, 100ms); // connect

run_until<ProControllerContext>(
env.console, context,
[&](ProControllerContext& context){
do{
shiny_sound_handler.process_pending(context);
send_program_status_notification(env, NOTIFICATION_STATUS);
stats.resets++;
loop(env, context);
env.update_stats();
}while (current_time() < start_time + DURATION.get());
},
{{shiny_detector}}
);

shiny_sound_handler.process_pending(context);
go_home(env.console, context);
send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH);
}


} // namespace PokemonLZA
} // namespace NintendoSwitch
} // namespace PokemonAutomation
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* Shiny Hunt - Shuttle Run
*
* From: https://github.com/PokemonAutomation/
*
*/

#ifndef PokemonAutomation_PokemonLZA_Shuttle_Run_H
#define PokemonAutomation_PokemonLZA_Shuttle_Run_H

#include "Common/Cpp/Options/EnumDropdownOption.h"
#include "Common/Cpp/Options/TimeDurationOption.h"
#include "CommonFramework/Notifications/EventNotificationsTable.h"
#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h"
#include "PokemonLA/Options/PokemonLA_ShinyDetectedAction.h"
#include "PokemonLZA/Options/PokemonLZA_ShinyDetectedAction.h"

namespace PokemonAutomation {
namespace NintendoSwitch {
namespace PokemonLZA {


class ShinyHunt_ShuttleRun_Descriptor : public SingleSwitchProgramDescriptor {
public:
ShinyHunt_ShuttleRun_Descriptor();

class Stats;
virtual std::unique_ptr<StatsTracker> make_stats() const override;
};


class ShinyHunt_ShuttleRun : public SingleSwitchProgramInstance {
public:
ShinyHunt_ShuttleRun();

virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override;

enum class Routes{
KLEFKI,
KLEFKI_INKAY_GOOMY,
LITWICK,
SKRELP,
SCRAGGY,
WILD_ZONE_19,
FIRE_STARTERS,
DRATINI,
CUSTOMISED_MACRO = 255,
};

private:
PokemonLA::ShinyRequiresAudioText SHINY_REQUIRES_AUDIO;
MillisecondsOption DURATION;
EnumDropdownOption<Routes> ROUTE;
ShinySoundDetectedActionOption SHINY_DETECTED;
EventNotificationOption NOTIFICATION_STATUS;
EventNotificationsOption NOTIFICATIONS;
};


} // namespace PokemonLZA
} // namespace NintendoSwitch
} // namespace PokemonAutomation
#endif
2 changes: 2 additions & 0 deletions SerialPrograms/SourceFiles.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1635,6 +1635,8 @@ file(GLOB LIBRARY_SOURCES
Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.h
Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_OverworldReset.cpp
Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_OverworldReset.h
Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShuttleRun.h
Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShuttleRun.cpp
Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.cpp
Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.h
Source/PokemonLZA/Programs/TestPrograms/PokemonLZA_MoveBoxArrow.cpp
Expand Down