Pursuit refactor (#5707)
This commit is contained in:
parent
da2a1e2aba
commit
775ea3b564
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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[];
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -302,6 +302,7 @@ enum MoveEndEffects
|
||||
MOVEEND_SAME_MOVE_TURNS,
|
||||
MOVEEND_SET_EVOLUTION_TRACKER,
|
||||
MOVEEND_CLEAR_BITS,
|
||||
MOVEEND_PURSUIT_NEXT_ACTION,
|
||||
MOVEEND_COUNT,
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user