diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index 8e1e39d629..96e0aad14a 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -6914,11 +6914,11 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId) SWAP(gMoveSelectionCursor[battlerAtk], gMoveSelectionCursor[battlerPartner], temp); // Swap turn order, so that all the battlers take action SWAP(gChosenActionByBattler[battlerAtk], gChosenActionByBattler[battlerPartner], temp); - for (i = 0; i < MAX_BATTLERS_COUNT; i++) + for (i = 0; i < gBattlersCount; i++) { if (gBattlerByTurnOrder[i] == battlerAtk || gBattlerByTurnOrder[i] == battlerPartner) { - for (j = i + 1; j < MAX_BATTLERS_COUNT; j++) + for (j = i + 1; j < gBattlersCount; j++) { if (gBattlerByTurnOrder[j] == battlerAtk || gBattlerByTurnOrder[j] == battlerPartner) break; @@ -6938,9 +6938,13 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId) TrySwapWishBattlerIds(battlerAtk, battlerPartner); // For Snipe Shot and abilities Stalwart/Propeller Tail - keep the original target. - for (i = 0; i < MAX_BATTLERS_COUNT; i++) + for (i = 0; i < gBattlersCount; i++) { u16 ability = GetBattlerAbility(i); + // if not targeting a slot that got switched, continue + if (!IsBattlerAlly(gBattleStruct->moveTarget[i], battlerAtk)) + continue; + if (gChosenMoveByBattler[i] == MOVE_SNIPE_SHOT || ability == ABILITY_PROPELLER_TAIL || ability == ABILITY_STALWART) gBattleStruct->moveTarget[i] ^= BIT_FLANK; } diff --git a/src/battle_util.c b/src/battle_util.c index 0a95f4e59c..d38135dbb2 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -309,7 +309,7 @@ bool32 HandleMoveTargetRedirection(void) // Functions void HandleAction_UseMove(void) { - u32 i; + u32 i, moveTarget; gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; if (gBattleStruct->battlerState[gBattlerAttacker].absentBattlerFlags @@ -393,9 +393,10 @@ void HandleAction_UseMove(void) gCurrentMove = gChosenMove = GetMaxMove(gBattlerAttacker, gCurrentMove); } + moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); + if (!HandleMoveTargetRedirection()) { - u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); if (IsDoubleBattle() && moveTarget & MOVE_TARGET_RANDOM) { gBattlerTarget = SetRandomTarget(gBattlerAttacker); @@ -407,7 +408,7 @@ void HandleAction_UseMove(void) } else if (moveTarget == MOVE_TARGET_ALLY) { - if (IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker))) + if (IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)) && !gProtectStructs[BATTLE_PARTNER(gBattlerAttacker)].usedAllySwitch) gBattlerTarget = BATTLE_PARTNER(gBattlerAttacker); else gBattlerTarget = gBattlerAttacker; @@ -422,6 +423,10 @@ void HandleAction_UseMove(void) break; } } + else if (moveTarget == MOVE_TARGET_USER) + { + gBattlerTarget = gBattlerAttacker; + } else { gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker); @@ -455,8 +460,13 @@ void HandleAction_UseMove(void) } } - if ((IsBattlerAlly(gBattlerAttacker, gBattlerTarget)) - && (!IsBattlerAlive(gBattlerTarget) || gProtectStructs[BATTLE_PARTNER(gBattlerAttacker)].usedAllySwitch)) + if (IsBattlerAlly(gBattlerAttacker, gBattlerTarget) && !IsBattlerAlive(gBattlerTarget)) + { + gBattlescriptCurrInstr = BattleScript_FailedFromAtkCanceler; + } + // If originally targetting an ally but now targetting user due to Ally Switch + else if (moveTarget & MOVE_TARGET_ALLY && gBattlerAttacker == gBattlerTarget + && gProtectStructs[BATTLE_PARTNER(gBattlerAttacker)].usedAllySwitch) { gBattlescriptCurrInstr = BattleScript_FailedFromAtkCanceler; } diff --git a/test/battle/move_effect/acupressure.c b/test/battle/move_effect/acupressure.c index d59a3faee3..02be60725d 100644 --- a/test/battle/move_effect/acupressure.c +++ b/test/battle/move_effect/acupressure.c @@ -16,20 +16,40 @@ DOUBLE_BATTLE_TEST("Acupressure fails on the user if it targeted its ally but sw OPPONENT(SPECIES_KADABRA); OPPONENT(SPECIES_ABRA); } WHEN { - TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); MOVE(playerRight, MOVE_ACUPRESSURE, target:playerLeft); } + TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); MOVE(playerRight, MOVE_ACUPRESSURE, target: playerLeft); } } SCENE { MESSAGE("Wobbuffet used Ally Switch!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLY_SWITCH, playerLeft); MESSAGE("Wobbuffet and Wynaut switched places!"); - + MESSAGE("Wynaut used Acupressure!"); MESSAGE("But it failed!"); NONE_OF { - ANIMATION(ANIM_TYPE_MOVE, MOVE_ACUPRESSURE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ACUPRESSURE, playerLeft); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); } } } +DOUBLE_BATTLE_TEST("Acupressure works on the ally if it targeted itself but switched positions via Ally Switch") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_KADABRA); + OPPONENT(SPECIES_ABRA); + } WHEN { + TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); MOVE(playerRight, MOVE_ACUPRESSURE, target: playerRight); } + } SCENE { + MESSAGE("Wobbuffet used Ally Switch!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLY_SWITCH, playerLeft); + MESSAGE("Wobbuffet and Wynaut switched places!"); + MESSAGE("Wynaut used Acupressure!"); + NOT MESSAGE("But it failed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ACUPRESSURE, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); + } +} + TO_DO_BATTLE_TEST("Acupressure works on the user if its side is protected by Crafty Shield"); TO_DO_BATTLE_TEST("Acupressure fails on the ally if its side is protected by Crafty Shield"); diff --git a/test/battle/move_effect/ally_switch.c b/test/battle/move_effect/ally_switch.c index 520de60106..ba2ac1a053 100644 --- a/test/battle/move_effect/ally_switch.c +++ b/test/battle/move_effect/ally_switch.c @@ -167,6 +167,24 @@ DOUBLE_BATTLE_TEST("Ally Switch - move fails if the target was ally which change } } +DOUBLE_BATTLE_TEST("Ally Switch doesn't make self-targeting status moves fail") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_HARDEN].target == MOVE_TARGET_USER); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); MOVE(playerRight, MOVE_HARDEN); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLY_SWITCH, playerLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_HARDEN, playerLeft); + } THEN { + EXPECT_EQ(playerLeft->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 1); + } +} + DOUBLE_BATTLE_TEST("Ally Switch increases the Protect-like moves counter") { GIVEN {