diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp index 621f81a657..b21b289777 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp @@ -86,14 +86,15 @@ void wait_with_teachy_tv(ProControllerContext& context, uint64_t TEACHY_DELAY){ pbf_press_button(context, BUTTON_A, 200ms, 2300ms); pbf_move_left_joystick(context, {+1, 0}, 200ms, 2300ms); pbf_press_button(context, BUTTON_A, 200ms, 300ms); - pbf_press_button(context, BUTTON_A, 200ms, std::chrono::milliseconds(TEACHY_DELAY)); + pbf_press_button(context, BUTTON_A, 200ms, 367ms); // the "static fuzz" that adds RNG advances doesn't kick in right away + pbf_wait(context, std::chrono::milliseconds(TEACHY_DELAY)); // close teachy tv -> close bag -> reset start menu cursor position - > close start menu pbf_press_button(context, BUTTON_B, 200ms, 2300ms); pbf_press_button(context, BUTTON_B, 200ms, 2300ms); pbf_move_left_joystick(context, {0, +1}, 200ms, 300ms); pbf_move_left_joystick(context, {0, +1}, 200ms, 300ms); pbf_press_button(context, BUTTON_B, 200ms, 300ms); - // total non-teachy delay duration: 13700ms + // total non-teachy delay duration: 14067ms } @@ -384,10 +385,10 @@ void check_timings( console ); } - if (SEED_DELAY < 29500){ + if (SEED_DELAY < 30000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "The title screen delay cannot be less than 29.5s. Check your seed calibration.", + "The title screen delay cannot be less than 30s. Check your seed delay and calibration.", console ); } @@ -397,7 +398,7 @@ void check_timings( if (INGAME_DELAY < 7500){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Starters: the in-game delay cannot be less than 7500ms (900 advances). Check your in-game advances and calibration.", + "Starters: the in-game delay cannot be less than 7500ms (740 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -406,7 +407,7 @@ void check_timings( if (INGAME_DELAY < 7500){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Magikarp: the in-game delay cannot be less than 7500ms (900 advances). Check your in-game advances and calibration.", + "Magikarp: the in-game delay cannot be less than 7500ms (740 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -417,7 +418,7 @@ void check_timings( if (INGAME_DELAY < 4500){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Hitmonchan/Hitmonlee: the in-game delay cannot be less than 4500ms (540 advances). Check your in-game advances and calibration.", + "Hitmonchan/Hitmonlee: the in-game delay cannot be less than 4500ms (380 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -426,7 +427,7 @@ void check_timings( if (INGAME_DELAY < 4000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Eevee: the in-game delay cannot be less than 4000ms (480 advances). Check your in-game advances and calibration.", + "Eevee: the in-game delay cannot be less than 4000ms (320 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -435,7 +436,7 @@ void check_timings( if (INGAME_DELAY < 7500){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Lapras: the in-game delay cannot be less than 7500ms (900 advances). Check your in-game advances and calibration.", + "Lapras: the in-game delay cannot be less than 7500ms (740 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -447,7 +448,7 @@ void check_timings( if (INGAME_DELAY < 6000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Fossils: the in-game delay cannot be less than 6000ms (720 advances). Check your in-game advances and calibration.", + "Fossils: the in-game delay cannot be less than 6000ms (560 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -462,7 +463,7 @@ void check_timings( if (INGAME_DELAY < 8500){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Game Corner: the in-game delay cannot be less than 8500ms (1020 advances). Check your in-game advances and calibration.", + "Game Corner: the in-game delay cannot be less than 8500ms (860 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -471,7 +472,7 @@ void check_timings( if (INGAME_DELAY < 12000) { OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Togepi: the in-game delay cannot be less than 12000ms (1440 advances). Check your in-game advances and calibration.", + "Togepi: the in-game delay cannot be less than 12000ms (1280 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -480,7 +481,7 @@ void check_timings( if (INGAME_DELAY < 5000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Static Encounter: the in-game delay cannot be less than 5000ms (600 advances). Check your in-game advances and calibration.", + "Static Encounter: the in-game delay cannot be less than 5000ms (440 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -489,7 +490,7 @@ void check_timings( if (INGAME_DELAY < 16000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Snorlax: the in-game delay cannot be less than 16000ms (1920 advances). Check your in-game advances and calibration.", + "Snorlax: the in-game delay cannot be less than 16000ms (1760 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -498,7 +499,7 @@ void check_timings( if (INGAME_DELAY < 4500){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Mewtwo: the in-game delay cannot be less than 4500ms (540 advances). Check your in-game advances and calibration.", + "Mewtwo: the in-game delay cannot be less than 4500ms (380 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -507,7 +508,7 @@ void check_timings( if (INGAME_DELAY < 4000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Ho-oh: the in-game delay cannot be less than 4000ms (480 advances). Check your in-game advances and calibration.", + "Ho-oh: the in-game delay cannot be less than 4000ms (320 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -516,7 +517,7 @@ void check_timings( if (INGAME_DELAY < 13000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Hypno: the in-game delay cannot be less than 13000ms (1560 advances). Check your in-game advances and calibration.", + "Hypno: the in-game delay cannot be less than 13000ms (1400 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -525,13 +526,13 @@ void check_timings( if (!SAFARI_ZONE && INGAME_DELAY < 8500){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Sweet Scent: the in-game delay cannot be less than 8500ms (1020 advances). Check your in-game advances and calibration.", + "Sweet Scent: the in-game delay cannot be less than 8500ms (1372 advances). Check your in-game advances and calibration or pick a new target.", console ); }else if (SAFARI_ZONE && INGAME_DELAY < 9500){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Sweet Scent: the in-game delay cannot be less than 9500ms (1140 advances). Check your in-game advances and calibration.", + "Sweet Scent: the in-game delay cannot be less than 9500ms (1492 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -540,7 +541,7 @@ void check_timings( if (INGAME_DELAY < 6500){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Rock Smash: the in-game delay cannot be less than 7000ms (840 advances). Check your in-game advances and calibration.", + "Rock Smash: the in-game delay cannot be less than 7000ms (1192 advances). Check your in-game advances and calibration or pick a new target.", console ); } @@ -548,61 +549,61 @@ void check_timings( if (INGAME_DELAY < 5500){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Fishing: the in-game delay cannot be less than 5500ms (660 advances). Check your in-game advances and calibration.", + "Fishing: the in-game delay cannot be less than 5500ms (500 advances). Check your in-game advances and calibration or pick a new target.", console ); } return; case PokemonFRLG_RngTarget::safarizonecenter: - if (INGAME_DELAY < 30500){ + if (INGAME_DELAY < 39000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Safari Zone Center: in-game delay cannot be less than 30500ms (3660 advances). Check your in-game advances and calibration.", + "Safari Zone Center: in-game delay cannot be less than 39000ms (5032 advances). Check your in-game advances and calibration or pick a new target.", console ); } return; case PokemonFRLG_RngTarget::safarizoneeast: - if (INGAME_DELAY < 36500){ + if (INGAME_DELAY < 45000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Safari Zone East: in-game delay cannot be less than 36500ms (4380 advances). Check your in-game advances and calibration.", + "Safari Zone East: in-game delay cannot be less than 45000ms (5752 advances). Check your in-game advances and calibration or pick a new target.", console ); } return; case PokemonFRLG_RngTarget::safarizonenorth: - if (INGAME_DELAY < 47500){ + if (INGAME_DELAY < 46000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Safari Zone North: in-game delay cannot be less than 47500ms (5700 advances). Check your in-game advances and calibration.", + "Safari Zone North: in-game delay cannot be less than 46000ms (5872 advances). Check your in-game advances and calibration or pick a new target.", console ); } return; case PokemonFRLG_RngTarget::safarizonewest: - if (INGAME_DELAY < 61500){ + if (INGAME_DELAY < 60000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Safari Zone West: in-game delay cannot be less than 52000ms (7380 advances). Check your in-game advances and calibration.", + "Safari Zone West: in-game delay cannot be less than 60000ms (7552 advances). Check your in-game advances and calibration or pick a new target.", console ); } return; case PokemonFRLG_RngTarget::safarizonesurf: - if (INGAME_DELAY < 40500){ + if (INGAME_DELAY < 46000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Safari Zone Surfing: in-game delay cannot be less than 40500ms (4860 advances). Check your in-game advances and calibration.", + "Safari Zone Surfing: in-game delay cannot be less than 46000ms (5872 advances). Check your in-game advances and calibration or pick a new target.", console ); } return; case PokemonFRLG_RngTarget::safarizonefish: - if (INGAME_DELAY < 30000){ + if (INGAME_DELAY < 35000){ OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, - "Safari Zone Fishing: in-game delay cannot be less than 30000ms (3600 advances). Check your in-game advances and calibration.", + "Safari Zone Fishing: in-game delay cannot be less than 35000ms (4040 advances). Check your in-game advances and calibration or pick a new target.", console ); } diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_GiftRng.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_GiftRng.cpp index b2aa39dc6c..615838cba2 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_GiftRng.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_GiftRng.cpp @@ -161,7 +161,7 @@ GiftRng::GiftRng() , ADVANCES( "Advances:
The total number of RNG advances for your target.", LockMode::LOCK_WHILE_RUNNING, - 10000, 600, 1000000000 // default, min + 10000, 520, 1000000000 // default, min, max ) // , CONTINUE_SCREEN_FRAMES( // "Continue Screen Frames:
The number of RNG advances to pass on the continue screen.
This should be less than the total number of advances above.", @@ -521,7 +521,9 @@ void GiftRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& uint64_t CONTINUE_SCREEN_FRAMES = 200; - const int64_t FIXED_SEED_OFFSET = -845; // milliseconds. approximate; + const int64_t FIXED_SEED_OFFSET = -845; // milliseconds, approximate + const int64_t FIXED_ADVANCES_OFFSET = 160; // frames, approximate + double SEED_CALIBRATION_FRAMES = RNG_CALIBRATION.seed_calibration / FRAME_DURATION; double ADVANCES_CALIBRATION = RNG_CALIBRATION.advances_calibration; double CONTINUE_SCREEN_ADJUSTMENT = RNG_CALIBRATION.csf_calibration; @@ -608,13 +610,13 @@ void GiftRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& double seed_bump = SEED_BUMPS[ADVANCE_HISTORY.results.size() % 5]; SEED_CALIBRATION_FRAMES += seed_bump; - double CALIBRATED_ADVANCES = ADVANCES + ADVANCES_CALIBRATION; + double CALIBRATED_ADVANCES = ADVANCES + ADVANCES_CALIBRATION + FIXED_ADVANCES_OFFSET; double INGAME_ADVANCES = CALIBRATED_ADVANCES - CONTINUE_SCREEN_FRAMES - CONTINUE_SCREEN_ADJUSTMENT; double TEACHY_ADVANCES = 0; - bool should_use_teachy_tv = USE_TEACHY_TV && (INGAME_ADVANCES > 5000); // don't use Teachy TV for short in-game advance targets + bool should_use_teachy_tv = USE_TEACHY_TV && (INGAME_ADVANCES > 10000); // don't use Teachy TV for short in-game advance targets if (should_use_teachy_tv) { - TEACHY_ADVANCES = std::floor((INGAME_ADVANCES - 5000) / 313) * 313; + TEACHY_ADVANCES = std::floor((INGAME_ADVANCES - 2500) / 313) * 313; } env.log("Seed calibration (frames): " + std::to_string(SEED_CALIBRATION_FRAMES)); @@ -624,7 +626,7 @@ void GiftRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& uint64_t CALIBRATED_SEED_DELAY = uint64_t(std::round(SEED_DELAY + FIXED_SEED_OFFSET + FRAME_DURATION * SEED_CALIBRATION_FRAMES)); uint64_t CONTINUE_SCREEN_DELAY = uint64_t(std::round(FRAME_DURATION * (CONTINUE_SCREEN_FRAMES + CONTINUE_SCREEN_ADJUSTMENT))); uint64_t TEACHY_DELAY = uint64_t(TEACHY_ADVANCES * FRAME_DURATION / 313); - uint64_t INGAME_DELAY = uint64_t(std::round(FRAME_DURATION * (INGAME_ADVANCES - TEACHY_ADVANCES) / 2)) - (should_use_teachy_tv ? 13700 : 0); + uint64_t INGAME_DELAY = uint64_t(std::round(FRAME_DURATION * (INGAME_ADVANCES - TEACHY_ADVANCES) / 2)) - (should_use_teachy_tv ? 14067 : 0); env.log("Title screen duration: " + std::to_string(CALIBRATED_SEED_DELAY) + "ms"); env.log("Continue screen duration: " + std::to_string(CONTINUE_SCREEN_DELAY) + "ms"); @@ -635,6 +637,8 @@ void GiftRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& env.log("In-game duration: " + std::to_string(INGAME_DELAY) + "ms"); } + check_timings(env.console, TARGET, CALIBRATED_SEED_DELAY, CONTINUE_SCREEN_DELAY, INGAME_DELAY, false); + env.log("Resetting Game..."); reset_and_perform_blind_sequence( env.console, context, TARGET, diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.cpp index 9d71f2b1c5..6594612c8c 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.cpp @@ -149,7 +149,7 @@ RngHelper::RngHelper() "These pass at double the rate compared to other consoles, where every frame results in 2 advances.
" "Warning: this needs to be long enough to accomodate all in-game button presses prior to the gift/encounter", LockMode::LOCK_WHILE_RUNNING, - 12345, 480 // default, min + 12345, 320 // default, min ) , INGAME_CALIBRATION( "In-Game Advances Calibration:" @@ -221,13 +221,24 @@ void RngHelper::program(SingleSwitchProgramEnvironment& env, ProControllerContex double FRAMERATE = 59.999977; // FPS double FRAME_DURATION = 1000 / FRAMERATE; - const int64_t FIXED_SEED_OFFSET = -845; // milliseconds. approximate + bool sweet_scent = ( + TARGET == PokemonFRLG_RngTarget::sweetscent || + TARGET == PokemonFRLG_RngTarget::rocksmash || + TARGET == PokemonFRLG_RngTarget::safarizonecenter || + TARGET == PokemonFRLG_RngTarget::safarizoneeast || + TARGET == PokemonFRLG_RngTarget::safarizonenorth || + TARGET == PokemonFRLG_RngTarget::safarizonewest || + TARGET == PokemonFRLG_RngTarget::safarizonesurf + ); + + const int64_t FIXED_SEED_OFFSET = -845; // milliseconds, approximate + const int64_t FIXED_ADVANCES_OFFSET = sweet_scent ? -352 : 160; // frames, approximate while (!shiny_found){ // prepare timings uint64_t TOTAL_SEED_DELAY = SEED_DELAY + SEED_CALIBRATION + FIXED_SEED_OFFSET; - double MODIFIED_INGAME_ADVANCES = INGAME_ADVANCES + INGAME_CALIBRATION; + double MODIFIED_INGAME_ADVANCES = INGAME_ADVANCES + INGAME_CALIBRATION + FIXED_ADVANCES_OFFSET; if (MODIFIED_INGAME_ADVANCES < 0) { OperationFailedException::fire( ErrorReport::NO_ERROR_REPORT, @@ -245,16 +256,16 @@ void RngHelper::program(SingleSwitchProgramEnvironment& env, ProControllerContex || TARGET == PokemonFRLG_RngTarget::safarizonefish ); - uint64_t TEACHY_TV_BUFFER = SAFARI_ZONE ? 12000 : 5000; // Safari zone targets need extra time to walk to the right position + uint64_t TEACHY_TV_BUFFER = SAFARI_ZONE ? 20000 : 10000; // Safari zone targets need extra time to walk to the right position - bool should_use_teachy_tv = USE_TEACHY_TV && (TARGET != PokemonFRLG_RngTarget::starters) && (MODIFIED_INGAME_ADVANCES > TEACHY_TV_BUFFER); // don't use Teachy TV for short in-game advance targets + bool should_use_teachy_tv = USE_TEACHY_TV && (MODIFIED_INGAME_ADVANCES > TEACHY_TV_BUFFER); // don't use Teachy TV for short in-game advance targets if (should_use_teachy_tv) { - TEACHY_ADVANCES = uint64_t((int)std::floor((MODIFIED_INGAME_ADVANCES - TEACHY_TV_BUFFER) / 313) * 313); + TEACHY_ADVANCES = uint64_t((int)std::floor((MODIFIED_INGAME_ADVANCES - TEACHY_TV_BUFFER + 7500) / 313) * 313); } const uint64_t CONTINUE_SCREEN_DELAY = uint64_t((CONTINUE_SCREEN_FRAMES + CONTINUE_SCREEN_CALIBRATION) * FRAME_DURATION); const uint64_t TEACHY_DELAY = uint64_t(TEACHY_ADVANCES * FRAME_DURATION / 313); - const uint64_t INGAME_DELAY = uint64_t((MODIFIED_INGAME_ADVANCES - TEACHY_ADVANCES) * FRAME_DURATION / 2) - (should_use_teachy_tv ? 13700 : 0); + const uint64_t INGAME_DELAY = uint64_t((MODIFIED_INGAME_ADVANCES - TEACHY_ADVANCES) * FRAME_DURATION / 2) - (should_use_teachy_tv ? 14067 : 0); env.log("Continue Screen delay: " + std::to_string(CONTINUE_SCREEN_DELAY) + "ms"); env.log("In-game delay: " + std::to_string(INGAME_DELAY) + "ms"); env.log("Teachy TV delay: " + std::to_string(TEACHY_DELAY) + "ms"); diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp index d56cc4dbdb..ad1bf67427 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp @@ -148,7 +148,7 @@ StarterRng::StarterRng() , ADVANCES( "Advances:
The total number of RNG advances for your target.", LockMode::LOCK_WHILE_RUNNING, - 10000, 600, 1000000000 // default, min + 10000, 940, 1000000000 // default, min ) // , CONTINUE_SCREEN_FRAMES( // "Continue Screen Frames:
The number of RNG advances to pass on the continue screen.
This should be less than the total number of advances above.", @@ -670,7 +670,9 @@ void StarterRng::program(SingleSwitchProgramEnvironment& env, ProControllerConte uint64_t CONTINUE_SCREEN_FRAMES = 200; - const int64_t FIXED_SEED_OFFSET = -845; // milliseconds. approximate; + const int64_t FIXED_SEED_OFFSET = -845; // milliseconds, approximate + const int64_t FIXED_ADVANCES_OFFSET = 160; // frames, approximate + double SEED_CALIBRATION_FRAMES = RNG_CALIBRATION.seed_calibration / FRAME_DURATION; double ADVANCES_CALIBRATION = RNG_CALIBRATION.advances_calibration; double CONTINUE_SCREEN_ADJUSTMENT = RNG_CALIBRATION.csf_calibration; @@ -762,7 +764,7 @@ void StarterRng::program(SingleSwitchProgramEnvironment& env, ProControllerConte double seed_bump = SEED_BUMPS[ADVANCE_HISTORY.results.size() % 5]; SEED_CALIBRATION_FRAMES += seed_bump; - double CALIBRATED_ADVANCES = ADVANCES + ADVANCES_CALIBRATION; + double CALIBRATED_ADVANCES = ADVANCES + ADVANCES_CALIBRATION + FIXED_ADVANCES_OFFSET; double INGAME_ADVANCES = CALIBRATED_ADVANCES - CONTINUE_SCREEN_FRAMES - CONTINUE_SCREEN_ADJUSTMENT; env.log("Seed calibration (frames): " + std::to_string(SEED_CALIBRATION_FRAMES)); @@ -777,6 +779,8 @@ void StarterRng::program(SingleSwitchProgramEnvironment& env, ProControllerConte env.log("Continue screen duration: " + std::to_string(CONTINUE_SCREEN_DELAY) + "ms"); env.log("In-game duration: " + std::to_string(INGAME_DELAY) + "ms"); + check_timings(env.console, PokemonFRLG_RngTarget::starters, CALIBRATED_SEED_DELAY, CONTINUE_SCREEN_DELAY, INGAME_DELAY, false); + env.log("Resetting Game..."); reset_and_perform_blind_sequence( env.console, context, PokemonFRLG_RngTarget::starters, diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StaticRng.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StaticRng.cpp index b87ef3e3e3..0372de4620 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StaticRng.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StaticRng.cpp @@ -168,7 +168,7 @@ StaticRng::StaticRng() , ADVANCES( "Advances:
The total number of RNG advances for your target.", LockMode::LOCK_WHILE_RUNNING, - 10000, 600, 1000000000 // default, min + 10000, 520, 1000000000 // default, min ) // , CONTINUE_SCREEN_FRAMES( // "Continue Screen Frames:
The number of RNG advances to pass on the continue screen.
This should be less than the total number of advances above.", @@ -659,7 +659,9 @@ void StaticRng::program(SingleSwitchProgramEnvironment& env, ProControllerContex uint64_t CONTINUE_SCREEN_FRAMES = 200; - const int64_t FIXED_SEED_OFFSET = -845; // milliseconds. approximate; + const int64_t FIXED_SEED_OFFSET = -845; // milliseconds, approximate + const int64_t FIXED_ADVANCES_OFFSET = 160; // frames, approximate + double SEED_CALIBRATION_FRAMES = RNG_CALIBRATION.seed_calibration / FRAME_DURATION; double ADVANCES_CALIBRATION = RNG_CALIBRATION.advances_calibration; double CONTINUE_SCREEN_ADJUSTMENT = RNG_CALIBRATION.csf_calibration; @@ -746,13 +748,13 @@ void StaticRng::program(SingleSwitchProgramEnvironment& env, ProControllerContex double seed_bump = SEED_BUMPS[ADVANCE_HISTORY.results.size() % 5]; SEED_CALIBRATION_FRAMES += seed_bump; - double CALIBRATED_ADVANCES = ADVANCES + ADVANCES_CALIBRATION; + double CALIBRATED_ADVANCES = ADVANCES + ADVANCES_CALIBRATION + FIXED_ADVANCES_OFFSET; double INGAME_ADVANCES = CALIBRATED_ADVANCES - CONTINUE_SCREEN_FRAMES - CONTINUE_SCREEN_ADJUSTMENT; double TEACHY_ADVANCES = 0; - bool should_use_teachy_tv = USE_TEACHY_TV && (INGAME_ADVANCES > 5000); // don't use Teachy TV for short in-game advance targets + bool should_use_teachy_tv = USE_TEACHY_TV && (INGAME_ADVANCES > 10000); // don't use Teachy TV for short in-game advance targets if (should_use_teachy_tv) { - TEACHY_ADVANCES = std::floor((INGAME_ADVANCES - 5000) / 313) * 313; + TEACHY_ADVANCES = std::floor((INGAME_ADVANCES - 2500) / 313) * 313; } env.log("Seed calibration (frames): " + std::to_string(SEED_CALIBRATION_FRAMES)); @@ -762,7 +764,7 @@ void StaticRng::program(SingleSwitchProgramEnvironment& env, ProControllerContex uint64_t CALIBRATED_SEED_DELAY = uint64_t(std::round(SEED_DELAY + FIXED_SEED_OFFSET + FRAME_DURATION * SEED_CALIBRATION_FRAMES)); uint64_t CONTINUE_SCREEN_DELAY = uint64_t(std::round(FRAME_DURATION * (CONTINUE_SCREEN_FRAMES + CONTINUE_SCREEN_ADJUSTMENT))); uint64_t TEACHY_DELAY = uint64_t(TEACHY_ADVANCES * FRAME_DURATION / 313); - uint64_t INGAME_DELAY = uint64_t(std::round(FRAME_DURATION * (INGAME_ADVANCES - TEACHY_ADVANCES) / 2)) - (should_use_teachy_tv ? 13700 : 0); + uint64_t INGAME_DELAY = uint64_t(std::round(FRAME_DURATION * (INGAME_ADVANCES - TEACHY_ADVANCES) / 2)) - (should_use_teachy_tv ? 14067 : 0); env.log("Title screen duration: " + std::to_string(CALIBRATED_SEED_DELAY) + "ms"); env.log("Continue screen duration: " + std::to_string(CONTINUE_SCREEN_DELAY) + "ms"); @@ -773,6 +775,8 @@ void StaticRng::program(SingleSwitchProgramEnvironment& env, ProControllerContex env.log("In-game duration: " + std::to_string(INGAME_DELAY) + "ms"); } + check_timings(env.console, TARGET, CALIBRATED_SEED_DELAY, CONTINUE_SCREEN_DELAY, INGAME_DELAY, false); + env.log("Resetting Game..."); reset_and_perform_blind_sequence( env.console, context, TARGET, diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_WildRng.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_WildRng.cpp index f25fa67f8d..84a211f1d0 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_WildRng.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_WildRng.cpp @@ -182,7 +182,7 @@ WildRng::WildRng() , ADVANCES( "Advances:
The total number of RNG advances for your target.", LockMode::LOCK_WHILE_RUNNING, - 10000, 600, 1000000000 // default, min + 10000, 700, 1000000000 // default, min ) // , CONTINUE_SCREEN_FRAMES( // "Continue Screen Frames:
The number of RNG advances to pass on the continue screen.
This should be less than the total number of advances above.", @@ -250,7 +250,13 @@ bool WildRng::have_hit_target(SingleSwitchProgramEnvironment& env, const uint32_ return (hit.seed == TARGET_SEED) && (hit.advance == ADVANCES); } -bool WildRng::auto_catch(SingleSwitchProgramEnvironment& env, ProControllerContext& context, WildRng_Descriptor::Stats& stats, const uint64_t& MAX_BALL_THROWS){ +bool WildRng::auto_catch( + SingleSwitchProgramEnvironment& env, + ProControllerContext& context, + WildRng_Descriptor::Stats& stats, + const uint64_t& MAX_BALL_THROWS, + bool safari_zone +){ for (uint64_t i=0; i<=MAX_BALL_THROWS; i++){ int count = 0; while(true){ @@ -330,36 +336,38 @@ bool WildRng::auto_catch(SingleSwitchProgramEnvironment& env, ProControllerConte if (i == MAX_BALL_THROWS) { break; } - // select BAG (selection arrow does not wrap around) - pbf_move_left_joystick(context, {+1, 0}, 100ms, 150ms); - pbf_move_left_joystick(context, {0, +1}, 100ms, 150ms); - pbf_move_left_joystick(context, {+1, 0}, 100ms, 150ms); - pbf_move_left_joystick(context, {0, +1}, 100ms, 150ms); + if (!safari_zone){ + // select BAG (selection arrow does not wrap around) + pbf_move_left_joystick(context, {+1, 0}, 100ms, 150ms); + pbf_move_left_joystick(context, {0, +1}, 100ms, 150ms); + pbf_move_left_joystick(context, {+1, 0}, 100ms, 150ms); + pbf_move_left_joystick(context, {0, +1}, 100ms, 150ms); - BagWatcher bag_open(COLOR_RED); - int ret2 = run_until( - env.console, context, - [](ProControllerContext& context) { - for (int i=0; i<5; i++){ - pbf_press_button(context, BUTTON_A, 200ms, 1800ms); - } - }, - { bag_open } - ); - if (ret2 < 0){ - send_program_recoverable_error_notification( - env, NOTIFICATION_ERROR_RECOVERABLE, - "auto_catch(): failed to open bag." - ); - stats.errors++; - return true; - } + BagWatcher bag_open(COLOR_RED); + int ret2 = run_until( + env.console, context, + [](ProControllerContext& context) { + for (int i=0; i<5; i++){ + pbf_press_button(context, BUTTON_A, 200ms, 1800ms); + } + }, + { bag_open } + ); + if (ret2 < 0){ + send_program_recoverable_error_notification( + env, NOTIFICATION_ERROR_RECOVERABLE, + "auto_catch(): failed to open bag." + ); + stats.errors++; + return true; + } - if (i == 0){ - // go to balls pocket (pockets do not wrap around, topmost item will already be selected) - pbf_move_left_joystick(context, {+1, 0}, 200ms, 800ms); - pbf_move_left_joystick(context, {+1, 0}, 200ms, 800ms); - pbf_move_left_joystick(context, {+1, 0}, 200ms, 800ms); + if (i == 0){ + // go to balls pocket (pockets do not wrap around, topmost item will already be selected) + pbf_move_left_joystick(context, {+1, 0}, 200ms, 800ms); + pbf_move_left_joystick(context, {+1, 0}, 200ms, 800ms); + pbf_move_left_joystick(context, {+1, 0}, 200ms, 800ms); + } } // use ball @@ -370,9 +378,14 @@ bool WildRng::auto_catch(SingleSwitchProgramEnvironment& env, ProControllerConte return true; } -AdvObservedPokemon WildRng::read_summary(SingleSwitchProgramEnvironment& env, ProControllerContext& context, const std::set& SPECIES_LIST){ +AdvObservedPokemon WildRng::read_summary( + SingleSwitchProgramEnvironment& env, + ProControllerContext& context, + const std::set& SPECIES_LIST, + bool safari_zone +){ // navigate to the summary page of the last occupied (not necessarily 6th) party slot - open_party_menu_from_overworld(env.console, context); + open_party_menu_from_overworld(env.console, context, safari_zone ? StartMenuContext::SAFARI_ZONE : StartMenuContext::STANDARD); pbf_move_left_joystick(context, {0, +1}, 200ms, 300ms); pbf_move_left_joystick(context, {0, +1}, 200ms, 300ms); @@ -472,11 +485,12 @@ bool WildRng::use_rare_candy( AdvObservedPokemon& pokemon, AdvRngFilters& filters, const BaseStats& BASE_STATS, + bool safari_zone, bool first ){ // navigate to the bag (only needed for the first use) if (first){ - open_bag_from_overworld(env.console, context); + open_bag_from_overworld(env.console, context, safari_zone ? PokemonFRLG::StartMenuContext::SAFARI_ZONE : PokemonFRLG::StartMenuContext::STANDARD); // move left to the correct pocket (in case Teachy TV was used) pbf_move_left_joystick(context, {-1, 0}, 200ms, 800ms); pbf_move_left_joystick(context, {-1, 0}, 200ms, 800ms); @@ -706,7 +720,9 @@ void WildRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& uint64_t CONTINUE_SCREEN_FRAMES = 200; - const int64_t FIXED_SEED_OFFSET = -845; // milliseconds. approximate; + const int64_t FIXED_SEED_OFFSET = -845; // milliseconds, approximate + const int64_t FIXED_ADVANCES_OFFSET = -352; // frames, approximate + double SEED_CALIBRATION_FRAMES = RNG_CALIBRATION.seed_calibration / FRAME_DURATION; double ADVANCES_CALIBRATION = RNG_CALIBRATION.advances_calibration; double CONTINUE_SCREEN_ADJUSTMENT = RNG_CALIBRATION.csf_calibration; @@ -791,13 +807,15 @@ void WildRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& double seed_bump = SEED_BUMPS[ADVANCE_HISTORY.results.size() % 5]; SEED_CALIBRATION_FRAMES += seed_bump; - double CALIBRATED_ADVANCES = ADVANCES + ADVANCES_CALIBRATION; + double CALIBRATED_ADVANCES = ADVANCES + ADVANCES_CALIBRATION + FIXED_ADVANCES_OFFSET; double INGAME_ADVANCES = CALIBRATED_ADVANCES - CONTINUE_SCREEN_FRAMES - CONTINUE_SCREEN_ADJUSTMENT; + uint64_t TEACHY_TV_BUFFER = safari_zone ? 20000 : 10000; // Safari zone targets need extra time to walk to the right position + double TEACHY_ADVANCES = 0; - bool should_use_teachy_tv = USE_TEACHY_TV && (INGAME_ADVANCES > 5000); // don't use Teachy TV for short in-game advance targets + bool should_use_teachy_tv = USE_TEACHY_TV && (INGAME_ADVANCES > TEACHY_TV_BUFFER); // don't use Teachy TV for short in-game advance targets if (should_use_teachy_tv) { - TEACHY_ADVANCES = std::floor((INGAME_ADVANCES - 5000) / 313) * 313; + TEACHY_ADVANCES = std::floor((INGAME_ADVANCES - TEACHY_TV_BUFFER + 7500) / 313) * 313; } env.log("Seed calibration (frames): " + std::to_string(SEED_CALIBRATION_FRAMES)); @@ -807,7 +825,7 @@ void WildRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& uint64_t CALIBRATED_SEED_DELAY = uint64_t(std::round(SEED_DELAY + FIXED_SEED_OFFSET + FRAME_DURATION * SEED_CALIBRATION_FRAMES)); uint64_t CONTINUE_SCREEN_DELAY = uint64_t(std::round(FRAME_DURATION * (CONTINUE_SCREEN_FRAMES + CONTINUE_SCREEN_ADJUSTMENT))); uint64_t TEACHY_DELAY = uint64_t(TEACHY_ADVANCES * FRAME_DURATION / 313); - uint64_t INGAME_DELAY = uint64_t(std::round(FRAME_DURATION * (INGAME_ADVANCES - TEACHY_ADVANCES) / 2)) - (should_use_teachy_tv ? 13700 : 0); + uint64_t INGAME_DELAY = uint64_t(std::round(FRAME_DURATION * (INGAME_ADVANCES - TEACHY_ADVANCES) / 2)) - (should_use_teachy_tv ? 14067 : 0); env.log("Title screen duration: " + std::to_string(CALIBRATED_SEED_DELAY) + "ms"); env.log("Continue screen duration: " + std::to_string(CONTINUE_SCREEN_DELAY) + "ms"); @@ -818,6 +836,8 @@ void WildRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& env.log("In-game duration: " + std::to_string(INGAME_DELAY) + "ms"); } + check_timings(env.console, TARGET, CALIBRATED_SEED_DELAY, CONTINUE_SCREEN_DELAY, INGAME_DELAY, safari_zone); + env.log("Resetting Game..."); reset_and_perform_blind_sequence( env.console, context, TARGET, @@ -863,14 +883,21 @@ void WildRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& break; } - bool failed = auto_catch(env, context, stats, MAX_BALL_THROWS); + bool failed = auto_catch(env, context, stats, MAX_BALL_THROWS, safari_zone); if (failed){ env.log("Failed catch."); continue; } - AdvObservedPokemon pokemon = read_summary(env, context, SPECIES_LIST); - RngStats species_stats = stats_data.get_throw(pokemon.species); + AdvObservedPokemon pokemon = read_summary(env, context, SPECIES_LIST, safari_zone); + RngStats species_stats; + try{ + species_stats = stats_data.get_throw(pokemon.species); + }catch (const InternalProgramError& err){ + env.log(err.message()); + env.log("Failed to load base stats."); + continue; + } BaseStats BASE_STATS = species_stats.base_stats; int16_t GENDER_THRESHOLD = species_stats.gender_threshold; @@ -897,7 +924,7 @@ void WildRng::program(SingleSwitchProgramEnvironment& env, ProControllerContext& } for (uint64_t i=0; i& SPECIES_LIST); + AdvObservedPokemon read_summary( + SingleSwitchProgramEnvironment& env, + ProControllerContext& context, + const std::set& SPECIES_LIST, + bool safari_zone + ); bool auto_catch( SingleSwitchProgramEnvironment& env, ProControllerContext& context, WildRng_Descriptor::Stats& stats, - const uint64_t& MAX_BALL_THROWS + const uint64_t& MAX_BALL_THROWS, + bool safari_zone ); bool use_rare_candy( @@ -76,6 +82,7 @@ class WildRng : public SingleSwitchProgramInstance{ AdvObservedPokemon& pokemon, AdvRngFilters& filters, const BaseStats& BASE_STATS, + bool safari_zone, bool first );