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 @@ -40,6 +40,22 @@ void TrainerIdReader::make_overlays(VideoOverlaySet &items) const {

uint16_t TrainerIdReader::read_tid(
Logger& logger, Language language, const ImageViewRGB32& frame
){
return uint16_t(read_tid_digits(logger, language, frame));
}

std::optional<uint16_t> TrainerIdReader::try_read_tid(
Logger& logger, Language language, const ImageViewRGB32& frame
){
const int tid = read_tid_digits(logger, language, frame);
if (tid < 0 || tid > 0xffff){
return std::nullopt;
}
return uint16_t(tid);
}

int TrainerIdReader::read_tid_digits(
Logger& logger, Language language, const ImageViewRGB32& frame
){
ImageViewRGB32 game_screen =
extract_box_reference(frame, GameSettings::instance().GAME_BOX);
Expand All @@ -52,7 +68,7 @@ uint16_t TrainerIdReader::read_tid(

// waterfill segmentation + template matching
// against the PokemonFRLG/Digits/0-9.png templates.
return uint16_t(read_digits_waterfill_template(logger, tid_region, DigitTemplateType::DialogBox));
return read_digits_waterfill_template(logger, tid_region, DigitTemplateType::DialogBox);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,16 @@ class TrainerIdReader {
uint16_t read_tid(
Logger& logger, Language language, const ImageViewRGB32& frame
);
// As read_tid(), but nothing when the digits can't be read or are more
// than a TID can be, instead of a wrapped-around number.
std::optional<uint16_t> try_read_tid(
Logger& logger, Language language, const ImageViewRGB32& frame
);

private:
// The digits read, or -1.
int read_tid_digits(Logger& logger, Language language, const ImageViewRGB32& frame);

Color m_color;
ImageFloatBox m_box_tid;
ImageFloatBox m_box_tid_spa;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/* Trainer Card
*
* From: https://github.com/PokemonAutomation/
*
*/

#include "CommonFramework/Exceptions/OperationFailedExceptionWithScreenshot.h"
#include "CommonFramework/VideoPipeline/VideoFeed.h"
#include "CommonFramework/VideoPipeline/VideoOverlay.h"
#include "CommonTools/Async/InferenceRoutines.h"
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
#include "VideoGames/PokemonFRLG/Inference/Menus/PokemonFRLG_TrainerCardDetector.h"
#include "VideoGames/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.h"
#include "PokemonFRLG_StartMenuNavigation.h"
#include "PokemonFRLG_TrainerCard.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonFRLG{


void navigate_to_trainer_card(ConsoleHandle& console, ProControllerContext& context){

Check warning on line 22 in SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_TrainerCard.cpp

View workflow job for this annotation

GitHub Actions / code-health

Code health (advisory)

PokemonAutomation::NintendoSwitch::PokemonFRLG::navigate_to_trainer_card( ConsoleHandle & console , ProControllerContext & context): function_lines=42 (advisory above 25, limit 50)
int errors = 0;
while (true){
if (errors >= 5){
OperationFailedExceptionWithScreenshot::fire(
ErrorReportMode::SEND_ERROR_REPORT, "navigate_to_trainer_card(): failed 5 times to navigate to the Trainer Card", console
);
}

open_start_menu(console, context);

// the positions are different before recieving a Pokemon and Pokedex
bool cursor = move_cursor_to_position(
console, context, SelectionArrowPositionStartMenu(1)
);
if (!cursor){
errors++;
pbf_mash_button(context, BUTTON_B, 2000ms);
continue;
}

TrainerCardWatcher trainer_card(COLOR_RED);
context.wait_for_all_requests();
int ret = run_until<ProControllerContext>(
console, context,
[](ProControllerContext& context){
pbf_press_button(context, BUTTON_A, 200ms, 2300ms);
pbf_press_button(context, BUTTON_A, 200ms, 2300ms);
},
{ trainer_card }
);

if (ret < 0){
console.log("navigate_to_trainer_card(): failed to detect Trainer Card");
errors++;
pbf_mash_button(context, BUTTON_B, 2000ms);
continue;
}

break;
}
}

namespace{

template <typename Read>
auto read_on_card(ConsoleHandle& console, ProControllerContext& context, Read read){
TrainerIdReader reader;
VideoOverlaySet overlays(console.overlay());
reader.make_overlays(overlays);

VideoSnapshot screen = console.video().snapshot();
console.log("Trainer Card detected.");
console.log("Reading TID...");
auto tid = read(reader, screen);

context.wait_for_all_requests();

return tid;
}

}

Check failure on line 83 in SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_TrainerCard.cpp

View workflow job for this annotation

GitHub Actions / code-health

Code health

namespace-close: close this namespace with // namespace

uint16_t read_trainer_card_tid(ConsoleHandle& console, ProControllerContext& context, Language language){
uint16_t tid = read_on_card(console, context, [&](TrainerIdReader& reader, const VideoSnapshot& screen){
return reader.read_tid(console.logger(), language, screen);
});
console.log("TID: " + std::to_string(tid));
return tid;
}

std::optional<uint16_t> try_read_trainer_card_tid(ConsoleHandle& console, ProControllerContext& context, Language language){
std::optional<uint16_t> tid = read_on_card(console, context, [&](TrainerIdReader& reader, const VideoSnapshot& screen){
return reader.try_read_tid(console.logger(), language, screen);
});
console.log(tid ? "TID: " + std::to_string(*tid) : std::string("TID: not read"));
return tid;
}



}

Check failure on line 103 in SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_TrainerCard.cpp

View workflow job for this annotation

GitHub Actions / code-health

Code health

namespace-close: close this namespace with // namespace PokemonFRLG
}

Check failure on line 104 in SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_TrainerCard.cpp

View workflow job for this annotation

GitHub Actions / code-health

Code health

namespace-close: close this namespace with // namespace NintendoSwitch
}

Check failure on line 105 in SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_TrainerCard.cpp

View workflow job for this annotation

GitHub Actions / code-health

Code health

namespace-close: close this namespace with // namespace PokemonAutomation
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* Trainer Card
*
* From: https://github.com/PokemonAutomation/
*
* Opening the Trainer Card from the overworld and reading the TID on it,
* as SID Helper does. Shared with AutoStory, which reads the TID for its
* Starter RNG plan.
*
*/

#ifndef PokemonAutomation_PokemonFRLG_TrainerCard_H
#define PokemonAutomation_PokemonFRLG_TrainerCard_H

#include <cstdint>
#include <optional>
#include "CommonFramework/Language.h"
#include "NintendoSwitch/Controllers/Procon/NintendoSwitch_ProController.h"
#include "NintendoSwitch/NintendoSwitch_ConsoleHandle.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonFRLG{


// From the overworld, START then the player's entry, until the card shows.
// The entry is second only before the first Pokemon and the Pokedex.
// Throws OperationFailedException after 5 failed tries.
void navigate_to_trainer_card(ConsoleHandle& console, ProControllerContext& context);

// The TID on the Trainer Card on screen. An unreadable TID comes back as
// TrainerIdReader::read_tid() returns it.
uint16_t read_trainer_card_tid(ConsoleHandle& console, ProControllerContext& context, Language language);
// Nothing when the TID can't be read.
std::optional<uint16_t> try_read_trainer_card_tid(ConsoleHandle& console, ProControllerContext& context, Language language);



}

Check failure on line 38 in SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_TrainerCard.h

View workflow job for this annotation

GitHub Actions / code-health

Code health

namespace-close: close this namespace with // namespace PokemonFRLG
}

Check failure on line 39 in SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_TrainerCard.h

View workflow job for this annotation

GitHub Actions / code-health

Code health

namespace-close: close this namespace with // namespace NintendoSwitch
}

Check failure on line 40 in SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_TrainerCard.h

View workflow job for this annotation

GitHub Actions / code-health

Code health

namespace-close: close this namespace with // namespace PokemonAutomation
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "VideoGames/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.h"
#include "VideoGames/PokemonFRLG/PokemonFRLG_Navigation.h"
#include "VideoGames/PokemonFRLG/Programs/PokemonFRLG_StartMenuNavigation.h"
#include "VideoGames/PokemonFRLG/Programs/PokemonFRLG_TrainerCard.h"
#include "PokemonFRLG_RngCalibration.h"
#include "PokemonFRLG_SidHelper.h"

Expand Down Expand Up @@ -168,65 +169,6 @@ void finish_intro_animations(SingleSwitchProgramEnvironment& env, ProControllerC
context.wait_for_all_requests();
}

void navigate_to_trainer_card(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
int errors = 0;
while (true){
if (errors >= 5){
OperationFailedExceptionWithScreenshot::fire(
ErrorReportMode::SEND_ERROR_REPORT, "SidHelper(): failed 5 times to navigate to the Trainer Card", env.console
);
}

open_start_menu(env.console, context);

// the positions are different before recieving a Pokemon and Pokedex
bool cursor = move_cursor_to_position(
env.console, context, SelectionArrowPositionStartMenu(1)
);
if (!cursor){
errors++;
pbf_mash_button(context, BUTTON_B, 2000ms);
continue;
}

TrainerCardWatcher trainer_card(COLOR_RED);
context.wait_for_all_requests();
int ret = run_until<ProControllerContext>(
env.console, context,
[](ProControllerContext& context){
pbf_press_button(context, BUTTON_A, 200ms, 2300ms);
pbf_press_button(context, BUTTON_A, 200ms, 2300ms);
},
{ trainer_card }
);

if (ret < 0){
env.log("SidHelper(): failed to detect Trainer Card");
errors++;
pbf_mash_button(context, BUTTON_B, 2000ms);
continue;
}

break;
}
}

uint16_t read_tid(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language lang){
TrainerIdReader reader;
VideoOverlaySet overlays(env.console.overlay());
reader.make_overlays(overlays);

VideoSnapshot screen = env.console.video().snapshot();
env.log("Trainer Card detected.");
env.log("Reading TID...");
uint16_t tid = reader.read_tid(env.logger(), lang, screen);
env.log("TID: " + std::to_string(tid));

context.wait_for_all_requests();

return tid;
}

std::vector<std::pair<std::string, std::string>> get_sid_messages(
SingleSwitchProgramEnvironment& env,
ProControllerContext& context,
Expand Down Expand Up @@ -310,9 +252,9 @@ void SidHelper::program(SingleSwitchProgramEnvironment& env, ProControllerContex

set_sid_from_name_screen(env, context, SID_DELAY, extra_press_at_end);
finish_intro_animations(env, context);
navigate_to_trainer_card(env, context);
navigate_to_trainer_card(env.console, context);

uint16_t tid = read_tid(env, context, lang);
uint16_t tid = read_trainer_card_tid(env.console, context, lang);

std::vector<std::pair<std::string, std::string>> sid_messages = get_sid_messages(
env, context, tid, TARGET_ADVANCES, NUM_CANDIDATES
Expand Down
2 changes: 2 additions & 0 deletions SerialPrograms/cmake/SourceFiles.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1795,6 +1795,8 @@ file(GLOB LIBRARY_SOURCES
Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_SafariOptimalAction.h
Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_StartMenuNavigation.cpp
Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_StartMenuNavigation.h
Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_TrainerCard.cpp
Source/VideoGames/PokemonFRLG/Programs/PokemonFRLG_TrainerCard.h
Source/VideoGames/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp
Source/VideoGames/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.h
Source/VideoGames/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_EggRng.cpp
Expand Down
Loading