Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@

#include "Common/Cpp/Exceptions.h"
#include "Kernels/Waterfill/Kernels_Waterfill_Types.h"
#include "CommonFramework/Globals.h"
#include "CommonTools/ImageMatch/WaterfillTemplateMatcher.h"
#include "CommonTools/Images/WaterfillUtilities.h"
#include "CommonTools/Images/ImageFilter.h"
#include "CommonTools/Images/BinaryImage_FilterRgb32.h"
#include "PokemonPokopia_MovesDetection.h"

namespace PokemonAutomation{
Expand All @@ -23,10 +26,12 @@ OverworldDetector::OverworldDetector(
: m_color(color)
, m_overlay(overlay)
{}

void OverworldDetector::make_overlays(VideoOverlaySet& items) const{
items.add(m_color, MOVES_LEFT_ARROW_BOX);
items.add(m_color, MOVES_RIGHT_ARROW_BOX);
}

bool OverworldDetector::detect(const ImageViewRGB32& screen){
ButtonDetector moves_left_detector(m_color, ButtonType::ButtonDpadLeft, MOVES_LEFT_ARROW_BOX, m_overlay);
ButtonDetector moves_right_detector(m_color, ButtonType::ButtonDpadRight, MOVES_RIGHT_ARROW_BOX, m_overlay);
Expand All @@ -36,6 +41,48 @@ bool OverworldDetector::detect(const ImageViewRGB32& screen){
return found;
}

PPDetector::PPDetector(
Color color,
VideoOverlay* overlay
)
: m_color(color)
, m_pp_box({0.827000, 0.772500, 0.137500, 0.075000})
{}

void PPDetector::make_overlays(VideoOverlaySet& items) const{
items.add(m_color, m_pp_box);
}

bool PPDetector::detect(const ImageViewRGB32& screen){
ImageViewRGB32 region = extract_box_reference(screen, m_pp_box);
ImageRGB32 cropped = region.copy();

const size_t box_w = cropped.width();
const size_t box_h = cropped.height();

// Apply mask to region to isolate the curved PP bar
static const ImageRGB32 mask_template(RESOURCE_PATH() + "PokemonPokopia/PPDetector-Mask.png");
ImageRGB32 mask = mask_template.scale_to(box_w, box_h);
PackedBinaryMatrix opaque = compress_rgb32_to_binary_range(mask, 0xff000000, 0xffffffff);
filter_by_mask(opaque, cropped, Color(0, 0, 0, 0), true);

// Apply filters to get percentage of bar filled and the color of the bar
std::vector<FilterRgb32Range> filters = {
{Color(0), false, 0xff000000, 0xffffffff}, // fully opaque
{Color(0), false, 0xfff0af00, 0xfffff5b9}, // yellow: RGB(240, 175, 0), RGB(255, 245, 185)
{Color(0), false, 0xff6496e6, 0xffc8d7ff}, // blue: RGB(100, 150, 230), RGB(200, 215, 255)
};
std::vector<std::pair<ImageRGB32, size_t>> filter_out = filter_rgb32_range(cropped, filters);
m_yellow_ratio = filter_out[0].second > 0 ? (double)filter_out[1].second / filter_out[0].second : 0.0;
m_blue_ratio = filter_out[0].second > 0 ? (double)filter_out[2].second / filter_out[0].second : 0.0;

if (m_yellow_ratio > 0 || m_blue_ratio > 0){
m_pp_percent = std::max(m_yellow_ratio, m_blue_ratio);
m_powered_up = m_yellow_ratio > 0.01 && m_blue_ratio < 0.01;
return true;
}
return false;
}


}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class OverworldDetector : public StaticScreenDetector{
ImageFloatBox m_last_detected;
std::optional<OverlayBoxScope> m_last_detected_box;
};

class OverworldWatcher : public DetectorToFinder<OverworldDetector>{
public:
OverworldWatcher(
Expand All @@ -50,6 +51,7 @@ class OverworldWatcher : public DetectorToFinder<OverworldDetector>{
: DetectorToFinder("OverworldWatcher", hold_duration, color, overlay)
{}
};

class OverworldGoneWatcher : public DetectorToFinder<OverworldDetector>{
public:
OverworldGoneWatcher(
Expand All @@ -61,6 +63,37 @@ class OverworldGoneWatcher : public DetectorToFinder<OverworldDetector>{
{}
};

class PPDetector : public StaticScreenDetector{
public:
PPDetector(
Color color,
VideoOverlay* overlay = nullptr
);
virtual void make_overlays(VideoOverlaySet& items) const override;
virtual bool detect(const ImageViewRGB32& screen) override;

double get_pp_percent() const { return m_pp_percent; }
bool is_powered_up() const { return m_powered_up; }

private:
Color m_color;
ImageFloatBox m_pp_box;
double m_yellow_ratio = 0.0;
double m_blue_ratio = 0.0;
double m_pp_percent = 0.0;
bool m_powered_up = false;
};

class PPWatcher : public DetectorToFinder<PPDetector>{
public:
PPWatcher(
Color color,
VideoOverlay* overlay = nullptr,
std::chrono::milliseconds hold_duration = std::chrono::milliseconds(250)
)
: DetectorToFinder("PPWatcher", hold_duration, color, overlay)
{}
};


}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

// General
#include "Programs/PokemonPokopia_CloudIslandReset.h"
#include "Programs/PokemonPokopia_AutoMiner.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
Expand Down Expand Up @@ -39,6 +40,8 @@ std::vector<PanelEntry> PanelListFactory::make_panels() const{
ret.emplace_back("---- Untested/Beta/WIP ----");
ret.emplace_back(make_single_switch_program<CloudIslandReset_Descriptor, CloudIslandReset>());
if (IS_BETA_VERSION || PreloadSettings::instance().DEVELOPER_MODE){
ret.emplace_back("---- Untested/Beta/WIP ----");
ret.emplace_back(make_single_switch_program<AutoMiner_Descriptor, AutoMiner>());
}

// if (PreloadSettings::instance().DEVELOPER_MODE){
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* Auto Miner
*
* From: https://github.com/PokemonAutomation/
*
*/

//#include "CommonFramework/Logging/Logger.h"
#include "CommonFramework/Exceptions/OperationFailedException.h"
#include "CommonFramework/ProgramStats/StatsTracking.h"
#include "CommonFramework/Tools/ErrorDumper.h"
#include "CommonTools/Async/InferenceRoutines.h"
#include "CommonTools/VisualDetectors/BlackScreenDetector.h"
#include "CommonTools/StartupChecks/VideoResolutionCheck.h"
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
#include "Pokemon/Pokemon_Strings.h"
#include "PokemonPokopia/Inference/PokemonPokopia_ButtonDetector.h"
#include "PokemonPokopia/Inference/PokemonPokopia_MovesDetection.h"
#include "PokemonPokopia/Inference/PokemonPokopia_PCDetection.h"
#include "PokemonPokopia/Inference/PokemonPokopia_SettingsScreenDetector.h"
#include "CommonFramework/Notifications/ProgramNotifications.h"

#include "PokemonPokopia/Programs/PokemonPokopia_PCNavigation.h"
#include "PokemonPokopia/Programs/PokemonPokopia_AutoMiner.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonPokopia{

using namespace Pokemon;


AutoMiner_Descriptor::AutoMiner_Descriptor()
: SingleSwitchProgramDescriptor(
"PokemonPokopia:AutoMiner",
STRING_POKEMON + " Pokopia", "Auto Miner",
"Programs/PokemonPokopia/AutoMiner.html",
"Automatically mine resources on a Dream Island.",
ProgramControllerClass::StandardController_NoRestrictions,
FeedbackType::REQUIRED,
AllowCommandsWhenRunning::DISABLE_COMMANDS
)
{}
class AutoMiner_Descriptor::Stats : public StatsTracker{
public:
Stats()
: errors(m_stats["Errors"])
{
m_display_order.emplace_back("Errors", HIDDEN_IF_ZERO);
}

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


AutoMiner::AutoMiner()
: GO_HOME_WHEN_DONE(false)
, NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600))
, NOTIFICATIONS({
&NOTIFICATION_STATUS_UPDATE,
&NOTIFICATION_PROGRAM_FINISH,
&NOTIFICATION_ERROR_FATAL,
})
{
PA_ADD_OPTION(GO_HOME_WHEN_DONE);
PA_ADD_OPTION(NOTIFICATIONS);
}

void AutoMiner::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
assert_16_9_720p_min(env.logger(), env.console);

// AutoMiner_Descriptor::Stats& stats = env.current_stats<AutoMiner_Descriptor::Stats>();

PPWatcher pp_watcher(COLOR_YELLOW, &env.console.overlay());
wait_until(
env.console, context,
60s,
{pp_watcher}
);
env.console.log("percent: " + std::to_string(pp_watcher.get_pp_percent() * 100) + "%, powered up: " + (pp_watcher.is_powered_up() ? "yes" : "no"));

send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH);
GO_HOME_WHEN_DONE.run_end_of_program(context);
}



}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* Auto Miner
*
* From: https://github.com/PokemonAutomation/
*
*/

#ifndef PokemonAutomation_PokemonPokopia_AutoMiner_H
#define PokemonAutomation_PokemonPokopia_AutoMiner_H

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

namespace PokemonAutomation{

template <typename Type> class ControllerContext;

namespace NintendoSwitch{

class ProController;
using ProControllerContext = ControllerContext<ProController>;

namespace PokemonPokopia{


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

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


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

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

private:

private:
GoHomeWhenDoneOption GO_HOME_WHEN_DONE;

EventNotificationOption NOTIFICATION_STATUS_UPDATE;
EventNotificationsOption NOTIFICATIONS;
};



}
}
}
#endif
2 changes: 2 additions & 0 deletions SerialPrograms/cmake/SourceFiles.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1994,6 +1994,8 @@ file(GLOB LIBRARY_SOURCES
Source/PokemonPokopia/PokemonPokopia_Panels.h
Source/PokemonPokopia/PokemonPokopia_Settings.cpp
Source/PokemonPokopia/PokemonPokopia_Settings.h
Source/PokemonPokopia/Programs/PokemonPokopia_AutoMiner.cpp
Source/PokemonPokopia/Programs/PokemonPokopia_AutoMiner.h
Source/PokemonPokopia/Programs/PokemonPokopia_CloudIslandReset.cpp
Source/PokemonPokopia/Programs/PokemonPokopia_CloudIslandReset.h
Source/PokemonPokopia/Programs/PokemonPokopia_PCNavigation.cpp
Expand Down
Loading