diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.cpp index b68c4563df..799ea19442 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.cpp @@ -26,6 +26,7 @@ namespace PokemonFRLG { TrainerIdReader::TrainerIdReader(Color color) : m_color(color) , m_box_tid(0.742683, 0.117314, 0.129734, 0.076006) + , m_box_tid_jpn(0.712981, 0.118836, 0.207212, 0.077373) {} void TrainerIdReader::make_overlays(VideoOverlaySet &items) const { @@ -34,13 +35,13 @@ void TrainerIdReader::make_overlays(VideoOverlaySet &items) const { } uint16_t TrainerIdReader::read_tid( - Logger &logger, const ImageViewRGB32 &frame + Logger& logger, Language language, const ImageViewRGB32& frame ){ ImageViewRGB32 game_screen = extract_box_reference(frame, GameSettings::instance().GAME_BOX); - ImageViewRGB32 tid_region = extract_box_reference(game_screen, m_box_tid); + ImageViewRGB32 tid_region = extract_box_reference(game_screen, language == Language::Japanese ? m_box_tid_jpn : m_box_tid); if (!GlobalSettings::instance().USE_PADDLE_OCR){ // Tesseract-free path: waterfill segmentation + template matching diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.h b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.h index e8b00cf8cc..c33fdbcbe1 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.h +++ b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.h @@ -31,13 +31,13 @@ class TrainerIdReader { // Reads the Trainer ID on the Trainer Card uint16_t read_tid( - Logger &logger, const ImageViewRGB32 &frame + Logger& logger, Language language, const ImageViewRGB32& frame ); private: Color m_color; ImageFloatBox m_box_tid; - + ImageFloatBox m_box_tid_jpn; }; } // namespace PokemonFRLG diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp index f2e06aac71..621f81a657 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp @@ -22,7 +22,7 @@ void set_seed_after_delay(ProControllerContext& context, SeedButton SEED_BUTTON, switch (console_type){ case ConsoleType::Switch1: // Switch 1 enters the game a little bit earlier - pbf_wait(context, 755ms); + pbf_wait(context, 750ms); break; default: break; diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_GiftRng.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_GiftRng.cpp index 4656f249a3..dc0da6120c 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_GiftRng.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_GiftRng.cpp @@ -539,7 +539,8 @@ void GiftRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& RngAdvanceHistory ADVANCE_HISTORY; RngCalibrationHistory CALIBRATION_HISTORY; uint64_t INITIAL_ADVANCES_RADIUS = USE_TEACHY_TV ? 8192 : 1024; - uint64_t resets = 0; + + uint16_t failed_searches = 0; while (true){ if (CALIBRATION_HISTORY.results.size() > 0){ @@ -552,7 +553,17 @@ void GiftRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& env.log("Missed target."); } - if (resets > MAX_RESETS){ + if (failed_searches >= 5){ + env.log("Failed to find any matches 5 times in a row"); + OperationFailedException::fire( + ErrorReport::NO_ERROR_REPORT, + "Failed to find any matches 5 times in a row. Check your seed and advances settings.", + env.console + ); + break; + } + + if (stats.resets > MAX_RESETS){ env.log("Max resets reached."); break; } @@ -670,6 +681,11 @@ void GiftRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& bool finished = update_history(env.console, ADVANCE_HISTORY, CALIBRATION_HISTORY, MAX_HISTORY_LENGTH, SEED_CALIBRATION_FRAMES, ADVANCES_CALIBRATION, CONTINUE_SCREEN_ADJUSTMENT, search_hits, 1); if (finished || (MAX_RARE_CANDIES == 0)){ env.log("RNG search finished."); + if (search_hits.size() == 0){ + failed_searches++; + }else{ + failed_searches = 0; + } continue; } @@ -694,6 +710,12 @@ void GiftRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& ); if (finished){ + env.log("RNG Search finished"); + if (search_hits.size() == 0){ + failed_searches++; + }else{ + failed_searches = 0; + } break; } } diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp index 9f4a8863a9..ac902fe525 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp @@ -72,7 +72,7 @@ SidHelper::SidHelper() "The target advances for finalizing the SID. This is arbitrary unless you're attempting to hit a specific TID/SID combination.
" "This value should always be odd.", LockMode::LOCK_WHILE_RUNNING, - 2301, 2275 // default, min + 3001, 2275 // default, min ) , NUM_CANDIDATES( "# Candidate SIDs:
" @@ -125,8 +125,8 @@ void set_sid_from_name_screen( ); if (extra_press_at_end){ - pbf_press_button(context, BUTTON_A, 200ms, 800ms); - delay = delay > 1000ms ? delay - 1000ms : 0ms; + pbf_press_button(context, BUTTON_A, 200ms, 1300ms); + delay = delay > 1500ms ? delay - 1500ms : 0ms; } pbf_press_button(context, BUTTON_A, 200ms, delay); @@ -209,7 +209,7 @@ void navigate_to_trainer_card(SingleSwitchProgramEnvironment& env, ProController } } -uint16_t read_tid(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ +uint16_t read_tid(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language lang){ TrainerIdReader reader; VideoOverlaySet overlays(env.console.overlay()); reader.make_overlays(overlays); @@ -217,7 +217,7 @@ uint16_t read_tid(SingleSwitchProgramEnvironment& env, ProControllerContext& con VideoSnapshot screen = env.console.video().snapshot(); env.log("Trainer Card detected."); env.log("Reading TID..."); - uint16_t tid = reader.read_tid(env.logger(), screen); + uint16_t tid = reader.read_tid(env.logger(), lang, screen); env.log("TID: " + std::to_string(tid)); context.wait_for_all_requests(); @@ -299,7 +299,10 @@ void SidHelper::program(SingleSwitchProgramEnvironment& env, ProControllerContex const double& FIXED_ADVANCES_OFFSET = 7; // determined empirically. Probably not console/setup dependent - bool extra_press_at_end = (LANGUAGE == Language::German); + bool extra_press_at_end = ( + LANGUAGE == Language::German || + LANGUAGE == Language::Japanese + ); const uint64_t SID_DELAY = uint64_t((TARGET_ADVANCES - 2*FINAL_TEXT_FRAMES + FIXED_ADVANCES_OFFSET) * FRAME_DURATION / 2); // advances pass 2 by 2 env.log("Delay: " + std::to_string(SID_DELAY) + "ms"); @@ -308,7 +311,7 @@ void SidHelper::program(SingleSwitchProgramEnvironment& env, ProControllerContex finish_intro_animations(env, context); navigate_to_trainer_card(env, context); - uint16_t tid = read_tid(env, context); + uint16_t tid = read_tid(env, context, lang); std::vector> sid_messages = get_sid_messages( env, context, tid, TARGET_ADVANCES, NUM_CANDIDATES diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp index 084c4ca8e1..91e886ca68 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp @@ -688,9 +688,10 @@ void StarterRng::program(SingleSwitchProgramEnvironment& env, ProControllerConte RngAdvanceHistory ADVANCE_HISTORY; RngCalibrationHistory CALIBRATION_HISTORY; uint64_t INITIAL_ADVANCES_RADIUS = 1024; - uint64_t resets = 0; bool wildshiny_found = false; + uint16_t failed_searches = 0; + while (true){ if (CALIBRATION_HISTORY.results.size() > 0){ env.log("Checking for nonshiny target hit..."); @@ -702,7 +703,17 @@ void StarterRng::program(SingleSwitchProgramEnvironment& env, ProControllerConte env.log("Missed target."); } - if (resets > MAX_RESETS){ + if (failed_searches >= 5){ + env.log("Failed to find any matches 5 times in a row"); + OperationFailedException::fire( + ErrorReport::NO_ERROR_REPORT, + "Failed to find any matches 5 times in a row. Check your seed and advances settings.", + env.console + ); + break; + } + + if (stats.resets > MAX_RESETS){ env.log("Max resets reached."); break; } @@ -812,6 +823,11 @@ void StarterRng::program(SingleSwitchProgramEnvironment& env, ProControllerConte bool finished = update_history(env.console, ADVANCE_HISTORY, CALIBRATION_HISTORY, MAX_HISTORY_LENGTH, SEED_CALIBRATION_FRAMES, ADVANCES_CALIBRATION, CONTINUE_SCREEN_ADJUSTMENT, search_hits, 1); if (finished){ env.log("RNG search finished."); + if (search_hits.size() == 0){ + failed_searches++; + }else{ + failed_searches = 0; + } continue; } @@ -838,6 +854,11 @@ void StarterRng::program(SingleSwitchProgramEnvironment& env, ProControllerConte finished = update_history(env.console, ADVANCE_HISTORY, CALIBRATION_HISTORY, MAX_HISTORY_LENGTH, SEED_CALIBRATION_FRAMES, ADVANCES_CALIBRATION, CONTINUE_SCREEN_ADJUSTMENT, search_hits, 5); if (finished){ env.log("RNG search finished."); + if (search_hits.size() == 0){ + failed_searches++; + }else{ + failed_searches = 0; + } continue; } } @@ -898,6 +919,11 @@ void StarterRng::program(SingleSwitchProgramEnvironment& env, ProControllerConte finished = update_history(env.console, ADVANCE_HISTORY, CALIBRATION_HISTORY, MAX_HISTORY_LENGTH, SEED_CALIBRATION_FRAMES, ADVANCES_CALIBRATION, CONTINUE_SCREEN_ADJUSTMENT, search_hits, 5); if (finished){ env.log("RNG search finished."); + if (search_hits.size() == 0){ + failed_searches++; + }else{ + failed_searches = 0; + } break; } } diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StaticRng.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StaticRng.cpp index e674c2262a..86a5333e14 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StaticRng.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StaticRng.cpp @@ -677,7 +677,8 @@ void StaticRng::program(SingleSwitchProgramEnvironment& env, ProControllerContex RngAdvanceHistory ADVANCE_HISTORY; RngCalibrationHistory CALIBRATION_HISTORY; uint64_t INITIAL_ADVANCES_RADIUS = USE_TEACHY_TV ? 8192 : 1024; - uint64_t resets = 0; + + uint16_t failed_searches = 0; while (true){ if (CALIBRATION_HISTORY.results.size() > 0){ @@ -690,7 +691,17 @@ void StaticRng::program(SingleSwitchProgramEnvironment& env, ProControllerContex env.log("Missed target."); } - if (resets > MAX_RESETS){ + if (failed_searches >= 5){ + env.log("Failed to find any matches 5 times in a row"); + OperationFailedException::fire( + ErrorReport::NO_ERROR_REPORT, + "Failed to find any matches 5 times in a row. Check your seed and advances settings.", + env.console + ); + break; + } + + if (stats.resets > MAX_RESETS){ env.log("Max resets reached."); break; } @@ -814,6 +825,11 @@ void StaticRng::program(SingleSwitchProgramEnvironment& env, ProControllerContex bool finished = update_history(env.console, ADVANCE_HISTORY, CALIBRATION_HISTORY, MAX_HISTORY_LENGTH, SEED_CALIBRATION_FRAMES, ADVANCES_CALIBRATION, CONTINUE_SCREEN_ADJUSTMENT, search_hits, 1); if (finished || (MAX_RARE_CANDIES == 0)){ env.log("RNG search finished."); + if (search_hits.size() == 0){ + failed_searches++; + }else{ + failed_searches = 0; + } continue; } @@ -838,6 +854,12 @@ void StaticRng::program(SingleSwitchProgramEnvironment& env, ProControllerContex ); if (finished){ + env.log("RNG Search finished"); + if (search_hits.size() == 0){ + failed_searches++; + }else{ + failed_searches = 0; + } break; } } diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_WildRng.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_WildRng.cpp index 4b6cebc004..5a0685f0a9 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_WildRng.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_WildRng.cpp @@ -722,7 +722,8 @@ void WildRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& RngAdvanceHistory ADVANCE_HISTORY; RngCalibrationHistory CALIBRATION_HISTORY; uint64_t INITIAL_ADVANCES_RADIUS = USE_TEACHY_TV ? 8192 : 1024; - uint64_t resets = 0; + + uint16_t failed_searches = 0; while (true){ if (CALIBRATION_HISTORY.results.size() > 0){ @@ -735,7 +736,17 @@ void WildRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& env.log("Missed target."); } - if (resets > MAX_RESETS){ + if (failed_searches >= 5){ + env.log("Failed to find any matches 5 times in a row"); + OperationFailedException::fire( + ErrorReport::NO_ERROR_REPORT, + "Failed to find any matches 5 times in a row. Check your seed and advances settings.", + env.console + ); + break; + } + + if (stats.resets > MAX_RESETS){ env.log("Max resets reached."); break; } @@ -877,6 +888,11 @@ void WildRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& finished = finished || all_indistinguishable(search_hits, searcher, SUPER_ROD); if (finished || (MAX_RARE_CANDIES == 0)){ env.log("RNG search finished."); + if (search_hits.size() == 0){ + failed_searches++; + }else{ + failed_searches = 0; + } continue; } @@ -902,6 +918,12 @@ void WildRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& finished = finished || all_indistinguishable(search_hits, searcher, SUPER_ROD); if (finished){ + env.log("RNG Search finished"); + if (search_hits.size() == 0){ + failed_searches++; + }else{ + failed_searches = 0; + } break; } } diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/TestPrograms/PokemonFRLG_ReadTrainerId.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/TestPrograms/PokemonFRLG_ReadTrainerId.cpp index a2d365f1c9..f1765a8a5a 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/TestPrograms/PokemonFRLG_ReadTrainerId.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/TestPrograms/PokemonFRLG_ReadTrainerId.cpp @@ -36,7 +36,23 @@ ReadTrainerId_Descriptor::ReadTrainerId_Descriptor() ){} ReadTrainerId::ReadTrainerId() -{} + : LANGUAGE( + "Game Language:
" + "Language affects the number of advances (based on the number of text characters) that pass after the last button press.", + { + Language::English, + Language::Japanese, + Language::Spanish, + Language::French, + Language::German, + Language::Italian, + }, + LockMode::LOCK_WHILE_RUNNING, + true + ) +{ + PA_ADD_OPTION(LANGUAGE); +} void ReadTrainerId::program( SingleSwitchProgramEnvironment &env, @@ -56,7 +72,7 @@ void ReadTrainerId::program( if (trainercard){ env.log("Trainer Card detected."); env.log("Reading TID..."); - uint16_t tid = reader.read_tid(env.logger(), screen); + uint16_t tid = reader.read_tid(env.logger(), LANGUAGE, screen); env.log("TID: " + std::to_string(tid)); }else{ env.log("Trainer Card not detected!"); diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/TestPrograms/PokemonFRLG_ReadTrainerId.h b/SerialPrograms/Source/PokemonFRLG/Programs/TestPrograms/PokemonFRLG_ReadTrainerId.h index fff3c2c268..54886c3e71 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/TestPrograms/PokemonFRLG_ReadTrainerId.h +++ b/SerialPrograms/Source/PokemonFRLG/Programs/TestPrograms/PokemonFRLG_ReadTrainerId.h @@ -33,6 +33,8 @@ class ReadTrainerId : public SingleSwitchProgramInstance{ VideoStream &stream, FeedbackType feedback_type ) override{} +private: + OCR::LanguageOCROption LANGUAGE; }; } // namespace PokemonFRLG