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;
|
gCurrentActionFuncId = B_ACTION_FINISHED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsBattlerAlive(gBattlerAttacker) && gMovesInfo[gCurrentMove].effect != EFFECT_EXPLOSION && !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
|
if (!IsBattlerAlive(gBattlerAttacker) && gMovesInfo[gCurrentMove].effect != EFFECT_EXPLOSION && !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
|
||||||
{
|
{
|
||||||
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||||||
|
|
|
@ -279,19 +279,10 @@ void HandleAction_UseMove(void)
|
||||||
gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker);
|
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)));
|
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerPosition(gBattlerAttacker)));
|
|
||||||
if (!IsBattlerAlive(gBattlerTarget))
|
|
||||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -307,8 +298,7 @@ void HandleAction_UseMove(void)
|
||||||
gBattlerTarget = battler;
|
gBattlerTarget = battler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && moveTarget & MOVE_TARGET_RANDOM)
|
||||||
&& moveTarget & MOVE_TARGET_RANDOM)
|
|
||||||
{
|
{
|
||||||
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
|
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
|
||||||
{
|
{
|
||||||
|
@ -352,19 +342,12 @@ void HandleAction_UseMove(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker);
|
gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker);
|
||||||
if (!IsBattlerAlive(gBattlerTarget) && moveTarget != MOVE_TARGET_OPPONENTS_FIELD)
|
if (!IsBattlerAlive(gBattlerTarget)
|
||||||
{
|
&& moveTarget != MOVE_TARGET_OPPONENTS_FIELD
|
||||||
if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
|
&& (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)))
|
||||||
{
|
{
|
||||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
|
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerPosition(gBattlerAttacker)));
|
|
||||||
if (!IsBattlerAlive(gBattlerTarget))
|
|
||||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE && gProtectStructs[gBattlerAttacker].palaceUnableToUseMove)
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE && gProtectStructs[gBattlerAttacker].palaceUnableToUseMove)
|
||||||
|
@ -387,8 +370,9 @@ void HandleAction_UseMove(void)
|
||||||
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
|
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;
|
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);
|
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 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");
|
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")
|
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 {
|
GIVEN {
|
||||||
PLAYER(SPECIES_WOBBUFFET);
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
PLAYER(SPECIES_WYNAUT);
|
PLAYER(SPECIES_WYNAUT);
|
||||||
|
|
Loading…
Reference in a new issue