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
);