Gen 9 configs for Protean/Libero, Intrepid Sword and Dauntless Sword (#3614)
* Gen 9 configs for Protean/Libero, Intrepid Sword and Dauntless Sword * use bitfield * battler fix * fields
This commit is contained in:
parent
882c5529e0
commit
44e81d4f4c
8 changed files with 223 additions and 22 deletions
|
@ -113,6 +113,7 @@ struct DisableStruct
|
|||
u8 steelSurgeDone:1;
|
||||
u8 weatherAbilityDone:1;
|
||||
u8 terrainAbilityDone:1;
|
||||
u8 usedProteanLibero:1;
|
||||
};
|
||||
|
||||
struct ProtectStruct
|
||||
|
@ -699,10 +700,10 @@ struct BattleStruct
|
|||
u16 changedSpecies[NUM_BATTLE_SIDES][PARTY_SIZE]; // For forms when multiple mons can change into the same pokemon.
|
||||
u8 quickClawBattlerId;
|
||||
struct LostItem itemLost[PARTY_SIZE]; // Player's team that had items consumed or stolen (two bytes per party member)
|
||||
u8 blunderPolicy:1; // should blunder policy activate
|
||||
u8 swapDamageCategory:1; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
u8 forcedSwitch:4; // For each battler
|
||||
u8 switchInAbilityPostponed:4; // To not activate against an empty field, each bit for battler
|
||||
u8 blunderPolicy:1; // should blunder policy activate
|
||||
u8 swapDamageCategory:1; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
u8 ballSpriteIds[2]; // item gfx, window gfx
|
||||
u8 appearedInBattle; // Bitfield to track which Pokemon appeared in battle. Used for Burmy's form change
|
||||
u8 skyDropTargets[MAX_BATTLERS_COUNT]; // For Sky Drop, to account for if multiple Pokemon use Sky Drop in a double battle.
|
||||
|
@ -721,22 +722,24 @@ struct BattleStruct
|
|||
uq4_12_t supremeOverlordModifier[MAX_BATTLERS_COUNT];
|
||||
u8 itemPartyIndex[MAX_BATTLERS_COUNT];
|
||||
u8 itemMoveIndex[MAX_BATTLERS_COUNT];
|
||||
bool8 trainerSlideHalfHpMsgDone;
|
||||
u8 trainerSlideFirstCriticalHitMsgState:2;
|
||||
u8 trainerSlideFirstSuperEffectiveHitMsgState:2;
|
||||
u8 trainerSlideFirstSTABMoveMsgState:2;
|
||||
u8 trainerSlidePlayerMonUnaffectedMsgState:2;
|
||||
bool8 trainerSlideMegaEvolutionMsgDone;
|
||||
bool8 trainerSlideZMoveMsgDone;
|
||||
bool8 trainerSlideBeforeFirstTurnMsgDone;
|
||||
bool8 trainerSlideDynamaxMsgDone;
|
||||
u8 trainerSlideHalfHpMsgDone:1;
|
||||
u8 trainerSlideMegaEvolutionMsgDone:1;
|
||||
u8 trainerSlideZMoveMsgDone:1;
|
||||
u8 trainerSlideBeforeFirstTurnMsgDone:1;
|
||||
u8 trainerSlideDynamaxMsgDone:1;
|
||||
u8 pledgeMove:1;
|
||||
u8 isSkyBattle:1;
|
||||
u32 aiDelayTimer; // Counts number of frames AI takes to choose an action.
|
||||
u32 aiDelayFrames; // Number of frames it took to choose an action.
|
||||
bool8 transformZeroToHero[PARTY_SIZE][NUM_BATTLE_SIDES];
|
||||
u8 pledgeMove:1;
|
||||
bool8 isSkyBattle:1;
|
||||
u8 timesGotHit[NUM_BATTLE_SIDES][PARTY_SIZE];
|
||||
u8 enduredDamage;
|
||||
u8 transformZeroToHero[NUM_BATTLE_SIDES];
|
||||
u8 intrepidSwordBoost[NUM_BATTLE_SIDES];
|
||||
u8 dauntlessShieldBoost[NUM_BATTLE_SIDES];
|
||||
};
|
||||
|
||||
// The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider,
|
||||
|
|
|
@ -109,6 +109,9 @@
|
|||
#define B_TRANSFORM_SHINY GEN_LATEST // In Gen4+, Transform will copy the shiny state of the opponent instead of maintaining its own shiny state.
|
||||
#define B_TRANSFORM_FORM_CHANGES GEN_LATEST // In Gen5+, Transformed Pokemon cannot change forms.
|
||||
|
||||
#define B_WIDE_GUARD GEN_LATEST // In Gen5 only, Quick Guard has a chance to fail if used consecutively.
|
||||
#define B_QUICK_GUARD GEN_LATEST // In Gen5 only, Wide Guard has a chance to fail if used consecutively.
|
||||
|
||||
// Ability settings
|
||||
#define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters.
|
||||
#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.
|
||||
|
@ -130,6 +133,9 @@
|
|||
#define B_TRANSISTOR_BOOST GEN_LATEST // In Gen9+, Transistor will only boost Electric-type moves by 1.3x as opposed to 1.5x.
|
||||
#define B_ILLUMINATE_EFFECT GEN_LATEST // In Gen9+, Illuminate prevents accuracy reductions and ignores the target's evasion.
|
||||
#define B_WEAK_ARMOR_SPEED GEN_LATEST // In Gen7+, Weak Armor raises Speed by 2 stages instead of 1 when hit by a physical move.
|
||||
#define B_PROTEAN_LIBERO GEN_LATEST // In Gen7+, Weak Armor raises Speed by 2 stages instead of 1 when hit by a physical move.
|
||||
#define B_INTREPID_SWORD GEN_LATEST // In Gen9+, Intrepid Sword raises Attack by one stage only once per Battle.
|
||||
#define B_DAUNTLESS_SHIELD GEN_LATEST // In Gen9+, Dauntless Shield raises Defense by one stage only once per Battle.
|
||||
|
||||
// Item settings
|
||||
#define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore HP activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.
|
||||
|
|
|
@ -1244,11 +1244,12 @@ static bool32 TryAegiFormChange(void)
|
|||
bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType)
|
||||
{
|
||||
if ((ability == ABILITY_PROTEAN || ability == ABILITY_LIBERO)
|
||||
&& !gDisableStructs[gBattlerAttacker].usedProteanLibero
|
||||
&& (gBattleMons[battler].type1 != moveType || gBattleMons[battler].type2 != moveType
|
||||
|| (gBattleMons[battler].type3 != moveType && gBattleMons[battler].type3 != TYPE_MYSTERY))
|
||||
&& move != MOVE_STRUGGLE)
|
||||
{
|
||||
SET_BATTLER_TYPE(gBattlerAttacker, moveType);
|
||||
SET_BATTLER_TYPE(battler, moveType);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -1324,6 +1325,8 @@ static void Cmd_attackcanceler(void)
|
|||
// Check Protean activation.
|
||||
if (ProteanTryChangeType(gBattlerAttacker, attackerAbility, gCurrentMove, moveType))
|
||||
{
|
||||
if (B_PROTEAN_LIBERO == GEN_9)
|
||||
gDisableStructs[gBattlerAttacker].usedProteanLibero = TRUE;
|
||||
PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType);
|
||||
gBattlerAbility = gBattlerAttacker;
|
||||
BattleScriptPushCursor();
|
||||
|
@ -10639,7 +10642,9 @@ static void Cmd_setprotectlike(void)
|
|||
if (gCurrentTurnActionNumber == (gBattlersCount - 1))
|
||||
notLastTurn = FALSE;
|
||||
|
||||
if (sProtectSuccessRates[gDisableStructs[gBattlerAttacker].protectUses] >= Random() && notLastTurn)
|
||||
if ((sProtectSuccessRates[gDisableStructs[gBattlerAttacker].protectUses] >= Random() && notLastTurn)
|
||||
|| (gCurrentMove == MOVE_WIDE_GUARD && B_WIDE_GUARD != GEN_5)
|
||||
|| (gCurrentMove == MOVE_QUICK_GUARD && B_QUICK_GUARD != GEN_5))
|
||||
{
|
||||
if (!gBattleMoves[gCurrentMove].argument) // Protects one mon only.
|
||||
{
|
||||
|
|
|
@ -4704,9 +4704,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
}
|
||||
break;
|
||||
case ABILITY_INTREPID_SWORD:
|
||||
if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
||||
if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN)
|
||||
&& !(gBattleStruct->intrepidSwordBoost[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]]))
|
||||
{
|
||||
gBattlerAttacker = battler;
|
||||
if (B_INTREPID_SWORD == GEN_9)
|
||||
gBattleStruct->intrepidSwordBoost[GetBattlerSide(battler)] |= gBitTable[gBattlerPartyIndexes[battler]];
|
||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||
SET_STATCHANGER(STAT_ATK, 1, FALSE);
|
||||
BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn);
|
||||
|
@ -4714,9 +4717,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
}
|
||||
break;
|
||||
case ABILITY_DAUNTLESS_SHIELD:
|
||||
if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN))
|
||||
if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN)
|
||||
&& !(gBattleStruct->dauntlessShieldBoost[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]]))
|
||||
{
|
||||
gBattlerAttacker = battler;
|
||||
if (B_DAUNTLESS_SHIELD == GEN_9)
|
||||
gBattleStruct->dauntlessShieldBoost[GetBattlerSide(battler)] |= gBitTable[gBattlerPartyIndexes[battler]];
|
||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||
SET_STATCHANGER(STAT_DEF, 1, FALSE);
|
||||
BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn);
|
||||
|
@ -4816,10 +4822,10 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
|
||||
if (!gSpecialStatuses[battler].switchInAbilityDone
|
||||
&& GetMonData(mon, MON_DATA_SPECIES) == SPECIES_PALAFIN_HERO
|
||||
&& !gBattleStruct->transformZeroToHero[gBattlerPartyIndexes[battler]][side])
|
||||
&& !(gBattleStruct->transformZeroToHero[side] & gBitTable[gBattlerPartyIndexes[battler]]))
|
||||
{
|
||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||
gBattleStruct->transformZeroToHero[gBattlerPartyIndexes[battler]][side] = TRUE;
|
||||
gBattleStruct->transformZeroToHero[side] |= gBitTable[gBattlerPartyIndexes[battler]];
|
||||
BattleScriptPushCursorAndCallback(BattleScript_ZeroToHeroActivates);
|
||||
effect++;
|
||||
}
|
||||
|
|
47
test/battle/ability/dauntless_shield.c
Normal file
47
test/battle/ability/dauntless_shield.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(P_GEN_8_POKEMON == TRUE);
|
||||
ASSUME(B_PROTEAN_LIBERO == GEN_9);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dauntless Shield raises Attack by one stage")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_ZAMAZENTA) { Ability(ABILITY_DAUNTLESS_SHIELD); }
|
||||
} WHEN {
|
||||
TURN { }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_DAUNTLESS_SHIELD);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Zamazenta's Dauntless Shield raised its Defense!");
|
||||
} THEN {
|
||||
EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 1);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dauntless Shield raises Attack by one stage only once per battle")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_ZAMAZENTA) { Ability(ABILITY_DAUNTLESS_SHIELD); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { SWITCH(opponent, 1); }
|
||||
TURN { SWITCH(opponent, 0); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_DAUNTLESS_SHIELD);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Zamazenta's Dauntless Shield raised its Defense!");
|
||||
NONE_OF {
|
||||
ABILITY_POPUP(opponent, ABILITY_DAUNTLESS_SHIELD);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Zamazenta's Dauntless Shield raised its Defense!");
|
||||
}
|
||||
} THEN {
|
||||
EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
47
test/battle/ability/intrepid_sword.c
Normal file
47
test/battle/ability/intrepid_sword.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(P_GEN_8_POKEMON == TRUE);
|
||||
ASSUME(B_INTREPID_SWORD == GEN_9);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Intrepid Sword raises Attack by one stage")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_ZACIAN) { Ability(ABILITY_INTREPID_SWORD); }
|
||||
} WHEN {
|
||||
TURN { }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_INTREPID_SWORD);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Zacian's Intrepid Sword raised its Attack!");
|
||||
} THEN {
|
||||
EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Intrepid Sword raises Attack by one stage only once per battle")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_ZACIAN) { Ability(ABILITY_INTREPID_SWORD); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { SWITCH(opponent, 1); }
|
||||
TURN { SWITCH(opponent, 0); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_INTREPID_SWORD);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Zacian's Intrepid Sword raised its Attack!");
|
||||
NONE_OF {
|
||||
ABILITY_POPUP(opponent, ABILITY_INTREPID_SWORD);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Zacian's Intrepid Sword raised its Attack!");
|
||||
}
|
||||
} THEN {
|
||||
EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
34
test/battle/ability/protean.c
Normal file
34
test/battle/ability/protean.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(B_PROTEAN_LIBERO == GEN_9);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Protean changes the type of the user only once per switch in")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_REGIROCK);
|
||||
OPPONENT(SPECIES_KECLEON) { Ability(ABILITY_PROTEAN); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_WATER_GUN); }
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
TURN { SWITCH(opponent, 1); }
|
||||
TURN { SWITCH(opponent, 0); }
|
||||
TURN { MOVE(opponent, MOVE_WATER_GUN); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_PROTEAN);
|
||||
MESSAGE("Foe Kecleon transformed into the Water type!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent);
|
||||
NONE_OF {
|
||||
ABILITY_POPUP(opponent, ABILITY_PROTEAN);
|
||||
MESSAGE("Foe Kecleon transformed into the Normal type!");
|
||||
}
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
ABILITY_POPUP(opponent, ABILITY_PROTEAN);
|
||||
MESSAGE("Foe Kecleon transformed into the Water type!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent);
|
||||
}
|
||||
}
|
|
@ -124,13 +124,13 @@ SINGLE_BATTLE_TEST("Spiky Shield does 1/8 dmg of max hp of attackers making cont
|
|||
u16 usedMove = MOVE_NONE;
|
||||
u16 hp = 400, maxHp = 400;
|
||||
|
||||
PARAMETRIZE { usedMove = MOVE_TACKLE; hp = 1;}
|
||||
PARAMETRIZE { usedMove = MOVE_TACKLE;}
|
||||
PARAMETRIZE { usedMove = MOVE_LEER;}
|
||||
PARAMETRIZE { usedMove = MOVE_WATER_GUN;}
|
||||
PARAMETRIZE { usedMove = MOVE_TACKLE; hp = 1; }
|
||||
PARAMETRIZE { usedMove = MOVE_TACKLE; }
|
||||
PARAMETRIZE { usedMove = MOVE_LEER; }
|
||||
PARAMETRIZE { usedMove = MOVE_WATER_GUN; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) {HP(hp); MaxHP(maxHp); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(hp); MaxHP(maxHp); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
|
@ -295,7 +295,7 @@ DOUBLE_BATTLE_TEST("Wide Guard protects self and ally from multi-target moves")
|
|||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_WIDE_GUARD); MOVE(playerLeft, move, target:opponentLeft); }
|
||||
TURN { MOVE(opponentLeft, MOVE_WIDE_GUARD); MOVE(playerLeft, move, target: opponentLeft); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wobbuffet used Wide Guard!");
|
||||
|
@ -320,6 +320,34 @@ DOUBLE_BATTLE_TEST("Wide Guard protects self and ally from multi-target moves")
|
|||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Wide Guard can not fail on consecutive turns")
|
||||
{
|
||||
u8 turns;
|
||||
|
||||
PASSES_RANDOMLY(2, 2);
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_WIDE_GUARD); MOVE(playerLeft, MOVE_HYPER_VOICE, target: opponentLeft); }
|
||||
TURN { MOVE(opponentLeft, MOVE_WIDE_GUARD); MOVE(playerLeft, MOVE_HYPER_VOICE, target: opponentLeft); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
for (turns = 0; turns < 2; turns++) {
|
||||
MESSAGE("Foe Wobbuffet used Wide Guard!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WIDE_GUARD, opponentLeft);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, playerLeft);
|
||||
MESSAGE("Foe Wobbuffet protected itself!");
|
||||
NOT HP_BAR(opponentLeft);
|
||||
MESSAGE("Foe Wobbuffet protected itself!");
|
||||
NOT HP_BAR(opponentRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Quick Guard protects self and ally from priority moves")
|
||||
{
|
||||
u16 move = MOVE_NONE;
|
||||
|
@ -355,6 +383,31 @@ DOUBLE_BATTLE_TEST("Quick Guard protects self and ally from priority moves")
|
|||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Quick Guard can not fail on consecutive turns")
|
||||
{
|
||||
u8 turns;
|
||||
|
||||
PASSES_RANDOMLY(2, 2);
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_QUICK_ATTACK].priority == 1);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_QUICK_GUARD); MOVE(playerLeft, MOVE_QUICK_ATTACK, target: opponentRight); }
|
||||
TURN { MOVE(opponentLeft, MOVE_QUICK_GUARD); MOVE(playerLeft, MOVE_QUICK_ATTACK, target: opponentRight); }
|
||||
} SCENE {
|
||||
for (turns = 0; turns < 2; turns++) {
|
||||
MESSAGE("Foe Wobbuffet used Quick Guard!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUICK_GUARD, opponentLeft);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_QUICK_ATTACK, playerLeft);
|
||||
MESSAGE("Foe Wobbuffet protected itself!");
|
||||
NOT HP_BAR(opponentRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from status moves")
|
||||
{
|
||||
u16 move = MOVE_NONE;
|
||||
|
|
Loading…
Reference in a new issue