diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index becdadac1a..d5d81cf709 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -1032,6 +1032,7 @@ gBattleAnims_General:: .4byte General_WonderRoom @ B_ANIM_WONDER_ROOM .4byte General_MagicRoom @ B_ANIM_MAGIC_ROOM .4byte General_Tailwind @ B_ANIM_TAILLWIND + .4byte General_Fog @ B_ANIM_FOG_CONTINUES .align 2 gBattleAnims_Special:: @@ -17424,7 +17425,7 @@ Move_LAST_RESPECTS:: restorebg waitbgfadein end - + Move_TIDY_UP:: loadspritegfx ANIM_TAG_PINK_CLOUD monbg ANIM_ATTACKER @@ -17445,7 +17446,7 @@ Move_TIDY_UP:: clearmonbg ANIM_ATTACKER blendoff end - + Move_KOWTOW_CLEAVE:: loadspritegfx ANIM_TAG_SLASH loadspritegfx ANIM_TAG_CROSS_IMPACT @@ -17739,7 +17740,7 @@ Move_HYDRO_STEAM:: createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 3, 9, 0, RGB_RED waitforvisualfinish end - + Move_POUNCE:: loadspritegfx ANIM_TAG_IMPACT monbg ANIM_TARGET @@ -27351,6 +27352,7 @@ Move_WEATHER_BALL: jumpreteq ANIM_WEATHER_SANDSTORM, WeatherBallSandstorm jumpreteq ANIM_WEATHER_HAIL, WeatherBallIce jumpreteq ANIM_WEATHER_SNOW, WeatherBallIce + jumpreteq ANIM_WEATHER_FOG, WeatherBallNormal WeatherBallNormal: loadspritegfx ANIM_TAG_IMPACT createsprite gWeatherBallNormalDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, 0, 0 @@ -28097,6 +28099,9 @@ General_Hail: General_Snow: goto Move_SNOWSCAPE +General_Fog: + goto Move_HAZE + General_LeechSeedDrain: createvisualtask AnimTask_GetBattlersFromArg, 5 delay 0 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 0b606d3516..e66f4c2a8e 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5951,6 +5951,23 @@ BattleScript_SunlightFaded:: call BattleScript_ActivateWeatherAbilities end2 +BattleScript_FogContinues:: + printstring STRINGID_FOGISDEEP + waitmessage B_WAIT_TIME_LONG + playanimation BS_ATTACKER, B_ANIM_FOG_CONTINUES + call BattleScript_ActivateWeatherAbilities + end2 + +BattleScript_FogEnded_Ret:: + printstring STRINGID_FOGLIFTED + waitmessage B_WAIT_TIME_LONG + call BattleScript_ActivateWeatherAbilities + return + +BattleScript_FogEnded:: + call BattleScript_FogEnded_Ret + end2 + BattleScript_OverworldStatusStarts:: printfromtable gStartingStatusStringIds waitmessage B_WAIT_TIME_LONG diff --git a/include/battle_scripts.h b/include/battle_scripts.h index b09ccc2190..1a7654d37b 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -54,6 +54,9 @@ extern const u8 BattleScript_DamagingWeatherContinues[]; extern const u8 BattleScript_SandStormHailSnowEnds[]; extern const u8 BattleScript_SunlightContinues[]; extern const u8 BattleScript_SunlightFaded[]; +extern const u8 BattleScript_FogContinues[]; +extern const u8 BattleScript_FogEnded_Ret[]; +extern const u8 BattleScript_FogEnded[]; extern const u8 BattleScript_OverworldStatusStarts[]; extern const u8 BattleScript_OverworldWeatherStarts[]; extern const u8 BattleScript_OverworldTerrain[]; diff --git a/include/config/battle.h b/include/config/battle.h index ec9966cbee..796516a993 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -198,7 +198,6 @@ // Terrain settings #define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades. #define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8. -#define B_FOG_TERRAIN TRUE // If TRUE, overworld Fog generates Misty Terrain as in Gen 8. #define B_TERRAIN_TYPE_BOOST GEN_LATEST // In Gen8, damage is boosted by 30% instead of 50%. #define B_SECRET_POWER_EFFECT GEN_LATEST // Secret Power's effects change depending on terrain and generation. See MOVE_EFFECT_SECRET_POWER's case in `SetMoveEffect`. #define B_SECRET_POWER_ANIMATION GEN_LATEST // Secret Power's animations change depending on terrain and generation. @@ -236,7 +235,8 @@ #define B_TRAINER_MON_RANDOM_ABILITY FALSE // If this is set to TRUE a random legal ability will be generated for a trainer mon #define B_OBEDIENCE_MECHANICS GEN_LATEST // In PLA+ (here Gen8+), obedience restrictions also apply to non-outsider Pokémon, albeit based on their level met rather than actual level #define B_USE_FROSTBITE FALSE // In PLA, Frostbite replaces Freeze. Enabling this flag does the same here. Moves can still be cherry-picked to either Freeze or Frostbite. Freeze-Dry, Secret Power & Tri Attack depend on this config. -#define B_OVERWORLD_SNOW GEN_LATEST // In Gen9+, overworld Snow will summon snow instead of hail. +#define B_OVERWORLD_SNOW GEN_LATEST // In Gen9+, overworld Snow will summon snow instead of hail in battle. +#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. diff --git a/include/constants/battle.h b/include/constants/battle.h index 17606586af..0acb857ad0 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -304,6 +304,9 @@ #define B_WEATHER_SNOW_TEMPORARY (1 << 12) #define B_WEATHER_SNOW_PERMANENT (1 << 13) #define B_WEATHER_SNOW (B_WEATHER_SNOW_TEMPORARY | B_WEATHER_SNOW_PERMANENT) +#define B_WEATHER_FOG_TEMPORARY (1 << 14) +#define B_WEATHER_FOG_PERMANENT (1 << 15) +#define B_WEATHER_FOG (B_WEATHER_FOG_TEMPORARY | B_WEATHER_FOG_PERMANENT) // Battle Weather as enum #define ENUM_WEATHER_NONE 0 @@ -315,6 +318,7 @@ #define ENUM_WEATHER_RAIN_PRIMAL 6 #define ENUM_WEATHER_STRONG_WINDS 7 #define ENUM_WEATHER_SNOW 8 +#define ENUM_WEATHER_FOG 9 // Move Effects #define MOVE_EFFECT_SLEEP 1 diff --git a/include/constants/battle_anim.h b/include/constants/battle_anim.h index 8bc09ba530..162eb11c99 100644 --- a/include/constants/battle_anim.h +++ b/include/constants/battle_anim.h @@ -567,6 +567,7 @@ #define B_ANIM_WONDER_ROOM 46 #define B_ANIM_MAGIC_ROOM 47 #define B_ANIM_TAILWIND 48 +#define B_ANIM_FOG_CONTINUES 49 // special animations table (gBattleAnims_Special) #define B_ANIM_LVL_UP 0 @@ -615,6 +616,7 @@ #define ANIM_WEATHER_SANDSTORM 3 #define ANIM_WEATHER_HAIL 4 #define ANIM_WEATHER_SNOW 5 +#define ANIM_WEATHER_FOG 6 // horseshoe/fist frames #define ANIM_RIGHT_FIST 0 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index edab0e659d..86b48f9d4a 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -708,8 +708,11 @@ #define STRINGID_BIZARREAREACREATED 706 #define STRINGID_TIDYINGUPCOMPLETE 707 #define STRINGID_BOOSTERENERGYACTIVATES 708 +#define STRINGID_FOGCREPTUP 709 +#define STRINGID_FOGISDEEP 710 +#define STRINGID_FOGLIFTED 711 -#define BATTLESTRINGS_COUNT 709 +#define BATTLESTRINGS_COUNT 712 // This is the string id that gBattleStringsTable starts with. // String ids before this (e.g. STRINGID_INTROMSG) are not in the table, @@ -761,6 +764,7 @@ #define B_MSG_STARTED_SUNLIGHT 4 #define B_MSG_STARTED_HAIL 5 #define B_MSG_STARTED_SNOW 6 +#define B_MSG_STARTED_FOG 7 // gRainContinuesStringIds #define B_MSG_RAIN_CONTINUES 0 diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index e904bb0c16..4c162348c7 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -1838,7 +1838,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_MORNING_SUN: case EFFECT_SYNTHESIS: case EFFECT_MOONLIGHT: - if ((AI_GetWeather(aiData) & (B_WEATHER_RAIN | B_WEATHER_SANDSTORM | B_WEATHER_HAIL))) + if ((AI_GetWeather(aiData) & (B_WEATHER_RAIN | B_WEATHER_SANDSTORM | B_WEATHER_HAIL | B_WEATHER_SNOW | B_WEATHER_FOG))) ADJUST_SCORE(-3); else if (AtMaxHp(battlerAtk)) ADJUST_SCORE(-10); diff --git a/src/battle_anim_effects_3.c b/src/battle_anim_effects_3.c index ffba3429eb..5dd91b7f49 100644 --- a/src/battle_anim_effects_3.c +++ b/src/battle_anim_effects_3.c @@ -5580,6 +5580,8 @@ void AnimTask_GetWeather(u8 taskId) gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_HAIL; else if (gWeatherMoveAnim & B_WEATHER_SNOW) gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SNOW; + else if (gWeatherMoveAnim & B_WEATHER_FOG) + gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_FOG; DestroyAnimVisualTask(taskId); } diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 31e4dcae2f..09b85e7768 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -513,6 +513,7 @@ static bool8 ShouldAnimBeDoneRegardlessOfSubstitute(u8 animId) case B_ANIM_SANDSTORM_CONTINUES: case B_ANIM_HAIL_CONTINUES: case B_ANIM_SNOW_CONTINUES: + case B_ANIM_FOG_CONTINUES: case B_ANIM_SNATCH_MOVE: return TRUE; default: diff --git a/src/battle_main.c b/src/battle_main.c index aa2245022a..8100c59fc9 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5968,7 +5968,7 @@ void SetTypeBeforeUsingMove(u32 move, u32 battlerAtk) gBattleStruct->dynamicMoveType = TYPE_ROCK | F_DYNAMIC_TYPE_SET; else if (gBattleWeather & B_WEATHER_SUN && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA) gBattleStruct->dynamicMoveType = TYPE_FIRE | F_DYNAMIC_TYPE_SET; - else if (gBattleWeather & (B_WEATHER_HAIL |B_WEATHER_SNOW)) + else if (gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) gBattleStruct->dynamicMoveType = TYPE_ICE | F_DYNAMIC_TYPE_SET; else gBattleStruct->dynamicMoveType = TYPE_NORMAL | F_DYNAMIC_TYPE_SET; diff --git a/src/battle_message.c b/src/battle_message.c index dc6dd20639..2efb99ff5f 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -370,6 +370,9 @@ static const u8 sText_HailStopped[] = _("The hail stopped."); static const u8 sText_StartedSnow[] = _("It started to snow!"); static const u8 sText_SnowContinues[] = _("Snow continues to fall."); static const u8 sText_SnowStopped[] = _("The snow stopped."); +static const u8 sText_FogCreptUp[] = _("Fog crept up as thick as soup!"); +static const u8 sText_FogIsDeep[] = _("The fog is deep…"); +static const u8 sText_FogLifted[] = _("The fog lifted."); static const u8 sText_FailedToSpitUp[] = _("But it failed to spit up\na thing!"); static const u8 sText_FailedToSwallow[] = _("But it failed to swallow\na thing!"); static const u8 sText_WindBecameHeatWave[] = _("The wind turned into a\nHEAT WAVE!"); @@ -1230,6 +1233,9 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_STARTEDSNOW - BATTLESTRINGS_TABLE_START] = sText_StartedSnow, [STRINGID_SNOWCONTINUES -BATTLESTRINGS_TABLE_START] = sText_SnowContinues, [STRINGID_SNOWSTOPPED - BATTLESTRINGS_TABLE_START] = sText_SnowStopped, + [STRINGID_FOGCREPTUP - BATTLESTRINGS_TABLE_START] = sText_FogCreptUp, + [STRINGID_FOGISDEEP - BATTLESTRINGS_TABLE_START] = sText_FogIsDeep, + [STRINGID_FOGLIFTED - BATTLESTRINGS_TABLE_START] = sText_FogLifted, [STRINGID_FAILEDTOSPITUP - BATTLESTRINGS_TABLE_START] = sText_FailedToSpitUp, [STRINGID_FAILEDTOSWALLOW - BATTLESTRINGS_TABLE_START] = sText_FailedToSwallow, [STRINGID_WINDBECAMEHEATWAVE - BATTLESTRINGS_TABLE_START] = sText_WindBecameHeatWave, @@ -1673,6 +1679,7 @@ const u16 gMoveWeatherChangeStringIds[] = [B_MSG_STARTED_SUNLIGHT] = STRINGID_SUNLIGHTGOTBRIGHT, [B_MSG_STARTED_HAIL] = STRINGID_STARTEDHAIL, [B_MSG_STARTED_SNOW] = STRINGID_STARTEDSNOW, + [B_MSG_STARTED_FOG] = STRINGID_FOGCREPTUP, // Unused, can use for custom moves that set fog }; const u16 gSandStormHailSnowContinuesStringIds[] = @@ -1925,10 +1932,10 @@ const u16 gWeatherStartsStringIds[] = [WEATHER_RAIN] = STRINGID_ITISRAINING, [WEATHER_SNOW] = (B_OVERWORLD_SNOW >= GEN_9 ? STRINGID_STARTEDSNOW : STRINGID_STARTEDHAIL), [WEATHER_RAIN_THUNDERSTORM] = STRINGID_ITISRAINING, - [WEATHER_FOG_HORIZONTAL] = STRINGID_ITISRAINING, + [WEATHER_FOG_HORIZONTAL] = STRINGID_FOGISDEEP, [WEATHER_VOLCANIC_ASH] = STRINGID_ITISRAINING, [WEATHER_SANDSTORM] = STRINGID_SANDSTORMISRAGING, - [WEATHER_FOG_DIAGONAL] = STRINGID_ITISRAINING, + [WEATHER_FOG_DIAGONAL] = STRINGID_FOGISDEEP, [WEATHER_UNDERWATER] = STRINGID_ITISRAINING, [WEATHER_SHADE] = STRINGID_ITISRAINING, [WEATHER_DROUGHT] = STRINGID_SUNLIGHTSTRONG, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index f74322611b..e3f6615832 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1704,6 +1704,9 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u if (B_AFFECTION_MECHANICS == TRUE && GetBattlerAffectionHearts(battlerDef) == AFFECTION_FIVE_HEARTS) calc = (calc * 90) / 100; + if (WEATHER_HAS_EFFECT && gBattleWeather & B_WEATHER_FOG) + calc = (calc * 60) / 100; // modified by 3/5 + return calc; } @@ -5104,7 +5107,8 @@ static void PlayAnimation(u32 battler, u8 animId, const u16 *argPtr, const u8 *n || animId == B_ANIM_SUN_CONTINUES || animId == B_ANIM_SANDSTORM_CONTINUES || animId == B_ANIM_HAIL_CONTINUES - || animId == B_ANIM_SNOW_CONTINUES) + || animId == B_ANIM_SNOW_CONTINUES + || animId == B_ANIM_FOG_CONTINUES) { BtlController_EmitBattleAnimation(battler, BUFFER_A, animId, &gDisableStructs[battler], *argPtr); MarkBattlerForControllerExec(battler); @@ -8435,6 +8439,13 @@ static bool32 TryDefogClear(u32 battlerAtk, bool32 clear) DEFOG_CLEAR(SIDE_STATUS_TOXIC_SPIKES, toxicSpikesAmount, BattleScript_ToxicSpikesDefog, 0); DEFOG_CLEAR(SIDE_STATUS_STICKY_WEB, stickyWebAmount, BattleScript_StickyWebDefog, 0); DEFOG_CLEAR(SIDE_STATUS_STEELSURGE, steelsurgeAmount, BattleScript_SteelsurgeDefog, 0); + if (gBattleWeather & B_WEATHER_FOG) + { + gBattleWeather &= ~B_WEATHER_FOG; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_FogEnded_Ret; + return TRUE; + } if (B_DEFOG_CLEARS_TERRAIN >= GEN_8 && (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY)) { RemoveAllTerrains(); diff --git a/src/battle_util.c b/src/battle_util.c index 36f0379a1c..55df4761de 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1674,6 +1674,7 @@ enum ENDTURN_SUN, ENDTURN_HAIL, ENDTURN_SNOW, + ENDTURN_FOG, ENDTURN_DAMAGE_NON_TYPES, ENDTURN_GRAVITY, ENDTURN_WATER_SPORT, @@ -2059,6 +2060,24 @@ u8 DoFieldEndTurnEffects(void) } gBattleStruct->turnCountersTracker++; break; + case ENDTURN_FOG: + if (gBattleWeather & B_WEATHER_FOG) + { + if (!(gBattleWeather & B_WEATHER_FOG_PERMANENT) && --gWishFutureKnock.weatherDuration == 0) + { + gBattleWeather &= ~B_WEATHER_FOG_TEMPORARY; + gBattlescriptCurrInstr = BattleScript_FogEnded; + } + else + { + gBattlescriptCurrInstr = BattleScript_FogContinues; + } + + BattleScriptExecute(gBattlescriptCurrInstr); + effect++; + } + gBattleStruct->turnCountersTracker++; + break; case ENDTURN_DAMAGE_NON_TYPES: while (gBattleStruct->turnSideTracker < 2) { @@ -3813,6 +3832,7 @@ static const u16 sWeatherFlagsInfo[][3] = [ENUM_WEATHER_HAIL] = {B_WEATHER_HAIL_TEMPORARY, B_WEATHER_HAIL_PERMANENT, HOLD_EFFECT_ICY_ROCK}, [ENUM_WEATHER_STRONG_WINDS] = {B_WEATHER_STRONG_WINDS, B_WEATHER_STRONG_WINDS, HOLD_EFFECT_NONE}, [ENUM_WEATHER_SNOW] = {B_WEATHER_SNOW_TEMPORARY, B_WEATHER_SNOW_PERMANENT, HOLD_EFFECT_ICY_ROCK}, + [ENUM_WEATHER_FOG] = {B_WEATHER_FOG_TEMPORARY, B_WEATHER_FOG_PERMANENT, HOLD_EFFECT_NONE}, }; static void ShouldChangeFormInWeather(u32 battler) @@ -4153,7 +4173,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); effect++; } - else if (B_FOG_TERRAIN == TRUE + else if (B_OVERWORLD_FOG >= GEN_8 && (GetCurrentWeather() == WEATHER_FOG_HORIZONTAL || GetCurrentWeather() == WEATHER_FOG_DIAGONAL) && !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)) { @@ -4211,6 +4231,18 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 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) @@ -8842,7 +8874,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32 modifier = uq4_12_multiply(modifier, UQ_4_12(2.0)); break; case EFFECT_SOLAR_BEAM: - if (IsBattlerWeatherAffected(battlerAtk, (B_WEATHER_HAIL | B_WEATHER_SANDSTORM | B_WEATHER_RAIN | B_WEATHER_SNOW))) + if (IsBattlerWeatherAffected(battlerAtk, (B_WEATHER_HAIL | B_WEATHER_SANDSTORM | B_WEATHER_RAIN | B_WEATHER_SNOW | B_WEATHER_FOG))) modifier = uq4_12_multiply(modifier, UQ_4_12(0.5)); break; case EFFECT_STOMPING_TANTRUM: