Fixes Partner targeting and Acupressure/Ally Switch interaction (#5446)
* Fixes Partner targeting and Acupressure/Ally Switch interaction * More tests * Update test/battle/move.c
This commit is contained in:
parent
b9ac5d1d8a
commit
ed65c4a2f7
4 changed files with 79 additions and 47 deletions
|
@ -1210,6 +1210,7 @@ static void Cmd_attackcanceler(void)
|
|||
gCurrentActionFuncId = B_ACTION_FINISHED;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsBattlerAlive(gBattlerAttacker) && gMovesInfo[gCurrentMove].effect != EFFECT_EXPLOSION && !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
|
||||
{
|
||||
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||||
|
|
|
@ -279,18 +279,9 @@ void HandleAction_UseMove(void)
|
|||
gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker);
|
||||
}
|
||||
|
||||
if (!IsBattlerAlive(gBattlerTarget))
|
||||
if (!IsBattlerAlive(gBattlerTarget) && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
|
||||
{
|
||||
if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
|
||||
{
|
||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerPosition(gBattlerAttacker)));
|
||||
if (!IsBattlerAlive(gBattlerTarget))
|
||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
|
||||
}
|
||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -307,8 +298,7 @@ void HandleAction_UseMove(void)
|
|||
gBattlerTarget = battler;
|
||||
}
|
||||
}
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& moveTarget & MOVE_TARGET_RANDOM)
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && moveTarget & MOVE_TARGET_RANDOM)
|
||||
{
|
||||
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
|
||||
{
|
||||
|
@ -352,18 +342,11 @@ void HandleAction_UseMove(void)
|
|||
else
|
||||
{
|
||||
gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker);
|
||||
if (!IsBattlerAlive(gBattlerTarget) && moveTarget != MOVE_TARGET_OPPONENTS_FIELD)
|
||||
if (!IsBattlerAlive(gBattlerTarget)
|
||||
&& moveTarget != MOVE_TARGET_OPPONENTS_FIELD
|
||||
&& (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)))
|
||||
{
|
||||
if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
|
||||
{
|
||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerPosition(gBattlerAttacker)));
|
||||
if (!IsBattlerAlive(gBattlerTarget))
|
||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
|
||||
}
|
||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -387,8 +370,9 @@ void HandleAction_UseMove(void)
|
|||
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
|
||||
}
|
||||
}
|
||||
// Edge case: moves targeting the ally fail after a successful Ally Switch.
|
||||
else if (moveTarget == MOVE_TARGET_ALLY && gProtectStructs[BATTLE_PARTNER(gBattlerAttacker)].usedAllySwitch)
|
||||
|
||||
if ((GetBattlerSide(gBattlerAttacker) == GetBattlerSide(gBattlerTarget))
|
||||
&& (!IsBattlerAlive(gBattlerTarget) || gProtectStructs[BATTLE_PARTNER(gBattlerAttacker)].usedAllySwitch))
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_FailedFromAtkCanceler;
|
||||
}
|
||||
|
|
|
@ -222,3 +222,71 @@ SINGLE_BATTLE_TEST("Critical hits ignore negative stat stages", s16 damage)
|
|||
EXPECT_EQ(results[0].damage, results[i].damage);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Moves fail if they target the partner but they faint before the move could have been used")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_TACKLE, target: playerRight); MOVE(playerLeft, MOVE_TACKLE, target: playerRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentLeft);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Moves do not fail if an alive partner is the target")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_TACKLE, target: playerRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Moves fail if they target into a pokemon that was fainted by the previous move")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(playerLeft, MOVE_HYPER_VOICE);
|
||||
MOVE(playerRight, MOVE_TACKLE, target: opponentLeft);
|
||||
SEND_OUT(opponentLeft, 2);
|
||||
SEND_OUT(opponentRight, 3);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, playerLeft);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Moves that target the field are not going to fail if one mon fainted by the previous move")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_TACKLE, target: playerRight); MOVE(playerLeft, MOVE_SURF); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, playerLeft);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,29 +8,8 @@ TO_DO_BATTLE_TEST("Acupressure fails on the ally if all of its stats are maximiz
|
|||
TO_DO_BATTLE_TEST("Acupressure works on the user if it's behind a Substitute (Gen5+)");
|
||||
TO_DO_BATTLE_TEST("Acupressure fails on its ally if it's behind a Substitute");
|
||||
|
||||
DOUBLE_BATTLE_TEST("Acupressure works on the ally if the user 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!");
|
||||
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ACUPRESSURE);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
NOT MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Acupressure fails on the user if it targeted its ally but switched positions via Ally Switch")
|
||||
{
|
||||
KNOWN_FAILING; // Tested in Gen 5, Acupressure fails here
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
|
|
Loading…
Reference in a new issue