diff --git a/include/battle.h b/include/battle.h index cc6d6dcb87e8..27ecb78602bc 100644 --- a/include/battle.h +++ b/include/battle.h @@ -598,6 +598,7 @@ struct SleepClauseData { u8 isActive[NUM_BATTLE_SIDES]; // Stores sleep clause state for each battle side bool8 effectExempt; // Stores whether effect should be exempt from triggering sleep clause (Effect Spore) + bool8 isCausingSleepClause[NUM_BATTLE_SIDES][PARTY_SIZE]; // When a Pokemon falls asleep, need to know if it should deactivate sleep clause upon waking }; struct LostItem diff --git a/include/config/battle.h b/include/config/battle.h index 80c3c01b8c57..5ebf95c03706 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -249,7 +249,7 @@ #define B_OVERWORLD_FOG GEN_LATEST // In Gen8+, overworld Fog summons Misty Terrain in battle. In Gen4 only, overworld Fog summons the unique fog weather condition in battle. #define B_TOXIC_REVERSAL GEN_LATEST // In Gen5+, bad poison will change to regular poison at the end of battles. #define B_TRY_CATCH_TRAINER_BALL GEN_LATEST // In Gen4+, trying to catch a Trainer's Pokémon does not consume the Poké Ball. -#define B_SLEEP_CLAUSE TRUE // 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. +#define B_SLEEP_CLAUSE TRUE // 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. // Animation Settings #define B_NEW_SWORD_PARTICLE TRUE // If set to TRUE, it updates Swords Dance's particle. diff --git a/src/battle_dynamax.c b/src/battle_dynamax.c index d30cf52ef5f3..41f47a6ad86a 100644 --- a/src/battle_dynamax.c +++ b/src/battle_dynamax.c @@ -888,7 +888,11 @@ void BS_TrySetStatus1(void) else gBattleMons[gBattlerTarget].status1 |= STATUS1_SLEEP_TURN((Random() % 4) + 3); if (B_SLEEP_CLAUSE) + { gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerTarget)] = TRUE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]] = TRUE; + } + gBattleCommunication[MULTISTRING_CHOOSER] = 4; effect++; } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 41a64a9537f2..31bc86881f0e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3086,6 +3086,7 @@ void SetMoveEffect(bool32 primary, bool32 certain) if (B_SLEEP_CLAUSE && !gBattleStruct->sleepClause.effectExempt) { gBattleStruct->sleepClause.isActive[GetBattlerSide(gEffectBattler)] = TRUE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gEffectBattler)][gBattlerPartyIndexes[gEffectBattler]] = TRUE; gBattleStruct->sleepClause.effectExempt = FALSE; } } @@ -4007,6 +4008,11 @@ static void Cmd_tryfaintmon(void) PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].moves[moveIndex]) } + if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]]) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE; + } } else { @@ -5711,6 +5717,11 @@ static void Cmd_moveend(void) gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal; break; case STATUS1_SLEEP: + if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerTarget)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]]) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerTarget)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]] = FALSE; + } gBattlescriptCurrInstr = BattleScript_TargetWokeUp; break; case STATUS1_BURN: @@ -10008,11 +10019,26 @@ 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; + if (B_SLEEP_CLAUSE) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = TRUE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = TRUE; + } return; } case VARIOUS_CURE_STATUS: { VARIOUS_ARGS(); + + if (B_SLEEP_CLAUSE + && (gBattleMons[battler].status1 & STATUS1_SLEEP) + && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] + && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]]) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE; + } + gBattleMons[battler].status1 = 0; BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1); MarkBattlerForControllerExec(battler); @@ -13178,12 +13204,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 @@ -13249,7 +13274,25 @@ static void Cmd_healpartystatus(void) } if (ability != ABILITY_SOUNDPROOF) + { toHeal |= (1 << i); + + if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isCausingSleepClause[gBattlerAttacker][i]) + { + gBattleStruct->sleepClause.isActive[gBattlerAttacker] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[gBattlerAttacker][i] = FALSE; + } + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && !(gAbsentBattlerFlags & gBitTable[partner])) + { + if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isCausingSleepClause[partner][i]) + { + gBattleStruct->sleepClause.isActive[partner] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[partner][i] = FALSE; + } + } + } } } } @@ -13258,12 +13301,29 @@ static void Cmd_healpartystatus(void) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SOOTHING_AROMA; toHeal = (1 << PARTY_SIZE) - 1; + if (B_SLEEP_CLAUSE) + { + gBattleStruct->sleepClause.isActive[gBattlerAttacker] = FALSE; + for (i = 0; i < PARTY_SIZE; i++) + { + gBattleStruct->sleepClause.isCausingSleepClause[gBattlerAttacker][i] = FALSE; + } + } + gBattleMons[gBattlerAttacker].status1 = 0; gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gAbsentBattlerFlags & gBitTable[partner])) { + if (B_SLEEP_CLAUSE) + { + gBattleStruct->sleepClause.isActive[partner] = FALSE; + for (i = 0; i < PARTY_SIZE; i++) + { + gBattleStruct->sleepClause.isCausingSleepClause[partner][i] = FALSE; + } + } gBattleMons[partner].status1 = 0; gBattleMons[partner].status2 &= ~STATUS2_NIGHTMARE; } @@ -14629,6 +14689,14 @@ static void Cmd_switchoutabilities(void) switch (GetBattlerAbility(battler)) { case ABILITY_NATURAL_CURE: + if (B_SLEEP_CLAUSE + && (gBattleMons[battler].status1 & STATUS1_SLEEP ) + && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] + && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]]) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE; + } gBattleMons[battler].status1 = 0; BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, gBitTable[*(gBattleStruct->battlerPartyIndexes + battler)], diff --git a/src/battle_util.c b/src/battle_util.c index 92ee0810d11a..4e61a46f1e5b 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2826,7 +2826,11 @@ u8 DoBattlerEndTurnEffects(void) gBattleMons[battler].status1 |= ((Random() % 4) + 3); if (B_SLEEP_CLAUSE) + { gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerTarget)] = TRUE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]] = TRUE; + } + BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battler].status1); MarkBattlerForControllerExec(battler); BattleScriptExecute(BattleScript_YawnMakesAsleep); @@ -3269,6 +3273,12 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) { if (UproarWakeUpCheck(gBattlerAttacker)) { + if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerAttacker)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerAttacker)][gBattlerPartyIndexes[gBattlerAttacker]]) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerAttacker)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerAttacker)][gBattlerPartyIndexes[gBattlerAttacker]] = FALSE; + } + gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP; gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; BattleScriptPushCursor(); @@ -3298,8 +3308,12 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) } else { - if (B_SLEEP_CLAUSE) + if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerAttacker)][gBattlerPartyIndexes[gBattlerAttacker]]) + { gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerAttacker)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerAttacker)][gBattlerPartyIndexes[gBattlerAttacker]] = FALSE; + } + gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; BattleScriptPushCursor(); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP; @@ -4969,7 +4983,15 @@ 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); + if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]]) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE; + } + } + if (gBattleMons[battler].status1 & STATUS1_PARALYSIS) StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); if (gBattleMons[battler].status1 & STATUS1_BURN) @@ -5056,8 +5078,16 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 gBattleScripting.battler = BATTLE_PARTNER(battler); if (IsBattlerAlive(gBattleScripting.battler) && gBattleMons[gBattleScripting.battler].status1 & STATUS1_ANY - && (Random() % 100) < 30) + && (Random() % 100) < 90) { + if (B_SLEEP_CLAUSE + && (gBattleMons[gBattleScripting.battler].status1 & STATUS1_SLEEP ) + && gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattleScripting.battler)] + && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[gBattleScripting.battler]]) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattleScripting.battler)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattleScripting.battler)][gBattlerPartyIndexes[gBattleScripting.battler]] = FALSE; + } BattleScriptPushCursorAndCallback(BattleScript_HealerActivates); effect++; } @@ -6103,6 +6133,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITY_VITAL_SPIRIT: if (gBattleMons[battler].status1 & STATUS1_SLEEP) { + if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]]) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE; + } gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE; StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); effect = 1; @@ -7214,6 +7249,11 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect) BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet; effect = ITEM_STATUS_CHANGE; + if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]]) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE; + } } break; case HOLD_EFFECT_CURE_CONFUSION: @@ -7455,6 +7495,11 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE; BattleScriptExecute(BattleScript_BerryCureSlpEnd2); effect = ITEM_STATUS_CHANGE; + if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]]) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE; + } } break; case HOLD_EFFECT_CURE_STATUS: @@ -7761,6 +7806,11 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE; BattleScriptExecute(BattleScript_BerryCureSlpEnd2); effect = ITEM_STATUS_CHANGE; + if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]]) + { + gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE; + } } break; case HOLD_EFFECT_CURE_CONFUSION: diff --git a/src/pokemon.c b/src/pokemon.c index 2b731ef13cfa..fe13010ed186 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -4184,13 +4184,35 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov bool8 HealStatusConditions(struct Pokemon *mon, u32 healMask, u8 battlerId) { u32 status = GetMonData(mon, MON_DATA_STATUS, 0); - + u32 i = 0; + u32 battlerSide = GetBattlerSide(battlerId); + if (status & healMask) { status &= ~healMask; SetMonData(mon, MON_DATA_STATUS, &status); if (gMain.inBattle && battlerId != MAX_BATTLERS_COUNT) + { gBattleMons[battlerId].status1 &= ~healMask; + if((healMask & STATUS1_SLEEP) && B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[battlerSide]) + { + struct Pokemon *party; + if (battlerSide == B_SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + for (i = 0; i < PARTY_SIZE; i++) + { + if (&party[i] == mon && gBattleStruct->sleepClause.isCausingSleepClause[battlerSide][i]) + { + gBattleStruct->sleepClause.isActive[battlerSide] = FALSE; + gBattleStruct->sleepClause.isCausingSleepClause[battlerSide][i] = FALSE; + break; + } + } + } + } return FALSE; } else diff --git a/test/battle/sleep_clause.c b/test/battle/sleep_clause.c index e8745a8f6fe9..c9d0b4404b3e 100644 --- a/test/battle/sleep_clause.c +++ b/test/battle/sleep_clause.c @@ -1,9 +1,12 @@ #include "global.h" #include "test/battle.h" +#if B_SLEEP_CLAUSE == TRUE + AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will not use sleep moves while sleep clause is active") { GIVEN { + 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); @@ -18,6 +21,7 @@ AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will not use sleep moves while sleep cla SINGLE_BATTLE_TEST("Sleep Clause: Sleep moves fail when sleep clause is active") { GIVEN { + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -43,6 +47,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep moves fail when sleep clause is active") SINGLE_BATTLE_TEST("Sleep Clause: Rest does not activate sleep clause") { GIVEN { + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -60,6 +66,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Rest does not activate sleep clause") SINGLE_BATTLE_TEST("Sleep Clause: Rest can still be used when sleep clause is active") { GIVEN { + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -81,6 +89,9 @@ SINGLE_BATTLE_TEST("Sleep Clause: Rest can still be used when sleep clause is ac SINGLE_BATTLE_TEST("Sleep Clause: Psycho Shift'ing sleep will fail if sleep clause is active") { GIVEN { + 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); @@ -103,6 +114,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Psycho Shift'ing sleep will fail if sleep clau AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will not use Yawn while sleep clause is active") { GIVEN { + 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); @@ -118,6 +130,7 @@ AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will not use Yawn while sleep clause is SINGLE_BATTLE_TEST("Sleep Clause: Yawn will fail when sleep clause is active") { GIVEN { + ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -145,6 +158,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Effect Spore causes sleep 11% of the time with GIVEN { 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); } @@ -167,6 +181,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep from Effect Spore will not activate slee GIVEN { 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); } @@ -190,6 +205,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Moves with sleep effect chance will activate s { PASSES_RANDOMLY(10, 100, RNG_SECONDARY_EFFECT); GIVEN { + ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP)); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -215,6 +232,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Moves with sleep effect chance will still do d { PASSES_RANDOMLY(100, 100, RNG_SECONDARY_EFFECT); GIVEN { + ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP)); + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -235,18 +254,12 @@ SINGLE_BATTLE_TEST("Sleep Clause: Moves with sleep effect chance will still do d } } -// I added a dire claw test because im too lazy to read what MOVE_EFFECT_DIRE_CLAW does and i suspect it could be -// different than a normal "secondary sleep chance" effect -- feel free to delete this comment also -// or even this test as it might be redundant -ASSUMPTIONS -{ - ASSUME(MoveHasAdditionalEffect(MOVE_DIRE_CLAW, MOVE_EFFECT_DIRE_CLAW) == 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 { + 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); @@ -271,6 +284,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Dark Void can only sleep one opposing mon if s { // Source: https://bulbapedia.bulbagarden.net/wiki/Dark_Void_(move) GIVEN { + ASSUME(gMovesInfo[MOVE_DARK_VOID].effect == EFFECT_DARK_VOID); PLAYER(SPECIES_DARKRAI); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -315,80 +329,526 @@ DOUBLE_BATTLE_TEST("Sleep Clause: G-Max Befuddle can only sleep one opposing mon } } -//honestly some of these are probably covered by just normal sleep tests -// also possible that these should be done in doubles since its kinda just a nomral "mon woke up" test -TO_DO_BATTLE_TEST("Sleep Clause: sleep clause is deactivated when a sleeping mon wakes up"); -// something like: - // player has wob - // ai has wob - // player uses spore, AI wob falls asleep - // player celebrates until sleeping wob wakes up - // player uses spore, AI wob falls asleep - -// OR something like - // player has wob - // ai has wob and wob - // player uses spore, AI wob falls asleep - // player celebrates until sleeping wob wakes up - // AI switches, player uses spore, AI wob 2 falls asleep - - -TO_DO_BATTLE_TEST("Sleep Clause: sleep clause is deactivated when a sleeping mon is woken up with aromatherapy"); -// something like: - // player has wob - // ai has wob and wob - // player uses spore, AI wob falls asleep - // AI switches, player uses spore, it fails - // player uses spore, it fails (or any move that can succeed) - // AI wob uses aromatherapy, cures sleeping wob - // player uses spore, it succeeds - -// might be redundant if they use the same effect -TO_DO_BATTLE_TEST("Sleep Clause: sleep clause is deactivated when a sleeping mon is woken up with heal bell"); -// something like: - // player has wob - // ai has wob and wob - // player uses spore, AI wob falls asleep - // AI switches, player uses spore, it fails - // player uses spore, it fails (or any move that can succeed) - // AI wob uses heal bell, cures sleeping wob - // player uses spore, it succeeds - -//I think doubles -TO_DO_BATTLE_TEST("DOUBLES: Sleep Clause: sleep clause is deactivated when a sleeping mon is woken up with g-max sweetness whatever the fuck that is"); -// something like: - // player has wob and wob - // ai has wob and wob - // someone puts someone to sleep and someone on the sleeping team uses gmax sweetness, which should cure the party of status - // can sleep again after that - -// now that im writing the pseudo for this test it feels wack -TO_DO_BATTLE_TEST("Sleep Clause: sleep clause is deactivated when a sleeping mon is woken up forcefully by a move from an opponent"); -// something like: - // player has wob - // ai has wob and wob - // player uses spore, AI wob falls asleep - // AI switches, player uses spore, it fails - // AI switches back to sleeping wob, player uses wake-up-slap/uproar, which wakes up enemy wob - // AI switches AGAIN, player uses spore, it succeeds - -// this feels like a horribly complicated scenario that would probably not happen in a million runs but unfortunately i thought of it so i will -// write it down -TO_DO_BATTLE_TEST("Sleep Clause: sleep clause is deactivated when a sleeping mon is woken up by using sleep talk into psycho shift"); -// replace psycho shift with the following moves: - // jungle healing, lunar blessing, refresh, purify (maybe?), take heart - -TO_DO_BATTLE_TEST("Sleep Clause: sleep clause is deactivated when a sleeping mon is woken up by the ability hydration in the rain"); - -TO_DO_BATTLE_TEST("Sleep Clause: sleep clause is deactivated when a sleeping mon is woken up by the ability natural cure"); - -TO_DO_BATTLE_TEST("Sleep Clause: sleep clause is deactivated when a sleeping mon is woken up by the ability shed skin"); - -TO_DO_BATTLE_TEST("DOUBLES TEST: Sleep Clause: sleep clause is deactivated when a sleeping mon is woken up by the ability healer"); - -TO_DO_BATTLE_TEST("Sleep Clause: sleep clause is deactivated when a sleeping mon is woken up by the item awakening"); -// replace awakening with the following items: - // blue flute, chesto berry, big malasada, casteliacone, full heal, full restore, heal powder, lava cookie, lum berry - // lumiose galett, miracle berry?, old gateau, pewter Crunchies, rage candy bar, shalour sable - // idk wtf half these items even are and id imagine a lot of them share effects so i doubt a test will be needed for all of them +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon wakes up") +{ + GIVEN { + 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("Foe Wobbuffet woke up!"); + MESSAGE("Wobbuffet used Spore!"); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("Foe 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 or Heal Bell") +{ + u32 move; + PARAMETRIZE { move = MOVE_AROMATHERAPY; } + PARAMETRIZE { move = MOVE_HEAL_BELL; } + GIVEN { + 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(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:opponentLeft); } + TURN { SWITCH(opponentLeft, 2); MOVE(playerLeft, MOVE_SPORE, target:opponentRight); } + TURN { SWITCH(opponentLeft, 0); MOVE(opponentRight, move); 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("Foe 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("Foe Zigzagoon fell asleep!"); + } + MESSAGE("But it failed!"); + if (move == MOVE_AROMATHERAPY) + { + MESSAGE("Foe Zigzagoon used Aromatherapy!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_AROMATHERAPY, opponentRight); + } + else + { + MESSAGE("Foe Zigzagoon used Heal Bell!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_HEAL_BELL, opponentRight); + } + 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("Foe 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 { + 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("Foe 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("Foe Zigzagoon fell asleep!"); + } + MESSAGE("But it failed!"); + MESSAGE("Zigzagoon used Wake-Up Slap!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_WAKE_UP_SLAP, playerLeft); + MESSAGE("Foe 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("Foe 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 { + 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("Foe Zigzagoon fell asleep!"); + STATUS_ICON(opponentLeft, sleep: TRUE); + MESSAGE("Zigzagoon used Uproar!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_UPROAR, playerRight); + MESSAGE("Zigzagoon caused an UPROAR!"); // Why is this one in all caps this should be brought up to RHH + MESSAGE("Foe Zigzagoon woke up in the UPROAR!"); + STATUS_ICON(opponentLeft, sleep: FALSE); + MESSAGE("Foe 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("Foe 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; // Fails due to bug, keep an eye on 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 { + 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("Foe Zigzagoon fell asleep!"); + MESSAGE("Foe Zigzagoon used Sleep Talk!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent); + if (move == MOVE_PSYCHO_SHIFT) + { + MESSAGE("Foe Zigzagoon used Psycho Shift!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_PSYCHO_SHIFT, opponent); + } + else if (move == MOVE_JUNGLE_HEALING) + { + MESSAGE("Foe Zigzagoon used Jungle Healing!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_JUNGLE_HEALING, opponent); + } + else if (move == MOVE_LUNAR_BLESSING) + { + MESSAGE("Foe Zigzagoon used Lunar Blessing!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_LUNAR_BLESSING, opponent); + } + else if (move == MOVE_TAKE_HEART) + { + MESSAGE("Foe Zigzagoon used Take Heart!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TAKE_HEART, opponent); + } + else if (move == MOVE_AROMATHERAPY) + { + MESSAGE("Foe 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 { + 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("Foe Luvdisc fell asleep!"); + MESSAGE("Foe 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("Foe Luvdisc fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Natural Cure") +{ + GIVEN { + 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("Foe 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("Foe Swablu fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Shed Skin") +{ + PASSES_RANDOMLY(30, 100, RNG_SHED_SKIN); // Needs to be changed to 33 once my PR gets merged to RHH (https://github.com/rh-hideout/pokeemerald-expansion/pull/5558) + GIVEN { + 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("Foe Dratini fell asleep!"); + MESSAGE("Foe 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("Foe Dratini fell asleep!"); + } +} + +DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Healer") +{ + KNOWN_FAILING; // Needs to wait for PR to get merged to RHH (https://github.com/rh-hideout/pokeemerald-expansion/pull/5559) + // PASSES_RANDOMLY(30, 100, RNG_HEALER); + GIVEN { + 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("Foe 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("Foe Zigzagoon fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by using a held item") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON) { Item(ITEM_CHESTO_BERRY); } + } 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("Foe Zigzagoon fell asleep!"); + MESSAGE("Foe Zigzagoon's Chesto Berry woke it from its sleep!"); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("Foe Zigzagoon fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by using an item") +{ + GIVEN { + 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("Foe 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("Foe Zigzagoon fell asleep!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon faints") +{ + GIVEN { + 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("Foe Zigzagoon fell asleep!"); + MESSAGE("Foe Zigzagoon fainted!"); + MESSAGE("Zigzagoon used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("Foe 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 { + 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("Foe Zigzagoon fell asleep!"); + MESSAGE("Foe Zigzagoon used Sleep Talk!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent); + MESSAGE("Foe Zigzagoon used Skill Swap!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SKILL_SWAP, opponent); + if (ability == ABILITY_VITAL_SPIRIT) + MESSAGE("Foe Zigzagoon's Vital Spirit cured its sleep problem!"); + if (ability == ABILITY_INSOMNIA) + MESSAGE("Foe Zigzagoon's Insomnia cured its sleep problem!"); + MESSAGE("Foe 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("Foe 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 { + 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("Foe Ralts fell asleep!"); + MESSAGE("2 sent out Zigzagoon!"); + MESSAGE("2 sent out Ralts!"); + if (ability == ABILITY_VITAL_SPIRIT) + MESSAGE("Foe Ralts's Vital Spirit cured its sleep problem!"); + if (ability == ABILITY_INSOMNIA) + MESSAGE("Foe 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("Foe 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") +{ + KNOWN_FAILING; // Sleep Clause parts work, but Imposter seems broken with battle messages / targeting. Make RHH issue if no response to dev message + GIVEN { + 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_VITAL_SPIRIT); } + 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("Foe 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("Foe Ditto fell asleep!"); + MESSAGE("2 sent out Zigzagoon!"); + MESSAGE("2 sent out Ditto!"); + MESSAGE("Foe Ditto's Vital Spirit 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("Foe Zigzagoon fell asleep!"); + } +} + +AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will use sleep moves again when sleep clause has been deactivated") +{ + GIVEN { + 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 { + 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("Foe 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("Foe Wobbuffet used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); + MESSAGE("Wobbuffet fell asleep!"); + } +} + +TO_DO_BATTLE_TEST("Sleep Clause: Falling asleep due to disobedience does not set sleep clause"); +#endif