diff --git a/include/battle.h b/include/battle.h index 474de3098..22080e338 100644 --- a/include/battle.h +++ b/include/battle.h @@ -248,6 +248,19 @@ struct SideTimer /*0x0B*/ u8 fieldB; }; +struct FieldTimer +{ + u8 mudSportTimer; + u8 waterSportTimer; + u8 wonderRoomTimer; + u8 magicRoomTimer; + u8 trickRoomTimer; + u8 grassyTerrainTimer; + u8 mistyTerrainTimer; + u8 electricTerrainTimer; + u8 psychicTerrainTimer; +}; + struct WishFutureKnock { u8 futureSightCounter[MAX_BATTLERS_COUNT]; @@ -800,6 +813,8 @@ extern struct BattleHealthboxInfo *gUnknown_020244DC; extern u16 gBattleMovePower; extern u16 gMoveToLearn; extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; +extern u32 gFieldStatuses; +extern struct FieldTimer gFieldTimers; extern void (*gPreBattleCallback1)(void); extern void (*gBattleMainFunc)(void); diff --git a/include/battle_util.h b/include/battle_util.h index 0531966df..df44b6fac 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -22,7 +22,6 @@ #define ABILITYEFFECT_TRACE 0xB #define ABILITYEFFECT_CHECK_OTHER_SIDE 0xC #define ABILITYEFFECT_CHECK_BATTLER_SIDE 0xD -#define ABILITYEFFECT_FIELD_SPORT 0xE #define ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER 0xF #define ABILITYEFFECT_COUNT_OTHER_SIDE 0x10 #define ABILITYEFFECT_COUNT_BATTLER_SIDE 0x11 @@ -32,12 +31,10 @@ #define ABILITY_ON_OPPOSING_FIELD(battlerId, abilityId)(AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, battlerId, abilityId, 0, 0)) #define ABILITY_ON_FIELD(abilityId)(AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, abilityId, 0, 0)) -#define ABILITY_ON_FIELD2(abilityId)(AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, abilityId, 0, 0)) #define ITEMEFFECT_ON_SWITCH_IN 0x0 #define WEATHER_HAS_EFFECT ((!ABILITY_ON_FIELD(ABILITY_CLOUD_NINE) && !ABILITY_ON_FIELD(ABILITY_AIR_LOCK))) -#define WEATHER_HAS_EFFECT2 ((!ABILITY_ON_FIELD2(ABILITY_CLOUD_NINE) && !ABILITY_ON_FIELD2(ABILITY_AIR_LOCK))) u8 GetBattlerForBattleScript(u8 caseId); void PressurePPLose(u8 bankDef, u8 bankAtk, u16 move); diff --git a/include/constants/battle.h b/include/constants/battle.h index 6aad8e486..baad2712a 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -143,8 +143,8 @@ #define STATUS3_IMPRISONED_OTHERS 0x2000 #define STATUS3_GRUDGE 0x4000 #define STATUS3_CANT_SCORE_A_CRIT 0x8000 -#define STATUS3_MUDSPORT 0x10000 -#define STATUS3_WATERSPORT 0x20000 +// #define STATUS3_MUDSPORT 0x10000 +// #define STATUS3_WATERSPORT 0x20000 #define STATUS3_UNDERWATER 0x40000 #define STATUS3_INTIMIDATE_POKES 0x80000 #define STATUS3_TRACE 0x100000 @@ -188,6 +188,18 @@ #define SIDE_STATUS_MIST (1 << 8) #define SIDE_STATUS_SPIKES_DAMAGED (1 << 9) +// Field affecting statuses. +#define STATUS_FIELD_MAGIC_ROOM 0x1 +#define STATUS_FIELD_TRICK_ROOM 0x2 +#define STATUS_FIELD_WONDER_ROOM 0x4 +#define STATUS_FIELD_MUDSPORT 0x8 +#define STATUS_FIELD_WATERSPORT 0x10 +#define STATUS_FIELD_GRAVITY 0x20 +#define STATUS_FIELD_GRASSY_TERRAIN 0x40 +#define STATUS_FIELD_MISTY_TERRAIN 0x80 +#define STATUS_FIELD_ELECTRIC_TERRAIN 0x100 +#define STATUS_FIELD_PSYCHIC_TERRAIN 0x200 + // Flags describing move's result #define MOVE_RESULT_MISSED (1 << 0) #define MOVE_RESULT_SUPER_EFFECTIVE (1 << 1) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index a105e7edf..4e2e13635 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -438,7 +438,7 @@ static bool8 ShouldSwitch(void) return FALSE; if (ABILITY_ON_OPPOSING_FIELD(gActiveBattler, ABILITY_ARENA_TRAP)) // Misses the flying type and Levitate check. return FALSE; - if (ABILITY_ON_FIELD2(ABILITY_MAGNET_PULL)) + if (ABILITY_ON_FIELD(ABILITY_MAGNET_PULL)) { if (gBattleMons[gActiveBattler].type1 == TYPE_STEEL) return FALSE; diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 052c5f610..418f875b9 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -1063,7 +1063,7 @@ void BtlController_EmitMoveAnimation(u8 bufferId, u16 move, u8 turnOfMove, u16 m sBattleBuffersTransferData[9] = (dmg & 0xFF000000) >> 24; sBattleBuffersTransferData[10] = friendship; sBattleBuffersTransferData[11] = multihit; - if (WEATHER_HAS_EFFECT2) + if (WEATHER_HAS_EFFECT) { sBattleBuffersTransferData[12] = gBattleWeather; sBattleBuffersTransferData[13] = (gBattleWeather & 0xFF00) >> 8; diff --git a/src/battle_main.c b/src/battle_main.c index cbfaba2d7..a7d870e72 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -288,6 +288,8 @@ EWRAM_DATA struct BattleHealthboxInfo *gUnknown_020244DC = NULL; EWRAM_DATA u16 gBattleMovePower = 0; EWRAM_DATA u16 gMoveToLearn = 0; EWRAM_DATA u8 gBattleMonForms[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u32 gFieldStatuses = 0; +EWRAM_DATA struct FieldTimer gFieldTimers = {0}; // IWRAM common vars void (*gPreBattleCallback1)(void); @@ -3116,7 +3118,7 @@ void SwitchInClearSetData(void) if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS) { gBattleMons[gActiveBattler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED); - gStatuses3[gActiveBattler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED | STATUS3_MUDSPORT | STATUS3_WATERSPORT); + gStatuses3[gActiveBattler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED); for (i = 0; i < gBattlersCount; i++) { diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 6e1c93e74..6ddfa9846 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9941,18 +9941,20 @@ static void atkE8_settypebasedhalvers(void) // water and mud sport if (gBattleMoves[gCurrentMove].effect == EFFECT_MUD_SPORT) { - if (!(gStatuses3[gBattlerAttacker] & STATUS3_MUDSPORT)) + if (!(gFieldStatuses & STATUS_FIELD_MUDSPORT)) { - gStatuses3[gBattlerAttacker] |= STATUS3_MUDSPORT; + gFieldStatuses |= STATUS_FIELD_MUDSPORT; + gFieldTimers.mudSportTimer = 5; gBattleCommunication[MULTISTRING_CHOOSER] = 0; worked = TRUE; } } else // water sport { - if (!(gStatuses3[gBattlerAttacker] & STATUS3_WATERSPORT)) + if (!(gFieldStatuses & STATUS_FIELD_WATERSPORT)) { - gStatuses3[gBattlerAttacker] |= STATUS3_WATERSPORT; + gFieldStatuses |= STATUS_FIELD_WATERSPORT; + gFieldTimers.waterSportTimer = 5; gBattleCommunication[MULTISTRING_CHOOSER] = 1; worked = TRUE; } diff --git a/src/battle_util.c b/src/battle_util.c index 6e3fc3e7f..df5fb9232 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2390,35 +2390,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA } } break; - case ABILITYEFFECT_FIELD_SPORT: // 14 - switch (gLastUsedAbility) - { - case 0xFD: - for (i = 0; i < gBattlersCount; i++) - { - if (gStatuses3[i] & STATUS3_MUDSPORT) - effect = i + 1; - } - break; - case 0xFE: - for (i = 0; i < gBattlersCount; i++) - { - if (gStatuses3[i] & STATUS3_WATERSPORT) - effect = i + 1; - } - break; - default: - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].ability == ability) - { - gLastUsedAbility = ability; - effect = i + 1; - } - } - break; - } - break; case ABILITYEFFECT_CHECK_ON_FIELD: // 19 for (i = 0; i < gBattlersCount; i++) { diff --git a/src/pokemon.c b/src/pokemon.c index 5406cfee9..113a4b2aa 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -2293,17 +2293,17 @@ s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *de spAttack /= 2; if (attacker->ability == ABILITY_HUSTLE) attack = (150 * attack) / 100; - if (attacker->ability == ABILITY_PLUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MINUS, 0, 0)) + if (attacker->ability == ABILITY_PLUS && ABILITY_ON_FIELD(ABILITY_MINUS)) spAttack = (150 * spAttack) / 100; - if (attacker->ability == ABILITY_MINUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_PLUS, 0, 0)) + if (attacker->ability == ABILITY_MINUS && ABILITY_ON_FIELD(ABILITY_PLUS)) spAttack = (150 * spAttack) / 100; if (attacker->ability == ABILITY_GUTS && attacker->status1) attack = (150 * attack) / 100; if (defender->ability == ABILITY_MARVEL_SCALE && defender->status1) defense = (150 * defense) / 100; - if (type == TYPE_ELECTRIC && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFD, 0)) + if (type == TYPE_ELECTRIC && gFieldStatuses & STATUS_FIELD_MUDSPORT) gBattleMovePower /= 2; - if (type == TYPE_FIRE && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFE, 0)) + if (type == TYPE_FIRE && gFieldStatuses & STATUS_FIELD_WATERSPORT) gBattleMovePower /= 2; if (type == TYPE_GRASS && attacker->ability == ABILITY_OVERGROW && attacker->hp <= (attacker->maxHP / 3)) gBattleMovePower = (150 * gBattleMovePower) / 100; @@ -2405,9 +2405,8 @@ s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *de if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(2) == 2) damage /= 2; - // are effects of weather negated with cloud nine or air lock - if (!AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_CLOUD_NINE, 0, 0) - && !AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_AIR_LOCK, 0, 0)) + // Are effects of weather negated with cloud nine or air lock? + if (WEATHER_HAS_EFFECT) { if (gBattleWeather & WEATHER_RAIN_TEMPORARY) {