Pursuit refactor (#5707)

This commit is contained in:
PhallenTree 2024-12-06 18:14:46 +00:00 committed by GitHub
parent da2a1e2aba
commit 775ea3b564
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 694 additions and 94 deletions

View File

@ -298,12 +298,20 @@ BattleScript_CheckPrimalWeather:
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, B_WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
return
BattleScript_MoveSwitchPursuit:
jumpifbattletype BATTLE_TYPE_ARENA, BattleScript_MoveSwitchEnd
jumpifcantswitch SWITCH_IGNORE_ESCAPE_PREVENTION | BS_ATTACKER, BattleScript_MoveSwitchEnd
printstring STRINGID_PKMNWENTBACK
waitmessage B_WAIT_TIME_SHORT
jumpifnopursuitswitchdmg BattleScript_MoveSwitchOpenPartyScreen
end
BattleScript_MoveSwitch:
jumpifbattletype BATTLE_TYPE_ARENA, BattleScript_MoveSwitchEnd
jumpifcantswitch SWITCH_IGNORE_ESCAPE_PREVENTION | BS_ATTACKER, BattleScript_MoveSwitchEnd
printstring STRINGID_PKMNWENTBACK
waitmessage B_WAIT_TIME_SHORT
BattleScript_MoveSwitchOpenPartyScreen:
BattleScript_MoveSwitchOpenPartyScreen::
openpartyscreen BS_ATTACKER, BattleScript_MoveSwitchEnd
switchoutabilities BS_ATTACKER
waitstate
@ -1343,7 +1351,7 @@ BattleScript_EffectPartingShotTrySpAtk:
waitmessage B_WAIT_TIME_LONG
BattleScript_EffectPartingShotSwitch:
moveendall
goto BattleScript_MoveSwitch
goto BattleScript_MoveSwitchPursuit
BattleScript_EffectPowder::
attackcanceler
@ -2785,7 +2793,7 @@ BattleScript_EffectHitEscape::
jumpifbattleend BattleScript_HitEscapeEnd
jumpifbyte CMP_NOT_EQUAL, gBattleOutcome, 0, BattleScript_HitEscapeEnd
jumpifemergencyexited BS_TARGET, BattleScript_HitEscapeEnd
goto BattleScript_MoveSwitch
goto BattleScript_MoveSwitchPursuit
BattleScript_HitEscapeEnd:
end
@ -5767,19 +5775,10 @@ BattleScript_PrintFullBox::
BattleScript_ActionSwitch::
hpthresholds2 BS_ATTACKER
printstring STRINGID_RETURNMON
jumpifbattletype BATTLE_TYPE_DOUBLE, BattleScript_PursuitSwitchDmgSetMultihit
setmultihit 1
goto BattleScript_PursuitSwitchDmgLoop
BattleScript_PursuitSwitchDmgSetMultihit::
setmultihit 2
BattleScript_PursuitSwitchDmgLoop::
jumpifnopursuitswitchdmg BattleScript_DoSwitchOut
swapattackerwithtarget
trysetdestinybondtohappen
call BattleScript_PursuitDmgOnSwitchOut
swapattackerwithtarget
end2
BattleScript_DoSwitchOut::
decrementmultihit BattleScript_PursuitSwitchDmgLoop
switchoutabilities BS_ATTACKER
updatedynamax
waitstate
@ -5801,34 +5800,6 @@ BattleScript_DoSwitchOut::
moveendcase MOVEEND_MIRROR_MOVE
end2
BattleScript_PursuitDmgOnSwitchOut::
pause B_WAIT_TIME_SHORT
orword gHitMarker, HITMARKER_OBEYS
attackstring
ppreduce
critcalc
damagecalc
adjustdamage
attackanimation
waitanimation
effectivenesssound
hitanimation BS_TARGET
waitstate
healthbarupdate BS_TARGET
datahpupdate BS_TARGET
critmessage
waitmessage B_WAIT_TIME_LONG
resultmessage
waitmessage B_WAIT_TIME_LONG
tryfaintmon BS_TARGET
moveendfromto MOVEEND_ABILITIES, MOVEEND_ATTACKER_INVISIBLE @ MOVEEND_CHOICE_MOVE has to be included
jumpiffainted BS_TARGET, FALSE, BattleScript_PursuitDmgOnSwitchOutRet
setbyte sGIVEEXP_STATE, 0
getexp BS_TARGET
BattleScript_PursuitDmgOnSwitchOutRet:
bicword gHitMarker, HITMARKER_OBEYS
return
BattleScript_Pausex20::
pause B_WAIT_TIME_SHORT
return

View File

@ -836,6 +836,9 @@ struct BattleStruct
u8 monCausingSleepClause[NUM_BATTLE_SIDES]; // Stores which pokemon on a given side is causing Sleep Clause to be active as the mon's index in the party
u8 sleepClauseEffectExempt:4; // Stores whether effect should be exempt from triggering Sleep Clause (Effect Spore)
u8 usedMicleBerry:4;
u8 pursuitTarget:4; // Each battler as a bit.
u8 pursuitSwitchByMove:1;
u8 pursuitStoredSwitch; // Stored id for the Pursuit target's switch
s32 battlerExpReward;
// Simultaneous hp reduction for spread moves

View File

@ -46,6 +46,8 @@ extern const u8 BattleScript_PrintFailedToRunString[];
extern const u8 BattleScript_PrintCantEscapeFromBattle[];
extern const u8 BattleScript_PrintFullBox[];
extern const u8 BattleScript_ActionSwitch[];
extern const u8 BattleScript_DoSwitchOut[];
extern const u8 BattleScript_MoveSwitchOpenPartyScreen[];
extern const u8 BattleScript_Pausex20[];
extern const u8 BattleScript_LevelUp[];
extern const u8 BattleScript_RainContinuesOrEnds[];

View File

@ -126,6 +126,7 @@
#define B_AFTER_YOU_TURN_ORDER GEN_LATEST // In Gen8+, After You doesn't fail if the turn order wouldn't change after use.
#define B_QUASH_TURN_ORDER GEN_LATEST // In Gen8+, Quash-affected battlers move according to speed order. Before Gen8, Quash-affected battlers move in the order they were affected by Quash.
#define B_DESTINY_BOND_FAIL GEN_LATEST // In Gen7+, Destiny Bond fails if used repeatedly.
#define B_PURSUIT_TARGET GEN_LATEST // In Gen4+, Pursuit attacks a switching opponent even if they weren't targeting them. Before Gen4, Pursuit only attacks a switching opponent that it originally targeted.
// Ability settings
#define B_ABILITY_WEATHER GEN_LATEST // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability.

View File

@ -302,6 +302,7 @@ enum MoveEndEffects
MOVEEND_SAME_MOVE_TURNS,
MOVEEND_SET_EVOLUTION_TRACKER,
MOVEEND_CLEAR_BITS,
MOVEEND_PURSUIT_NEXT_ACTION,
MOVEEND_COUNT,
};

View File

@ -3114,6 +3114,9 @@ static void BattleStartClearSetData(void)
gBattleStruct->swapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
gBattleStruct->categoryOverride = FALSE; // used for Z-Moves and Max Moves
gBattleStruct->pursuitTarget = 0;
gBattleStruct->pursuitSwitchByMove = FALSE;
gBattleStruct->pursuitStoredSwitch = 0;
gSelectedMonPartyId = PARTY_SIZE; // Revival Blessing
gCategoryIconSpriteId = 0xFF;
@ -3355,6 +3358,9 @@ const u8* FaintClearSetData(u32 battler)
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
gBattleStruct->lastTakenMoveFrom[battler][2] = 0;
gBattleStruct->lastTakenMoveFrom[battler][3] = 0;
gBattleStruct->pursuitTarget = 0;
gBattleStruct->pursuitSwitchByMove = FALSE;
gBattleStruct->pursuitStoredSwitch = 0;
gBattleStruct->palaceFlags &= ~(1u << battler);
gBattleStruct->boosterEnergyActivates &= ~(1u << battler);
@ -5164,6 +5170,9 @@ static void TurnValuesCleanUp(bool8 var0)
gSideTimers[B_SIDE_OPPONENT].followmeTimer = 0;
gBattleStruct->usedEjectItem = 0;
gBattleStruct->pursuitTarget = 0;
gBattleStruct->pursuitSwitchByMove = FALSE;
gBattleStruct->pursuitStoredSwitch = 0;
gBattleStruct->pledgeMove = FALSE; // combined pledge move may not have been used due to a canceller
ClearDamageCalcResults();
}
@ -5180,11 +5189,26 @@ static void PopulateArrayWithBattlers(u8 *battlers)
battlers[i] = i;
}
static bool32 TryActivateGimmick(u32 battler)
{
if ((gBattleStruct->gimmick.toActivate & (1u << battler)) && !(gProtectStructs[battler].noValidMoves))
{
gBattlerAttacker = gBattleScripting.battler = battler;
gBattleStruct->gimmick.toActivate &= ~(1u << battler);
if (gGimmicksInfo[gBattleStruct->gimmick.usableGimmick[battler]].ActivateGimmick != NULL)
{
gGimmicksInfo[gBattleStruct->gimmick.usableGimmick[battler]].ActivateGimmick(battler);
return TRUE;
}
}
return FALSE;
}
static bool32 TryDoGimmicksBeforeMoves(void)
{
if (!(gHitMarker & HITMARKER_RUN) && gBattleStruct->gimmick.toActivate)
{
u32 i, battler;
u32 i;
u8 order[MAX_BATTLERS_COUNT];
PopulateArrayWithBattlers(order);
@ -5192,16 +5216,8 @@ static bool32 TryDoGimmicksBeforeMoves(void)
for (i = 0; i < gBattlersCount; i++)
{
// Search through each battler and activate their gimmick if they have one prepared.
if ((gBattleStruct->gimmick.toActivate & (1u << order[i])) && !(gProtectStructs[order[i]].noValidMoves))
{
battler = gBattlerAttacker = gBattleScripting.battler = order[i];
gBattleStruct->gimmick.toActivate &= ~(1u << battler);
if (gGimmicksInfo[gBattleStruct->gimmick.usableGimmick[battler]].ActivateGimmick != NULL)
{
gGimmicksInfo[gBattleStruct->gimmick.usableGimmick[battler]].ActivateGimmick(battler);
return TRUE;
}
}
if (TryActivateGimmick(order[i]))
return TRUE;
}
}
@ -5251,7 +5267,7 @@ static bool32 TryDoMoveEffectsBeforeMoves(void)
static void TryChangeTurnOrder(void)
{
u32 i, j;
for (i = 0; i < gBattlersCount - 1; i++)
for (i = gCurrentTurnActionNumber; i < gBattlersCount - 1; i++)
{
for (j = i + 1; j < gBattlersCount; j++)
{
@ -5369,11 +5385,19 @@ static void RunTurnActionsFunctions(void)
// Mega Evolve / Focus Punch-like moves after switching, items, running, but before using a move.
if (gCurrentActionFuncId == B_ACTION_USE_MOVE && !gBattleStruct->effectsBeforeUsingMoveDone)
{
if (TryDoGimmicksBeforeMoves())
return;
else if (TryDoMoveEffectsBeforeMoves())
return;
gBattleStruct->effectsBeforeUsingMoveDone = TRUE;
if (!gBattleStruct->pursuitTarget)
{
if (TryDoGimmicksBeforeMoves())
return;
else if (TryDoMoveEffectsBeforeMoves())
return;
gBattleStruct->effectsBeforeUsingMoveDone = TRUE;
}
else
{
if (TryActivateGimmick(gBattlerByTurnOrder[gCurrentTurnActionNumber]))
return;
}
}
*(&gBattleStruct->savedTurnActionNumber) = gCurrentTurnActionNumber;

View File

@ -329,6 +329,7 @@ static void BestowItem(u32 battlerAtk, u32 battlerDef);
static bool8 IsFinalStrikeEffect(u32 moveEffect);
static void TryUpdateRoundTurnOrder(void);
static bool32 ChangeOrderTargetAfterAttacker(void);
static bool32 SetTargetToNextPursuiter(u32 battlerDef);
void ApplyExperienceMultipliers(s32 *expAmount, u8 expGetterMonId, u8 faintedBattler);
static void RemoveAllWeather(void);
static void RemoveAllTerrains(void);
@ -1487,6 +1488,10 @@ static bool32 AccuracyCalcHelper(u32 move, u32 battler)
{
effect = TRUE;
}
else if (gBattleStruct->pursuitTarget & (1u << battler))
{
effect = TRUE;
}
else if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !(gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE))
{
effect = TRUE;
@ -6947,6 +6952,32 @@ static void Cmd_moveend(void)
}
}
gBattleScripting.moveendState++;
break;
case MOVEEND_PURSUIT_NEXT_ACTION:
if (gBattleStruct->pursuitTarget & (1u << gBattlerTarget))
{
u32 storedTarget = gBattlerTarget;
if (SetTargetToNextPursuiter(gBattlerTarget))
{
ChangeOrderTargetAfterAttacker();
*(gBattleStruct->moveTarget + gBattlerTarget) = storedTarget;
gBattlerTarget = storedTarget;
}
else if (IsBattlerAlive(gBattlerTarget))
{
gBattlerAttacker = gBattlerTarget;
if (gBattleStruct->pursuitSwitchByMove)
gBattlescriptCurrInstr = BattleScript_MoveSwitchOpenPartyScreen;
else
gBattlescriptCurrInstr = BattleScript_DoSwitchOut;
*(gBattleStruct->monToSwitchIntoId + gBattlerTarget) = gBattleStruct->pursuitStoredSwitch;
gBattleStruct->pursuitTarget = 0;
gBattleStruct->pursuitSwitchByMove = FALSE;
gBattleStruct->pursuitStoredSwitch = 0;
effect = TRUE;
}
}
gBattleScripting.moveendState++;
break;
case MOVEEND_COUNT:
@ -13967,45 +13998,44 @@ static void Cmd_magnitudedamagecalculation(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
static bool32 SetTargetToNextPursuiter(u32 battlerDef)
{
u32 i;
for (i = gCurrentTurnActionNumber + 1; i < gBattlersCount; i++)
{
u32 battler = gBattlerByTurnOrder[i];
if (gChosenActionByBattler[battler] == B_ACTION_USE_MOVE
&& gMovesInfo[gChosenMoveByBattler[battler]].effect == EFFECT_PURSUIT
&& IsBattlerAlive(battlerDef)
&& IsBattlerAlive(battler)
&& GetBattlerSide(battler) != GetBattlerSide(battlerDef)
&& (B_PURSUIT_TARGET >= GEN_4 || *(gBattleStruct->moveTarget + battler) == battlerDef)
&& !IsGimmickSelected(battler, GIMMICK_Z_MOVE)
&& !IsGimmickSelected(battler, GIMMICK_DYNAMAX)
&& GetActiveGimmick(battler) != GIMMICK_DYNAMAX)
{
gBattlerTarget = battler;
return TRUE;
}
}
return FALSE;
}
static void Cmd_jumpifnopursuitswitchdmg(void)
{
CMD_ARGS(const u8 *jumpInstr);
if (gMultiHitCounter == 1)
{
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
else
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
}
else
{
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
else
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
}
u32 savedTarget = gBattlerTarget;
if (gChosenActionByBattler[gBattlerTarget] == B_ACTION_USE_MOVE
&& gBattlerAttacker == *(gBattleStruct->moveTarget + gBattlerTarget)
&& !(gBattleMons[gBattlerTarget].status1 & (STATUS1_SLEEP | STATUS1_FREEZE))
&& gBattleMons[gBattlerAttacker].hp
&& !gDisableStructs[gBattlerTarget].truantCounter
&& gMovesInfo[gChosenMoveByBattler[gBattlerTarget]].effect == EFFECT_PURSUIT)
if (SetTargetToNextPursuiter(gBattlerAttacker))
{
s32 i;
for (i = 0; i < gBattlersCount; i++)
{
if (gBattlerByTurnOrder[i] == gBattlerTarget)
gActionsByTurnOrder[i] = B_ACTION_TRY_FINISH;
}
gCurrentMove = gChosenMove = gChosenMoveByBattler[gBattlerTarget];
gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerTarget);
ChangeOrderTargetAfterAttacker();
gBattleStruct->pursuitTarget = 1u << gBattlerAttacker;
gBattleStruct->pursuitSwitchByMove = gActionsByTurnOrder[gCurrentTurnActionNumber] == B_ACTION_USE_MOVE;
gBattleStruct->pursuitStoredSwitch = gBattleStruct->monToSwitchIntoId[gBattlerAttacker];
*(gBattleStruct->moveTarget + gBattlerTarget) = gBattlerAttacker;
gBattlerTarget = savedTarget;
gBattlescriptCurrInstr = cmd->nextInstr;
gBattleScripting.animTurn = 1;
gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED;
}
else
{

View File

@ -119,6 +119,9 @@ bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move)
|| ability == ABILITY_PROPELLER_TAIL || ability == ABILITY_STALWART)
return FALSE;
if (gMovesInfo[move].effect == EFFECT_PURSUIT && gBattleStruct->pursuitTarget)
return FALSE;
if (gSideTimers[defSide].followmePowder && !IsAffectedByPowder(battlerAtk, ability, GetBattlerHoldEffect(battlerAtk, TRUE)))
return FALSE;
@ -226,6 +229,7 @@ void HandleAction_UseMove(void)
}
else if (IsDoubleBattle()
&& gSideTimers[side].followmeTimer == 0
&& !(gBattleStruct->pursuitTarget & (1u << *(gBattleStruct->moveTarget + gBattlerAttacker)))
&& (gMovesInfo[gCurrentMove].power != 0 || (moveTarget != MOVE_TARGET_USER && moveTarget != MOVE_TARGET_ALL_BATTLERS))
&& ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|| (GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_STORM_DRAIN && moveType == TYPE_WATER)))
@ -705,7 +709,7 @@ void HandleAction_ActionFinished(void)
gBattleScripting.multihitMoveEffect = 0;
gBattleResources->battleScriptsStack->size = 0;
if (B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 && !afterYouActive && !gBattleStruct->pledgeMove)
if (B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 && !afterYouActive && !gBattleStruct->pledgeMove && !gBattleStruct->pursuitTarget)
{
// i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already
// taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action
@ -8961,7 +8965,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData
basePower *= 2;
break;
case EFFECT_PURSUIT:
if (gActionsByTurnOrder[GetBattlerTurnOrderNum(battlerDef)] == B_ACTION_SWITCH)
if (gBattleStruct->pursuitTarget & (1u << battlerDef))
basePower *= 2;
break;
case EFFECT_NATURAL_GIFT:

View File

@ -6,10 +6,462 @@ ASSUMPTIONS
ASSUME(gMovesInfo[MOVE_PURSUIT].effect == EFFECT_PURSUIT);
}
SINGLE_BATTLE_TEST("Pursuit attacks a switching foe")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
HP_BAR(player);
SEND_IN_MESSAGE("Zigzagoon");
}
}
SINGLE_BATTLE_TEST("Pursuit attacks a foe using Volt Switch / U-Turn / Parting Shot to switch out")
{
u32 move;
PARAMETRIZE { move = MOVE_VOLT_SWITCH; }
PARAMETRIZE { move = MOVE_U_TURN; }
PARAMETRIZE { move = MOVE_PARTING_SHOT; }
GIVEN {
ASSUME(gMovesInfo[MOVE_VOLT_SWITCH].effect == EFFECT_HIT_ESCAPE);
ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE);
ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { MOVE(player, move); MOVE(opponent, MOVE_PURSUIT); SEND_OUT(player, 1); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, move, player);
MESSAGE("Wobbuffet went back to 1!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
SEND_IN_MESSAGE("Zigzagoon");
}
}
DOUBLE_BATTLE_TEST("Pursuit doesn't attack a foe using Teleport / Baton Pass to switch out")
{
u32 move;
PARAMETRIZE { move = MOVE_TELEPORT; }
PARAMETRIZE { move = MOVE_BATON_PASS; }
GIVEN {
ASSUME(gMovesInfo[MOVE_QUASH].effect == EFFECT_QUASH);
ASSUME(gMovesInfo[MOVE_TELEPORT].effect == EFFECT_TELEPORT);
ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_NIDOKING);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_LINOONE);
} WHEN {
TURN { MOVE(playerRight, MOVE_QUASH, target: opponentLeft); MOVE(playerLeft, move); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUASH, playerRight);
ANIMATION(ANIM_TYPE_MOVE, move, playerLeft);
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
SEND_IN_MESSAGE("Zigzagoon");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
}
}
SINGLE_BATTLE_TEST("Pursuit doesn't attack switching foe if user already acted that turn")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { MOVE(opponent, MOVE_PURSUIT); MOVE(player, MOVE_VOLT_SWITCH); SEND_OUT(player, 1); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, player);
MESSAGE("Wobbuffet went back to 1!");
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
SEND_IN_MESSAGE("Zigzagoon");
}
}
SINGLE_BATTLE_TEST("Pursuit doubles in power if attacking while target switches out", s16 damage)
{
u32 speed;
PARAMETRIZE { speed = 5; }
PARAMETRIZE { speed = 3; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
PLAYER(SPECIES_ZIGZAGOON) { Speed(2); }
OPPONENT(SPECIES_WYNAUT) { Speed(speed); }
} WHEN {
TURN { MOVE(opponent, MOVE_PURSUIT); MOVE(player, MOVE_VOLT_SWITCH); SEND_OUT(player, 1); }
} SCENE {
if (speed == 3)
ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
HP_BAR(player, captureDamage: &results[i].damage);
if (speed == 5)
ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, player);
SEND_IN_MESSAGE("Zigzagoon");
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
}
}
SINGLE_BATTLE_TEST("Pursuit ignores accuracy checks when attacking a switching target")
{
PASSES_RANDOMLY(100, 100, RNG_ACCURACY);
GIVEN {
ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN);
ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL);
PLAYER(SPECIES_GLACEON) { Ability(ABILITY_SNOW_CLOAK); }
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_SAND_ATTACK); MOVE(opponent, MOVE_HAIL); }
TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SAND_ATTACK, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_HAIL, opponent);
SWITCH_OUT_MESSAGE("Glaceon");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
SEND_IN_MESSAGE("Zigzagoon");
}
}
DOUBLE_BATTLE_TEST("Pursuit attacks switching foes even if not targetting them (Gen 4+)")
{
GIVEN {
ASSUME(B_PURSUIT_TARGET >= GEN_4);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
PLAYER(SPECIES_GRIMER);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_LINOONE);
} WHEN {
TURN { SWITCH(playerLeft, 2); MOVE(opponentLeft, MOVE_PURSUIT, target: playerRight); MOVE(opponentRight, MOVE_PURSUIT, target: playerRight); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
HP_BAR(playerLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
HP_BAR(playerLeft);
SEND_IN_MESSAGE("Grimer");
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
}
}
DOUBLE_BATTLE_TEST("Pursuit attacks a switching foe from fastest to slowest")
{
u32 speedLeft, speedRight;
PARAMETRIZE { speedLeft = 5; speedRight = 3; }
PARAMETRIZE { speedLeft = 3; speedRight = 5; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
PLAYER(SPECIES_ZIGZAGOON) { Speed(4); }
PLAYER(SPECIES_GRIMER) { Speed(2); }
OPPONENT(SPECIES_WYNAUT) { Speed(speedLeft); }
OPPONENT(SPECIES_LINOONE) { Speed(speedRight); }
} WHEN {
TURN { SWITCH(playerLeft, 2); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerLeft); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
if (speedLeft > speedRight) {
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
HP_BAR(playerLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
HP_BAR(playerLeft);
} else {
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
HP_BAR(playerLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
HP_BAR(playerLeft);
}
SEND_IN_MESSAGE("Grimer");
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
}
}
DOUBLE_BATTLE_TEST("Pursuit attacks a switching foe but not switching allies")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
PLAYER(SPECIES_GRIMER);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_LINOONE);
OPPONENT(SPECIES_ABRA);
} WHEN {
TURN { SWITCH(playerLeft, 2); SWITCH(opponentRight, 2); MOVE(playerRight, MOVE_PURSUIT, target: opponentRight); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, playerRight);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
SEND_IN_MESSAGE("Grimer");
MESSAGE("2 withdrew Linoone!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, playerRight);
MESSAGE("2 sent out Abra!");
}
}
DOUBLE_BATTLE_TEST("Pursuit only attacks the first switching foe")
{
// This test does not make sense for B_PURSUIT_TARGET < GEN_4
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
PLAYER(SPECIES_GRIMER);
PLAYER(SPECIES_SUNKERN);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_LINOONE);
} WHEN {
TURN { SWITCH(playerLeft, 2); SWITCH(playerRight, 3); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerLeft); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
HP_BAR(playerLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
HP_BAR(playerLeft);
SEND_IN_MESSAGE("Grimer");
SWITCH_OUT_MESSAGE("Zigzagoon");
NONE_OF {
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
HP_BAR(playerRight);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
HP_BAR(playerRight);
}
SEND_IN_MESSAGE("Sunkern");
}
}
DOUBLE_BATTLE_TEST("Pursuit only attacks a switching foe if foe is alive")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
PLAYER(SPECIES_ZIGZAGOON);
PLAYER(SPECIES_GRIMER);
PLAYER(SPECIES_SUNKERN);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_LINOONE);
} WHEN {
TURN { SWITCH(playerLeft, 2); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
HP_BAR(playerLeft);
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
MESSAGE("Wobbuffet fainted!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
SEND_IN_MESSAGE("Grimer");
}
}
DOUBLE_BATTLE_TEST("Pursuit attacks the second switching foe if the first faints from pursuit")
{
// This test does not make sense for B_PURSUIT_TARGET < GEN_4
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
PLAYER(SPECIES_ZIGZAGOON);
PLAYER(SPECIES_GRIMER);
PLAYER(SPECIES_SUNKERN);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_LINOONE);
} WHEN {
TURN { SWITCH(playerLeft, 2); SWITCH(playerRight, 3); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerRight); SEND_OUT(playerLeft, 2); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
HP_BAR(playerLeft);
MESSAGE("Wobbuffet fainted!");
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
SWITCH_OUT_MESSAGE("Zigzagoon");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
HP_BAR(playerRight);
SEND_IN_MESSAGE("Sunkern");
SEND_IN_MESSAGE("Grimer");
}
}
DOUBLE_BATTLE_TEST("Pursuit only attacks a switching foe if user is alive")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
PLAYER(SPECIES_GRIMER);
OPPONENT(SPECIES_WYNAUT) { HP(1); }
OPPONENT(SPECIES_LINOONE);
OPPONENT(SPECIES_SUNKERN);
} WHEN {
TURN { MOVE(playerLeft, MOVE_VOLT_SWITCH, target: opponentLeft); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); SEND_OUT(opponentLeft, 2); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, playerLeft);
MESSAGE("The opposing Wynaut fainted!");
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
SEND_IN_MESSAGE("Grimer");
}
}
SINGLE_BATTLE_TEST("Pursuit attacks a switching foe but fails if user is asleep")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WYNAUT) { Status1(STATUS1_SLEEP_TURN(2)); }
} WHEN {
TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
MESSAGE("The opposing Wynaut is fast asleep.");
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
SEND_IN_MESSAGE("Zigzagoon");
}
}
SINGLE_BATTLE_TEST("Pursuit attacks a switching foe and takes Life Orb damage")
{
GIVEN {
ASSUME(gItemsInfo[ITEM_LIFE_ORB].holdEffect == HOLD_EFFECT_LIFE_ORB);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WYNAUT) { Item(ITEM_LIFE_ORB); }
} WHEN {
TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
HP_BAR(opponent);
SEND_IN_MESSAGE("Zigzagoon");
}
}
DOUBLE_BATTLE_TEST("Pursuit attacks a switching foe but isn't affected by Follow Me")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_FOLLOW_ME].effect == EFFECT_FOLLOW_ME);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_CLEFABLE);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_LINOONE);
} WHEN {
TURN { MOVE(playerRight, MOVE_FOLLOW_ME); MOVE(playerLeft, MOVE_VOLT_SWITCH, target: opponentLeft); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_FOLLOW_ME, playerRight);
ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, playerLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
SEND_IN_MESSAGE("Zigzagoon");
}
}
SINGLE_BATTLE_TEST("Pursuit user mega evolves before attacking a switching foe and hits twice if user has Parental Bond")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
} WHEN {
TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT, gimmick: GIMMICK_MEGA); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
HP_BAR(player);
HP_BAR(player);
SEND_IN_MESSAGE("Zigzagoon");
}
}
DOUBLE_BATTLE_TEST("Pursuit user mega evolves before attacking a switching foe and others mega evolve after switch")
{
GIVEN {
PLAYER(SPECIES_CHARIZARD) { Item(ITEM_CHARIZARDITE_X); }
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
} WHEN {
TURN { SWITCH(playerRight, 2); MOVE(opponentRight, MOVE_PURSUIT, gimmick: GIMMICK_MEGA, target: playerRight); MOVE(playerLeft, MOVE_CELEBRATE, gimmick: GIMMICK_MEGA); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponentRight);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
HP_BAR(playerRight);
HP_BAR(playerRight);
SEND_IN_MESSAGE("Zigzagoon");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, playerLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerLeft);
}
}
SINGLE_BATTLE_TEST("Pursuit user terastalizes before attacking a switching foe and gets the damage boost from the tera type", s16 damage)
{
u32 tera;
PARAMETRIZE { tera = GIMMICK_NONE; }
PARAMETRIZE { tera = GIMMICK_TERA; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_KANGASKHAN) { TeraType(TYPE_DARK); }
} WHEN {
TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT, gimmick: tera); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
if (tera == GIMMICK_TERA)
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
HP_BAR(player, captureDamage: &results[i].damage);
SEND_IN_MESSAGE("Zigzagoon");
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
}
}
DOUBLE_BATTLE_TEST("Pursuit affected by Electrify fails against immune target")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY);
PLAYER(SPECIES_DONPHAN);
PLAYER(SPECIES_HELIOLISK);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_LINOONE);
} WHEN {
TURN { MOVE(playerRight, MOVE_ELECTRIFY, target: opponentLeft); MOVE(playerLeft, MOVE_VOLT_SWITCH, target: opponentLeft); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIFY, playerRight);
ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, playerLeft);
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
SEND_IN_MESSAGE("Zigzagoon");
}
}
DOUBLE_BATTLE_TEST("Pursuit affected by Electrify fails against target with Volt Absorb")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY);
PLAYER(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); }
PLAYER(SPECIES_HELIOLISK);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_LINOONE);
} WHEN {
TURN { MOVE(playerRight, MOVE_ELECTRIFY, target: opponentLeft); MOVE(playerLeft, MOVE_VOLT_SWITCH, target: opponentLeft); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIFY, playerRight);
ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, playerLeft);
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
ABILITY_POPUP(playerLeft, ABILITY_VOLT_ABSORB);
SEND_IN_MESSAGE("Zigzagoon");
}
}
SINGLE_BATTLE_TEST("Pursuited mon correctly switches out after it got hit and activated ability Tangling Hair")
{
GIVEN {
PLAYER(SPECIES_DUGTRIO) { Ability(ABILITY_TANGLING_HAIR); }
PLAYER(SPECIES_DUGTRIO_ALOLA) { Ability(ABILITY_TANGLING_HAIR); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
@ -25,6 +477,80 @@ SINGLE_BATTLE_TEST("Pursuited mon correctly switches out after it got hit and ac
}
}
DOUBLE_BATTLE_TEST("Pursuited mon correctly switches out after it got hit and activated ability Tangling Hair - Doubles")
{
GIVEN {
PLAYER(SPECIES_DUGTRIO_ALOLA) { Ability(ABILITY_TANGLING_HAIR); }
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { SWITCH(playerLeft, 2); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerLeft); }
} SCENE {
SWITCH_OUT_MESSAGE("Dugtrio");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
ABILITY_POPUP(playerLeft, ABILITY_TANGLING_HAIR);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
MESSAGE("The opposing Wynaut's Speed fell!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
ABILITY_POPUP(playerLeft, ABILITY_TANGLING_HAIR);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
MESSAGE("The opposing Wobbuffet's Speed fell!");
SEND_IN_MESSAGE("Wobbuffet");
}
}
SINGLE_BATTLE_TEST("Pursuited mon correctly switches out after it got hit and activated ability Tangling Hair - Mirror Armor")
{
GIVEN {
PLAYER(SPECIES_DUGTRIO_ALOLA) { Ability(ABILITY_TANGLING_HAIR); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); }
} SCENE {
SWITCH_OUT_MESSAGE("Dugtrio");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
ABILITY_POPUP(player, ABILITY_TANGLING_HAIR);
ABILITY_POPUP(opponent, ABILITY_MIRROR_ARMOR);
SEND_IN_MESSAGE("Wobbuffet");
}
}
DOUBLE_BATTLE_TEST("Pursuited mon correctly switches out after it got hit and activated ability Cotton Down")
{
GIVEN {
PLAYER(SPECIES_ELDEGOSS) { Ability(ABILITY_COTTON_DOWN); }
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { SWITCH(playerLeft, 2); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerLeft); }
} SCENE {
SWITCH_OUT_MESSAGE("Eldegoss");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
ABILITY_POPUP(playerLeft, ABILITY_COTTON_DOWN);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
MESSAGE("The opposing Wynaut's Speed fell!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
MESSAGE("Wobbuffet's Speed fell!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
MESSAGE("The opposing Wobbuffet's Speed fell!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
ABILITY_POPUP(playerLeft, ABILITY_COTTON_DOWN);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
MESSAGE("The opposing Wynaut's Speed fell!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
MESSAGE("Wobbuffet's Speed fell!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
MESSAGE("The opposing Wobbuffet's Speed fell!");
SEND_IN_MESSAGE("Wobbuffet");
}
}
// Checked so that Pursuit has only 1 PP and it forces the player to use Struggle.
SINGLE_BATTLE_TEST("Pursuit becomes a locked move after being used on switch-out while holding a Choice Item")
{
@ -46,4 +572,42 @@ SINGLE_BATTLE_TEST("Pursuit becomes a locked move after being used on switch-out
}
}
SINGLE_BATTLE_TEST("Pursuit attacks a switching foe and switchin is correctly stored")
{
u32 switchin;
PARAMETRIZE { switchin = 1; }
PARAMETRIZE { switchin = 2; }
PARAMETRIZE { switchin = 3; }
PARAMETRIZE { switchin = 4; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON);
PLAYER(SPECIES_AIPOM);
PLAYER(SPECIES_ABRA);
PLAYER(SPECIES_VENIPEDE);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { SWITCH(player, switchin); MOVE(opponent, MOVE_PURSUIT); }
} SCENE {
SWITCH_OUT_MESSAGE("Wobbuffet");
ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
switch (switchin)
{
case 1:
SEND_IN_MESSAGE("Zigzagoon");
break;
case 2:
SEND_IN_MESSAGE("Aipom");
break;
case 3:
SEND_IN_MESSAGE("Abra");
break;
case 4:
SEND_IN_MESSAGE("Venipede");
break;
}
}
}
TO_DO_BATTLE_TEST("Baton Pass doesn't cause Pursuit to increase its power or priority");