Decouple (overworld) statuses from ability function (#8002)

This commit is contained in:
Alex 2025-10-26 14:57:34 +01:00 committed by GitHub
parent 3260d2a42a
commit 4ed1c3309d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 257 additions and 243 deletions

View File

@ -681,15 +681,13 @@ struct BattleStruct
struct LinkBattlerHeader linkBattlerHeader;
struct BattleVideo battleVideo;
} multiBuffer;
u8 startingStatus:6; // status to apply at battle start. defined in constants/battle.h
u8 startingStatusDone:1;
u8 terrainDone:1;
u8 overworldWeatherDone:1;
u8 startingStatus; // status to apply at battle start. defined in constants/battle.h
u8 battlerKOAnimsRunning:3;
u8 friskedAbility:1; // If identifies two mons, show the ability pop-up only once.
u8 fickleBeamBoosted:1;
u8 poisonPuppeteerConfusion:1;
u8 toxicChainPriority:1; // If Toxic Chain will trigger on target, all other non volatiles will be blocked
u8 padding1:1;
u16 startingStatusTimer;
u8 atkCancellerTracker;
struct BattleTvMovePoints tvMovePoints;
@ -772,14 +770,14 @@ struct BattleStruct
u8 printedStrongWindsWeakenedAttack:1;
u8 numSpreadTargets:2;
u8 noTargetPresent:1;
u8 padding1:1;
u8 padding2:1;
struct MessageStatus slideMessageStatus;
u8 trainerSlideSpriteIds[MAX_BATTLERS_COUNT];
u8 hazardsQueue[NUM_BATTLE_SIDES][HAZARDS_MAX_COUNT];
u8 numHazards[NUM_BATTLE_SIDES];
u8 hazardsCounter:4; // Counter for applying hazard on switch in
enum SubmoveState submoveAnnouncement:2;
u8 padding2:2;
u8 padding3:2;
u16 flingItem;
u8 incrementEchoedVoice:1;
u8 echoedVoiceCounter:3;

View File

@ -40,6 +40,13 @@ enum MoveAbsorbed
MOVE_ABSORBED_BY_BOOST_FLASH_FIRE,
};
enum FieldEffectCases
{
FIELD_EFFECT_TRAINER_STATUSES,
FIELD_EFFECT_OVERWORLD_TERRAIN,
FIELD_EFFECT_OVERWORLD_WEATHER,
};
enum AbilityEffect
{
ABILITYEFFECT_ON_SWITCHIN,
@ -55,11 +62,8 @@ enum AbilityEffect
ABILITYEFFECT_NEUTRALIZINGGAS_FIRST_TURN,
ABILITYEFFECT_ON_WEATHER,
ABILITYEFFECT_ON_TERRAIN,
ABILITYEFFECT_SWITCH_IN_TERRAIN,
ABILITYEFFECT_SWITCH_IN_WEATHER,
ABILITYEFFECT_OPPORTUNIST,
ABILITYEFFECT_OPPORTUNIST_FIRST_TURN,
ABILITYEFFECT_SWITCH_IN_STATUSES,
ABILITYEFFECT_ON_SWITCHIN_IMMUNITIES,
};
@ -256,6 +260,7 @@ bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, u32 ability);
bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag);
bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, enum Ability abilityAtk, enum Ability abilityDef, u32 move, enum FunctionCallOption option);
bool32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, enum Ability abilityDef, u32 move, u32 moveType, enum FunctionCallOption option);
bool32 TryFieldEffects(enum FieldEffectCases caseId);
u32 AbilityBattleEffects(enum AbilityEffect caseID, u32 battler, enum Ability ability, u32 special, u32 moveArg);
bool32 TryPrimalReversion(u32 battler);
bool32 IsNeutralizingGasOnField(void);

View File

@ -3732,7 +3732,6 @@ static void DoBattleIntro(void)
{
gBattleStruct->eventsBeforeFirstTurnState = 0;
gBattleStruct->switchInBattlerCounter = 0;
gBattleStruct->overworldWeatherDone = FALSE;
Ai_InitPartyStruct(); // Save mons party counts, and first 2/4 mons on the battlefield.
// mark all battlers as sent out
@ -3822,32 +3821,19 @@ static void TryDoEventsBeforeFirstTurn(void)
gBattleStruct->eventsBeforeFirstTurnState++;
break;
case FIRST_TURN_EVENTS_OVERWORLD_WEATHER:
if (!gBattleStruct->overworldWeatherDone
&& AbilityBattleEffects(ABILITYEFFECT_SWITCH_IN_WEATHER, 0, 0, ABILITYEFFECT_SWITCH_IN_WEATHER, 0) != 0)
{
gBattleStruct->overworldWeatherDone = TRUE;
return;
}
gBattleStruct->eventsBeforeFirstTurnState++;
if (TryFieldEffects(FIELD_EFFECT_OVERWORLD_WEATHER))
return;
break;
case FIRST_TURN_EVENTS_TERRAIN:
if (!gBattleStruct->terrainDone
&& AbilityBattleEffects(ABILITYEFFECT_SWITCH_IN_TERRAIN, 0, 0, ABILITYEFFECT_SWITCH_IN_TERRAIN, 0) != 0)
{
gBattleStruct->terrainDone = TRUE;
return;
}
gBattleStruct->eventsBeforeFirstTurnState++;
if (TryFieldEffects(FIELD_EFFECT_OVERWORLD_TERRAIN))
return;
break;
case FIRST_TURN_EVENTS_STARTING_STATUS:
if (!gBattleStruct->startingStatusDone
&& gBattleStruct->startingStatus
&& AbilityBattleEffects(ABILITYEFFECT_SWITCH_IN_STATUSES, 0, 0, ABILITYEFFECT_SWITCH_IN_STATUSES, 0) != 0)
{
gBattleStruct->startingStatusDone = TRUE;
return;
}
gBattleStruct->eventsBeforeFirstTurnState++;
if (TryFieldEffects(FIELD_EFFECT_TRAINER_STATUSES))
return;
break;
case FIRST_TURN_EVENTS_TOTEM_BOOST:
for (i = 0; i < gBattlersCount; i++)

View File

@ -3588,7 +3588,7 @@ bool32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, enum Ability ability
return effect;
}
static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u16 *timer)
static inline bool32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u16 *timer)
{
if (!(gFieldStatuses & flag))
{
@ -3600,13 +3600,13 @@ static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u16 *t
else
*timer = 0; // Infinite
return 1;
return TRUE;
}
return 0;
return FALSE;
}
static inline u32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 anim, u16 *timer)
static inline bool32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 anim, u16 *timer)
{
if (!(gSideStatuses[side] & flag))
{
@ -3619,10 +3619,243 @@ static inline u32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 ani
else
*timer = 0; // Infinite
return 1;
return TRUE;
}
return 0;
return FALSE;
}
bool32 TryFieldEffects(enum FieldEffectCases caseId)
{
bool32 effect = FALSE;
bool32 isTerrain = FALSE;
if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
return FALSE;
switch (caseId)
{
case FIELD_EFFECT_TRAINER_STATUSES: // starting field/side/etc statuses with a variable
switch ((enum StartingStatus) gBattleStruct->startingStatus)
{
case STARTING_STATUS_NONE:
break;
case STARTING_STATUS_ELECTRIC_TERRAIN:
effect = SetStartingFieldStatus(
STATUS_FIELD_ELECTRIC_TERRAIN,
B_MSG_TERRAIN_SET_ELECTRIC,
0,
&gFieldTimers.terrainTimer);
isTerrain = TRUE;
break;
case STARTING_STATUS_MISTY_TERRAIN:
effect = SetStartingFieldStatus(
STATUS_FIELD_MISTY_TERRAIN,
B_MSG_TERRAIN_SET_MISTY,
0,
&gFieldTimers.terrainTimer);
isTerrain = TRUE;
break;
case STARTING_STATUS_GRASSY_TERRAIN:
effect = SetStartingFieldStatus(
STATUS_FIELD_GRASSY_TERRAIN,
B_MSG_TERRAIN_SET_GRASSY,
0,
&gFieldTimers.terrainTimer);
isTerrain = TRUE;
break;
case STARTING_STATUS_PSYCHIC_TERRAIN:
effect = SetStartingFieldStatus(
STATUS_FIELD_PSYCHIC_TERRAIN,
B_MSG_TERRAIN_SET_PSYCHIC,
0,
&gFieldTimers.terrainTimer);
isTerrain = TRUE;
break;
case STARTING_STATUS_TRICK_ROOM:
effect = SetStartingFieldStatus(
STATUS_FIELD_TRICK_ROOM,
B_MSG_SET_TRICK_ROOM,
B_ANIM_TRICK_ROOM,
&gFieldTimers.trickRoomTimer);
break;
case STARTING_STATUS_MAGIC_ROOM:
effect = SetStartingFieldStatus(
STATUS_FIELD_MAGIC_ROOM,
B_MSG_SET_MAGIC_ROOM,
B_ANIM_MAGIC_ROOM,
&gFieldTimers.magicRoomTimer);
break;
case STARTING_STATUS_WONDER_ROOM:
effect = SetStartingFieldStatus(
STATUS_FIELD_WONDER_ROOM,
B_MSG_SET_WONDER_ROOM,
B_ANIM_WONDER_ROOM,
&gFieldTimers.wonderRoomTimer);
break;
case STARTING_STATUS_TAILWIND_PLAYER:
effect = SetStartingSideStatus(
SIDE_STATUS_TAILWIND,
B_SIDE_PLAYER,
B_MSG_SET_TAILWIND,
B_ANIM_TAILWIND,
&gSideTimers[B_SIDE_PLAYER].tailwindTimer);
break;
case STARTING_STATUS_TAILWIND_OPPONENT:
effect = SetStartingSideStatus(
SIDE_STATUS_TAILWIND,
B_SIDE_OPPONENT,
B_MSG_SET_TAILWIND,
B_ANIM_TAILWIND,
&gSideTimers[B_SIDE_OPPONENT].tailwindTimer);
break;
case STARTING_STATUS_RAINBOW_PLAYER:
effect = SetStartingSideStatus(
SIDE_STATUS_RAINBOW,
B_SIDE_PLAYER,
B_MSG_SET_RAINBOW,
B_ANIM_RAINBOW,
&gSideTimers[B_SIDE_PLAYER].rainbowTimer);
break;
case STARTING_STATUS_RAINBOW_OPPONENT:
effect = SetStartingSideStatus(
SIDE_STATUS_RAINBOW,
B_SIDE_OPPONENT,
B_MSG_SET_RAINBOW,
B_ANIM_RAINBOW,
&gSideTimers[B_SIDE_OPPONENT].rainbowTimer);
break;
case STARTING_STATUS_SEA_OF_FIRE_PLAYER:
effect = SetStartingSideStatus(
SIDE_STATUS_SEA_OF_FIRE,
B_SIDE_PLAYER,
B_MSG_SET_SEA_OF_FIRE,
B_ANIM_SEA_OF_FIRE,
&gSideTimers[B_SIDE_PLAYER].seaOfFireTimer);
break;
case STARTING_STATUS_SEA_OF_FIRE_OPPONENT:
effect = SetStartingSideStatus(
SIDE_STATUS_SEA_OF_FIRE,
B_SIDE_OPPONENT,
B_MSG_SET_SEA_OF_FIRE,
B_ANIM_SEA_OF_FIRE,
&gSideTimers[B_SIDE_OPPONENT].seaOfFireTimer);
break;
case STARTING_STATUS_SWAMP_PLAYER:
effect = SetStartingSideStatus(
SIDE_STATUS_SWAMP,
B_SIDE_PLAYER,
B_MSG_SET_SWAMP,
B_ANIM_SWAMP,
&gSideTimers[B_SIDE_PLAYER].swampTimer);
break;
case STARTING_STATUS_SWAMP_OPPONENT:
effect = SetStartingSideStatus(
SIDE_STATUS_SWAMP,
B_SIDE_OPPONENT,
B_MSG_SET_SWAMP,
B_ANIM_SWAMP,
&gSideTimers[B_SIDE_OPPONENT].swampTimer);
break;
}
if (effect)
{
if (isTerrain)
BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain);
else
BattleScriptPushCursorAndCallback(BattleScript_OverworldStatusStarts);
}
break;
case FIELD_EFFECT_OVERWORLD_TERRAIN: // terrain starting from overworld weather
if (B_THUNDERSTORM_TERRAIN == TRUE
&& !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)
&& GetCurrentWeather() == WEATHER_RAIN_THUNDERSTORM)
{
// overworld weather started rain, so just do electric terrain anim
gFieldStatuses = STATUS_FIELD_ELECTRIC_TERRAIN;
gFieldTimers.terrainTimer = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC;
BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain);
effect = TRUE;
}
else if (B_OVERWORLD_FOG >= GEN_8
&& (GetCurrentWeather() == WEATHER_FOG_HORIZONTAL || GetCurrentWeather() == WEATHER_FOG_DIAGONAL)
&& !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN))
{
gFieldStatuses = STATUS_FIELD_MISTY_TERRAIN;
gFieldTimers.terrainTimer = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY;
BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain);
effect = TRUE;
}
break;
case FIELD_EFFECT_OVERWORLD_WEATHER:
if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED))
{
switch (GetCurrentWeather())
{
case WEATHER_RAIN:
case WEATHER_RAIN_THUNDERSTORM:
case WEATHER_DOWNPOUR:
if (!(gBattleWeather & B_WEATHER_RAIN))
{
gBattleWeather = B_WEATHER_RAIN_NORMAL;
gBattleScripting.animArg1 = B_ANIM_RAIN_CONTINUES;
effect = TRUE;
}
break;
case WEATHER_SANDSTORM:
if (!(gBattleWeather & B_WEATHER_SANDSTORM))
{
gBattleWeather = B_WEATHER_SANDSTORM;
gBattleScripting.animArg1 = B_ANIM_SANDSTORM_CONTINUES;
effect = TRUE;
}
break;
case WEATHER_DROUGHT:
if (!(gBattleWeather & B_WEATHER_SUN))
{
gBattleWeather = B_WEATHER_SUN_NORMAL;
gBattleScripting.animArg1 = B_ANIM_SUN_CONTINUES;
effect = TRUE;
}
break;
case WEATHER_SNOW:
if (!(gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)))
{
if (B_OVERWORLD_SNOW >= GEN_9)
{
gBattleWeather = B_WEATHER_SNOW;
gBattleScripting.animArg1 = B_ANIM_SNOW_CONTINUES;
}
else
{
gBattleWeather = B_WEATHER_HAIL;
gBattleScripting.animArg1 = B_ANIM_HAIL_CONTINUES;
}
effect = TRUE;
}
break;
case WEATHER_FOG_DIAGONAL:
case WEATHER_FOG_HORIZONTAL:
if (B_OVERWORLD_FOG == GEN_4 && !(gBattleWeather & B_WEATHER_FOG))
{
gBattleWeather = B_WEATHER_FOG;
gBattleScripting.animArg1 = B_ANIM_FOG_CONTINUES;
effect = TRUE;
}
break;
}
}
if (effect)
{
gBattleCommunication[MULTISTRING_CHOOSER] = GetCurrentWeather();
BattleScriptPushCursorAndCallback(BattleScript_OverworldWeatherStarts);
}
break;
}
return effect;
}
u32 AbilityBattleEffects(enum AbilityEffect caseID, u32 battler, enum Ability ability, u32 special, u32 moveArg)
@ -3655,215 +3888,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, u32 battler, enum Ability ab
switch (caseID)
{
case ABILITYEFFECT_SWITCH_IN_STATUSES: // starting field/side/etc statuses with a variable
{
gBattleScripting.battler = battler;
switch (gBattleStruct->startingStatus)
{
case STARTING_STATUS_ELECTRIC_TERRAIN:
effect = SetStartingFieldStatus(STATUS_FIELD_ELECTRIC_TERRAIN,
B_MSG_TERRAIN_SET_ELECTRIC,
0,
&gFieldTimers.terrainTimer);
effect = (effect == 1) ? 2 : 0;
break;
case STARTING_STATUS_MISTY_TERRAIN:
effect = SetStartingFieldStatus(STATUS_FIELD_MISTY_TERRAIN,
B_MSG_TERRAIN_SET_MISTY,
0,
&gFieldTimers.terrainTimer);
effect = (effect == 1) ? 2 : 0;
break;
case STARTING_STATUS_GRASSY_TERRAIN:
effect = SetStartingFieldStatus(STATUS_FIELD_GRASSY_TERRAIN,
B_MSG_TERRAIN_SET_GRASSY,
0,
&gFieldTimers.terrainTimer);
effect = (effect == 1) ? 2 : 0;
break;
case STARTING_STATUS_PSYCHIC_TERRAIN:
effect = SetStartingFieldStatus(STATUS_FIELD_PSYCHIC_TERRAIN,
B_MSG_TERRAIN_SET_PSYCHIC,
0,
&gFieldTimers.terrainTimer);
effect = (effect == 1) ? 2 : 0;
break;
case STARTING_STATUS_TRICK_ROOM:
effect = SetStartingFieldStatus(STATUS_FIELD_TRICK_ROOM,
B_MSG_SET_TRICK_ROOM,
B_ANIM_TRICK_ROOM,
&gFieldTimers.trickRoomTimer);
break;
case STARTING_STATUS_MAGIC_ROOM:
effect = SetStartingFieldStatus(STATUS_FIELD_MAGIC_ROOM,
B_MSG_SET_MAGIC_ROOM,
B_ANIM_MAGIC_ROOM,
&gFieldTimers.magicRoomTimer);
break;
case STARTING_STATUS_WONDER_ROOM:
effect = SetStartingFieldStatus(STATUS_FIELD_WONDER_ROOM,
B_MSG_SET_WONDER_ROOM,
B_ANIM_WONDER_ROOM,
&gFieldTimers.wonderRoomTimer);
break;
case STARTING_STATUS_TAILWIND_PLAYER:
effect = SetStartingSideStatus(SIDE_STATUS_TAILWIND,
B_SIDE_PLAYER,
B_MSG_SET_TAILWIND,
B_ANIM_TAILWIND,
&gSideTimers[B_SIDE_PLAYER].tailwindTimer);
break;
case STARTING_STATUS_TAILWIND_OPPONENT:
effect = SetStartingSideStatus(SIDE_STATUS_TAILWIND,
B_SIDE_OPPONENT,
B_MSG_SET_TAILWIND,
B_ANIM_TAILWIND,
&gSideTimers[B_SIDE_OPPONENT].tailwindTimer);
break;
case STARTING_STATUS_RAINBOW_PLAYER:
effect = SetStartingSideStatus(SIDE_STATUS_RAINBOW,
B_SIDE_PLAYER,
B_MSG_SET_RAINBOW,
B_ANIM_RAINBOW,
&gSideTimers[B_SIDE_PLAYER].rainbowTimer);
break;
case STARTING_STATUS_RAINBOW_OPPONENT:
effect = SetStartingSideStatus(SIDE_STATUS_RAINBOW,
B_SIDE_OPPONENT,
B_MSG_SET_RAINBOW,
B_ANIM_RAINBOW,
&gSideTimers[B_SIDE_OPPONENT].rainbowTimer);
break;
case STARTING_STATUS_SEA_OF_FIRE_PLAYER:
effect = SetStartingSideStatus(SIDE_STATUS_SEA_OF_FIRE,
B_SIDE_PLAYER,
B_MSG_SET_SEA_OF_FIRE,
B_ANIM_SEA_OF_FIRE,
&gSideTimers[B_SIDE_PLAYER].seaOfFireTimer);
break;
case STARTING_STATUS_SEA_OF_FIRE_OPPONENT:
effect = SetStartingSideStatus(SIDE_STATUS_SEA_OF_FIRE,
B_SIDE_OPPONENT,
B_MSG_SET_SEA_OF_FIRE,
B_ANIM_SEA_OF_FIRE,
&gSideTimers[B_SIDE_OPPONENT].seaOfFireTimer);
break;
case STARTING_STATUS_SWAMP_PLAYER:
effect = SetStartingSideStatus(SIDE_STATUS_SWAMP,
B_SIDE_PLAYER,
B_MSG_SET_SWAMP,
B_ANIM_SWAMP,
&gSideTimers[B_SIDE_PLAYER].swampTimer);
break;
case STARTING_STATUS_SWAMP_OPPONENT:
effect = SetStartingSideStatus(SIDE_STATUS_SWAMP,
B_SIDE_OPPONENT,
B_MSG_SET_SWAMP,
B_ANIM_SWAMP,
&gSideTimers[B_SIDE_OPPONENT].swampTimer);
break;
}
if (effect == 1)
BattleScriptPushCursorAndCallback(BattleScript_OverworldStatusStarts);
else if (effect == 2)
BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain);
}
break;
case ABILITYEFFECT_SWITCH_IN_TERRAIN: // terrain starting from overworld weather
if (B_THUNDERSTORM_TERRAIN == TRUE
&& !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)
&& GetCurrentWeather() == WEATHER_RAIN_THUNDERSTORM)
{
// overworld weather started rain, so just do electric terrain anim
gFieldStatuses = STATUS_FIELD_ELECTRIC_TERRAIN;
gFieldTimers.terrainTimer = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC;
BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain);
effect++;
}
else if (B_OVERWORLD_FOG >= GEN_8
&& (GetCurrentWeather() == WEATHER_FOG_HORIZONTAL || GetCurrentWeather() == WEATHER_FOG_DIAGONAL)
&& !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN))
{
gFieldStatuses = STATUS_FIELD_MISTY_TERRAIN;
gFieldTimers.terrainTimer = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY;
BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain);
effect++;
}
break;
case ABILITYEFFECT_SWITCH_IN_WEATHER:
gBattleScripting.battler = battler;
if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED))
{
switch (GetCurrentWeather())
{
case WEATHER_RAIN:
case WEATHER_RAIN_THUNDERSTORM:
case WEATHER_DOWNPOUR:
if (!(gBattleWeather & B_WEATHER_RAIN))
{
gBattleWeather = B_WEATHER_RAIN_NORMAL;
gBattleScripting.animArg1 = B_ANIM_RAIN_CONTINUES;
effect++;
}
break;
case WEATHER_SANDSTORM:
if (!(gBattleWeather & B_WEATHER_SANDSTORM))
{
gBattleWeather = B_WEATHER_SANDSTORM;
gBattleScripting.animArg1 = B_ANIM_SANDSTORM_CONTINUES;
effect++;
}
break;
case WEATHER_DROUGHT:
if (!(gBattleWeather & B_WEATHER_SUN))
{
gBattleWeather = B_WEATHER_SUN_NORMAL;
gBattleScripting.animArg1 = B_ANIM_SUN_CONTINUES;
effect++;
}
break;
case WEATHER_SNOW:
if (!(gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)))
{
if (B_OVERWORLD_SNOW >= GEN_9)
{
gBattleWeather = B_WEATHER_SNOW;
gBattleScripting.animArg1 = B_ANIM_SNOW_CONTINUES;
}
else
{
gBattleWeather = B_WEATHER_HAIL;
gBattleScripting.animArg1 = B_ANIM_HAIL_CONTINUES;
}
effect++;
}
break;
case WEATHER_FOG_DIAGONAL:
case WEATHER_FOG_HORIZONTAL:
if (B_OVERWORLD_FOG == GEN_4)
{
if (!(gBattleWeather & B_WEATHER_FOG))
{
gBattleWeather = B_WEATHER_FOG;
gBattleScripting.animArg1 = B_ANIM_FOG_CONTINUES;
effect++;
}
break;
}
}
}
if (effect != 0)
{
gBattleCommunication[MULTISTRING_CHOOSER] = GetCurrentWeather();
BattleScriptPushCursorAndCallback(BattleScript_OverworldWeatherStarts);
}
break;
case ABILITYEFFECT_ON_SWITCHIN:
if (gHoldEffectsInfo[HOLD_EFFECT_MIRROR_HERB].onSwitchIn)
break;
gBattleScripting.battler = battler;
switch (gLastUsedAbility)
{