From b244740f52d526f8b4f376d22e58848cb8be72a3 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Wed, 24 Sep 2025 13:34:08 +0200 Subject: [PATCH] Fixes OHKO moves calculating accuracy twice (#7785) --- data/battle_scripts_1.s | 1 - src/battle_script_commands.c | 35 +++++++++++++++++++++------------ test/battle/move_effect/ohko.c | 36 +++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index b0b0c61fcd..7c33bfef0f 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3219,7 +3219,6 @@ BattleScript_EffectOHKO:: attackcanceler attackstring ppreduce - accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE typecalc jumpifmovehadnoeffect BattleScript_HitFromAtkAnimation tryKO BattleScript_KOFail diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 84d58d6f64..37f25637d4 100755 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -10857,6 +10857,11 @@ static void Cmd_setlightscreen(void) gBattlescriptCurrInstr = cmd->nextInstr; } +// for var lands +#define NO_HIT 0 +#define CALC_ACC 1 +#define SURE_HIT 2 +// for var endured #define NOT_ENDURED 0 #define FOCUS_SASHED 1 #define FOCUS_BANDED 2 @@ -10865,7 +10870,6 @@ static void Cmd_tryKO(void) { CMD_ARGS(const u8 *failInstr); - bool32 lands = FALSE; enum BattleMoveEffects effect = GetMoveEffect(gCurrentMove); enum ItemHoldEffect holdEffect = GetBattlerHoldEffect(gBattlerTarget, TRUE); u16 targetAbility = GetBattlerAbility(gBattlerTarget); @@ -10911,24 +10915,28 @@ static void Cmd_tryKO(void) } else { - if (gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level - && ((gBattleMons[gBattlerTarget].volatiles.lockOn - && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker) - || IsAbilityAndRecord(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), ABILITY_NO_GUARD) - || IsAbilityAndRecord(gBattlerTarget, targetAbility, ABILITY_NO_GUARD))) - { - lands = TRUE; - } - else + u32 lands = NO_HIT; + if (gBattleMons[gBattlerTarget].level > gBattleMons[gBattlerAttacker].level) + lands = NO_HIT; + else if ((gBattleMons[gBattlerTarget].volatiles.lockOn && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker) + || IsAbilityAndRecord(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), ABILITY_NO_GUARD) + || IsAbilityAndRecord(gBattlerTarget, targetAbility, ABILITY_NO_GUARD)) + lands = SURE_HIT; + else if (IsSemiInvulnerable(gBattlerTarget, CHECK_ALL)) + lands = NO_HIT; + else if (!JumpIfMoveAffectedByProtect(gCurrentMove, gBattlerTarget, TRUE, cmd->failInstr)) + lands = CALC_ACC; + + if (lands == CALC_ACC) { u16 odds = GetMoveAccuracy(gCurrentMove) + (gBattleMons[gBattlerAttacker].level - gBattleMons[gBattlerTarget].level); if (B_SHEER_COLD_ACC >= GEN_7 && effect == EFFECT_SHEER_COLD && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_ICE)) odds -= 10; if (RandomPercentage(RNG_ACCURACY, odds) && gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level) - lands = TRUE; + lands = SURE_HIT; } - if (lands) + if (lands == SURE_HIT) { if (gDisableStructs[gBattlerTarget].endured) { @@ -10964,6 +10972,9 @@ static void Cmd_tryKO(void) } } } +#undef NO_HIT +#undef CALC_ACC +#undef SURE_HIT #undef NOT_ENDURED #undef FOCUS_SASHED #undef FOCUS_BANDED diff --git a/test/battle/move_effect/ohko.c b/test/battle/move_effect/ohko.c index 580219e3db..81847a1ba5 100644 --- a/test/battle/move_effect/ohko.c +++ b/test/battle/move_effect/ohko.c @@ -21,6 +21,18 @@ SINGLE_BATTLE_TEST("OHKO moves can hit semi-invulnerable mons when the user has } } +SINGLE_BATTLE_TEST("OHKO moves can not hit semi-invulnerable") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_FLY); MOVE(player, MOVE_FISSURE); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_FISSURE, player); + } +} + SINGLE_BATTLE_TEST("OHKO moves can can be endured by Focus Sash") { GIVEN { @@ -48,7 +60,29 @@ SINGLE_BATTLE_TEST("OHKO moves can can be endured by Sturdy") } } +SINGLE_BATTLE_TEST("OHKO moves always fails if the target has a higher level than the user") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Level(1); } + OPPONENT(SPECIES_WOBBUFFET) { Level(2); } + } WHEN { + TURN { MOVE(player, MOVE_FISSURE); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_FISSURE, player); + } +} + +SINGLE_BATTLE_TEST("OHKO moves fail if target protects") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_FISSURE); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_FISSURE, player); + } +} TO_DO_BATTLE_TEST("OHKO moves faints the target, skipping regular damage calculations") -TO_DO_BATTLE_TEST("OHKO moves always fails if the target has a higher level than the user") TO_DO_BATTLE_TEST("OHKO moves's accuracy increases by 1% for every level the user has over the target") TO_DO_BATTLE_TEST("OHKO moves's ignores non-stage accuracy modifiers") // Gravity, Wide Lens, Compound Eyes