mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 03:34:15 +01:00
Sticky web / Court Change / Mirror Armor tests + small fixes (#3160)
Co-authored-by: Eduardo Quezada D'Ottone <eduardo602002@gmail.com> Co-authored-by: Martin Griffin <martin.griffin@algosport.co.uk>
This commit is contained in:
parent
d74cbca0b9
commit
1fb42e4497
@ -212,6 +212,7 @@ struct SideTimer
|
||||
u8 toxicSpikesAmount;
|
||||
u8 stealthRockAmount;
|
||||
u8 stickyWebAmount;
|
||||
u8 stickyWebBattlerId;
|
||||
u8 stickyWebBattlerSide; // Used for Court Change
|
||||
u8 auroraVeilTimer;
|
||||
u8 auroraVeilBattlerId;
|
||||
@ -644,7 +645,6 @@ struct BattleStruct
|
||||
u8 forcedSwitch:4; // For each battler
|
||||
u8 switchInAbilityPostponed:4; // To not activate against an empty field, each bit for battler
|
||||
u8 ballSpriteIds[2]; // item gfx, window gfx
|
||||
u8 stickyWebUser;
|
||||
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.
|
||||
// When using a move which hits multiple opponents which is then bounced by a target, we need to make sure, the move hits both opponents, the one with bounce, and the one without.
|
||||
|
@ -3170,7 +3170,10 @@ static void BattleStartClearSetData(void)
|
||||
|
||||
gBattleStruct->mega.triggerSpriteId = 0xFF;
|
||||
|
||||
gBattleStruct->stickyWebUser = 0xFF;
|
||||
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
|
||||
{
|
||||
gSideTimers[i].stickyWebBattlerId = 0xFF;
|
||||
}
|
||||
gBattleStruct->appearedInBattle = 0;
|
||||
gBattleStruct->beatUpSlot = 0;
|
||||
|
||||
@ -3276,8 +3279,12 @@ void SwitchInClearSetData(void)
|
||||
gBattleStruct->lastMoveFailed &= ~(gBitTable[gActiveBattler]);
|
||||
gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
|
||||
|
||||
if (gActiveBattler == gBattleStruct->stickyWebUser)
|
||||
gBattleStruct->stickyWebUser = 0xFF; // Switched into sticky web user slot so reset it
|
||||
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
|
||||
{
|
||||
// Switched into sticky web user slot, so reset stored battler ID
|
||||
if (gSideTimers[i].stickyWebBattlerId == gActiveBattler)
|
||||
gSideTimers[i].stickyWebBattlerId = 0xFF;
|
||||
}
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
@ -3390,8 +3397,12 @@ void FaintClearSetData(void)
|
||||
|
||||
gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
|
||||
|
||||
if (gActiveBattler == gBattleStruct->stickyWebUser)
|
||||
gBattleStruct->stickyWebUser = 0xFF; // User of sticky web fainted, so reset the stored battler ID
|
||||
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
|
||||
{
|
||||
// User of sticky web fainted, so reset the stored battler ID
|
||||
if (gSideTimers[i].stickyWebBattlerId == gActiveBattler)
|
||||
gSideTimers[i].stickyWebBattlerId = 0xFF;
|
||||
}
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
|
@ -142,8 +142,8 @@ static const u8 sText_PkmnRaisedSpDefALittle[] = _("{B_ATK_PREFIX2}'s {B_CURRENT
|
||||
static const u8 sText_PkmnRaisedDef[] = _("{B_ATK_PREFIX2}'s {B_CURRENT_MOVE}\nraised DEFENSE!");
|
||||
static const u8 sText_PkmnRaisedDefALittle[] = _("{B_ATK_PREFIX2}'s {B_CURRENT_MOVE}\nraised DEFENSE a little!");
|
||||
static const u8 sText_PkmnCoveredByVeil[] = _("{B_ATK_PREFIX2}'s party is covered\nby a veil!");
|
||||
static const u8 sText_PkmnUsedSafeguard[] = _("{B_DEF_NAME_WITH_PREFIX}'s party is protected\nby SAFEGUARD!");
|
||||
static const u8 sText_PkmnSafeguardExpired[] = _("{B_ATK_PREFIX3}'s party is no longer\nprotected by SAFEGUARD!");
|
||||
static const u8 sText_PkmnUsedSafeguard[] = _("{B_DEF_NAME_WITH_PREFIX}'s party is protected\nby Safeguard!");
|
||||
static const u8 sText_PkmnSafeguardExpired[] = _("{B_ATK_PREFIX3}'s party is no longer\nprotected by Safeguard!");
|
||||
static const u8 sText_PkmnWentToSleep[] = _("{B_ATK_NAME_WITH_PREFIX} went\nto sleep!");
|
||||
static const u8 sText_PkmnSleptHealthy[] = _("{B_ATK_NAME_WITH_PREFIX} slept and\nbecame healthy!");
|
||||
static const u8 sText_PkmnWhippedWhirlwind[] = _("{B_ATK_NAME_WITH_PREFIX} whipped\nup a whirlwind!");
|
||||
|
@ -8760,8 +8760,9 @@ static bool32 IsTeatimeAffected(u32 battlerId)
|
||||
|
||||
#define UPDATE_COURTCHANGED_BATTLER(structField)\
|
||||
{ \
|
||||
sideTimerPlayer->structField ^= BIT_SIDE; \
|
||||
sideTimerOpp->structField ^= BIT_SIDE; \
|
||||
temp = sideTimerPlayer->structField; \
|
||||
sideTimerPlayer->structField = BATTLE_OPPOSITE(sideTimerOpp->structField); \
|
||||
sideTimerOpp->structField = BATTLE_OPPOSITE(temp); \
|
||||
} \
|
||||
|
||||
static bool32 CourtChangeSwapSideStatuses(void)
|
||||
@ -8796,9 +8797,7 @@ static bool32 CourtChangeSwapSideStatuses(void)
|
||||
UPDATE_COURTCHANGED_BATTLER(auroraVeilBattlerId);
|
||||
UPDATE_COURTCHANGED_BATTLER(tailwindBattlerId);
|
||||
UPDATE_COURTCHANGED_BATTLER(luckyChantBattlerId);
|
||||
|
||||
// For Mirror Armor only
|
||||
gBattleStruct->stickyWebUser = gBattlerAttacker;
|
||||
UPDATE_COURTCHANGED_BATTLER(stickyWebBattlerId);
|
||||
|
||||
// Track which side originally set the Sticky Web
|
||||
SWAP(sideTimerPlayer->stickyWebBattlerSide, sideTimerOpp->stickyWebBattlerSide, temp);
|
||||
@ -10830,8 +10829,8 @@ static void Cmd_various(void)
|
||||
// If Pokémon which set up Sticky Web is not on the field, no Pokémon have their Speed lowered."
|
||||
gBattlerAttacker = gBattlerTarget; // Initialize 'fail' condition
|
||||
SET_STATCHANGER(STAT_SPEED, 1, TRUE);
|
||||
if (gBattleStruct->stickyWebUser != 0xFF)
|
||||
gBattlerAttacker = gBattleStruct->stickyWebUser;
|
||||
if (gSideTimers[GetBattlerSide(gActiveBattler)].stickyWebBattlerId != 0xFF)
|
||||
gBattlerAttacker = gSideTimers[GetBattlerSide(gActiveBattler)].stickyWebBattlerId;
|
||||
break;
|
||||
}
|
||||
case VARIOUS_CUT_1_3_HP_RAISE_STATS:
|
||||
@ -14092,9 +14091,9 @@ static void Cmd_setstickyweb(void)
|
||||
else
|
||||
{
|
||||
gSideStatuses[targetSide] |= SIDE_STATUS_STICKY_WEB;
|
||||
gSideTimers[targetSide].stickyWebBattlerId = gBattlerAttacker; // For Mirror Armor
|
||||
gSideTimers[targetSide].stickyWebBattlerSide = GetBattlerSide(gBattlerAttacker); // For Court Change/Defiant - set this to the user's side
|
||||
gSideTimers[targetSide].stickyWebAmount = 1;
|
||||
gBattleStruct->stickyWebUser = gBattlerAttacker; // For Mirror Armor
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
202
test/ability_mirror_armor.c
Normal file
202
test/ability_mirror_armor.c
Normal file
@ -0,0 +1,202 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(P_GEN_8_POKEMON == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mirror Armor lowers a stat of the attacking pokemon")
|
||||
{
|
||||
u16 move, statId;
|
||||
|
||||
PARAMETRIZE { move = MOVE_LEER; statId = STAT_DEF; }
|
||||
PARAMETRIZE { move = MOVE_GROWL; statId = STAT_ATK; }
|
||||
PARAMETRIZE { move = MOVE_SWEET_SCENT; statId = STAT_EVASION; }
|
||||
PARAMETRIZE { move = MOVE_SAND_ATTACK; statId = STAT_ACC; }
|
||||
PARAMETRIZE { move = MOVE_CONFIDE; statId = STAT_SPATK; }
|
||||
PARAMETRIZE { move = MOVE_FAKE_TEARS; statId = STAT_SPDEF; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_CORVIKNIGHT) {Ability(ABILITY_MIRROR_ARMOR);}
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, move); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ABILITY_MIRROR_ARMOR);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
switch (statId)
|
||||
{
|
||||
case STAT_DEF:
|
||||
MESSAGE("Foe Wynaut's Defense fell!");
|
||||
break;
|
||||
case STAT_ATK:
|
||||
MESSAGE("Foe Wynaut's Attack fell!");
|
||||
break;
|
||||
case STAT_EVASION:
|
||||
MESSAGE("Foe Wynaut's evasiveness harshly fell!");
|
||||
break;
|
||||
case STAT_ACC:
|
||||
MESSAGE("Foe Wynaut's accuracy fell!");
|
||||
break;
|
||||
case STAT_SPATK:
|
||||
MESSAGE("Foe Wynaut's Sp. Atk fell!");
|
||||
break;
|
||||
case STAT_SPDEF:
|
||||
MESSAGE("Foe Wynaut's Sp. Def harshly fell!");
|
||||
break;
|
||||
}
|
||||
} THEN {
|
||||
EXPECT_EQ(player->statStages[statId], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(opponent->statStages[statId], (statId == STAT_SPDEF || statId == STAT_EVASION) ? DEFAULT_STAT_STAGE - 2 : DEFAULT_STAT_STAGE - 1);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mirror Armor triggers even if the attacking Pokemon also has Mirror Armor ability")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
|
||||
OPPONENT(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_LEER); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Corviknigh used Leer!");
|
||||
ABILITY_POPUP(player, ABILITY_MIRROR_ARMOR);
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Corviknigh's Defense fell!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE - 1);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mirror Armor doesn't lower the stats of an attacking Pokemon with the Clear Body ability")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Ability(ABILITY_CLEAR_BODY); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_LEER); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wynaut used Leer!");
|
||||
ABILITY_POPUP(player, ABILITY_MIRROR_ARMOR);
|
||||
ABILITY_POPUP(opponent, ABILITY_CLEAR_BODY);
|
||||
MESSAGE("Foe Wynaut's Clear Body prevents stat loss!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mirror Armor lowers the Attack of Pokemon with Intimidate")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
|
||||
OPPONENT(SPECIES_GYARADOS) { Ability(ABILITY_INTIMIDATE); }
|
||||
} WHEN {
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_INTIMIDATE);
|
||||
ABILITY_POPUP(player, ABILITY_MIRROR_ARMOR);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Gyarados's Attack fell!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Unsure whether this should or should not fail, as Showdown has conflicting information. Needs testing in gen8 games.
|
||||
SINGLE_BATTLE_TEST("Mirror Armor doesn't lower the stats of an attacking Pokemon behind Substitute")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SUBSTITUTE); }
|
||||
TURN { MOVE(opponent, MOVE_LEER); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wynaut used Substitute!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUBSTITUTE, opponent);
|
||||
MESSAGE("Foe Wynaut used Leer!");
|
||||
ABILITY_POPUP(player, ABILITY_MIRROR_ARMOR);
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
} THEN {
|
||||
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mirror Armor raises the stat of an attacking Pokemon with Contrary")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_CORVIKNIGHT) {Ability(ABILITY_MIRROR_ARMOR);}
|
||||
OPPONENT(SPECIES_SHUCKLE) {Ability(ABILITY_CONTRARY);}
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_LEER); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Shuckle used Leer!");
|
||||
ABILITY_POPUP(player, ABILITY_MIRROR_ARMOR);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Shuckle's Defense rose!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 1);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mirror Armor doesn't lower the stat of the attacking Pokemon if it is already at -6")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_CORVIKNIGHT) {Ability(ABILITY_MIRROR_ARMOR);}
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SCREECH); }
|
||||
TURN { MOVE(player, MOVE_SCREECH); }
|
||||
TURN { MOVE(player, MOVE_SCREECH); }
|
||||
TURN { MOVE(opponent, MOVE_LEER); }
|
||||
} SCENE {
|
||||
MESSAGE("Corviknigh used Screech!");
|
||||
MESSAGE("Corviknigh used Screech!");
|
||||
MESSAGE("Corviknigh used Screech!");
|
||||
MESSAGE("Foe Wynaut used Leer!");
|
||||
ABILITY_POPUP(player, ABILITY_MIRROR_ARMOR);
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Wynaut's Defense won't go lower!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(opponent->statStages[STAT_DEF], MIN_STAT_STAGE);
|
||||
}
|
||||
}
|
||||
|
||||
// This behaviour needs to be verified in the actual games. Currently it's written to follow Showdown's logic.
|
||||
DOUBLE_BATTLE_TEST("Mirror Armor lowers Speed of the partner Pokemon after Court Change was used by the opponent after it set up Sticky Web")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB);
|
||||
ASSUME(gBattleMoves[MOVE_COURT_CHANGE].effect == EFFECT_COURT_CHANGE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_CORVIKNIGHT) {Ability(ABILITY_MIRROR_ARMOR); Item(ITEM_IRON_BALL); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_STICKY_WEB); }
|
||||
TURN { MOVE(opponentLeft, MOVE_COURT_CHANGE); }
|
||||
TURN { SWITCH(playerRight, 2);}
|
||||
TURN { }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Sticky Web!");
|
||||
MESSAGE("Foe Wynaut used Court Change!");
|
||||
MESSAGE("Foe Wynaut swapped the battle effects affecting each side!");
|
||||
MESSAGE("Go! Corviknigh!");
|
||||
MESSAGE("Corviknigh was caught in a Sticky Web!");
|
||||
ABILITY_POPUP(playerRight, ABILITY_MIRROR_ARMOR);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
|
||||
MESSAGE("Wobbuffet's Speed fell!");
|
||||
}
|
||||
}
|
@ -112,7 +112,7 @@ SINGLE_BATTLE_TEST("Berserk Gene does not confuse when Safeguard is active")
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
MESSAGE("Using Berserk Gene, the Attack of Wobbuffet sharply rose!");
|
||||
MESSAGE("Wobbuffet's party is protected by SAFEGUARD!");
|
||||
MESSAGE("Wobbuffet's party is protected by Safeguard!");
|
||||
NOT MESSAGE("Wobbuffet became confused!");
|
||||
}
|
||||
}
|
||||
|
153
test/move_effect_court_change.c
Normal file
153
test/move_effect_court_change.c
Normal file
@ -0,0 +1,153 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_COURT_CHANGE].effect == EFFECT_COURT_CHANGE);
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Court Change swaps entry hazards used by the opponent")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_STICKY_WEB); MOVE(opponentRight, MOVE_STEALTH_ROCK); }
|
||||
TURN { MOVE(opponentLeft, MOVE_SPIKES); MOVE(opponentRight, MOVE_TOXIC_SPIKES); }
|
||||
TURN { MOVE(playerLeft, MOVE_COURT_CHANGE); }
|
||||
TURN { SWITCH(playerLeft, 2); SWITCH(opponentLeft, 2); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wobbuffet used Sticky Web!");
|
||||
MESSAGE("Foe Wobbuffet used Stealth Rock!");
|
||||
MESSAGE("Foe Wobbuffet used Spikes!");
|
||||
MESSAGE("Foe Wobbuffet used Toxic Spikes!");
|
||||
MESSAGE("Wynaut used Court Change!");
|
||||
MESSAGE("Wynaut swapped the battle effects affecting each side!");
|
||||
MESSAGE("Go! Wynaut!");
|
||||
NONE_OF {
|
||||
MESSAGE("Wynaut is hurt by spikes!");
|
||||
MESSAGE("Pointed stones dug into Wynaut!");
|
||||
MESSAGE("Wynaut was poisoned!");
|
||||
MESSAGE("Wynaut was caught in a Sticky Web!");
|
||||
}
|
||||
MESSAGE("2 sent out Wobbuffet!");
|
||||
MESSAGE("Foe Wobbuffet is hurt by spikes!");
|
||||
MESSAGE("Pointed stones dug into Foe Wobbuffet!");
|
||||
MESSAGE("Foe Wobbuffet was poisoned!");
|
||||
MESSAGE("Foe Wobbuffet was caught in a Sticky Web!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Court Change swaps entry hazards used by the player")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_STICKY_WEB); MOVE(playerRight, MOVE_STEALTH_ROCK); }
|
||||
TURN { MOVE(playerLeft, MOVE_SPIKES); MOVE(playerRight, MOVE_TOXIC_SPIKES); }
|
||||
TURN { MOVE(opponentLeft, MOVE_COURT_CHANGE); }
|
||||
TURN { SWITCH(opponentLeft, 2); SWITCH(playerLeft, 2); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Sticky Web!");
|
||||
MESSAGE("Wobbuffet used Stealth Rock!");
|
||||
MESSAGE("Wobbuffet used Spikes!");
|
||||
MESSAGE("Wobbuffet used Toxic Spikes!");
|
||||
MESSAGE("Foe Wynaut used Court Change!");
|
||||
MESSAGE("Foe Wynaut swapped the battle effects affecting each side!");
|
||||
MESSAGE("Go! Wobbuffet!");
|
||||
MESSAGE("Wobbuffet is hurt by spikes!");
|
||||
MESSAGE("Pointed stones dug into Wobbuffet!");
|
||||
MESSAGE("Wobbuffet was poisoned!");
|
||||
MESSAGE("Wobbuffet was caught in a Sticky Web!");
|
||||
MESSAGE("2 sent out Wynaut!");
|
||||
NONE_OF {
|
||||
MESSAGE("Foe Wynaut is hurt by spikes!");
|
||||
MESSAGE("Pointed stones dug into Foe Wynaut!");
|
||||
MESSAGE("Foe Wynaut was poisoned!");
|
||||
MESSAGE("Foe Wynaut was caught in a Sticky Web!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Court Change used by the player swaps Mist, Safeguard, Lucky Chant, Reflect, Light Screen, Tailwind")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_MIST); MOVE(opponentRight, MOVE_SAFEGUARD); }
|
||||
TURN { MOVE(opponentLeft, MOVE_LUCKY_CHANT); MOVE(opponentRight, MOVE_REFLECT); }
|
||||
TURN { MOVE(opponentLeft, MOVE_LIGHT_SCREEN); MOVE(opponentRight, MOVE_TAILWIND); }
|
||||
TURN { MOVE(playerLeft, MOVE_COURT_CHANGE); }
|
||||
TURN { }
|
||||
TURN { }
|
||||
TURN { }
|
||||
TURN { }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wobbuffet used Mist!");
|
||||
MESSAGE("Foe Wobbuffet used Safeguard!");
|
||||
MESSAGE("Foe Wobbuffet used Lucky Chant!");
|
||||
MESSAGE("Foe Wobbuffet used Reflect!");
|
||||
MESSAGE("Foe Wobbuffet used Light Screen!");
|
||||
MESSAGE("Foe Wobbuffet used Tailwind!");
|
||||
MESSAGE("Wynaut used Court Change!");
|
||||
MESSAGE("Wynaut swapped the battle effects affecting each side!");
|
||||
// The effects now end for the player side.
|
||||
MESSAGE("Ally's Mist wore off!");
|
||||
MESSAGE("Ally's party is no longer protected by Safeguard!");
|
||||
MESSAGE("Ally's Reflect wore off!");
|
||||
MESSAGE("Your team's Lucky Chant wore off!");
|
||||
MESSAGE("Your team's tailwind petered out!");
|
||||
MESSAGE("Ally's Light Screen wore off!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Court Change used by the opponent swaps Mist, Safeguard, Lucky Chant, Reflect, Light Screen, Tailwind")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_MIST); MOVE(playerRight, MOVE_SAFEGUARD); }
|
||||
TURN { MOVE(playerLeft, MOVE_LUCKY_CHANT); MOVE(playerRight, MOVE_REFLECT); }
|
||||
TURN { MOVE(playerLeft, MOVE_LIGHT_SCREEN); MOVE(playerRight, MOVE_TAILWIND); }
|
||||
TURN { MOVE(opponentLeft, MOVE_COURT_CHANGE); }
|
||||
TURN { }
|
||||
TURN { }
|
||||
TURN { }
|
||||
TURN { }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Mist!");
|
||||
MESSAGE("Wobbuffet used Safeguard!");
|
||||
MESSAGE("Wobbuffet used Lucky Chant!");
|
||||
MESSAGE("Wobbuffet used Reflect!");
|
||||
MESSAGE("Wobbuffet used Light Screen!");
|
||||
MESSAGE("Wobbuffet used Tailwind!");
|
||||
MESSAGE("Foe Wynaut used Court Change!");
|
||||
MESSAGE("Foe Wynaut swapped the battle effects affecting each side!");
|
||||
// The effects now end for the player side.
|
||||
MESSAGE("Foe's Mist wore off!");
|
||||
MESSAGE("Foe's party is no longer protected by Safeguard!");
|
||||
MESSAGE("Foe's Reflect wore off!");
|
||||
MESSAGE("The opposing team's Lucky Chant wore off!");
|
||||
MESSAGE("The opposing team's tailwind petered out!");
|
||||
MESSAGE("Foe's Light Screen wore off!");
|
||||
}
|
||||
}
|
@ -125,7 +125,7 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Mist and Safeguard
|
||||
STATUS_ICON(opponentRight, badPoison: TRUE);
|
||||
}
|
||||
else {
|
||||
MESSAGE("Foe Wobbuffet's party is protected by SAFEGUARD!");
|
||||
MESSAGE("Foe Wobbuffet's party is protected by Safeguard!");
|
||||
NOT STATUS_ICON(opponentRight, badPoison: TRUE);
|
||||
}
|
||||
}
|
||||
|
237
test/move_effect_sticky_web.c
Normal file
237
test/move_effect_sticky_web.c
Normal file
@ -0,0 +1,237 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sticky Web lowers Speed by 1 on switch-in")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_STICKY_WEB); }
|
||||
TURN { SWITCH(opponent, 1); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, player);
|
||||
MESSAGE("A sticky web spreads out on the ground around the opposing team!");
|
||||
MESSAGE("2 sent out Wynaut!");
|
||||
MESSAGE("Foe Wynaut was caught in a Sticky Web!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Wynaut's Speed fell!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sticky Web can only be set up 1 time")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_STICKY_WEB); }
|
||||
TURN { MOVE(player, MOVE_STICKY_WEB); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Sticky Web!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, player);
|
||||
MESSAGE("A sticky web spreads out on the ground around the opposing team!");
|
||||
|
||||
MESSAGE("Wobbuffet used Sticky Web!");
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, player);
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DOUBLE_BATTLE_TEST("Sticky Web lowers Speed by 1 in a double battle after Explosion fainting both mons")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
|
||||
PLAYER(SPECIES_WOBBUFFET) {Speed(5);}
|
||||
PLAYER(SPECIES_WOBBUFFET) {HP(1500); Speed(10);}
|
||||
PLAYER(SPECIES_WOBBUFFET) {Speed(10);}
|
||||
OPPONENT(SPECIES_WOBBUFFET) {HP(1); Speed(1);}
|
||||
OPPONENT(SPECIES_WOBBUFFET) {HP(1); Speed(1);}
|
||||
OPPONENT(SPECIES_WYNAUT) {Speed(10);}
|
||||
OPPONENT(SPECIES_WYNAUT) {Speed(10);}
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_STICKY_WEB); MOVE(playerLeft, MOVE_EXPLOSION); SEND_OUT(playerLeft, 2); SEND_OUT(opponentLeft, 2); SEND_OUT(opponentRight, 3); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, playerRight);
|
||||
MESSAGE("A sticky web spreads out on the ground around the opposing team!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EXPLOSION, playerLeft);
|
||||
MESSAGE("2 sent out Wynaut!");
|
||||
MESSAGE("Foe Wynaut was caught in a Sticky Web!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
|
||||
MESSAGE("Foe Wynaut's Speed fell!");
|
||||
MESSAGE("2 sent out Wynaut!");
|
||||
MESSAGE("Foe Wynaut was caught in a Sticky Web!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
|
||||
MESSAGE("Foe Wynaut's Speed fell!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sticky Web raises Speed by 1 for a Pokemon with Contrary")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_SHUCKLE) { Ability(ABILITY_CONTRARY); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_STICKY_WEB); }
|
||||
TURN { SWITCH(opponent, 1); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, player);
|
||||
MESSAGE("A sticky web spreads out on the ground around the opposing team!");
|
||||
MESSAGE("2 sent out Shuckle!");
|
||||
MESSAGE("Foe Shuckle was caught in a Sticky Web!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Shuckle's Speed rose!");
|
||||
}
|
||||
}
|
||||
|
||||
#define BATTLER_OPPONENT (opponentSetUpper == 0 ? opponentLeft : opponentRight)
|
||||
#define BATTLER_PLAYER (playerSetUpper == 0 ? playerLeft : playerRight)
|
||||
|
||||
DOUBLE_BATTLE_TEST("Sticky Web has correct interactions with Mirror Armor - the battler which set up Sticky Web has its Speed lowered instead")
|
||||
{
|
||||
u8 playerSetUpper, opponentSetUpper; // 0 left, 1 right
|
||||
|
||||
PARAMETRIZE {playerSetUpper = 0; opponentSetUpper = 0; }
|
||||
PARAMETRIZE {playerSetUpper = 0; opponentSetUpper = 1; }
|
||||
PARAMETRIZE {playerSetUpper = 1; opponentSetUpper = 0; }
|
||||
PARAMETRIZE {playerSetUpper = 1; opponentSetUpper = 1; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(P_GEN_8_POKEMON == TRUE);
|
||||
PLAYER(SPECIES_SQUIRTLE);
|
||||
PLAYER(SPECIES_CHARMANDER);
|
||||
PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); Item(ITEM_IRON_BALL); } // Iron Ball, so that flying type Corviknight is affected by Sticky Web.
|
||||
OPPONENT(SPECIES_CATERPIE);
|
||||
OPPONENT(SPECIES_WEEDLE);
|
||||
} WHEN {
|
||||
TURN { MOVE(BATTLER_OPPONENT, MOVE_STICKY_WEB); }
|
||||
TURN { MOVE(BATTLER_PLAYER, MOVE_STICKY_WEB); }
|
||||
TURN { SWITCH(playerRight, 2); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, BATTLER_OPPONENT);
|
||||
MESSAGE("A sticky web spreads out on the ground around your team!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, BATTLER_PLAYER);
|
||||
MESSAGE("A sticky web spreads out on the ground around the opposing team!");
|
||||
|
||||
MESSAGE("Go! Corviknigh!");
|
||||
MESSAGE("Corviknigh was caught in a Sticky Web!");
|
||||
ABILITY_POPUP(playerRight, ABILITY_MIRROR_ARMOR);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, BATTLER_OPPONENT);
|
||||
if (opponentSetUpper == 0) {
|
||||
MESSAGE("Foe Caterpie's Speed fell!");
|
||||
} else {
|
||||
MESSAGE("Foe Weedle's Speed fell!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef BATTLER_OPPONENT
|
||||
#undef BATTLER_PLAYER
|
||||
|
||||
DOUBLE_BATTLE_TEST("Sticky Web has correct interactions with Mirror Armor - no one has their Speed lowered if the set upper switched")
|
||||
{
|
||||
u16 speedPlayer, speedOpponent;
|
||||
|
||||
// We need to make sure Sticky Web user saves for both sides, so it doesn't matter who sets it first.
|
||||
PARAMETRIZE { speedPlayer = 5; speedOpponent = 10; }
|
||||
PARAMETRIZE { speedPlayer = 10; speedOpponent = 5; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(P_GEN_8_POKEMON == TRUE);
|
||||
PLAYER(SPECIES_SQUIRTLE) { Speed(speedPlayer); }
|
||||
PLAYER(SPECIES_CHARMANDER) { Speed(speedPlayer); }
|
||||
PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); Item(ITEM_IRON_BALL); Speed(speedOpponent); } // Iron Ball, so that flying type Corviknight is affected by Sticky Web.
|
||||
OPPONENT(SPECIES_CATERPIE) { Speed(speedOpponent); }
|
||||
OPPONENT(SPECIES_WEEDLE) { Speed(speedOpponent); }
|
||||
OPPONENT(SPECIES_PIDGEY) { Speed(speedOpponent); } // Flying type,so not affected by Sticky Web.
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_STICKY_WEB); MOVE(playerRight, MOVE_STICKY_WEB); }
|
||||
TURN { SWITCH(opponentLeft, 2); }
|
||||
TURN { SWITCH(playerRight, 2); }
|
||||
} SCENE {
|
||||
if (speedPlayer > speedOpponent) {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, playerRight);
|
||||
MESSAGE("A sticky web spreads out on the ground around the opposing team!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, opponentLeft);
|
||||
MESSAGE("A sticky web spreads out on the ground around your team!");
|
||||
} else {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, opponentLeft);
|
||||
MESSAGE("A sticky web spreads out on the ground around your team!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, playerRight);
|
||||
MESSAGE("A sticky web spreads out on the ground around the opposing team!");
|
||||
}
|
||||
|
||||
MESSAGE("Go! Corviknigh!");
|
||||
MESSAGE("Corviknigh was caught in a Sticky Web!");
|
||||
ABILITY_POPUP(playerRight, ABILITY_MIRROR_ARMOR);
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
|
||||
} THEN {
|
||||
EXPECT_EQ(playerLeft->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(playerRight->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(opponentLeft->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(opponentRight->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Sticky Web has correct interactions with Mirror Armor - no one has their Speed lowered if the set upper fainted")
|
||||
{
|
||||
bool8 hasReplacement;
|
||||
|
||||
// We need to make sure Sticky Web user saves for both sides, so it doesn't matter who sets it first.
|
||||
PARAMETRIZE {hasReplacement = TRUE;}
|
||||
PARAMETRIZE {hasReplacement = FALSE;}
|
||||
|
||||
GIVEN {
|
||||
ASSUME(P_GEN_8_POKEMON == TRUE);
|
||||
ASSUME(gBattleMoves[MOVE_MEMENTO].effect == EFFECT_MEMENTO);
|
||||
PLAYER(SPECIES_SQUIRTLE) {Speed(5); }
|
||||
PLAYER(SPECIES_CHARMANDER) {Speed(5); }
|
||||
PLAYER(SPECIES_CORVIKNIGHT) {Ability(ABILITY_MIRROR_ARMOR); Item(ITEM_IRON_BALL); Speed(5); } // Iron Ball, so that flying type Corviknight is affected by Sticky Web.
|
||||
OPPONENT(SPECIES_CATERPIE) {Speed(7); }
|
||||
OPPONENT(SPECIES_WEEDLE) {Speed(7); }
|
||||
if (hasReplacement) {
|
||||
OPPONENT(SPECIES_PIDGEY) {Speed(7); }
|
||||
}
|
||||
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_STICKY_WEB); }
|
||||
if (hasReplacement) {
|
||||
TURN { MOVE(opponentLeft, MOVE_MEMENTO, target:playerLeft); SEND_OUT(opponentLeft, 2); }
|
||||
} else {
|
||||
TURN { MOVE(opponentLeft, MOVE_MEMENTO, target:playerLeft);}
|
||||
}
|
||||
TURN { SWITCH(playerRight, 2); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, opponentLeft);
|
||||
MESSAGE("A sticky web spreads out on the ground around your team!");
|
||||
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MEMENTO, opponentLeft);
|
||||
MESSAGE("Foe Caterpie fainted!");
|
||||
if (hasReplacement) {
|
||||
MESSAGE("2 sent out Pidgey!");
|
||||
}
|
||||
|
||||
MESSAGE("Go! Corviknigh!");
|
||||
MESSAGE("Corviknigh was caught in a Sticky Web!");
|
||||
ABILITY_POPUP(playerRight, ABILITY_MIRROR_ARMOR);
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
|
||||
} THEN {
|
||||
if (hasReplacement) {
|
||||
EXPECT_EQ(opponentLeft->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
EXPECT_EQ(playerLeft->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(playerRight->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
|
||||
EXPECT_EQ(opponentRight->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user