diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index f5338531421d..03787396147a 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1669,6 +1669,12 @@ callnative BS_DamageToQuarterTargetHP .endm + .macro jumpifsleepclause battler:req, jumpInstr:req + callnative BS_JumpIfSleepClause + .byte \battler + .4byte \jumpInstr + .endm + .macro ficklebeamdamagecalculation callnative BS_FickleBeamDamageCalculation .endm @@ -1993,9 +1999,10 @@ .4byte \jumpInstr .endm - .macro trypsychoshift failInstr:req + .macro trypsychoshift failInstr:req sleepClauseFailInstr:req various BS_ATTACKER, VARIOUS_PSYCHO_SHIFT .4byte \failInstr + .4byte \sleepClauseFailInstr .endm .macro curestatus battler:req diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 52c21dc68a76..97d4f79d2992 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -1639,7 +1639,7 @@ BattleScript_EffectPsychoShift:: BattleScript_EffectPsychoShiftCanWork: jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed jumpifsafeguard BattleScript_SafeguardProtected - trypsychoshift BattleScript_ButItFailed + trypsychoshift BattleScript_ButItFailed, BattleScript_SleepClauseBlocked attackanimation waitanimation copybyte gEffectBattler, gBattlerTarget @@ -2893,6 +2893,7 @@ BattleScript_EffectSleep:: jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed + jumpifsleepclause BS_TARGET, BattleScript_SleepClauseBlocked jumpifterrainaffected BS_TARGET, STATUS_FIELD_ELECTRIC_TERRAIN, BattleScript_ElectricTerrainPrevents jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE @@ -5154,6 +5155,7 @@ BattleScript_EffectYawn:: jumpifflowerveil BattleScript_FlowerVeilProtects jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect + jumpifsleepclause BS_TARGET, BattleScript_SleepClauseBlocked jumpifsubstituteblocks BattleScript_ButItFailed jumpifsafeguard BattleScript_SafeguardProtected accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON @@ -10098,3 +10100,16 @@ BattleScript_EffectSnow:: call BattleScript_CheckPrimalWeather setfieldweather ENUM_WEATHER_SNOW goto BattleScript_MoveWeatherChange + +BattleScript_SleepClauseBlocked:: + pause B_WAIT_TIME_SHORT + orhalfword gMoveResultFlags, MOVE_RESULT_FAILED + printstring STRINGID_BLOCKEDBYSLEEPCLAUSE + waitmessage B_WAIT_TIME_LONG + goto BattleScript_MoveEnd + +BattleScript_SleepClausePreventsEnd:: + pause B_WAIT_TIME_SHORT + printstring STRINGID_BLOCKEDBYSLEEPCLAUSE + waitmessage B_WAIT_TIME_LONG + end2 diff --git a/include/battle.h b/include/battle.h index 364ee9ecd410..e548bcc9a29d 100644 --- a/include/battle.h +++ b/include/battle.h @@ -831,6 +831,8 @@ struct BattleStruct u8 padding:4; u8 usedEjectItem; u8 usedMicleBerry; + u8 monCausingSleepClause[NUM_BATTLE_SIDES]; // Stores which pokemon on a given side is causing Sleep Clause to be active as the mon's index in the party + u8 sleepClauseEffectExempt[MAX_BATTLERS_COUNT]; // Stores whether effect should be exempt from triggering Sleep Clause (Effect Spore) }; // The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider, diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index a3cd38293b0c..b6be72422a61 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -184,6 +184,7 @@ bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u32 partnerMove); bool32 PartnerMoveIs(u32 battlerAtkPartner, u32 partnerMove, u32 moveCheck); bool32 PartnerMoveIsSameAsAttacker(u32 battlerAtkPartner, u32 battlerDef, u32 move, u32 partnerMove); bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u32 move, u32 partnerMove); +bool32 PartnerMoveActivatesSleepClause(u32 move); bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move); // party logic diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 9e2fb84485f8..d11849c82231 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -517,6 +517,7 @@ extern const u8 BattleScript_Terastallization[]; extern const u8 BattleScript_BoosterEnergyEnd2[]; extern const u8 BattleScript_TeraShellDistortingTypeMatchups[]; extern const u8 BattleScript_TeraFormChange[]; +extern const u8 BattleScript_SleepClausePreventsEnd[]; // zmoves extern const u8 BattleScript_ZMoveActivateDamaging[]; diff --git a/include/battle_util.h b/include/battle_util.h index 504c3be3ad1b..e103ddbf56ab 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -278,7 +278,7 @@ bool32 MoveHasChargeTurnAdditionalEffect(u32 move); bool32 CanTargetPartner(u32 battlerAtk, u32 battlerDef); bool32 TargetFullyImmuneToCurrMove(u32 battlerAtk, u32 battlerDef); -bool32 CanBeSlept(u32 battler, u32 ability); +bool32 CanBeSlept(u32 battler, u32 ability, u32 isBlockedBySleepClause); bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 defAbility); bool32 CanBeBurned(u32 battler, u32 ability); bool32 CanBeParalyzed(u32 battler, u32 ability); @@ -300,5 +300,8 @@ bool8 CanMonParticipateInSkyBattle(struct Pokemon *mon); bool8 IsMonBannedFromSkyBattles(u16 species); void RemoveBattlerType(u32 battler, u8 type); u32 GetMoveType(u32 move); +void TryActivateSleepClause(u32 battler, u32 indexInParty); +void TryDeactivateSleepClause(u32 battlerSide, u32 indexInParty); +bool8 IsSleepClauseActiveForSide(u32 battlerSide); #endif // GUARD_BATTLE_UTIL_H diff --git a/include/config/battle.h b/include/config/battle.h index 14d2b47d32ca..afb789280aa4 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -192,6 +192,7 @@ #define B_FLAG_DYNAMAX_BATTLE 0 // If this flag is set, the ability to Dynamax in battle is enabled for all trainers. #define B_FLAG_TERA_ORB_CHARGED 0 // If this flag is set, the Tera Orb is charged. It is automatically set upon healing and cleared upon Terastallizing once configured. #define B_FLAG_TERA_ORB_NO_COST 0 // If this flag is set, the Tera Orb does not use up its charge upon Terastallization. In S/V, this occurs after an event with Terapagos. +#define B_FLAG_SLEEP_CLAUSE 0 // If this flag is set, sleep clause is enabled; if the player / AI has already put a Pokémon on the opponent's side to sleep and it is still sleeping, another one can't be put to sleep. AI requires AI_FLAG_CHECK_BAD_MOVE to understand. // Var Settings // To use the following features in scripting, replace the 0s with the var ID you're assigning it to. diff --git a/include/config/test.h b/include/config/test.h index 708c2ca5816c..cce97484df32 100644 --- a/include/config/test.h +++ b/include/config/test.h @@ -1129,4 +1129,8 @@ #undef P_FAMILY_PECHARUNT #define P_FAMILY_PECHARUNT TRUE +// Flags +#undef B_FLAG_SLEEP_CLAUSE +#define B_FLAG_SLEEP_CLAUSE FLAG_SPECIAL_FLAG_UNUSED_0x4003 + #endif // GUARD_CONFIG_TEST_H diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 563e70fc06f4..bd6c5b9501d9 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -724,8 +724,9 @@ #define STRINGID_ELECTRICCURRENTISRUNNING 722 #define STRINGID_SEEMSWEIRD 723 #define STRINGID_WAGGLINGAFINGER 724 +#define STRINGID_BLOCKEDBYSLEEPCLAUSE 725 -#define BATTLESTRINGS_COUNT 725 +#define BATTLESTRINGS_COUNT 726 // This is the string id that gBattleStringsTable starts with. // String ids before this (e.g. STRINGID_INTROMSG) are not in the table, diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index f69a8640f870..d66139c23abe 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -995,6 +995,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_SLEEP: if (!AI_CanPutToSleep(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, aiData->partnerMove)) ADJUST_SCORE(-10); + if (PartnerMoveActivatesSleepClause(aiData->partnerMove)) + ADJUST_SCORE(-20); break; case EFFECT_EXPLOSION: if (!(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_WILL_SUICIDE)) @@ -1807,7 +1809,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); break; case EFFECT_REST: - if (!CanBeSlept(battlerAtk, aiData->abilities[battlerAtk])) + if (!CanBeSlept(battlerAtk, aiData->abilities[battlerAtk], FALSE)) ADJUST_SCORE(-10); //fallthrough case EFFECT_RESTORE_HP: @@ -2090,6 +2092,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); else if (!AI_CanPutToSleep(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, aiData->partnerMove)) ADJUST_SCORE(-10); + if (PartnerMoveActivatesSleepClause(aiData->partnerMove)) + ADJUST_SCORE(-20); break; case EFFECT_SKILL_SWAP: if (aiData->abilities[battlerAtk] == ABILITY_NONE || aiData->abilities[battlerDef] == ABILITY_NONE @@ -2692,7 +2696,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (IsMoveEffectWeather(move)) ADJUST_SCORE(-10); break; - } + } } // check partner move effect // Adjust for always crit moves @@ -3470,7 +3474,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) } break; case EFFECT_REST: - if (!(CanBeSlept(battlerAtk, aiData->abilities[battlerAtk]))) + if (!(CanBeSlept(battlerAtk, aiData->abilities[battlerAtk], FALSE))) { break; } diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index c80b531d5586..7dca4a29c90c 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -563,7 +563,7 @@ static bool32 ShouldSwitchIfGameStatePrompt(u32 battler, bool32 emitResult) { //Yawn if (gStatuses3[battler] & STATUS3_YAWN - && CanBeSlept(battler, monAbility) + && CanBeSlept(battler, monAbility, TRUE) && gBattleMons[battler].hp > gBattleMons[battler].maxHP / 3) { switchMon = TRUE; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 193071e7c549..b675f5d6b4d4 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -2859,7 +2859,7 @@ bool32 IsBattlerIncapacitated(u32 battler, u32 ability) bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove) { - if (!CanBeSlept(battlerDef, defAbility) + if (!CanBeSlept(battlerDef, defAbility, TRUE) || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) // shouldn't try to sleep mon that partner is trying to make sleep return FALSE; @@ -3352,6 +3352,17 @@ bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u32 move, u32 partnerMov return FALSE; } +bool32 PartnerMoveActivatesSleepClause(u32 partnerMove) +{ + u32 effect = gMovesInfo[partnerMove].effect; + if (!IsDoubleBattle() || !FlagGet(B_FLAG_SLEEP_CLAUSE)) + return FALSE; + if (effect == EFFECT_SLEEP + || effect == EFFECT_YAWN) + return TRUE; + return FALSE; +} + bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move) { u32 i; diff --git a/src/battle_dynamax.c b/src/battle_dynamax.c index fae0e8377a2f..7269cabc66fc 100644 --- a/src/battle_dynamax.c +++ b/src/battle_dynamax.c @@ -762,7 +762,7 @@ void BS_SetMaxMoveEffect(void) { static const u8 sSnoozeEffects[] = {TRUE, FALSE}; if (!(gStatuses3[gBattlerTarget] & STATUS3_YAWN) - && CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget)) + && CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget), TRUE) && RandomElement(RNG_G_MAX_SNOOZE, sSnoozeEffects)) // 50% chance of success { gStatuses3[gBattlerTarget] |= STATUS3_YAWN_TURN(2); @@ -884,12 +884,15 @@ void BS_TrySetStatus1(void) } break; case STATUS1_SLEEP: - if (CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget))) + if (CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget), TRUE)) { if (B_SLEEP_TURNS >= GEN_5) gBattleMons[gBattlerTarget].status1 |= STATUS1_SLEEP_TURN((Random() % 3) + 2); else gBattleMons[gBattlerTarget].status1 |= STATUS1_SLEEP_TURN((Random() % 4) + 3); + + // Try to activate Sleep Clause when a mon is put to Sleep + TryActivateSleepClause(gBattlerTarget, gBattlerPartyIndexes[gBattlerTarget]); gBattleCommunication[MULTISTRING_CHOOSER] = 4; effect++; } diff --git a/src/battle_main.c b/src/battle_main.c index 7a074c9645ba..149a62a8c852 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3129,6 +3129,13 @@ static void BattleStartClearSetData(void) gSelectedMonPartyId = PARTY_SIZE; // Revival Blessing gCategoryIconSpriteId = 0xFF; + + if(FlagGet(B_FLAG_SLEEP_CLAUSE)) + { + // If monCausingSleepClause[side] equals PARTY_SIZE, Sleep Clause is not active for the given side. + gBattleStruct->monCausingSleepClause[B_SIDE_PLAYER] = PARTY_SIZE; + gBattleStruct->monCausingSleepClause[B_SIDE_OPPONENT] = PARTY_SIZE; + } } void SwitchInClearSetData(u32 battler) diff --git a/src/battle_message.c b/src/battle_message.c index 74aa26d6dda0..e8ff73f2871d 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -463,6 +463,7 @@ static const u8 sText_SpAttack[] = _("Sp. Atk"); static const u8 sText_SpDefense[] = _("Sp. Def"); static const u8 sText_Accuracy[] = _("accuracy"); static const u8 sText_Evasiveness[] = _("evasiveness"); +static const u8 sText_BlockedBySleepClause[] = _("Sleep Clause kept {B_DEF_NAME_WITH_PREFIX2} awake!"); const u8 *const gStatNamesTable[NUM_BATTLE_STATS] = { @@ -1585,6 +1586,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_ELECTRICCURRENTISRUNNING - BATTLESTRINGS_TABLE_START] = sText_ElectricCurrentIsRunning, [STRINGID_SEEMSWEIRD - BATTLESTRINGS_TABLE_START] = sText_SeemsWeird, [STRINGID_WAGGLINGAFINGER - BATTLESTRINGS_TABLE_START] = sText_WagglingAFinger, + [STRINGID_BLOCKEDBYSLEEPCLAUSE - BATTLESTRINGS_TABLE_START] = sText_BlockedBySleepClause, }; const u16 gTrainerUsedItemStringIds[] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 005ee855a5ff..a1ed96f90ed5 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1309,6 +1309,8 @@ static void Cmd_attackcanceler(void) gHitMarker |= HITMARKER_OBEYS; return; case DISOBEYS_FALL_ASLEEP: + if (FlagGet(B_FLAG_SLEEP_CLAUSE)) + gBattleStruct->sleepClauseEffectExempt[gBattlerAttacker] = TRUE; gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep; gMoveResultFlags |= MOVE_RESULT_MISSED; return; @@ -3019,7 +3021,7 @@ void SetMoveEffect(bool32 primary, bool32 certain) if (i != gBattlersCount) break; - if (!CanBeSlept(gEffectBattler, GetBattlerAbility(gEffectBattler))) + if (!CanBeSlept(gEffectBattler, GetBattlerAbility(gEffectBattler), TRUE) && !gBattleStruct->sleepClauseEffectExempt[gEffectBattler]) break; cancelMultiTurnMovesResult = CancelMultiTurnMoves(gEffectBattler); @@ -3238,6 +3240,8 @@ void SetMoveEffect(bool32 primary, bool32 certain) gBattleMons[gEffectBattler].status1 |= STATUS1_SLEEP_TURN(1 + RandomUniform(RNG_SLEEP_TURNS, 1, 3)); else gBattleMons[gEffectBattler].status1 |= STATUS1_SLEEP_TURN(1 + RandomUniform(RNG_SLEEP_TURNS, 2, 5)); + + TryActivateSleepClause(gEffectBattler, gBattlerPartyIndexes[gEffectBattler]); } else { @@ -4194,6 +4198,9 @@ static void Cmd_tryfaintmon(void) PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].moves[moveIndex]) } + + // Try to deactivate Sleep Clause when a mon faints + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); } else { @@ -5906,6 +5913,8 @@ static void Cmd_moveend(void) gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal; break; case STATUS1_SLEEP: + // Try to deactivate Sleep Clause when a mon gets woken up by Wake-Up Slap + TryDeactivateSleepClause(GetBattlerSide(gBattlerTarget), gBattlerPartyIndexes[gBattlerTarget]); gBattlescriptCurrInstr = BattleScript_TargetWokeUp; break; case STATUS1_BURN: @@ -10161,7 +10170,7 @@ static void Cmd_various(void) } case VARIOUS_PSYCHO_SHIFT: { - VARIOUS_ARGS(const u8 *failInstr); + VARIOUS_ARGS(const u8 *failInstr, const u8 * sleepClauseFailInstr); u32 targetAbility = GetBattlerAbility(gBattlerTarget); // Psycho shift works if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, targetAbility)) @@ -10172,10 +10181,15 @@ static void Cmd_various(void) gBattleCommunication[MULTISTRING_CHOOSER] = 2; else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && CanBeParalyzed(gBattlerTarget, targetAbility)) gBattleCommunication[MULTISTRING_CHOOSER] = 3; - else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) && CanBeSlept(gBattlerTarget, targetAbility)) + else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) && CanBeSlept(gBattlerTarget, targetAbility, TRUE)) gBattleCommunication[MULTISTRING_CHOOSER] = 4; else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE) && CanGetFrostbite(gBattlerTarget)) gBattleCommunication[MULTISTRING_CHOOSER] = 5; + else if (IsSleepClauseActiveForSide(GetBattlerSide(battler))) + { + gBattlescriptCurrInstr = cmd->sleepClauseFailInstr; + return; + } else { gBattlescriptCurrInstr = cmd->failInstr; @@ -10186,11 +10200,18 @@ static void Cmd_various(void) BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1); MarkBattlerForControllerExec(battler); gBattlescriptCurrInstr = cmd->nextInstr; + // Try to activate Sleep Clause when a mon is put to Sleep by Psycho Shift + TryActivateSleepClause(battler, gBattlerPartyIndexes[battler]); return; } case VARIOUS_CURE_STATUS: { VARIOUS_ARGS(); + + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via Jungle Healing, Purify, Psycho Shift, Healer, G-Max Sweetness + if (gBattleMons[battler].status1 & STATUS1_SLEEP) + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); + gBattleMons[battler].status1 = 0; BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1); MarkBattlerForControllerExec(battler); @@ -13307,12 +13328,11 @@ static void Cmd_healpartystatus(void) u32 zero = 0; u32 partner = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker))); u8 toHeal = 0; + struct Pokemon *party = GetBattlerParty(gBattlerAttacker); + s32 i; if (gCurrentMove == MOVE_HEAL_BELL) { - struct Pokemon *party = GetBattlerParty(gBattlerAttacker); - s32 i; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_BELL; if (GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF @@ -13378,7 +13398,11 @@ static void Cmd_healpartystatus(void) } if (ability != ABILITY_SOUNDPROOF) + { toHeal |= (1 << i); + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via Heal Bell + TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), i); + } } } } @@ -13387,6 +13411,12 @@ static void Cmd_healpartystatus(void) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SOOTHING_AROMA; toHeal = (1 << PARTY_SIZE) - 1; + for (i = 0; i < PARTY_SIZE; i++) + { + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via Aromatherapy, Sparkly Swirl + TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), i); + } + gBattleMons[gBattlerAttacker].status1 = 0; gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; @@ -14764,6 +14794,10 @@ static void Cmd_switchoutabilities(void) switch (GetBattlerAbility(battler)) { case ABILITY_NATURAL_CURE: + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via Natural Cure + if (gBattleMons[battler].status1 & STATUS1_SLEEP) + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); + gBattleMons[battler].status1 = 0; BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 1u << *(gBattleStruct->battlerPartyIndexes + battler), @@ -17283,6 +17317,26 @@ void BS_DamageToQuarterTargetHP(void) gBattlescriptCurrInstr = cmd->nextInstr; } +void BS_JumpIfSleepClause(void) +{ + NATIVE_ARGS(u8 battler, const u8 *jumpInstr); + u8 battler = GetBattlerForBattleScript(cmd->battler); + + // Can freely sleep own partner + if (IsDoubleBattle() && B_FLAG_SLEEP_CLAUSE && GetBattlerSide(gBattlerAttacker) == GetBattlerSide(gBattlerTarget)) + { + gBattleStruct->sleepClauseEffectExempt[gBattlerTarget] = TRUE; + gBattlescriptCurrInstr = cmd->nextInstr; + return; + } + gBattleStruct->sleepClauseEffectExempt[gBattlerTarget] = FALSE; + // Can't sleep if clause is active otherwise + if (IsSleepClauseActiveForSide(GetBattlerSide(battler))) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + void BS_FickleBeamDamageCalculation(void) { NATIVE_ARGS(); diff --git a/src/battle_util.c b/src/battle_util.c index 1dd7b419384f..5345622200cd 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2773,6 +2773,10 @@ u8 DoBattlerEndTurnEffects(void) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAINPREVENTS_MISTY; BattleScriptExecute(BattleScript_TerrainPreventsEnd2); } + else if (IsSleepClauseActiveForSide(GetBattlerSide(battler))) + { + BattleScriptExecute(BattleScript_SleepClausePreventsEnd); + } else { if (B_SLEEP_TURNS >= GEN_5) @@ -2780,6 +2784,8 @@ u8 DoBattlerEndTurnEffects(void) else gBattleMons[battler].status1 |= ((Random() % 4) + 3); + // Try to activate Sleep Clause when a mon is put to Sleep by Yawn + TryActivateSleepClause(battler, gBattlerPartyIndexes[battler]); BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battler].status1); MarkBattlerForControllerExec(battler); BattleScriptExecute(BattleScript_YawnMakesAsleep); @@ -3224,6 +3230,8 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) { if (UproarWakeUpCheck(gBattlerAttacker)) { + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via Uproar + TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), gBattlerPartyIndexes[gBattlerAttacker]); gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP; gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; BattleScriptPushCursor(); @@ -3253,6 +3261,8 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) } else { + // Try to deactivate Sleep Clause when a mon wakes up + TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), gBattlerPartyIndexes[gBattlerAttacker]); gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; BattleScriptPushCursor(); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP; @@ -5138,7 +5148,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (gBattleMons[battler].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON)) StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); if (gBattleMons[battler].status1 & STATUS1_SLEEP) + { StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via Shed Skin, Hydration + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); + } + if (gBattleMons[battler].status1 & STATUS1_PARALYSIS) StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); if (gBattleMons[battler].status1 & STATUS1_BURN) @@ -5742,10 +5757,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && IsBattlerAlive(gBattlerAttacker) && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && TARGET_TURN_DAMAGED - && CanBeSlept(gBattlerAttacker, ability) + && CanBeSlept(gBattlerAttacker, ability, FALSE) && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(move, gBattlerAttacker)) { + if (FlagGet(B_FLAG_SLEEP_CLAUSE)) + gBattleStruct->sleepClauseEffectExempt[gBattlerAttacker] = TRUE; gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_SLEEP; PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility); BattleScriptPushCursor(); @@ -6178,6 +6195,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITY_VITAL_SPIRIT: if (gBattleMons[battler].status1 & STATUS1_SLEEP) { + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via gaining the ability Insomnia or Vital Spirit + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE; StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); effect = 1; @@ -6609,7 +6628,7 @@ bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag) return IsBattlerGrounded(battler); } -bool32 CanBeSlept(u32 battler, u32 ability) +bool32 CanBeSlept(u32 battler, u32 ability, u32 isBlockedBySleepClause) { if (ability == ABILITY_INSOMNIA || ability == ABILITY_VITAL_SPIRIT @@ -6619,7 +6638,8 @@ bool32 CanBeSlept(u32 battler, u32 ability) || gBattleMons[battler].status1 & STATUS1_ANY || IsAbilityOnSide(battler, ABILITY_SWEET_VEIL) || IsAbilityStatusProtected(battler) - || IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_MISTY_TERRAIN)) + || IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_MISTY_TERRAIN) + || (isBlockedBySleepClause && IsSleepClauseActiveForSide(GetBattlerSide(battler)))) return FALSE; return TRUE; } @@ -7262,6 +7282,8 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect) BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet; effect = ITEM_STATUS_CHANGE; + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via a Chesto Berry + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); } break; case HOLD_EFFECT_CURE_CONFUSION: @@ -7293,6 +7315,8 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect) { gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE; StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via a Lum Berry + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); } if (gBattleMons[battler].status1 & STATUS1_PARALYSIS) @@ -7503,6 +7527,8 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE; BattleScriptExecute(BattleScript_BerryCureSlpEnd2); effect = ITEM_STATUS_CHANGE; + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via a Chesto Berry + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); } break; case HOLD_EFFECT_CURE_STATUS: @@ -7521,6 +7547,8 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE; StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); i++; + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via a Lum Berry + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); } if (gBattleMons[battler].status1 & STATUS1_PARALYSIS) { @@ -7810,6 +7838,8 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE; BattleScriptExecute(BattleScript_BerryCureSlpEnd2); effect = ITEM_STATUS_CHANGE; + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via a Chesto Berry + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); } break; case HOLD_EFFECT_CURE_CONFUSION: @@ -7834,6 +7864,8 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE; StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); i++; + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via a Lum Berry + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); } if (gBattleMons[battler].status1 & STATUS1_PARALYSIS) { @@ -8484,7 +8516,7 @@ u8 GetAttackerObedienceForAction() obedienceLevel = levelReferenced - obedienceLevel; calc = ((rnd >> 16) & 255); - if (calc < obedienceLevel && CanBeSlept(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))) + if (calc < obedienceLevel && CanBeSlept(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), FALSE)) { // try putting asleep int i; @@ -11864,3 +11896,31 @@ u32 GetMoveType(u32 move) return TYPE_MYSTERY; return gMovesInfo[move].type; } + +void TryActivateSleepClause(u32 battler, u32 indexInParty) +{ + if (gBattleStruct->sleepClauseEffectExempt[battler]) + { + gBattleStruct->sleepClauseEffectExempt[battler] = FALSE; + return; + } + + if (FlagGet(B_FLAG_SLEEP_CLAUSE)) + gBattleStruct->monCausingSleepClause[GetBattlerSide(battler)] = indexInParty; +} + +void TryDeactivateSleepClause(u32 battlerSide, u32 indexInParty) +{ + // If the pokemon on the given side at the given index in the party is the one causing Sleep Clause to be active, + // set monCausingSleepClause[battlerSide] = PARTY_SIZE, which means Sleep Clause is not active for the given side + if (FlagGet(B_FLAG_SLEEP_CLAUSE) && gBattleStruct->monCausingSleepClause[battlerSide] == indexInParty) + gBattleStruct->monCausingSleepClause[battlerSide] = PARTY_SIZE; +} + +bool8 IsSleepClauseActiveForSide(u32 battlerSide) +{ + // If monCausingSleepClause[battlerSide] == PARTY_SIZE, Sleep Clause is not active for the given side. + // If monCausingSleepClause[battlerSide] < PARTY_SIZE, it means it is storing the index of the mon that is causing Sleep Clause to be active, + // from which it follows that Sleep Clause is active. + return (FlagGet(B_FLAG_SLEEP_CLAUSE) && (gBattleStruct->monCausingSleepClause[battlerSide] < PARTY_SIZE)); +} diff --git a/src/pokemon.c b/src/pokemon.c index c5dcbb190350..0a6e992b3112 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -4180,7 +4180,25 @@ bool8 HealStatusConditions(struct Pokemon *mon, u32 healMask, u8 battlerId) status &= ~healMask; SetMonData(mon, MON_DATA_STATUS, &status); if (gMain.inBattle && battlerId != MAX_BATTLERS_COUNT) + { gBattleMons[battlerId].status1 &= ~healMask; + if((healMask & STATUS1_SLEEP)) + { + u32 i = 0; + u32 battlerSide = GetBattlerSide(battlerId); + struct Pokemon *party = GetSideParty(battlerSide); + + for (i = 0; i < PARTY_SIZE; i++) + { + if (&party[i] == mon) + { + // Try to deactivate Sleep Clause when a mon gets woken up by curing sleep via a Used Item, such as Awakening or Full Heal + TryDeactivateSleepClause(battlerSide, i); + break; + } + } + } + } return FALSE; } else diff --git a/test/battle/sleep_clause.c b/test/battle/sleep_clause.c new file mode 100644 index 000000000000..86e590ecf566 --- /dev/null +++ b/test/battle/sleep_clause.c @@ -0,0 +1,1817 @@ +#include "global.h" +#include "test/battle.h" + +AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will not use sleep moves while sleep clause is active") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_SPORE, MOVE_MACH_PUNCH); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_SPORE); } + TURN { SWITCH(player, 1); EXPECT_MOVE(opponent, MOVE_MACH_PUNCH); } + TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_MACH_PUNCH); } + } +} + +AI_DOUBLE_BATTLE_TEST("Sleep Clause: AI will not use sleep moves while sleep clause is active (Doubles)") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_SPORE, MOVE_MACH_PUNCH); } + OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_MACH_PUNCH); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); EXPECT_MOVE(opponentLeft, MOVE_SPORE); EXPECT_MOVE(opponentRight, MOVE_MACH_PUNCH); } + TURN { SWITCH(playerLeft, 2); MOVE(playerRight, MOVE_CELEBRATE); EXPECT_MOVE(opponentLeft, MOVE_MACH_PUNCH); EXPECT_MOVE(opponentRight, MOVE_MACH_PUNCH); } + TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); EXPECT_MOVE(opponentLeft, MOVE_MACH_PUNCH); EXPECT_MOVE(opponentRight, MOVE_MACH_PUNCH); } + } +} + +AI_DOUBLE_BATTLE_TEST("Sleep Clause: AI will not use sleep move if partner is already using a sleep move") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_SPORE, MOVE_MACH_PUNCH); } + OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_SPORE, MOVE_MACH_PUNCH); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); EXPECT_MOVE(opponentLeft, MOVE_SPORE); EXPECT_MOVE(opponentRight, MOVE_MACH_PUNCH); } + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep moves fail when sleep clause is active") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { MOVE(player, MOVE_SPORE); SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } + MESSAGE("Sleep Clause kept the opposing Wobbuffet awake!"); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep moves fail when sleep clause is active (Doubles)") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { HP(1); MaxHP(100); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentRight); MOVE(playerRight, MOVE_SPORE, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponentRight, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerRight); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + } + MESSAGE("Sleep Clause kept the opposing Wobbuffet awake!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Rest does not activate sleep clause") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_REST); } + TURN { MOVE(player, MOVE_SPORE); SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Rest does not activate sleep clause (Doubles)") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { HP(1); MaxHP(100); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponentLeft, MOVE_REST); MOVE(playerLeft, MOVE_SPORE, target: opponentRight); } + } SCENE { + STATUS_ICON(opponentLeft, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, opponentLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponentRight, sleep: TRUE); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Rest can still be used when sleep clause is active") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { MOVE(player, MOVE_TACKLE); SWITCH(opponent, 1); } + TURN { MOVE(opponent, MOVE_REST); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + STATUS_ICON(opponent, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, opponent); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Rest can still be used when sleep clause is active (Doubles)") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { HP(1); MaxHP(100); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentRight); MOVE(opponentLeft, MOVE_REST); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponentRight, sleep: TRUE); + STATUS_ICON(opponentLeft, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, opponentLeft); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Psycho Shift'ing sleep will fail if sleep clause is active") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + ASSUME(gMovesInfo[MOVE_PSYCHO_SHIFT].effect == EFFECT_PSYCHO_SHIFT); + PLAYER(SPECIES_WOBBUFFET) + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_SLEEP_TALK, MOVE_PSYCHO_SHIFT); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { SWITCH(player, 1); SWITCH(opponent, 1); } + TURN { MOVE(opponent, MOVE_SPORE); MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_PSYCHO_SHIFT, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + STATUS_ICON(opponent, sleep: TRUE); + } + MESSAGE("Sleep Clause kept the opposing Wobbuffet awake!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Psycho Shift'ing sleep will activate sleep clause") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + ASSUME(gMovesInfo[MOVE_PSYCHO_SHIFT].effect == EFFECT_PSYCHO_SHIFT); + PLAYER(SPECIES_ZIGZAGOON) + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SLEEP_TALK, MOVE_PSYCHO_SHIFT); } + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SLEEP_TALK); } + TURN { SWITCH(player, 1); SWITCH(opponent, 1); } + TURN { MOVE(opponent, MOVE_SPORE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_PSYCHO_SHIFT, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + STATUS_ICON(player, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } + MESSAGE("Sleep Clause kept Zigzagoon awake!"); + } +} + +AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will not use Yawn while sleep clause is active") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_YAWN, MOVE_MACH_PUNCH); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_YAWN); } + TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_MACH_PUNCH); } + TURN { SWITCH(player, 1); EXPECT_MOVE(opponent, MOVE_MACH_PUNCH); } + TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_MACH_PUNCH); } + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Yawn will fail when sleep clause is active") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_YAWN); } + TURN { } + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_YAWN); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("Wobbuffet fell asleep!"); + STATUS_ICON(player, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + STATUS_ICON(player, sleep: TRUE); + } + MESSAGE("Sleep Clause kept Wobbuffet awake!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Effect Spore causes sleep 11% of the time with sleep clause active") +{ + PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); + ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } + } WHEN { + TURN { MOVE(opponent, MOVE_SPORE); } + TURN { SWITCH(player, 1); } + TURN { MOVE(player, MOVE_TACKLE); } + TURN { } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("The opposing Breloom's Effect Spore made Wobbuffet sleep!"); + STATUS_ICON(player, sleep: TRUE); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Effect Spore causes sleep 11% of the time with sleep clause active (Doubles)") +{ + PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); + ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } + OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } + } WHEN { + TURN { MOVE(opponentLeft, MOVE_SPORE, target:playerRight); MOVE(playerLeft, MOVE_TACKLE, target:opponentLeft);} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Wobbuffet fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + ABILITY_POPUP(opponentLeft, ABILITY_EFFECT_SPORE); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft); + MESSAGE("The opposing Breloom's Effect Spore made Wobbuffet sleep!"); + STATUS_ICON(playerLeft, sleep: TRUE); + } +} + + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep from Effect Spore will not activate sleep clause") +{ + PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); + ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + TURN {} + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_SPORE); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("The opposing Breloom's Effect Spore made Wobbuffet sleep!"); + STATUS_ICON(player, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("Wobbuffet fell asleep!"); + STATUS_ICON(player, sleep: TRUE); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep from Effect Spore will not activate sleep clause (Doubles)") +{ + PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); + ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } + OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_TACKLE, target:opponentLeft); MOVE(opponentLeft, MOVE_SPORE, target:playerRight); } + } SCENE { + ABILITY_POPUP(opponentLeft, ABILITY_EFFECT_SPORE); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft); + MESSAGE("The opposing Breloom's Effect Spore made Wobbuffet sleep!"); + STATUS_ICON(playerLeft, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Wobbuffet fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Moves with sleep effect chance will activate sleep clause") +{ + PASSES_RANDOMLY(10, 100, RNG_SECONDARY_EFFECT); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP)); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_RELIC_SONG); } + TURN { MOVE(player, MOVE_SPORE); SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + STATUS_ICON(opponent, sleep: TRUE); + MESSAGE("Wobbuffet used Spore!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Moves with sleep effect chance will still do damage when sleep clause active, but won't sleep") +{ + PASSES_RANDOMLY(100, 100, RNG_SECONDARY_EFFECT); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP)); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { MOVE(player, MOVE_RELIC_SONG); SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + STATUS_ICON(opponent, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, player); + HP_BAR(opponent); + NONE_OF { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Dire Claw cannot sleep a mon when sleep clause is active") +{ + PASSES_RANDOMLY(100, 100, RNG_SECONDARY_EFFECT); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(MoveHasAdditionalEffect(MOVE_DIRE_CLAW, MOVE_EFFECT_DIRE_CLAW)); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { MOVE(player, MOVE_DIRE_CLAW); SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + STATUS_ICON(opponent, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_DIRE_CLAW, player); + HP_BAR(opponent); + NONE_OF { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Dark Void can only sleep one opposing mon if sleep clause is active") +{ + // Source: https://bulbapedia.bulbagarden.net/wiki/Dark_Void_(move) + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_DARK_VOID].effect == EFFECT_DARK_VOID); + PLAYER(SPECIES_DARKRAI); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_DARK_VOID); } + TURN { MOVE(playerLeft, MOVE_DARK_VOID); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DARK_VOID, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight); + STATUS_ICON(opponentRight, sleep: TRUE); + MESSAGE("The opposing Wobbuffet fell asleep!"); + } + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: G-Max Befuddle can only sleep one opposing mon if sleep clause is active") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_G_MAX_BEFUDDLE].argument == MAX_EFFECT_EFFECT_SPORE_FOES); + PLAYER(SPECIES_BUTTERFREE) { GigantamaxFactor(TRUE); } + PLAYER(SPECIES_CATERPIE); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_BUG_BITE, target: opponentLeft, gimmick: GIMMICK_DYNAMAX, + WITH_RNG(RNG_G_MAX_BEFUDDLE, STATUS1_SLEEP)); } + } SCENE { + MESSAGE("Butterfree used G-Max Befuddle!"); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight); + STATUS_ICON(opponentRight, sleep: TRUE); + MESSAGE("The opposing Wobbuffet fell asleep!"); + } + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon wakes up") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(B_SLEEP_TURNS >= GEN_5); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN {} + TURN {} + TURN {} + TURN { MOVE(player, MOVE_SPORE); } + } SCENE { + MESSAGE("The opposing Wobbuffet woke up!"); + MESSAGE("Wobbuffet used Spore!"); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up with Aromatherapy / Heal Bell / Sparkly Swirl") +{ + u32 move = MOVE_NONE, switchIndex = 0; + struct BattlePokemon *healingSlot = opponentRight; + struct BattlePokemon *sporedSlot = opponentLeft; + PARAMETRIZE { move = MOVE_AROMATHERAPY; healingSlot = opponentRight; sporedSlot = opponentLeft; switchIndex = 0; } + PARAMETRIZE { move = MOVE_HEAL_BELL; healingSlot = opponentRight; sporedSlot = opponentLeft; switchIndex = 0; } + PARAMETRIZE { move = MOVE_SPARKLY_SWIRL; healingSlot = opponentRight; sporedSlot = opponentLeft; switchIndex = 0; } + PARAMETRIZE { move = MOVE_AROMATHERAPY; healingSlot = opponentLeft; sporedSlot = opponentRight; switchIndex = 1; } + PARAMETRIZE { move = MOVE_HEAL_BELL; healingSlot = opponentLeft; sporedSlot = opponentRight; switchIndex = 1; } + PARAMETRIZE { move = MOVE_SPARKLY_SWIRL; healingSlot = opponentLeft; sporedSlot = opponentRight; switchIndex = 1; } + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_AROMATHERAPY].effect == EFFECT_HEAL_BELL); + ASSUME(gMovesInfo[MOVE_HEAL_BELL].effect == EFFECT_HEAL_BELL); + ASSUME(gMovesInfo[MOVE_SPARKLY_SWIRL].effect == EFFECT_SPARKLY_SWIRL); + ASSUME(B_SLEEP_TURNS >= GEN_5); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPORE, target:sporedSlot); } + TURN { SWITCH(sporedSlot, 2); MOVE(playerLeft, MOVE_SPORE, target:healingSlot); } + if (move == MOVE_SPARKLY_SWIRL) + TURN { SWITCH(sporedSlot, switchIndex); MOVE(healingSlot, move, target: playerRight); MOVE(playerLeft, MOVE_SPORE, target:sporedSlot); } + else + TURN { SWITCH(sporedSlot, switchIndex); MOVE(healingSlot, move); MOVE(playerLeft, MOVE_SPORE, target:sporedSlot); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, sporedSlot); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(sporedSlot, sleep: TRUE); + MESSAGE("Zigzagoon used Spore!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, healingSlot); + STATUS_ICON(healingSlot, sleep: TRUE); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } + MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!"); + if (move == MOVE_AROMATHERAPY) + { + MESSAGE("The opposing Zigzagoon used Aromatherapy!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_AROMATHERAPY, healingSlot); + } + else if (move == MOVE_HEAL_BELL) + { + MESSAGE("The opposing Zigzagoon used Heal Bell!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_HEAL_BELL, healingSlot); + } + else + { + MESSAGE("The opposing Zigzagoon used Sparkly Swirl!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPARKLY_SWIRL, healingSlot); + } + STATUS_ICON(sporedSlot, sleep: FALSE); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, sporedSlot); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up forcefully by a move from an opponent") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(MoveHasAdditionalEffect(MOVE_WAKE_UP_SLAP, MOVE_EFFECT_REMOVE_STATUS)); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); } + TURN { SWITCH(opponentLeft, 2); MOVE(playerLeft, MOVE_SPORE, target:opponentRight); } + TURN { SWITCH(opponentLeft, 0); MOVE(playerLeft, MOVE_WAKE_UP_SLAP, target:opponentLeft); } + TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + MESSAGE("Zigzagoon used Spore!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight); + STATUS_ICON(opponentRight, sleep: TRUE); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } + MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!"); + MESSAGE("Zigzagoon used Wake-Up Slap!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_WAKE_UP_SLAP, playerLeft); + MESSAGE("The opposing Zigzagoon woke up!"); + STATUS_ICON(opponentLeft, sleep: FALSE); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up forcefully by Uproar") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_UPROAR].effect == EFFECT_UPROAR); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); MOVE(playerRight, MOVE_UPROAR); MOVE(opponentRight, MOVE_ROAR, target:playerRight); } + TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + MESSAGE("Zigzagoon used Uproar!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_UPROAR, playerRight); + MESSAGE("Zigzagoon caused an uproar!"); + MESSAGE("The uproar woke the opposing Zigzagoon!"); + STATUS_ICON(opponentLeft, sleep: FALSE); + MESSAGE("The opposing Zigzagoon used Roar!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROAR, opponentRight); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by using Sleep Talk into a status curing move") +{ + KNOWN_FAILING; // Sleep clause works, fails due to Take Heart bug. Issue #5557 https://github.com/rh-hideout/pokeemerald-expansion/issues/5557 + u32 move; + PARAMETRIZE { move = MOVE_PSYCHO_SHIFT; } + PARAMETRIZE { move = MOVE_JUNGLE_HEALING; } + PARAMETRIZE { move = MOVE_LUNAR_BLESSING; } + PARAMETRIZE { move = MOVE_TAKE_HEART; } + PARAMETRIZE { move = MOVE_AROMATHERAPY; } + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + ASSUME(gMovesInfo[MOVE_PSYCHO_SHIFT].effect == EFFECT_PSYCHO_SHIFT); + ASSUME(gMovesInfo[MOVE_JUNGLE_HEALING].effect == EFFECT_JUNGLE_HEALING); + ASSUME(gMovesInfo[MOVE_LUNAR_BLESSING].effect == EFFECT_JUNGLE_HEALING); + ASSUME(gMovesInfo[MOVE_PURIFY].effect == EFFECT_PURIFY); + ASSUME(gMovesInfo[MOVE_TAKE_HEART].effect == EFFECT_TAKE_HEART); + ASSUME(gMovesInfo[MOVE_AROMATHERAPY].effect == EFFECT_HEAL_BELL); + ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP); + PLAYER(SPECIES_ZIGZAGOON) { Item(ITEM_CHESTO_BERRY); } + OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SLEEP_TALK, move); } + } WHEN { + TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SLEEP_TALK); } + TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, move); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + MESSAGE("The opposing Zigzagoon used Sleep Talk!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent); + if (move == MOVE_PSYCHO_SHIFT) + { + MESSAGE("The opposing Zigzagoon used Psycho Shift!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_PSYCHO_SHIFT, opponent); + } + else if (move == MOVE_JUNGLE_HEALING) + { + MESSAGE("The opposing Zigzagoon used Jungle Healing!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_JUNGLE_HEALING, opponent); + } + else if (move == MOVE_LUNAR_BLESSING) + { + MESSAGE("The opposing Zigzagoon used Lunar Blessing!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_LUNAR_BLESSING, opponent); + } + else if (move == MOVE_TAKE_HEART) + { + MESSAGE("The opposing Zigzagoon used Take Heart!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TAKE_HEART, opponent); + } + else if (move == MOVE_AROMATHERAPY) + { + MESSAGE("The opposing Zigzagoon used Aromatherapy!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_AROMATHERAPY, opponent); + } + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Hydration in the rain") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_PELIPPER) { Ability(ABILITY_DRIZZLE); } + OPPONENT(SPECIES_LUVDISC) { Ability(ABILITY_HYDRATION); } + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { MOVE(player, MOVE_SPORE); } + } SCENE { + MESSAGE("Pelipper used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Luvdisc fell asleep!"); + MESSAGE("The opposing Luvdisc's Hydration cured its sleep problem!"); + STATUS_ICON(opponent, sleep: FALSE); + MESSAGE("Pelipper used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Luvdisc fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Natural Cure") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_SWABLU) { Ability(ABILITY_NATURAL_CURE); } + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { SWITCH(opponent, 1); } + TURN { SWITCH(opponent, 0); MOVE(player, MOVE_SPORE); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Swablu fell asleep!"); + MESSAGE("2 withdrew Swablu!"); + MESSAGE("2 sent out Swablu!"); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Swablu fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Shed Skin") +{ + if (B_ABILITY_TRIGGER_CHANCE == GEN_4) + PASSES_RANDOMLY(30, 100, RNG_SHED_SKIN); + else + PASSES_RANDOMLY(33, 100, RNG_SHED_SKIN); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_DRATINI) { Ability(ABILITY_SHED_SKIN); } + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { MOVE(player, MOVE_SPORE); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Dratini fell asleep!"); + MESSAGE("The opposing Dratini's Shed Skin cured its sleep problem!"); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Dratini fell asleep!"); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Healer") +{ + PASSES_RANDOMLY(30, 100, RNG_HEALER); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_CHANSEY) { Ability(ABILITY_HEALER); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); } + TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Zigzagoon fell asleep!"); + MESSAGE("The opposing Chansey's Healer cured the opposing Zigzagoon's problem!"); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by using a held item") +{ + u32 heldItem = ITEM_NONE; + PARAMETRIZE { heldItem = ITEM_CHESTO_BERRY; } + PARAMETRIZE { heldItem = ITEM_LUM_BERRY; } + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP); + ASSUME(gItemsInfo[ITEM_LUM_BERRY].holdEffect == HOLD_EFFECT_CURE_STATUS); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON) { Item(heldItem); } + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { MOVE(player, MOVE_SPORE); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + if (heldItem == ITEM_CHESTO_BERRY) + MESSAGE("The opposing Zigzagoon's Chesto Berry woke it up!"); + else + MESSAGE("The opposing Zigzagoon's Lum Berry cured its sleep problem!"); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Flinging a held item") +{ + u32 heldItem = ITEM_NONE; + PARAMETRIZE { heldItem = ITEM_CHESTO_BERRY; } + PARAMETRIZE { heldItem = ITEM_LUM_BERRY; } + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING); + ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP); + ASSUME(gItemsInfo[ITEM_LUM_BERRY].holdEffect == HOLD_EFFECT_CURE_STATUS); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON) { Item(heldItem); } + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentLeft); MOVE(playerRight, MOVE_FLING, target: opponentLeft); } + TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentLeft); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Zigzagoon fell asleep!"); + MESSAGE("Zigzagoon used Fling!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, playerRight); + if (heldItem == ITEM_CHESTO_BERRY) + MESSAGE("The opposing Zigzagoon's Chesto Berry woke it up!"); + else + MESSAGE("The opposing Zigzagoon's Lum Berry cured its sleep problem!"); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by using an item") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gItemsInfo[ITEM_AWAKENING].battleUsage == EFFECT_ITEM_CURE_STATUS); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { USE_ITEM(opponent, ITEM_AWAKENING, partyIndex: 0); MOVE(player, MOVE_SPORE); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + MESSAGE("Zigzagoon had its status healed!"); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon faints") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON) { Level(5); } + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { MOVE(player, MOVE_TACKLE); SEND_OUT(opponent, 1); } + TURN { MOVE(player, MOVE_SPORE); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + MESSAGE("The opposing Zigzagoon fainted!"); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon faints (Doubles)") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON) { Level(5); } + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); } + TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentRight);} + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Zigzagoon fell asleep!"); + MESSAGE("The opposing Zigzagoon fainted!"); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by gaining the ability Insomnia / Vital Spirit") +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_VITAL_SPIRIT; } + PARAMETRIZE { ability = ABILITY_INSOMNIA; } + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_DELIBIRD) { Ability(ability); } + OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SLEEP_TALK, MOVE_SKILL_SWAP); } + } WHEN { + TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SLEEP_TALK); } + TURN { MOVE(opponent, MOVE_SKILL_SWAP); } + TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SKILL_SWAP); } + } SCENE { + MESSAGE("Delibird used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + MESSAGE("The opposing Zigzagoon used Sleep Talk!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent); + MESSAGE("The opposing Zigzagoon used Skill Swap!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SKILL_SWAP, opponent); + if (ability == ABILITY_VITAL_SPIRIT) + MESSAGE("The opposing Zigzagoon's Vital Spirit cured its sleep problem!"); + if (ability == ABILITY_INSOMNIA) + MESSAGE("The opposing Zigzagoon's Insomnia cured its sleep problem!"); + MESSAGE("The opposing Zigzagoon used Skill Swap!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SKILL_SWAP, opponent); + MESSAGE("Delibird used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is sent out, has Trace, and Traces Insomnia / Vital spirit") +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_VITAL_SPIRIT; } + PARAMETRIZE { ability = ABILITY_INSOMNIA; } + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_ZIGZAGOON) + PLAYER(SPECIES_DELIBIRD) { Ability(ability); } + OPPONENT(SPECIES_RALTS) { Ability(ABILITY_TRACE); } + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { SWITCH(player, 1); SWITCH(opponent, 1); } + TURN { SWITCH(opponent, 0); } + TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); } + } SCENE { + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Ralts fell asleep!"); + MESSAGE("2 sent out Zigzagoon!"); + MESSAGE("2 sent out Ralts!"); + if (ability == ABILITY_VITAL_SPIRIT) + MESSAGE("The opposing Ralts's Vital Spirit cured its sleep problem!"); + if (ability == ABILITY_INSOMNIA) + MESSAGE("The opposing Ralts's Insomnia cured its sleep problem!"); + MESSAGE("2 sent out Zigzagoon!"); + MESSAGE("Delibird used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is sent out and transforms into a mon with Insomnia / Vital spirit") +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_VITAL_SPIRIT; } + PARAMETRIZE { ability = ABILITY_INSOMNIA; } + KNOWN_FAILING; // Sleep Clause parts work, but Imposter seems broken with battle messages / targeting. Issue #5565 https://github.com/rh-hideout/pokeemerald-expansion/issues/5565 + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gItemsInfo[ITEM_LAGGING_TAIL].holdEffect == HOLD_EFFECT_LAGGING_TAIL); + PLAYER(SPECIES_ZIGZAGOON) + PLAYER(SPECIES_DELIBIRD) { Ability(ability); } + OPPONENT(SPECIES_DITTO) { Ability(ABILITY_IMPOSTER); } + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { SWITCH(player, 1); SWITCH(opponent, 1); } + TURN { SWITCH(opponent, 0); } + TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); } + } SCENE { + MESSAGE("The opposing Ditto transformed into Zigzagoon using Imposter!"); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Ditto fell asleep!"); + MESSAGE("2 sent out Zigzagoon!"); + MESSAGE("2 sent out Ditto!"); + if (ability == ABILITY_VITAL_SPIRIT) + MESSAGE("The opposing Ditto's Vital Spirit cured its sleep problem!"); + else + MESSAGE("The opposing Ditto's Insomnia cured its sleep problem!"); + MESSAGE("2 sent out Zigzagoon!"); + MESSAGE("Delibird used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + } +} + +AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will use sleep moves again when sleep clause has been deactivated") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_CHESTO_BERRY); } + OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_SPORE, MOVE_MACH_PUNCH); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_SPORE); } + TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_SPORE); } + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up with G-Max Sweetness") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_G_MAX_SWEETNESS].argument == MAX_EFFECT_AROMATHERAPY); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_APPLETUN) { GigantamaxFactor(TRUE); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponentRight, MOVE_SPORE, target: playerRight); } + TURN { MOVE(playerLeft, MOVE_VINE_WHIP, target: opponentLeft, gimmick: GIMMICK_DYNAMAX); } + TURN { MOVE(opponentRight, MOVE_SPORE, target: playerRight); } + } SCENE { + MESSAGE("The opposing Wobbuffet used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Wobbuffet fell asleep!"); + MESSAGE("Appletun used G-Max Sweetness!"); + MESSAGE("Wobbuffet's status returned to normal!"); + MESSAGE("The opposing Wobbuffet used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Wobbuffet fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Pre-existing sleep condition doesn't activate sleep clause") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON) { Status1(STATUS1_SLEEP); } + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep caused by Effect Spore does not prevent sleep clause from ever activating") // checks that sleepClauseEffectExempt works properly +{ + PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_AROMATHERAPY].effect == EFFECT_HEAL_BELL); + ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_SPORE); } + TURN { SWITCH(player, 2); MOVE(opponent, MOVE_SPORE); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("The opposing Breloom's Effect Spore made Zigzagoon sleep!"); + STATUS_ICON(player, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(player, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(player, sleep: TRUE); + } + MESSAGE("Sleep Clause kept Zigzagoon awake!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Waking up after Effect Spore doesn't deactivate sleep clause") +{ + PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + TURN {} + TURN {} + TURN {} + TURN { MOVE(opponent, MOVE_SPORE); } + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_SPORE); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("The opposing Breloom's Effect Spore made Zigzagoon sleep!"); + STATUS_ICON(player, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(player, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(player, sleep: TRUE); + } + MESSAGE("Sleep Clause kept Zigzagoon awake!"); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Waking up after Effect Spore doesn't deactivate sleep clause (Doubles)") +{ + PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_AROMATHERAPY].effect == EFFECT_HEAL_BELL); + ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); MOVE(opponentRight, MOVE_SPORE, target:playerRight); } + TURN { SWITCH(playerLeft, 2); } + TURN { MOVE(playerLeft, MOVE_AROMATHERAPY); MOVE(opponentRight, MOVE_SPORE, target:playerRight); MOVE(opponentLeft, MOVE_SPORE, target:playerLeft); } + } SCENE { + ABILITY_POPUP(opponentLeft, ABILITY_EFFECT_SPORE); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft); + MESSAGE("The opposing Breloom's Effect Spore made Zigzagoon sleep!"); + STATUS_ICON(playerLeft, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_AROMATHERAPY, playerLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerLeft, sleep: TRUE); + } + MESSAGE("Sleep Clause kept Zigzagoon awake!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Waking up after Rest doesn't deactivate sleep clause") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + PLAYER(SPECIES_ZIGZAGOON) { HP(1); MaxHP(100); } + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_REST); } + TURN {} + TURN {} + TURN {} + TURN { MOVE(opponent, MOVE_SPORE); } + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_SPORE); } + } SCENE { + MESSAGE("Zigzagoon went to sleep!"); + STATUS_ICON(player, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("Zigzagoon woke up!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(player, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(player, sleep: TRUE); + } + MESSAGE("Sleep Clause kept Zigzagoon awake!"); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Waking up after Rest doesn't deactivate sleep clause (Doubles)") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + PLAYER(SPECIES_ZIGZAGOON) { HP(1); MaxHP(100); } + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_REST); MOVE(opponentRight, MOVE_SPORE, target:playerRight); } + TURN { SWITCH(playerRight, 2); } + TURN {} + TURN {} + TURN { MOVE(opponentRight, MOVE_SPORE, target:playerRight); } + } SCENE { + MESSAGE("Zigzagoon went to sleep!"); + STATUS_ICON(playerLeft, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, playerLeft); + MESSAGE("The opposing Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + MESSAGE("Zigzagoon woke up!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + } + MESSAGE("Sleep Clause kept Zigzagoon awake!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Suppressing and then sleeping Vital Spirit / Insomnia and switching back in deactivates sleep clause") +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_VITAL_SPIRIT; } + PARAMETRIZE { ability = ABILITY_INSOMNIA; } + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_DELIBIRD) { Ability(ability); } + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_GASTRO_ACID); } + TURN { MOVE(player, MOVE_SPORE); } + TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); } + TURN { SWITCH(opponent, 0); } + TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Delibird fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Mold Breaker Pokémon sleeping Vital Spirit / Insomnia activates sleep clause") +{ + KNOWN_FAILING; // Interaction between Mold Breaker and Vital Spirit / Insomnia is broken. Issue #5578 https://github.com/rh-hideout/pokeemerald-expansion/issues/5578 + u32 ability; + PARAMETRIZE { ability = ABILITY_VITAL_SPIRIT; } + PARAMETRIZE { ability = ABILITY_INSOMNIA; } + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_PANCHAM) { Ability(ABILITY_MOLD_BREAKER); } + OPPONENT(SPECIES_DELIBIRD) { Ability(ability); } + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); } + TURN { SWITCH(opponent, 0); } + TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Delibird fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + MESSAGE("Sleep Clause kept the opposing Delibird awake!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Yawn'd Pokémon slept due to Effect Spore before Yawn triggers does not activate sleep clause") +{ + PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE); + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + PLAYER(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_YAWN); } + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); } + } SCENE { + MESSAGE("The opposing Zigzagoon grew drowsy!"); + ABILITY_POPUP(player, ABILITY_EFFECT_SPORE); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("Breloom's Effect Spore made the opposing Zigzagoon sleep!"); + STATUS_ICON(opponent, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Yawn'd Pokémon who's partner is slept before Yawn triggers will not fall asleep due to sleep clause being activated") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_YAWN, target: opponentLeft); MOVE(playerRight, MOVE_YAWN, target: opponentRight); } + TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentLeft); } + } SCENE { + MESSAGE("The opposing Zigzagoon grew drowsy!"); + MESSAGE("The opposing Zigzagoon grew drowsy!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + NONE_OF { + MESSAGE( "The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponentRight, sleep: TRUE); + } + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: If both Pokémon on one side are Yawn'd at the same time, one will fall asleep and the other will not") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + PLAYER(SPECIES_ZIGZAGOON) { Speed(5); } + PLAYER(SPECIES_ZIGZAGOON) { Speed(4); } + OPPONENT(SPECIES_ZIGZAGOON) { Speed(3); } + OPPONENT(SPECIES_ZIGZAGOON) { Speed(2); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_YAWN, target: opponentLeft); MOVE(playerRight, MOVE_YAWN, target: opponentRight); } + TURN { } + } SCENE { + MESSAGE("The opposing Zigzagoon grew drowsy!"); + MESSAGE("The opposing Zigzagoon grew drowsy!"); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + NONE_OF { + MESSAGE( "The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponentRight, sleep: TRUE); + } + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Reflection moves (ie. Magic Coat) fail if sleep clause is active and they reflect a sleep move") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_SPORE); } + TURN { SWITCH(opponent, 1); } + TURN { MOVE(player, MOVE_MAGIC_COAT); MOVE(opponent, MOVE_SPORE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_MAGIC_COAT, player); + MESSAGE("The opposing Zigzagoon bounced the Spore back!"); // Should be MESSAGE("Zigzagoon bounced the Spore back!"); Issue #5579 https://github.com/rh-hideout/pokeemerald-expansion/issues/5579 + MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Reflection moves (ie. Magic Coat) that reflect a sleep move activate sleep clause") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_MAGIC_COAT); MOVE(opponent, MOVE_SPORE); } + TURN { SWITCH(opponent, 1); } + TURN { MOVE(player, MOVE_SPORE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_MAGIC_COAT, player); + MESSAGE("Zigzagoon bounced the Spore back!"); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } + MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!"); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Reflection moves (ie. Magic Coat) that reflect Dark Void only sleep one opposing Pokémon") +{ + // Source: https://bulbapedia.bulbagarden.net/wiki/Dark_Void_(move) + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT); + ASSUME(gMovesInfo[MOVE_DARK_VOID].effect == EFFECT_DARK_VOID); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_DARKRAI); + OPPONENT(SPECIES_DARKRAI); + } WHEN { + TURN { MOVE(playerLeft, MOVE_MAGIC_COAT); MOVE(opponentLeft, MOVE_DARK_VOID); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DARK_VOID, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Darkrai fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight); + STATUS_ICON(opponentRight, sleep: TRUE); + MESSAGE("The opposing Darkrai fell asleep!"); + } + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Magic Bounce'ing a sleep move activates sleep clause, and fails if sleep clause is active") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); } + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(opponent, MOVE_SPORE); } + TURN { SWITCH(opponent, 1); } + TURN { MOVE(opponent, MOVE_SPORE); } + } SCENE { + MESSAGE("The opposing Zigzagoon's Spore was bounced back by Espeon's Magic Bounce!"); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + MESSAGE("The opposing Zigzagoon's Spore was bounced back by Espeon's Magic Bounce!"); + NONE_OF { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + } + MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!"); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Magic Bounce reflecting Dark Void only sleeps one opposing Pokémon") +{ + // Source: https://bulbapedia.bulbagarden.net/wiki/Dark_Void_(move) + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_DARK_VOID].effect == EFFECT_DARK_VOID); + PLAYER(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_DARKRAI); + OPPONENT(SPECIES_DARKRAI); + } WHEN { + TURN { MOVE(opponentLeft, MOVE_DARK_VOID); } + } SCENE { + MESSAGE("The opposing Darkrai's Dark Void was bounced back by Espeon's Magic Bounce!"); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Darkrai fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight); + STATUS_ICON(opponentRight, sleep: TRUE); + MESSAGE("The opposing Darkrai fell asleep!"); + } + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep Clause does not prevent sleeping your partner Pokémon with sleep effects") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPORE, target: playerRight); } + TURN { SWITCH(playerRight, 2); MOVE(playerLeft, MOVE_SPORE, target: playerRight); } + TURN { SWITCH(playerRight, 3); MOVE(playerLeft, MOVE_SPORE, target: playerRight); } + TURN { SWITCH(playerRight, 4); MOVE(playerLeft, MOVE_SPORE, target: playerRight); } + TURN { SWITCH(playerRight, 5); MOVE(playerLeft, MOVE_SPORE, target: playerRight); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep Clause does not prevent sleeping your partner Pokémon with Yawn") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_YAWN, target: playerRight); } + TURN {} + TURN { SWITCH(playerRight, 2); MOVE(playerLeft, MOVE_YAWN, target: playerRight); } + TURN {} + TURN { SWITCH(playerRight, 3); MOVE(playerLeft, MOVE_YAWN, target: playerRight); } + TURN {} + TURN { SWITCH(playerRight, 4); MOVE(playerLeft, MOVE_YAWN, target: playerRight); } + TURN {} + TURN { SWITCH(playerRight, 5); MOVE(playerLeft, MOVE_YAWN, target: playerRight); } + TURN {} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft); + MESSAGE("Zigzagoon grew drowsy!"); + STATUS_ICON(playerRight, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft); + MESSAGE("Zigzagoon grew drowsy!"); + STATUS_ICON(playerRight, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft); + MESSAGE("Zigzagoon grew drowsy!"); + STATUS_ICON(playerRight, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft); + MESSAGE("Zigzagoon grew drowsy!"); + STATUS_ICON(playerRight, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft); + MESSAGE("Zigzagoon grew drowsy!"); + STATUS_ICON(playerRight, sleep: TRUE); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep moves used after being Encore'd are prevented when sleep clause is active") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(opponentLeft, MOVE_SPORE, target: playerLeft); MOVE(playerRight, MOVE_ENCORE, target: opponentLeft); } + TURN { SWITCH(playerLeft, 2); FORCED_MOVE(opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerLeft, sleep: TRUE); + MESSAGE("Zigzagoon used Encore!"); + MESSAGE("Go! Zigzagoon!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerLeft, sleep: TRUE); + } + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Spore'ing opponent after Yawn'ing partner does not prevent Yawn's effect from sleeping partner") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPORE, target: playerRight); } + TURN { SWITCH(playerRight, 2); MOVE(playerLeft, MOVE_YAWN, target: playerRight); } + TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentLeft); MOVE(playerRight, MOVE_SPORE, target: opponentRight); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + MESSAGE("Go! Zigzagoon!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft); + MESSAGE("Zigzagoon grew drowsy!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerRight); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponentRight, sleep: TRUE); + } + MESSAGE("Zigzagoon fell asleep!"); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Opponent Spore'ing player's partner after partner was Yawn'd by player does not prevent Spore's effect from sleeping partner and activating clause") +{ + GIVEN { + FLAG_SET(B_FLAG_SLEEP_CLAUSE); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(playerLeft, MOVE_YAWN, target: playerRight); } + TURN { MOVE(opponentLeft, MOVE_SPORE, target: playerRight); MOVE(opponentRight, MOVE_SPORE, target:playerLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft); + MESSAGE("Zigzagoon grew drowsy!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerRight, sleep: TRUE); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft); + MESSAGE("Zigzagoon fell asleep!"); + STATUS_ICON(playerLeft, sleep: TRUE); + } + MESSAGE("Sleep Clause kept Zigzagoon awake!"); + } +} diff --git a/test/test_runner_battle.c b/test/test_runner_battle.c index 7124077a41ec..8d6827204d88 100644 --- a/test/test_runner_battle.c +++ b/test/test_runner_battle.c @@ -1360,7 +1360,6 @@ static inline rng_value_t MakeRngValue(const u16 seed) static void CB2_BattleTest_NextTrial(void) { - ClearFlagAfterTest(); TearDownBattle(); SetMainCallback2(CB2_BattleTest_NextParameter);