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:
Alex 2024-10-15 23:04:35 +02:00 committed by GitHub
parent b9ac5d1d8a
commit ed65c4a2f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 79 additions and 47 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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);