diff --git a/include/battle_util.h b/include/battle_util.h index a13d59c22b..666415c16c 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -427,5 +427,6 @@ void TryUpdateEvolutionTracker(enum EvolutionConditions evolutionCondition, u32 bool32 CanUseMoveConsecutively(enum BattlerId battler); void TryResetConsecutiveUseCounter(enum BattlerId battler); void SetOrClearRageVolatile(void); +enum BattlerId GetTargetBySlot(enum BattlerId battlerAtk, enum BattlerId battlerDef); #endif // GUARD_BATTLE_UTIL_H diff --git a/src/battle_move_resolution.c b/src/battle_move_resolution.c index ded5f64583..d8ef7de821 100644 --- a/src/battle_move_resolution.c +++ b/src/battle_move_resolution.c @@ -1707,9 +1707,13 @@ static enum CancelerResult CancelerTargetFailure(struct BattleContext *ctx) ctx->updateFlags = TRUE; ctx->runScript = TRUE; - while (gBattleStruct->eventState.atkCancelerBattler < gBattlersCount) + while (gBattleStruct->eventState.atkCancelerBattler < MAX_BATTLERS_COUNT) { - ctx->battlerDef = gBattleStruct->eventState.atkCancelerBattler++; + ctx->battlerDef = GetTargetBySlot(ctx->battlerAtk, gBattleStruct->eventState.atkCancelerBattler); + gBattleStruct->eventState.atkCancelerBattler++; + + if (!IsDoubleBattle() && ctx->battlerDef >= gBattlersCount) + continue; if (ShouldSkipFailureCheckOnBattler(ctx->battlerAtk, ctx->battlerDef, FALSE)) continue; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 5e61fb5ae2..5f951f8c7e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6382,19 +6382,13 @@ static void Cmd_futuresighttargetfailure(void) static u32 GetPossibleNextTarget(u32 currTarget) { u32 i = 0; - const u8 targetOrder[MAX_BATTLERS_COUNT] = { - gBattlerAttacker, - BATTLE_PARTNER(gBattlerAttacker), - LEFT_FOE(gBattlerAttacker), - RIGHT_FOE(gBattlerAttacker), - }; // currTarget allows for a starting point without relying on values for previous targets being set if (currTarget != MAX_BATTLERS_COUNT) { for (i = 0; i < MAX_BATTLERS_COUNT; i++) { - if (targetOrder[i] == currTarget) + if (GetTargetBySlot(gBattlerAttacker, i) == currTarget) break; } i++; // next target after finding currTarget @@ -6402,7 +6396,8 @@ static u32 GetPossibleNextTarget(u32 currTarget) while (i < MAX_BATTLERS_COUNT) { - enum BattlerId battler = targetOrder[i++]; + enum BattlerId battler = GetTargetBySlot(gBattlerAttacker, i); + i++; if (!IsBattlerAlive(battler)) continue; diff --git a/src/battle_util.c b/src/battle_util.c index d6c7e3a1eb..1013960fab 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -10957,3 +10957,21 @@ void SetOrClearRageVolatile(void) else gBattleMons[gBattlerAttacker].volatiles.rage = FALSE; } + +enum BattlerId GetTargetBySlot(enum BattlerId battlerAtk, enum BattlerId battlerDef) +{ + switch (battlerDef) + { + case B_BATTLER_0: + return battlerAtk; + case B_BATTLER_1: + return BATTLE_PARTNER(battlerAtk); + case B_BATTLER_2: + return LEFT_FOE(battlerAtk); + case B_BATTLER_3: + return RIGHT_FOE(battlerAtk); + default: + errorf("Illegal battler"); + return B_BATTLER_0; + } +} diff --git a/test/battle/move_effect/synchronoise.c b/test/battle/move_effect/synchronoise.c index 2c76008546..afb9273d36 100644 --- a/test/battle/move_effect/synchronoise.c +++ b/test/battle/move_effect/synchronoise.c @@ -41,9 +41,9 @@ DOUBLE_BATTLE_TEST("Synchronoise will fail if there is no corresponding typing o } SCENE { NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SYNCHRONOISE, playerLeft); MESSAGE("Wobbuffet used Synchronoise!"); - MESSAGE("It doesn't affect the opposing Bulbasaur…"); MESSAGE("It doesn't affect Bulbasaur…"); MESSAGE("It doesn't affect the opposing Bulbasaur…"); + MESSAGE("It doesn't affect the opposing Bulbasaur…"); NOT MESSAGE("But it failed!"); } } @@ -108,8 +108,8 @@ DOUBLE_BATTLE_TEST("Synchronoise will fail for a typeless user even if a target } SCENE { NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SYNCHRONOISE, playerLeft); MESSAGE("Arcanine used Synchronoise!"); - MESSAGE("It doesn't affect the opposing Arcanine…"); MESSAGE("It doesn't affect Wobbuffet…"); + MESSAGE("It doesn't affect the opposing Arcanine…"); MESSAGE("It doesn't affect the opposing Wobbuffet…"); NOT MESSAGE("But it failed!"); } diff --git a/test/battle/spread_moves.c b/test/battle/spread_moves.c index eadd2ffff2..956591e49d 100644 --- a/test/battle/spread_moves.c +++ b/test/battle/spread_moves.c @@ -474,3 +474,22 @@ DOUBLE_BATTLE_TEST("Spread Moves: AOE ground type move vs Levitate and Air Ballo HP_BAR(playerRight); } } + +DOUBLE_BATTLE_TEST("Spread Moves: Earthquake fails in order of ally, left foe, right foe") +{ + GIVEN { + ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == TARGET_FOES_AND_ALLY); + ASSUME(GetMoveCategory(MOVE_EARTHQUAKE) == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_WOBBUFFET) { Speed(4); } + PLAYER(SPECIES_FLYGON) { Speed(1); Ability(ABILITY_LEVITATE); } + OPPONENT(SPECIES_FLYGON) { Speed(2); Ability(ABILITY_LEVITATE); } + OPPONENT(SPECIES_FLYGON) { Speed(3); Ability(ABILITY_LEVITATE); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_EARTHQUAKE); } + } SCENE { + ABILITY_POPUP(playerRight, ABILITY_LEVITATE); + ABILITY_POPUP(opponentLeft, ABILITY_LEVITATE); + ABILITY_POPUP(opponentRight, ABILITY_LEVITATE); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_EARTHQUAKE, playerLeft); + } +}