diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 66c82f39e53..c29d8f7c401 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1899,11 +1899,6 @@ various \battler, VARIOUS_TRY_END_NEUTRALIZING_GAS .endm - .macro trytoapplymimicry battler:req, ptr:req - various \battler, VARIOUS_TRY_TO_APPLY_MIMICRY - .4byte \ptr - .endm - .macro trynoretreat battler:req, ptr:req various \battler, VARIOUS_TRY_NO_RETREAT .4byte \ptr @@ -2024,7 +2019,6 @@ .byte \counter .4byte \ptr .endm - .macro swapstats stat:req various BS_ATTACKER, VARIOUS_SWAP_STATS .byte \stat diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 4845b49aad6..08da49fd049 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -2526,23 +2526,6 @@ BattleScript_EffectPsychicTerrain: playanimation BS_ATTACKER, B_ANIM_RESTORE_BG call BattleScript_ActivateTerrainAbilities call BattleScript_TerrainSeedLoop - jumpifabilitypresent ABILITY_MIMICRY, BattleScript_ApplyMimicry - goto BattleScript_MoveEnd - -BattleScript_ApplyMimicry:: - savetarget - setbyte gBattlerTarget, 0 -BattleScript_MimicryLoopIter: - copybyte sBATTLER, gBattlerTarget - trytoapplymimicry BS_TARGET, BattleScript_MimicryLoop_NextBattler - copybyte gBattlerAbility, sBATTLER - call BattleScript_AbilityPopUp - printstring STRINGID_BATTLERTYPECHANGEDTO - waitmessage B_WAIT_TIME_LONG -BattleScript_MimicryLoop_NextBattler: - addbyte gBattlerTarget, 0x1 - jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_MimicryLoopIter - restoretarget goto BattleScript_MoveEnd BattleScript_EffectTopsyTurvy: @@ -6725,12 +6708,14 @@ BattleScript_OverworldWeatherStarts:: printfromtable gWeatherStartsStringIds waitmessage B_WAIT_TIME_LONG playanimation_var BS_ATTACKER, sB_ANIM_ARG1 + call BattleScript_WeatherFormChanges end3 BattleScript_OverworldTerrain:: printfromtable gTerrainStringIds waitmessage B_WAIT_TIME_LONG playanimation BS_SCRIPTING, B_ANIM_RESTORE_BG + call BattleScript_TerrainSeedLoop end3 BattleScript_SideStatusWoreOff:: @@ -8619,6 +8604,13 @@ BattleScript_AttackWeakenedByStrongWinds:: waitmessage B_WAIT_TIME_LONG return +BattleScript_MimicryActivates_End3:: + pause B_WAIT_TIME_SHORT + call BattleScript_AbilityPopUp + printstring STRINGID_BATTLERTYPECHANGEDTO + waitmessage B_WAIT_TIME_SHORT + end3 + BattleScript_SnowWarningActivates:: pause B_WAIT_TIME_SHORT call BattleScript_AbilityPopUp @@ -8639,6 +8631,7 @@ BattleScript_TerrainSeedLoop_NextBattler: addbyte gBattlerTarget, 0x1 jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_TerrainSeedLoopIter restoretarget + call BattleScript_ActivateSwitchInAbilities return BattleScript_ActivateSwitchInAbilities: @@ -8937,12 +8930,6 @@ BattleScript_ColorChangeActivates:: waitmessage B_WAIT_TIME_LONG return -BattleScript_MimicryActivatesEnd3:: - call BattleScript_AbilityPopUp - printstring STRINGID_BATTLERTYPECHANGEDTO - waitmessage B_WAIT_TIME_LONG - end3 - BattleScript_ProteanActivates:: pause B_WAIT_TIME_SHORTEST call BattleScript_AbilityPopUp diff --git a/include/battle.h b/include/battle.h index aafc3d2f6d6..8af8be77c9b 100644 --- a/include/battle.h +++ b/include/battle.h @@ -192,6 +192,8 @@ struct SpecialStatus u8 dancerUsedMove:1; u8 dancerOriginalTarget:3; // End of byte + u8 weatherAbilityDone:1; + u8 terrainAbilityDone:1; }; struct SideTimer @@ -683,6 +685,13 @@ struct BattleStruct gBattleMons[battlerId].type2 = type; \ gBattleMons[battlerId].type3 = TYPE_MYSTERY; \ } +#define RESTORE_BATTLER_TYPE(battlerId) \ +{ \ + gBattleMons[battlerId].type1 = gSpeciesInfo[gBattleMons[battlerId].species].type1; \ + gBattleMons[battlerId].type2 = gSpeciesInfo[gBattleMons[battlerId].species].type2; \ + gBattleMons[battlerId].type3 = TYPE_MYSTERY; \ +} + #define IS_BATTLER_PROTECTED(battlerId)(gProtectStructs[battlerId].protected \ || gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD \ diff --git a/include/battle_scripts.h b/include/battle_scripts.h index d79566a44be..589a5075a65 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -448,6 +448,7 @@ extern const u8 BattleScript_SupremeOverlordActivates[]; extern const u8 BattleScript_CostarActivates[]; extern const u8 BattleScript_ToxicDebrisActivates[]; extern const u8 BattleScript_EarthEaterActivates[]; +extern const u8 BattleScript_MimicryActivates_End3[]; // zmoves extern const u8 BattleScript_ZMoveActivateDamaging[]; diff --git a/include/battle_util.h b/include/battle_util.h index 1a05c246cff..1c3f486cda7 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -26,16 +26,15 @@ #define ABILITYEFFECT_MOVE_END_ATTACKER 4 #define ABILITYEFFECT_MOVE_END 5 #define ABILITYEFFECT_IMMUNITY 6 -#define ABILITYEFFECT_WEATHER_FORM 7 -#define ABILITYEFFECT_SYNCHRONIZE 8 -#define ABILITYEFFECT_ATK_SYNCHRONIZE 9 -#define ABILITYEFFECT_TRACE1 10 -#define ABILITYEFFECT_TRACE2 11 -#define ABILITYEFFECT_MOVE_END_OTHER 12 -#define ABILITYEFFECT_NEUTRALIZINGGAS 13 -#define ABILITYEFFECT_FIELD_SPORT 14 // Only used if B_SPORT_TURNS < GEN_6 -#define ABILITYEFFECT_ON_WEATHER 15 -#define ABILITYEFFECT_ON_TERRAIN 16 +#define ABILITYEFFECT_SYNCHRONIZE 7 +#define ABILITYEFFECT_ATK_SYNCHRONIZE 8 +#define ABILITYEFFECT_TRACE1 9 +#define ABILITYEFFECT_TRACE2 10 +#define ABILITYEFFECT_MOVE_END_OTHER 11 +#define ABILITYEFFECT_NEUTRALIZINGGAS 12 +#define ABILITYEFFECT_FIELD_SPORT 13 // Only used if B_SPORT_TURNS < GEN_6 +#define ABILITYEFFECT_ON_WEATHER 14 +#define ABILITYEFFECT_ON_TERRAIN 15 // Special cases #define ABILITYEFFECT_MUD_SPORT 252 // Only used if B_SPORT_TURNS < GEN_6 #define ABILITYEFFECT_WATER_SPORT 253 // Only used if B_SPORT_TURNS < GEN_6 @@ -182,9 +181,6 @@ void DoBurmyFormChange(u32 monId); bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget); u16 GetUsedHeldItem(u8 battler); bool32 IsBattlerWeatherAffected(u8 battlerId, u32 weatherFlags); -void TryToApplyMimicry(u8 battlerId, bool8 various); -void TryToRevertMimicry(void); -void RestoreBattlerOriginalTypes(u8 battlerId); u32 GetBattlerMoveTargetType(u8 battlerId, u16 move); bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move); bool8 IsMoveAffectedByParentalBond(u16 move, u8 battlerId); @@ -207,5 +203,6 @@ bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag); u32 GetBattlerFriendshipScore(u8 battlerId); u32 CountBattlerStatIncreases(u8 battlerId, bool32 countEvasionAcc); bool32 IsMyceliumMightOnField(void); +bool8 ChangeTypeBasedOnTerrain(u8 battlerId); #endif // GUARD_BATTLE_UTIL_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 8f9ce0af8af..a13423bcb1a 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -216,45 +216,44 @@ #define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125 #define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126 #define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127 -#define VARIOUS_TRY_TO_APPLY_MIMICRY 128 -#define VARIOUS_PHOTON_GEYSER_CHECK 129 -#define VARIOUS_SHELL_SIDE_ARM_CHECK 130 -#define VARIOUS_TRY_NO_RETREAT 131 -#define VARIOUS_TRY_TAR_SHOT 132 -#define VARIOUS_CAN_TAR_SHOT_WORK 133 -#define VARIOUS_CHECK_POLTERGEIST 134 -#define VARIOUS_SET_OCTOLOCK 135 -#define VARIOUS_CUT_1_3_HP_RAISE_STATS 136 -#define VARIOUS_TRY_END_NEUTRALIZING_GAS 137 -#define VARIOUS_JUMP_IF_UNDER_200 138 -#define VARIOUS_SET_SKY_DROP 139 -#define VARIOUS_CLEAR_SKY_DROP 140 -#define VARIOUS_SKY_DROP_YAWN 141 -#define VARIOUS_JUMP_IF_CANT_FLING 142 -#define VARIOUS_JUMP_IF_HOLD_EFFECT 143 -#define VARIOUS_CURE_CERTAIN_STATUSES 144 -#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 145 -#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 146 -#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 147 -#define VARIOUS_SAVE_BATTLER_ITEM 148 -#define VARIOUS_RESTORE_BATTLER_ITEM 149 -#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 150 -#define VARIOUS_SET_BEAK_BLAST 151 -#define VARIOUS_SWAP_SIDE_STATUSES 152 -#define VARIOUS_SET_Z_EFFECT 153 -#define VARIOUS_TRY_SYMBIOSIS 154 -#define VARIOUS_CAN_TELEPORT 155 -#define VARIOUS_GET_BATTLER_SIDE 156 -#define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 157 -#define VARIOUS_SWAP_STATS 158 -#define VARIOUS_JUMP_IF_ROD 159 -#define VARIOUS_JUMP_IF_ABSORB 160 -#define VARIOUS_JUMP_IF_MOTOR 161 -#define VARIOUS_TEATIME_INVUL 162 -#define VARIOUS_TEATIME_TARGETS 163 -#define VARIOUS_TRY_WIND_RIDER_POWER 164 -#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 165 -#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 166 +#define VARIOUS_PHOTON_GEYSER_CHECK 128 +#define VARIOUS_SHELL_SIDE_ARM_CHECK 129 +#define VARIOUS_TRY_NO_RETREAT 130 +#define VARIOUS_TRY_TAR_SHOT 131 +#define VARIOUS_CAN_TAR_SHOT_WORK 132 +#define VARIOUS_CHECK_POLTERGEIST 133 +#define VARIOUS_SET_OCTOLOCK 134 +#define VARIOUS_CUT_1_3_HP_RAISE_STATS 135 +#define VARIOUS_TRY_END_NEUTRALIZING_GAS 136 +#define VARIOUS_JUMP_IF_UNDER_200 137 +#define VARIOUS_SET_SKY_DROP 138 +#define VARIOUS_CLEAR_SKY_DROP 139 +#define VARIOUS_SKY_DROP_YAWN 140 +#define VARIOUS_JUMP_IF_CANT_FLING 141 +#define VARIOUS_JUMP_IF_HOLD_EFFECT 142 +#define VARIOUS_CURE_CERTAIN_STATUSES 143 +#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 144 +#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 145 +#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 146 +#define VARIOUS_SAVE_BATTLER_ITEM 147 +#define VARIOUS_RESTORE_BATTLER_ITEM 148 +#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 149 +#define VARIOUS_SET_BEAK_BLAST 150 +#define VARIOUS_SWAP_SIDE_STATUSES 151 +#define VARIOUS_SET_Z_EFFECT 152 +#define VARIOUS_TRY_SYMBIOSIS 153 +#define VARIOUS_CAN_TELEPORT 154 +#define VARIOUS_GET_BATTLER_SIDE 155 +#define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 156 +#define VARIOUS_SWAP_STATS 157 +#define VARIOUS_JUMP_IF_ROD 158 +#define VARIOUS_JUMP_IF_ABSORB 159 +#define VARIOUS_JUMP_IF_MOTOR 160 +#define VARIOUS_TEATIME_INVUL 161 +#define VARIOUS_TEATIME_TARGETS 162 +#define VARIOUS_TRY_WIND_RIDER_POWER 163 +#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 164 +#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 165 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_message.c b/src/battle_message.c index 1189cf3e1cc..c1ebe8d797f 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -740,7 +740,7 @@ static const u8 sText_AbilityAllowsOnlyMove[] = _("{B_ATK_ABILITY} allows the\nu static const u8 sText_SwappedAbilities[] = _("{B_DEF_NAME_WITH_PREFIX} swapped Abilities\nwith its target!"); static const u8 sText_PastelVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is protected\nby a pastel veil!"); static const u8 sText_PastelVeilEnters[] = _("{B_DEF_NAME_WITH_PREFIX} was cured\nof its poisoning!"); -static const u8 sText_BattlerTypeChangedTo[] = _("{B_BUFF1}'s type\nchanged to {B_BUFF2}!"); +static const u8 sText_BattlerTypeChangedTo[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s type\nchanged to {B_BUFF1}!"); static const u8 sText_BothCanNoLongerEscape[] = _("Neither Pokémon can run away!"); static const u8 sText_CantEscapeDueToUsedMove[] = _("{B_ATK_NAME_WITH_PREFIX} can no longer escape\nbecause it used {B_CURRENT_MOVE}!"); static const u8 sText_PkmnBecameWeakerToFire[] = _("{B_DEF_NAME_WITH_PREFIX} became\nweaker to fire!"); @@ -762,9 +762,9 @@ static const u8 sText_TargetToughedItOut[] = _("{B_DEF_NAME_WITH_PREFIX} toughed static const u8 sText_AttackerLostElectricType[] = _("{B_ATK_NAME_WITH_PREFIX} used up all\nof its electricity!"); static const u8 sText_AttackerSwitchedStatWithTarget[] = _("{B_ATK_NAME_WITH_PREFIX} switched {B_BUFF1}\nwith its target!"); static const u8 sText_BeingHitChargedPkmnWithPower[] = _("Being hit by {B_CURRENT_MOVE}\ncharged {B_ATK_NAME_WITH_PREFIX} with power!"); -static const u8 sText_SunlightActivatedAbility[] = _("The harsh sunlight activated\n{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}!"); -static const u8 sText_StatWasHeightened[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1} was heightened!"); -static const u8 sText_ElectricTerrainActivatedAbility[] = _("The Electric Terrain activated\n{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}!"); +static const u8 sText_SunlightActivatedAbility[] = _("The harsh sunlight activated\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ABILITY}!"); +static const u8 sText_StatWasHeightened[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} was heightened!"); +static const u8 sText_ElectricTerrainActivatedAbility[] = _("The Electric Terrain activated\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ABILITY}!"); static const u8 sText_AbilityWeakenedSurroundingMonsStat[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\nweakened the {B_BUFF1} of\lall surrounding Pokémon!\p"); static const u8 sText_AttackerGainedStrengthFromTheFallen[] = _("{B_ATK_NAME_WITH_PREFIX} gained strength\nfrom the fallen!"); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ec4d72a0877..5f79c07793c 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6785,9 +6785,10 @@ static void Cmd_switchineffects(void) gDisableStructs[gActiveBattler].truantSwitchInHack = 0; if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0) - || ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, gActiveBattler, FALSE) - || AbilityBattleEffects(ABILITYEFFECT_TRACE2, 0, 0, 0, 0) - || AbilityBattleEffects(ABILITYEFFECT_WEATHER_FORM, 0, 0, 0, 0)) + || (gBattleWeather & B_WEATHER_ANY && WEATHER_HAS_EFFECT && AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, gActiveBattler, 0, 0, 0)) + || (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY && AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, gActiveBattler, 0, 0, 0)) + || ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, gActiveBattler, FALSE) + || AbilityBattleEffects(ABILITYEFFECT_TRACE2, 0, 0, 0, 0)) return; gSideStatuses[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_SPIKES_DAMAGED | SIDE_STATUS_TOXIC_SPIKES_DAMAGED | SIDE_STATUS_STEALTH_ROCK_DAMAGED | SIDE_STATUS_STICKY_WEB_DAMAGED); @@ -9652,7 +9653,6 @@ static void Cmd_various(void) break; } gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain - TryToRevertMimicry(); // restore the types of Pokémon with Mimicry break; case VARIOUS_JUMP_IF_UNDER_200: // If the Pokemon is less than 200 kg, or weighing less than 441 lbs, then Sky Drop will work. Otherwise, it will fail. @@ -10001,21 +10001,6 @@ static void Cmd_various(void) else gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); return; - case VARIOUS_TRY_TO_APPLY_MIMICRY: - { - bool8 isMimicryDone = FALSE; - - if (GetBattlerAbility(gActiveBattler) == ABILITY_MIMICRY) - { - TryToApplyMimicry(gActiveBattler, TRUE); - isMimicryDone = TRUE; - } - if (!isMimicryDone) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - else - gBattlescriptCurrInstr += 7; - return; - } case VARIOUS_JUMP_IF_CANT_FLING: if (!CanFling(gActiveBattler)) gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); diff --git a/src/battle_util.c b/src/battle_util.c index 5a9b155186f..2782e55e0fd 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2048,57 +2048,6 @@ u8 GetImprisonedMovesCount(u8 battlerId, u16 move) return imprisonedMoves; } -void RestoreBattlerOriginalTypes(u8 battlerId) -{ - gBattleMons[battlerId].type1 = gSpeciesInfo[gBattleMons[battlerId].species].type1; - gBattleMons[battlerId].type2 = gSpeciesInfo[gBattleMons[battlerId].species].type2; -} - -void TryToApplyMimicry(u8 battlerId, bool8 various) -{ - u32 moveType, move; - - GET_MOVE_TYPE(move, moveType); - switch (gFieldStatuses) - { - case STATUS_FIELD_ELECTRIC_TERRAIN: - moveType = TYPE_ELECTRIC; - break; - case STATUS_FIELD_MISTY_TERRAIN: - moveType = TYPE_FAIRY; - break; - case STATUS_FIELD_GRASSY_TERRAIN: - moveType = TYPE_GRASS; - break; - case STATUS_FIELD_PSYCHIC_TERRAIN: - moveType = TYPE_PSYCHIC; - break; - default: - moveType = 0; - break; - } - - if (moveType != 0 && !IS_BATTLER_OF_TYPE(battlerId, moveType)) - { - SET_BATTLER_TYPE(battlerId, moveType); - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, battlerId, gBattlerPartyIndexes[battlerId]) - PREPARE_TYPE_BUFFER(gBattleTextBuff2, moveType); - if (!various) - BattleScriptPushCursorAndCallback(BattleScript_MimicryActivatesEnd3); - } -} - -void TryToRevertMimicry(void) -{ - s32 i; - - for (i = 0; i < MAX_BATTLERS_COUNT; i++) - { - if (GetBattlerAbility(i) == ABILITY_MIMICRY) - RestoreBattlerOriginalTypes(i); - } -} - u32 GetBattlerFriendshipScore(u8 battlerId) { u8 side = GetBattlerSide(battlerId); @@ -2118,6 +2067,17 @@ u32 GetBattlerFriendshipScore(u8 battlerId) return GetMonFriendshipScore(&party[gBattlerPartyIndexes[battlerId]]); } +static void TryToRevertMimicry(void) +{ + u32 i; + + for (i = 0; i < gBattlersCount; i++) + { + if (GetBattlerAbility(i) == ABILITY_MIMICRY) + RESTORE_BATTLER_TYPE(i); + } +} + enum { ENDTURN_ORDER, @@ -2596,7 +2556,7 @@ u8 DoFieldEndTurnEffects(void) gBattleStruct->turnCountersTracker++; break; case ENDTURN_WEATHER_FORM: - AbilityBattleEffects(ABILITYEFFECT_WEATHER_FORM, 0, 0, 0, 0); + AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, 0, 0, 0, 0); gBattleStruct->turnCountersTracker++; break; case ENDTURN_STATUS_HEAL: @@ -4335,6 +4295,26 @@ static u8 ForewarnChooseMove(u32 battler) Free(data); } +bool8 ChangeTypeBasedOnTerrain(u8 battlerId) +{ + u8 battlerType; + + if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) + battlerType = TYPE_ELECTRIC; + else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) + battlerType = TYPE_GRASS; + else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) + battlerType = TYPE_FAIRY; + else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) + battlerType = TYPE_PSYCHIC; + else // failsafe + return FALSE; + + SET_BATTLER_TYPE(battlerId, battlerType); + PREPARE_TYPE_BUFFER(gBattleTextBuff1, battlerType); + return TRUE; +} + u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 moveArg) { u8 effect = 0; @@ -4835,31 +4815,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; - case ABILITY_MIMICRY: - if (gBattleMons[battler].hp != 0 && gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) - { - TryToApplyMimicry(battler, FALSE); - effect++; - } - break; - case ABILITY_PROTOSYNTHESIS: - if (!gSpecialStatuses[battler].switchInAbilityDone && gBattleWeather & B_WEATHER_SUN) - { - gSpecialStatuses[battler].switchInAbilityDone = TRUE; - PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); - BattleScriptPushCursorAndCallback(BattleScript_ProtosynthesisActivates); - effect++; - } - break; - case ABILITY_QUARK_DRIVE: - if (!gSpecialStatuses[battler].switchInAbilityDone && gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) - { - gSpecialStatuses[battler].switchInAbilityDone = TRUE; - PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); - BattleScriptPushCursorAndCallback(BattleScript_QuarkDriveActivates); - effect++; - } - break; case ABILITY_VESSEL_OF_RUIN: if (!gSpecialStatuses[battler].switchInAbilityDone) { @@ -6044,31 +5999,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } } break; - case ABILITYEFFECT_WEATHER_FORM: // 6 - for (battler = 0; battler < gBattlersCount; battler++) - { - switch (gBattleMons[battler].species) - { - case SPECIES_CASTFORM: - case SPECIES_CHERRIM: -#ifdef POKEMON_EXPANSION - case SPECIES_CASTFORM_RAINY: - case SPECIES_CASTFORM_SNOWY: - case SPECIES_CASTFORM_SUNNY: - case SPECIES_CHERRIM_SUNSHINE: -#endif - effect = TryWeatherFormChange(battler); - if (effect != 0) - { - BattleScriptPushCursorAndCallback(BattleScript_WeatherFormChange); - gBattleScripting.battler = battler; - gBattleStruct->formToChangeInto = effect - 1; - return effect; - } - break; - } - } - break; case ABILITYEFFECT_SYNCHRONIZE: if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT)) { @@ -6209,8 +6139,9 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITYEFFECT_ON_WEATHER: // For ability effects that activate when the battle weather changes. - battler = gBattlerAbility = gBattlerAttacker = gBattleScripting.battler; - switch (GetBattlerAbility(battler)) + battler = gBattlerAbility = gBattleScripting.battler; + gLastUsedAbility = GetBattlerAbility(battler); + switch (gLastUsedAbility) { case ABILITY_FORECAST: #if B_WEATHER_FORMS >= GEN_5 @@ -6226,8 +6157,9 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITY_PROTOSYNTHESIS: - if (IsBattlerWeatherAffected(battler, B_WEATHER_SUN)) + if (!gSpecialStatuses[battler].weatherAbilityDone && IsBattlerWeatherAffected(battler, B_WEATHER_SUN)) { + gSpecialStatuses[battler].weatherAbilityDone = TRUE; PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); BattleScriptPushCursorAndCallback(BattleScript_ProtosynthesisActivates); effect++; @@ -6236,12 +6168,23 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITYEFFECT_ON_TERRAIN: // For ability effects that activate when the field terrain changes. - battler = gBattlerAbility = gBattlerAttacker = gBattleScripting.battler; - switch (GetBattlerAbility(battler)) + battler = gBattlerAbility = gBattleScripting.battler; + gLastUsedAbility = GetBattlerAbility(battler); + switch (gLastUsedAbility) { + case ABILITY_MIMICRY: + if (!gSpecialStatuses[battler].terrainAbilityDone && ChangeTypeBasedOnTerrain(battler)) + { + gSpecialStatuses[battler].terrainAbilityDone = TRUE; + ChangeTypeBasedOnTerrain(battler); + BattleScriptPushCursorAndCallback(BattleScript_MimicryActivates_End3); + effect++; + } + break; case ABILITY_QUARK_DRIVE: - if (IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN)) + if (!gSpecialStatuses[battler].terrainAbilityDone && IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN)) { + gSpecialStatuses[battler].terrainAbilityDone = TRUE; PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); BattleScriptPushCursorAndCallback(BattleScript_QuarkDriveActivates); effect++;