Test Red Card

Dragon Tail activates Red Card if the target does not switch.
This commit is contained in:
Martin Griffin 2023-02-21 10:44:58 +00:00
parent afe09e9653
commit 29c64c82f3
6 changed files with 399 additions and 2 deletions

View File

@ -2247,3 +2247,7 @@
various \battler, VARIOUS_JUMP_IF_EMERGENCY_EXITED various \battler, VARIOUS_JUMP_IF_EMERGENCY_EXITED
.4byte \jumpInstr .4byte \jumpInstr
.endm .endm
.macro hitswitchtargetfailed
various 0, VARIOUS_HIT_SWITCH_TARGET_FAILED
.endm

View File

@ -2129,7 +2129,12 @@ BattleScript_EffectHitSwitchTarget:
jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut
jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted
tryhitswitchtarget BattleScript_MoveEnd tryhitswitchtarget BattleScript_MoveEnd
forcerandomswitch BattleScript_MoveEnd forcerandomswitch BattleScript_HitSwitchTargetForceRandomSwitchFailed
goto BattleScript_MoveEnd
BattleScript_HitSwitchTargetForceRandomSwitchFailed:
hitswitchtargetfailed
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_EffectClearSmog: BattleScript_EffectClearSmog:

View File

@ -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. // 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 attackerBeforeBounce:2;
u8 beatUpSlot:3; u8 beatUpSlot:3;
bool8 hitSwitchTargetFailed:1;
u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit. 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) 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. bool8 allowedToChangeFormInWeather[PARTY_SIZE][2]; // For each party member and side, used by Ice Face.

View File

@ -258,6 +258,7 @@
#define VARIOUS_JUMP_IF_NO_VALID_TARGETS 166 #define VARIOUS_JUMP_IF_NO_VALID_TARGETS 166
#define VARIOUS_JUMP_IF_EMERGENCY_EXITED 167 #define VARIOUS_JUMP_IF_EMERGENCY_EXITED 167
#define VARIOUS_STORE_HEALING_WISH 168 #define VARIOUS_STORE_HEALING_WISH 168
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 169
// Cmd_manipulatedamage // Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0 #define DMG_CHANGE_SIGN 0

View File

@ -5968,7 +5968,7 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++; gBattleScripting.moveendState++;
break; break;
case MOVEEND_RED_CARD: case MOVEEND_RED_CARD:
if (gBattleMoves[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET if ((gBattleMoves[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed)
&& IsBattlerAlive(gBattlerAttacker) && IsBattlerAlive(gBattlerAttacker)
&& !TestSheerForceFlag(gBattlerAttacker, gCurrentMove) && !TestSheerForceFlag(gBattlerAttacker, gCurrentMove)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG) && GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG)
@ -6199,6 +6199,7 @@ static void Cmd_moveend(void)
gBattleStruct->zmove.active = FALSE; gBattleStruct->zmove.active = FALSE;
gBattleStruct->zmove.toBeUsed[gBattlerAttacker] = MOVE_NONE; gBattleStruct->zmove.toBeUsed[gBattlerAttacker] = MOVE_NONE;
gBattleStruct->zmove.effect = EFFECT_HIT; gBattleStruct->zmove.effect = EFFECT_HIT;
gBattleStruct->hitSwitchTargetFailed = FALSE;
gBattleScripting.moveendState++; gBattleScripting.moveendState++;
break; break;
case MOVEEND_COUNT: case MOVEEND_COUNT:
@ -11067,6 +11068,13 @@ static void Cmd_various(void)
gBattleStruct->storedHealingWish |= gBitTable[gActiveBattler]; gBattleStruct->storedHealingWish |= gBitTable[gActiveBattler];
break; break;
} }
case VARIOUS_HIT_SWITCH_TARGET_FAILED:
{
VARIOUS_ARGS();
gBattleStruct->hitSwitchTargetFailed = TRUE;
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
} // End of switch (cmd->id) } // End of switch (cmd->id)
gBattlescriptCurrInstr = cmd->nextInstr; gBattlescriptCurrInstr = cmd->nextInstr;

378
test/hold_effect_red_card.c Normal file
View 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")