Merge pull request #2707 from mrgriffin/rhh-battle-tests-02-19
Battle Tests (Feb 19)
This commit is contained in:
commit
41e0278127
13 changed files with 613 additions and 33 deletions
|
@ -2247,3 +2247,7 @@
|
|||
various \battler, VARIOUS_JUMP_IF_EMERGENCY_EXITED
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro hitswitchtargetfailed
|
||||
various 0, VARIOUS_HIT_SWITCH_TARGET_FAILED
|
||||
.endm
|
||||
|
|
|
@ -2128,9 +2128,14 @@ BattleScript_EffectHitSwitchTarget:
|
|||
moveendall
|
||||
jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut
|
||||
jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted
|
||||
tryhitswitchtarget BattleScript_EffectHitSwitchTargetMoveEnd
|
||||
BattleScript_EffectHitSwitchTargetMoveEnd:
|
||||
end
|
||||
tryhitswitchtarget BattleScript_MoveEnd
|
||||
forcerandomswitch BattleScript_HitSwitchTargetForceRandomSwitchFailed
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_HitSwitchTargetForceRandomSwitchFailed:
|
||||
hitswitchtargetfailed
|
||||
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectClearSmog:
|
||||
setmoveeffect MOVE_EFFECT_CLEAR_SMOG
|
||||
|
@ -3708,7 +3713,6 @@ BattleScript_EffectRoar::
|
|||
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
|
||||
accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE
|
||||
jumpifbattletype BATTLE_TYPE_ARENA, BattleScript_ButItFailed
|
||||
BattleScript_ForceRandomSwitch::
|
||||
forcerandomswitch BattleScript_ButItFailed
|
||||
|
||||
BattleScript_EffectMultiHit::
|
||||
|
|
|
@ -651,6 +651,7 @@ struct BattleStruct
|
|||
// 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.
|
||||
u8 attackerBeforeBounce:2;
|
||||
u8 beatUpSlot:3;
|
||||
bool8 hitSwitchTargetFailed:1;
|
||||
u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit.
|
||||
u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching)
|
||||
bool8 allowedToChangeFormInWeather[PARTY_SIZE][2]; // For each party member and side, used by Ice Face.
|
||||
|
|
|
@ -293,7 +293,6 @@ extern const u8 BattleScript_WishMegaEvolution[];
|
|||
extern const u8 BattleScript_MoveEffectRecoilWithStatus[];
|
||||
extern const u8 BattleScript_EffectWithChance[];
|
||||
extern const u8 BattleScript_MoveEffectClearSmog[];
|
||||
extern const u8 BattleScript_ForceRandomSwitch[];
|
||||
extern const u8 BattleScript_SideStatusWoreOffReturn[];
|
||||
extern const u8 BattleScript_MoveEffectSmackDown[];
|
||||
extern const u8 BattleScript_MoveEffectFlameBurst[];
|
||||
|
|
|
@ -258,6 +258,7 @@
|
|||
#define VARIOUS_JUMP_IF_NO_VALID_TARGETS 166
|
||||
#define VARIOUS_JUMP_IF_EMERGENCY_EXITED 167
|
||||
#define VARIOUS_STORE_HEALING_WISH 168
|
||||
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 169
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 0
|
||||
|
|
|
@ -5968,7 +5968,7 @@ static void Cmd_moveend(void)
|
|||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_RED_CARD:
|
||||
if (gBattleMoves[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET
|
||||
if ((gBattleMoves[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !TestSheerForceFlag(gBattlerAttacker, gCurrentMove)
|
||||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG)
|
||||
|
@ -6199,6 +6199,7 @@ static void Cmd_moveend(void)
|
|||
gBattleStruct->zmove.active = FALSE;
|
||||
gBattleStruct->zmove.toBeUsed[gBattlerAttacker] = MOVE_NONE;
|
||||
gBattleStruct->zmove.effect = EFFECT_HIT;
|
||||
gBattleStruct->hitSwitchTargetFailed = FALSE;
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_COUNT:
|
||||
|
@ -9792,7 +9793,7 @@ static void Cmd_various(void)
|
|||
&& GetBattlerAbility(gBattlerTarget) != ABILITY_GUARD_DOG)
|
||||
{
|
||||
gBattleScripting.switchCase = B_SWITCH_HIT;
|
||||
gBattlescriptCurrInstr = BattleScript_ForceRandomSwitch;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -11067,6 +11068,13 @@ static void Cmd_various(void)
|
|||
gBattleStruct->storedHealingWish |= gBitTable[gActiveBattler];
|
||||
break;
|
||||
}
|
||||
case VARIOUS_HIT_SWITCH_TARGET_FAILED:
|
||||
{
|
||||
VARIOUS_ARGS();
|
||||
gBattleStruct->hitSwitchTargetFailed = TRUE;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
return;
|
||||
}
|
||||
} // End of switch (cmd->id)
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
@ -12089,8 +12097,8 @@ static void Cmd_forcerandomswitch(void)
|
|||
s32 lastMonId = 0; // + 1
|
||||
s32 monsCount;
|
||||
struct Pokemon *party = NULL;
|
||||
s32 validMons = 0;
|
||||
s32 minNeeded;
|
||||
u8 validMons[PARTY_SIZE];
|
||||
s32 validMonsCount = 0;
|
||||
|
||||
bool32 redCardForcedSwitch = FALSE;
|
||||
|
||||
|
@ -12147,7 +12155,6 @@ static void Cmd_forcerandomswitch(void)
|
|||
firstMonId = 0;
|
||||
lastMonId = 6;
|
||||
monsCount = 6;
|
||||
minNeeded = 2;
|
||||
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
|
||||
battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)];
|
||||
}
|
||||
|
@ -12166,7 +12173,6 @@ static void Cmd_forcerandomswitch(void)
|
|||
lastMonId = PARTY_SIZE / 2;
|
||||
}
|
||||
monsCount = PARTY_SIZE / 2;
|
||||
minNeeded = 1;
|
||||
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
|
||||
battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)];
|
||||
}
|
||||
|
@ -12184,7 +12190,6 @@ static void Cmd_forcerandomswitch(void)
|
|||
lastMonId = PARTY_SIZE / 2;
|
||||
}
|
||||
monsCount = PARTY_SIZE / 2;
|
||||
minNeeded = 1;
|
||||
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
|
||||
battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)];
|
||||
}
|
||||
|
@ -12195,7 +12200,6 @@ static void Cmd_forcerandomswitch(void)
|
|||
firstMonId = 0;
|
||||
lastMonId = PARTY_SIZE;
|
||||
monsCount = PARTY_SIZE;
|
||||
minNeeded = 2; // since there are two opponents, it has to be a double battle
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -12210,7 +12214,6 @@ static void Cmd_forcerandomswitch(void)
|
|||
lastMonId = PARTY_SIZE / 2;
|
||||
}
|
||||
monsCount = PARTY_SIZE / 2;
|
||||
minNeeded = 1;
|
||||
}
|
||||
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
|
||||
battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)];
|
||||
|
@ -12220,7 +12223,6 @@ static void Cmd_forcerandomswitch(void)
|
|||
firstMonId = 0;
|
||||
lastMonId = PARTY_SIZE;
|
||||
monsCount = PARTY_SIZE;
|
||||
minNeeded = 2;
|
||||
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
|
||||
battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)];
|
||||
}
|
||||
|
@ -12229,7 +12231,6 @@ static void Cmd_forcerandomswitch(void)
|
|||
firstMonId = 0;
|
||||
lastMonId = PARTY_SIZE;
|
||||
monsCount = PARTY_SIZE;
|
||||
minNeeded = 1;
|
||||
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget]; // there is only one pokemon out in single battles
|
||||
battler1PartyId = gBattlerPartyIndexes[gBattlerTarget];
|
||||
}
|
||||
|
@ -12238,13 +12239,15 @@ static void Cmd_forcerandomswitch(void)
|
|||
{
|
||||
if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
|
||||
&& !GetMonData(&party[i], MON_DATA_IS_EGG)
|
||||
&& GetMonData(&party[i], MON_DATA_HP) != 0)
|
||||
&& GetMonData(&party[i], MON_DATA_HP) != 0
|
||||
&& i != battler1PartyId
|
||||
&& i != battler2PartyId)
|
||||
{
|
||||
validMons++;
|
||||
validMons[validMonsCount++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!redCardForcedSwitch && validMons <= minNeeded)
|
||||
if (validMonsCount == 0)
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
|
@ -12252,19 +12255,7 @@ static void Cmd_forcerandomswitch(void)
|
|||
{
|
||||
*(gBattleStruct->battlerPartyIndexes + gBattlerTarget) = gBattlerPartyIndexes[gBattlerTarget];
|
||||
gBattlescriptCurrInstr = BattleScript_RoarSuccessSwitch;
|
||||
|
||||
do
|
||||
{
|
||||
i = Random() % monsCount;
|
||||
i += firstMonId;
|
||||
}
|
||||
while (i == battler2PartyId
|
||||
|| i == battler1PartyId
|
||||
|| GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_NONE
|
||||
|| GetMonData(&party[i], MON_DATA_IS_EGG) == TRUE
|
||||
|| GetMonData(&party[i], MON_DATA_HP) == 0);
|
||||
|
||||
*(gBattleStruct->monToSwitchIntoId + gBattlerTarget) = i;
|
||||
*(gBattleStruct->monToSwitchIntoId + gBattlerTarget) = validMons[Random() % validMonsCount];
|
||||
|
||||
if (!IsMultiBattle())
|
||||
SwitchPartyOrder(gBattlerTarget);
|
||||
|
|
|
@ -15,6 +15,6 @@ SINGLE_BATTLE_TEST("Blaze boosts Fire-type moves in a pinch", s16 damage)
|
|||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_GT(results[1].damage, results[0].damage);
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
|
20
test/ability_overgrow.c
Normal file
20
test/ability_overgrow.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Overgrow boosts Grass-type moves in a pinch", s16 damage)
|
||||
{
|
||||
u16 hp;
|
||||
PARAMETRIZE { hp = 99; }
|
||||
PARAMETRIZE { hp = 33; }
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_VINE_WHIP].type == TYPE_GRASS);
|
||||
PLAYER(SPECIES_BULBASAUR) { Ability(ABILITY_OVERGROW); MaxHP(99); HP(hp); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_VINE_WHIP); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
}
|
||||
}
|
20
test/ability_swarm.c
Normal file
20
test/ability_swarm.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Swarm boosts Bug-type moves in a pinch", s16 damage)
|
||||
{
|
||||
u16 hp;
|
||||
PARAMETRIZE { hp = 99; }
|
||||
PARAMETRIZE { hp = 33; }
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_BUG_BITE].type == TYPE_BUG);
|
||||
PLAYER(SPECIES_LEDYBA) { Ability(ABILITY_SWARM); MaxHP(99); HP(hp); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_BUG_BITE); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
}
|
||||
}
|
20
test/ability_torrent.c
Normal file
20
test/ability_torrent.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Torrent boosts Water-type moves in a pinch", s16 damage)
|
||||
{
|
||||
u16 hp;
|
||||
PARAMETRIZE { hp = 99; }
|
||||
PARAMETRIZE { hp = 33; }
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_BUBBLE].type == TYPE_WATER);
|
||||
PLAYER(SPECIES_SQUIRTLE) { Ability(ABILITY_TORRENT); MaxHP(99); HP(hp); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_BUBBLE); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
}
|
||||
}
|
378
test/hold_effect_red_card.c
Normal file
378
test/hold_effect_red_card.c
Normal file
|
@ -0,0 +1,378 @@
|
|||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gItems[ITEM_RED_CARD].holdEffect == HOLD_EFFECT_RED_CARD);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card switches the attacker with a random non-fainted replacement")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 2);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_BULBASAUR);
|
||||
OPPONENT(SPECIES_CHARMANDER);
|
||||
OPPONENT(SPECIES_SQUIRTLE) { HP(0); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
MESSAGE("Foe Bulbasaur was dragged out!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Red Card switches the target with a random non-battler, non-fainted replacement")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 2);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_BULBASAUR);
|
||||
OPPONENT(SPECIES_CHARMANDER);
|
||||
OPPONENT(SPECIES_SQUIRTLE) { HP(0); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_TACKLE, target: playerLeft); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
MESSAGE("Foe Bulbasaur was dragged out!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card does not activate if holder faints")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); Item(ITEM_RED_CARD); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card does not activate if target is behind a Substitute")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SUBSTITUTE); MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card activates after the last hit of a multi-hit move")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_DOUBLE_KICK); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DOUBLE_KICK, opponent);
|
||||
HP_BAR(player);
|
||||
HP_BAR(player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card does not activate if no replacements")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card does not activate if replacements fainted")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT) { HP(0); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card does not activate if knocked off")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_KNOCK_OFF); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_KNOCK_OFF, opponent);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card does not activate if stolen by a move")
|
||||
{
|
||||
u32 item;
|
||||
bool32 activate;
|
||||
PARAMETRIZE { item = ITEM_NONE; activate = FALSE; }
|
||||
PARAMETRIZE { item = ITEM_POTION; activate = TRUE; }
|
||||
ASSUME(gBattleMoves[MOVE_THIEF].effect == EFFECT_THIEF);
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(item); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_THIEF); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THIEF, opponent);
|
||||
if (activate) {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
} else {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card does not activate if stolen by Magician")
|
||||
{
|
||||
u32 item;
|
||||
bool32 activate;
|
||||
PARAMETRIZE { item = ITEM_NONE; activate = FALSE; }
|
||||
PARAMETRIZE { item = ITEM_POTION; activate = TRUE; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_FENNEKIN) { Ability(ABILITY_MAGICIAN); Item(item); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
if (activate) {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Fennekin!");
|
||||
} else {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Fennekin!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Red Card activates for only the fastest target")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(3); Item(ITEM_RED_CARD); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(2); Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(4); }
|
||||
OPPONENT(SPECIES_UNOWN) { Speed(1); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(opponentLeft, MOVE_ROCK_SLIDE);
|
||||
MOVE(opponentRight, MOVE_TACKLE, target: playerRight);
|
||||
}
|
||||
} SCENE {
|
||||
// Fastest target's Red Card activates.
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROCK_SLIDE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
MESSAGE("Foe Unown was dragged out!");
|
||||
|
||||
// Slower target's Red Card still able to activate on other battler.
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerRight);
|
||||
MESSAGE("Wynaut held up its Red Card against Foe Wynaut!");
|
||||
MESSAGE("Foe Wobbuffet was dragged out!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Red Card activates but fails if the attacker is rooted")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_UNOWN);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_INGRAIN); }
|
||||
TURN {
|
||||
MOVE(opponentLeft, MOVE_TACKLE, target: playerLeft);
|
||||
MOVE(opponentRight, MOVE_TACKLE, target: playerLeft);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
MESSAGE("Foe Wobbuffet anchored itself with its roots!");
|
||||
|
||||
// Red Card already consumed so cannot activate.
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentRight);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerRight);
|
||||
MESSAGE("Wynaut held up its Red Card against Foe Wynaut!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Red Card activates but fails if the attacker has Suction Cups")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_OCTILLERY) { Ability(ABILITY_SUCTION_CUPS); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_UNOWN);
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(opponentLeft, MOVE_TACKLE, target: playerLeft);
|
||||
MOVE(opponentRight, MOVE_TACKLE, target: playerLeft);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Octillery!");
|
||||
MESSAGE("Foe Octillery anchors itself with Suction Cups!");
|
||||
|
||||
// Red Card already consumed so cannot activate.
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentRight);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerRight);
|
||||
MESSAGE("Wynaut held up its Red Card against Foe Wynaut!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card does not activate if switched by Dragon Tail")
|
||||
{
|
||||
bool32 hasWynaut, activate;
|
||||
PARAMETRIZE { hasWynaut = TRUE; activate = FALSE; }
|
||||
PARAMETRIZE { hasWynaut = FALSE; activate = TRUE; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
if (hasWynaut) PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_DRAGON_TAIL); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, opponent);
|
||||
if (activate) {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
} else {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card activates and overrides U-turn")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_U_TURN); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_U_TURN, opponent);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Wobbuffet!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card does not activate if attacker's Sheer Force applied")
|
||||
{
|
||||
u32 move;
|
||||
bool32 activate;
|
||||
PARAMETRIZE { move = MOVE_TACKLE; activate = TRUE; }
|
||||
PARAMETRIZE { move = MOVE_STOMP; activate = FALSE; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, move); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, opponent);
|
||||
if (activate) {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Tauros!");
|
||||
} else {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet held up its Red Card against Foe Tauros!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card activates before Emergency Exit")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_GOLISOPOD) { MaxHP(100); HP(51); Item(ITEM_RED_CARD); }
|
||||
PLAYER(SPECIES_WIMPOD);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Golisopod held up its Red Card against Foe Wobbuffet!");
|
||||
ABILITY_POPUP(player, ABILITY_EMERGENCY_EXIT);
|
||||
MESSAGE("Go! Wimpod!");
|
||||
}
|
||||
}
|
||||
|
||||
// SINGLE_BATTLE_TEST("Red Card activates but fails if the attacker has Dynamaxed")
|
72
test/move_effect_hit_switch_target.c
Normal file
72
test/move_effect_hit_switch_target.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET);
|
||||
ASSUME(gBattleMoves[MOVE_LOCK_ON].effect == EFFECT_LOCK_ON);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragon Tail switches the target with a random non-fainted replacement")
|
||||
{
|
||||
KNOWN_FAILING; // Only 18/50. Waiting for an improved PASSES_RANDOMLY.
|
||||
PASSES_RANDOMLY(90 * 1, 100 * 2);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_BULBASAUR);
|
||||
OPPONENT(SPECIES_CHARMANDER);
|
||||
OPPONENT(SPECIES_SQUIRTLE) { HP(0); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_DRAGON_TAIL); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, player);
|
||||
MESSAGE("Foe Bulbasaur was dragged out!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Dragon Tail switches the target with a random non-battler, non-fainted replacement")
|
||||
{
|
||||
PASSES_RANDOMLY(90 * 1, 100 * 2);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_BULBASAUR);
|
||||
OPPONENT(SPECIES_CHARMANDER);
|
||||
OPPONENT(SPECIES_SQUIRTLE) { HP(0); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_DRAGON_TAIL, target: opponentRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, playerLeft);
|
||||
MESSAGE("Foe Bulbasaur was dragged out!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragon Tail does not fail if no replacements")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_DRAGON_TAIL); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, player);
|
||||
NOT MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragon Tail does not fail if replacements fainted")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT) { HP(0); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_DRAGON_TAIL); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, player);
|
||||
NOT MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
70
test/move_effect_roar.c
Normal file
70
test/move_effect_roar.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_ROAR].effect == EFFECT_ROAR);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Roar switches the target with a random non-fainted replacement")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 2);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_BULBASAUR);
|
||||
OPPONENT(SPECIES_CHARMANDER);
|
||||
OPPONENT(SPECIES_SQUIRTLE) { HP(0); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ROAR); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROAR, player);
|
||||
MESSAGE("Foe Bulbasaur was dragged out!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Roar switches the target with a random non-battler, non-fainted replacement")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 2);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_BULBASAUR);
|
||||
OPPONENT(SPECIES_CHARMANDER);
|
||||
OPPONENT(SPECIES_SQUIRTLE) { HP(0); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_ROAR, target: opponentRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROAR, playerLeft);
|
||||
MESSAGE("Foe Bulbasaur was dragged out!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Roar fails if no replacements")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ROAR); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Roar!");
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Roar fails if replacements fainted")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT) { HP(0); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ROAR); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Roar!");
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue