diff --git a/include/config/battle.h b/include/config/battle.h index 49b0c5a073..163e4c0f08 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -179,15 +179,15 @@ // Var Settings // To use the following features in scripting, replace the 0s with the var ID you're assigning it to. -// Eg: Replace with VAR_UNUSED_0x40F7 so you can use VAR_TERRAIN for that feature. -#define VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active +// Eg: Replace with VAR_UNUSED_0x40F7 so you can use B_VAR_TERRAIN for that feature. +#define B_VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active. +#define B_VAR_TERRAIN_TIMER 0 // If this var has a value greater or equal than 1 field terrains will last that number of turns, otherwise they will last until they're overwritten. #define B_VAR_WILD_AI_FLAGS 0 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15) // Sky Battles -#define B_FLAG_SKY_BATTLE 0 // If this flag has a value, the player will be able to engage in scripted Sky Battles. -#define B_VAR_SKY_BATTLE 0 // If this var has a value, the game will remember the positions of Pokémon used in Sky Battles. - -#define B_SKY_BATTLE_STRICT_ELIGIBILITY FALSE //If TRUE, Sky Battles will use the eligibility from Pokémon XY. If FALSE, all Flying-types or Pokémon with Levitate are allowed. +#define B_FLAG_SKY_BATTLE 0 // If this flag has a value, the player will be able to engage in scripted Sky Battles. +#define B_VAR_SKY_BATTLE 0 // If this var has a value, the game will remember the positions of Pokémon used in Sky Battles. +#define B_SKY_BATTLE_STRICT_ELIGIBILITY FALSE // If TRUE, Sky Battles will use the eligibility from Pokémon XY. If FALSE, all Flying-types or Pokémon with Levitate are allowed. // Flag and Var settings #define B_RESET_FLAGS_VARS_AFTER_WHITEOUT TRUE // If TRUE, Overworld_ResetBattleFlagsAndVars will reset battle-related Flags and Vars when the player whites out. diff --git a/src/battle_util.c b/src/battle_util.c index d2d5c50925..735b286e24 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -4016,50 +4016,79 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 switch (caseID) { case ABILITYEFFECT_SWITCH_IN_TERRAIN: - gBattleScripting.battler = battler; - if (VarGet(VAR_TERRAIN) & STATUS_FIELD_TERRAIN_ANY) { - u16 terrainFlags = VarGet(VAR_TERRAIN) & STATUS_FIELD_TERRAIN_ANY; // only works for status flag (1 << 15) - gFieldStatuses = terrainFlags | STATUS_FIELD_TERRAIN_PERMANENT; // terrain is permanent - switch (VarGet(VAR_TERRAIN) & STATUS_FIELD_TERRAIN_ANY) - { - case STATUS_FIELD_ELECTRIC_TERRAIN: - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC; - break; - case STATUS_FIELD_MISTY_TERRAIN: - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY; - break; - case STATUS_FIELD_GRASSY_TERRAIN: - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_GRASSY; - break; - case STATUS_FIELD_PSYCHIC_TERRAIN: - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC; - break; - } + u8 varTerrainTimer = VarGet(B_VAR_TERRAIN_TIMER); - BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); - effect++; + gBattleScripting.battler = battler; + if (VarGet(B_VAR_TERRAIN) & STATUS_FIELD_TERRAIN_ANY) + { + u16 terrainFlags = VarGet(B_VAR_TERRAIN) & STATUS_FIELD_TERRAIN_ANY; // only works for status flag (1 << 15) + + if (varTerrainTimer == 0) + { + gFieldStatuses = terrainFlags | STATUS_FIELD_TERRAIN_PERMANENT; // terrain is permanent + } + else + { + gFieldStatuses |= terrainFlags; + gFieldTimers.terrainTimer = varTerrainTimer; + } + + switch (VarGet(B_VAR_TERRAIN) & STATUS_FIELD_TERRAIN_ANY) + { + case STATUS_FIELD_ELECTRIC_TERRAIN: + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC; + break; + case STATUS_FIELD_MISTY_TERRAIN: + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY; + break; + case STATUS_FIELD_GRASSY_TERRAIN: + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_GRASSY; + break; + case STATUS_FIELD_PSYCHIC_TERRAIN: + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC; + break; + } + BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); + effect++; + } + else if (B_THUNDERSTORM_TERRAIN == TRUE + && GetCurrentWeather() == WEATHER_RAIN_THUNDERSTORM + && !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)) + { + // overworld weather started rain, so just do electric terrain anim + if (varTerrainTimer == 0) + { + gFieldStatuses = (STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); + } + else + { + gFieldStatuses |= STATUS_FIELD_ELECTRIC_TERRAIN; + gFieldTimers.terrainTimer = varTerrainTimer; + } + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC; + BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); + effect++; + } + else if (B_FOG_TERRAIN == TRUE + && (GetCurrentWeather() == WEATHER_FOG_HORIZONTAL || GetCurrentWeather() == WEATHER_FOG_DIAGONAL) + && !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)) + { + if (varTerrainTimer == 0) + { + gFieldStatuses = (STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); + } + else + { + gFieldStatuses |= STATUS_FIELD_ELECTRIC_TERRAIN; + gFieldTimers.terrainTimer = varTerrainTimer; + } + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY; + BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); + effect++; + } } - else if (B_THUNDERSTORM_TERRAIN == TRUE - && GetCurrentWeather() == WEATHER_RAIN_THUNDERSTORM - && !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)) - { - // overworld weather started rain, so just do electric terrain anim - gFieldStatuses = (STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC; - BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); - effect++; - } - else if (B_FOG_TERRAIN == TRUE - && (GetCurrentWeather() == WEATHER_FOG_HORIZONTAL || GetCurrentWeather() == WEATHER_FOG_DIAGONAL) - && !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)) - { - gFieldStatuses = (STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY; - BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); - effect++; - } - break; + break; case ABILITYEFFECT_SWITCH_IN_WEATHER: gBattleScripting.battler = battler; if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED)) diff --git a/src/overworld.c b/src/overworld.c index e18ae583c4..e4161a32f6 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -399,10 +399,14 @@ void Overworld_ResetStateAfterDigEscRope(void) } #if B_RESET_FLAGS_VARS_AFTER_WHITEOUT == TRUE - void Overworld_ResetBattleFlagsAndVars(void) +void Overworld_ResetBattleFlagsAndVars(void) { - #if VAR_TERRAIN != 0 - VarSet(VAR_TERRAIN, 0); + #if B_VAR_TERRAIN != 0 + VarSet(B_VAR_TERRAIN, 0); + #endif + + #if B_VAR_TERRAIN_TIMER != 0 + VarSet(B_VAR_TERRAIN_TIMER, 0); #endif #if B_VAR_WILD_AI_FLAGS != 0