diff --git a/include/battle.h b/include/battle.h index 5b2ed5c6de74..0ad6c172a41a 100644 --- a/include/battle.h +++ b/include/battle.h @@ -103,6 +103,8 @@ struct DisableStruct u8 toxicSpikesDone:1; u8 stickyWebDone:1; u8 stealthRockDone:1; + u8 weatherAbilityDone:1; + u8 terrainAbilityDone:1; }; struct ProtectStruct @@ -193,8 +195,6 @@ struct SpecialStatus u8 dancerUsedMove:1; u8 dancerOriginalTarget:3; // End of byte - u8 weatherAbilityDone:1; - u8 terrainAbilityDone:1; u8 emergencyExited:1; u8 afterYou:1; }; diff --git a/src/battle_util.c b/src/battle_util.c index e9bb83e19b28..bdce8fbc9dc3 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1968,12 +1968,13 @@ u32 GetBattlerFriendshipScore(u32 battler) return GetMonFriendshipScore(&party[gBattlerPartyIndexes[battler]]); } -static void TryToRevertMimicry(void) +static void TryToRevertMimicryAndFlags(void) { u32 i; for (i = 0; i < gBattlersCount; i++) { + gDisableStructs[i].terrainAbilityDone = FALSE; if (GetBattlerAbility(i) == ABILITY_MIMICRY) RESTORE_BATTLER_TYPE(i); } @@ -2022,7 +2023,7 @@ static bool32 EndTurnTerrain(u32 terrainFlag, u32 stringTableId) if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0) { gFieldStatuses &= ~terrainFlag; - TryToRevertMimicry(); + TryToRevertMimicryAndFlags(); gBattleCommunication[MULTISTRING_CHOOSER] = stringTableId; BattleScriptExecute(BattleScript_TerrainEnds); return TRUE; @@ -2322,6 +2323,8 @@ u8 DoFieldEndTurnEffects(void) && --gWishFutureKnock.weatherDuration == 0) { gBattleWeather &= ~B_WEATHER_SUN_TEMPORARY; + for (i = 0; i < gBattlersCount; i++) + gDisableStructs[i].weatherAbilityDone = FALSE; gBattlescriptCurrInstr = BattleScript_SunlightFaded; } else @@ -4051,6 +4054,7 @@ static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer) { gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN); gFieldStatuses |= statusFlag; + gDisableStructs[battler].terrainAbilityDone = FALSE; if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER) *timer = 8; @@ -6061,10 +6065,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 } break; case ABILITY_PROTOSYNTHESIS: - if (!gSpecialStatuses[battler].weatherAbilityDone && IsBattlerWeatherAffected(battler, B_WEATHER_SUN)) + if (!gDisableStructs[battler].weatherAbilityDone && IsBattlerWeatherAffected(battler, B_WEATHER_SUN)) { - gSpecialStatuses[battler].weatherAbilityDone = TRUE; + gDisableStructs[battler].weatherAbilityDone = TRUE; PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); + gBattlerAbility = gBattleScripting.battler = battler; BattleScriptPushCursorAndCallback(BattleScript_ProtosynthesisActivates); effect++; } @@ -6076,9 +6081,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 switch (gLastUsedAbility) { case ABILITY_MIMICRY: - if (!gSpecialStatuses[battler].terrainAbilityDone && ChangeTypeBasedOnTerrain(battler)) + if (!gDisableStructs[battler].terrainAbilityDone && ChangeTypeBasedOnTerrain(battler)) { - gSpecialStatuses[battler].terrainAbilityDone = TRUE; + gDisableStructs[battler].terrainAbilityDone = TRUE; ChangeTypeBasedOnTerrain(battler); gBattlerAbility = gBattleScripting.battler = battler; BattleScriptPushCursorAndCallback(BattleScript_MimicryActivates_End3); @@ -6086,11 +6091,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 } break; case ABILITY_QUARK_DRIVE: - if (!gSpecialStatuses[battler].terrainAbilityDone && IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN)) + if (!gDisableStructs[battler].terrainAbilityDone && IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN)) { - gSpecialStatuses[battler].terrainAbilityDone = TRUE; - gBattlerAbility = gBattleScripting.battler = battler; + gDisableStructs[battler].terrainAbilityDone = TRUE; PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); + gBattlerAbility = gBattleScripting.battler = battler; BattleScriptPushCursorAndCallback(BattleScript_QuarkDriveActivates); effect++; } diff --git a/test/battle/ability/protosynthesis.c b/test/battle/ability/protosynthesis.c index 0ed74d4f65ce..40711ecced73 100644 --- a/test/battle/ability/protosynthesis.c +++ b/test/battle/ability/protosynthesis.c @@ -85,3 +85,50 @@ SINGLE_BATTLE_TEST("Protosynthesis either boosts Defense or Special Defense, not EXPECT_EQ(damage[0], damage[1]); } } + +SINGLE_BATTLE_TEST("Protosynthesis ability pop up activates only once during the duration of sunny day") +{ + u16 turns; + + GIVEN { + PLAYER(SPECIES_BELLSPROUT) { Ability(ABILITY_PROTOSYNTHESIS); } + OPPONENT(SPECIES_NINETALES) { Ability(ABILITY_DROUGHT); }; + } WHEN { + for (turns = 0; turns < 5; turns++) + TURN {} + TURN { MOVE(opponent, MOVE_SUNNY_DAY); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_DROUGHT); + ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS); + MESSAGE("The harsh sunlight activated Bellsprout's Protosynthesis!"); + MESSAGE("Bellsprout's Attack was heightened!"); + NONE_OF { + for (turns = 0; turns < 4; turns++) { + ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS); + MESSAGE("The harsh sunlight activated Bellsprout's Protosynthesis!"); + MESSAGE("Bellsprout's Attack was heightened!"); + } + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, opponent); + ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS); + MESSAGE("The harsh sunlight activated Bellsprout's Protosynthesis!"); + MESSAGE("Bellsprout's Attack was heightened!"); + } +} + +SINGLE_BATTLE_TEST("Protosynthesis activates on switch-in") +{ + KNOWN_FAILING; // Fails because of wrong species + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_BELLSPROUT) { Ability(ABILITY_PROTOSYNTHESIS); } + OPPONENT(SPECIES_NINETALES) { Ability(ABILITY_DROUGHT); }; + } WHEN { + TURN { SWITCH(player, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_DROUGHT); + ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS); + MESSAGE("The harsh sunlight activated Bellsprout's Protosynthesis!"); + MESSAGE("Bellsprout's Attack was heightened!"); + } +} diff --git a/test/battle/ability/quark_drive.c b/test/battle/ability/quark_drive.c index bce6795caeac..abf0b7f5cb8f 100644 --- a/test/battle/ability/quark_drive.c +++ b/test/battle/ability/quark_drive.c @@ -85,3 +85,51 @@ SINGLE_BATTLE_TEST("Quark Drive either boosts Defense or Special Defense, not bo EXPECT_EQ(damage[0], damage[1]); } } + +SINGLE_BATTLE_TEST("Quark Drive ability pop up activates only once during the duration of electric terrain") +{ + u16 turns; + + GIVEN { + PLAYER(SPECIES_BELLSPROUT) { Ability(ABILITY_QUARK_DRIVE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_ELECTRIC_TERRAIN); } + for (turns = 0; turns < 4; turns++) + TURN {} + TURN { MOVE(opponent, MOVE_ELECTRIC_TERRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIC_TERRAIN, opponent); + ABILITY_POPUP(player, ABILITY_QUARK_DRIVE); + MESSAGE("The Electric Terrain activated Bellsprout's Quark Drive!"); + MESSAGE("Bellsprout's Attack was heightened!"); + NONE_OF { + for (turns = 0; turns < 4; turns++) { + ABILITY_POPUP(player, ABILITY_QUARK_DRIVE); + MESSAGE("The Electric Terrain activated Bellsprout's Quark Drive!"); + MESSAGE("Bellsprout's Attack was heightened!"); + } + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIC_TERRAIN, opponent); + ABILITY_POPUP(player, ABILITY_QUARK_DRIVE); + MESSAGE("The Electric Terrain activated Bellsprout's Quark Drive!"); + MESSAGE("Bellsprout's Attack was heightened!"); + } +} + +SINGLE_BATTLE_TEST("Quark Drive activates on switch-in") +{ + KNOWN_FAILING; // Fails because of wrong species + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_BELLSPROUT) { Ability(ABILITY_QUARK_DRIVE); } + OPPONENT(SPECIES_TAPU_KOKO) { Ability(ABILITY_ELECTRIC_SURGE); }; + } WHEN { + TURN { SWITCH(player, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_ELECTRIC_SURGE); + ABILITY_POPUP(player, ABILITY_QUARK_DRIVE); + MESSAGE("The Electric Terrain activated Bellsprout's Quark Drive!"); + MESSAGE("Bellsprout's Attack was heightened!"); + } +}