diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index c2a10b175c..9dd0479c92 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -416,8 +416,11 @@ .4byte \argPtr .endm - .macro unused_0x47 + .macro jumpfifsemiinvulnerable battler:req, state:req, jumpInstr:req .byte 0x47 + .byte \battler + .byte \state + .4byte \jumpInstr .endm .macro unused_0x48 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index e6bf8e1db8..aa4cfac123 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -2613,7 +2613,8 @@ BattleScript_EffectGravitySuccess:: selectfirstvalidtarget BattleScript_GravityLoop: movevaluescleanup - jumpifstatus3 BS_TARGET, STATUS3_ON_AIR | STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS, BattleScript_GravityLoopDrop + jumpfifsemiinvulnerable BS_TARGET, STATE_ON_AIR, BattleScript_GravityLoopDrop + jumpifstatus3 BS_TARGET, STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS, BattleScript_GravityLoopDrop goto BattleScript_GravityLoopEnd BattleScript_GravityLoopDrop: gravityonairbornemons @@ -6982,7 +6983,7 @@ BattleScript_YawnMakesAsleep:: waitmessage B_WAIT_TIME_LONG updatestatusicon BS_EFFECT_BATTLER waitstate - jumpifstatus3 BS_EFFECT_BATTLER, STATUS3_SKY_DROPPED, BattleScript_YawnEnd + jumpfifsemiinvulnerable BS_EFFECT_BATTLER, STATE_SKY_DROP, BattleScript_YawnEnd makevisible BS_EFFECT_BATTLER skydropyawn BattleScript_YawnEnd: diff --git a/include/battle.h b/include/battle.h index de25626c6b..78eed713f9 100644 --- a/include/battle.h +++ b/include/battle.h @@ -1074,7 +1074,6 @@ extern u8 gBideTarget[MAX_BATTLERS_COUNT]; extern u32 gSideStatuses[NUM_BATTLE_SIDES]; extern struct SideTimer gSideTimers[NUM_BATTLE_SIDES]; extern u32 gStatuses3[MAX_BATTLERS_COUNT]; -extern u32 gStatuses4[MAX_BATTLERS_COUNT]; extern struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT]; extern u16 gPauseCounterBattle; extern u16 gPaydayMoney; diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index f5af4acb33..e0f1a4de0c 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -184,7 +184,6 @@ bool32 HasAnyKnownMove(u32 battlerId); bool32 IsAromaVeilProtectedEffect(enum BattleMoveEffects moveEffect); bool32 IsNonVolatileStatusMove(u32 moveEffect); bool32 IsMoveRedirectionPrevented(u32 battlerAtk, u32 move, u32 atkAbility); -bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move); bool32 IsHazardMove(u32 move); bool32 IsTwoTurnNotSemiInvulnerableMove(u32 battlerAtk, u32 move); bool32 IsBattlerDamagedByStatus(u32 battler); @@ -208,7 +207,6 @@ bool32 IsSwitchOutEffect(enum BattleMoveEffects effect); bool32 IsChaseEffect(enum BattleMoveEffects effect); bool32 IsAttackBoostMoveEffect(enum BattleMoveEffects effect); bool32 IsUngroundingEffect(enum BattleMoveEffects effect); -bool32 IsSemiInvulnerable(u32 battlerDef, u32 move); bool32 HasMoveWithFlag(u32 battler, MoveFlag getFlag); bool32 IsHazardClearingMove(u32 move); bool32 IsSubstituteEffect(enum BattleMoveEffects effect); diff --git a/include/battle_util.h b/include/battle_util.h index 95efdd9922..8f38e0f572 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -406,5 +406,7 @@ bool32 IsHazardOnSideAndClear(u32 side, enum Hazards hazardType); void RemoveHazardFromField(u32 side, enum Hazards hazardType); bool32 CanMoveSkipAccuracyCalc(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef, u32 move, enum FunctionCallOption option); u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect); +bool32 IsSemiInvulnerable(u32 battler, enum SemiInvulnerableExclusion excludeCommander); +bool32 BreaksThroughSemiInvulnerablity(u32 battler, u32 move); #endif // GUARD_BATTLE_UTIL_H diff --git a/include/constants/battle.h b/include/constants/battle.h index 730dbd63c7..148438237b 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -169,8 +169,14 @@ enum VolatileFlags F(VOLATILE_FORESIGHT, foresight, (u32, 1)) \ F(VOLATILE_DRAGON_CHEER, dragonCheer, (u32, 1), V_BATON_PASSABLE) \ F(VOLATILE_FOCUS_ENERGY, focusEnergy, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_SEMI_INVULNERABLE, semiInvulnerable, (u32, 5)) \ + F(VOLATILE_ELECTRIFIED, electrified, (u32, 1)) \ F(VOLATILE_MUD_SPORT, mudSport, (u32, 1), V_BATON_PASSABLE) \ - F(VOLATILE_WATER_SPORT, waterSport, (u32, 1), V_BATON_PASSABLE) + F(VOLATILE_WATER_SPORT, waterSport, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_INFINITE_CONFUSION, infiniteConfusion, (u32, 1)) \ + F(VOLATILE_SALT_CURE, saltCure, (u32, 1)) \ + F(VOLATILE_SYRUP_BOMB, syrupBomb, (u32, 1)) \ + F(VOLATILE_GLAIVE_RUSH, glaiveRush, (u32, 1)) /* Use within a macro to get the maximum allowed value for a volatile. Requires _typeMaxValue as input. */ #define GET_VOLATILE_MAXIMUM(_typeMaxValue, ...) INVOKE_WITH_B(GET_VOLATILE_MAXIMUM_, _typeMaxValue) @@ -188,44 +194,13 @@ enum Volatile // Helper macros #define INFATUATED_WITH(battler) (battler + 1) -// Old flags -#define STATUS2_CONFUSION (1 << 0 | 1 << 1 | 1 << 2) -#define STATUS2_CONFUSION_TURN(num) ((num) << 0) -#define STATUS2_FLINCHED (1 << 3) -#define STATUS2_UPROAR (1 << 4 | 1 << 5 | 1 << 6) -#define STATUS2_UPROAR_TURN(num) ((num) << 4) -#define STATUS2_TORMENT (1 << 7) -#define STATUS2_BIDE (1 << 8 | 1 << 9) -#define STATUS2_BIDE_TURN(num) (((num) << 8) & STATUS2_BIDE) -#define STATUS2_LOCK_CONFUSE (1 << 10 | 1 << 11) // e.g. Thrash -#define STATUS2_LOCK_CONFUSE_TURN(num)((num) << 10) -#define STATUS2_MULTIPLETURNS (1 << 12) -#define STATUS2_WRAPPED (1 << 13) -#define STATUS2_POWDER (1 << 14) -//#define STATUS2_UNUSED (1 << 15) -#define STATUS2_INFATUATION (1 << 16 | 1 << 17 | 1 << 18 | 1 << 19) // 4 bits, one for every battler -#define STATUS2_INFATUATED_WITH(battler) (1u << (battler + 16)) -#define STATUS2_DEFENSE_CURL (1 << 20) -#define STATUS2_TRANSFORMED (1 << 21) -#define STATUS2_RECHARGE (1 << 22) -#define STATUS2_RAGE (1 << 23) -#define STATUS2_SUBSTITUTE (1 << 24) -#define STATUS2_DESTINY_BOND (1 << 25) -#define STATUS2_ESCAPE_PREVENTION (1 << 26) -#define STATUS2_NIGHTMARE (1 << 27) -#define STATUS2_CURSED (1 << 28) -#define STATUS2_FORESIGHT (1 << 29) -#define STATUS2_DRAGON_CHEER (1 << 30) -#define STATUS2_FOCUS_ENERGY (1 << 31) -#define STATUS2_FOCUS_ENERGY_ANY (STATUS2_DRAGON_CHEER | STATUS2_FOCUS_ENERGY) - #define STATUS3_LEECHSEED_BATTLER (1 << 0 | 1 << 1) // The battler to receive HP from Leech Seed #define STATUS3_LEECHSEED (1 << 2) #define STATUS3_ALWAYS_HITS (1 << 3 | 1 << 4) #define STATUS3_ALWAYS_HITS_TURN(num) (((num) << 3) & STATUS3_ALWAYS_HITS) // "Always Hits" is set as a 2 turn timer, i.e. next turn is the last turn when it's active #define STATUS3_PERISH_SONG (1 << 5) -#define STATUS3_ON_AIR (1 << 6) -#define STATUS3_UNDERGROUND (1 << 7) +#define STATUS3_UNUSED_6 (1 << 6) +#define STATUS3_UNUSED_7 (1 << 7) #define STATUS3_MINIMIZED (1 << 8) #define STATUS3_CHARGED_UP (1 << 9) #define STATUS3_ROOTED (1 << 10) @@ -233,33 +208,39 @@ enum Volatile #define STATUS3_YAWN_TURN(num) (((num) << 11) & STATUS3_YAWN) #define STATUS3_IMPRISONED_OTHERS (1 << 13) #define STATUS3_GRUDGE (1 << 14) -#define STATUS3_COMMANDER (1 << 15) +#define STATUS3_UNUSED_15 (1 << 15) #define STATUS3_GASTRO_ACID (1 << 16) #define STATUS3_EMBARGO (1 << 17) -#define STATUS3_UNDERWATER (1 << 18) +#define STATUS3_UNUSED_18 (1 << 18) #define STATUS3_UNUSED_19 (1 << 19) #define STATUS3_UNUSED_20 (1 << 20) #define STATUS3_SMACKED_DOWN (1 << 21) #define STATUS3_UNUSED_22 (1 << 22) #define STATUS3_TELEKINESIS (1 << 23) -#define STATUS3_PHANTOM_FORCE (1 << 24) +#define STATUS3_UNUSED_24 (1 << 24) #define STATUS3_MIRACLE_EYED (1 << 25) #define STATUS3_MAGNET_RISE (1 << 26) #define STATUS3_HEAL_BLOCK (1 << 27) #define STATUS3_AQUA_RING (1 << 28) #define STATUS3_LASER_FOCUS (1 << 29) #define STATUS3_POWER_TRICK (1 << 30) -#define STATUS3_SKY_DROPPED (1 << 31) // Target of Sky Drop -#define STATUS3_SEMI_INVULNERABLE_NO_COMMANDER (STATUS3_UNDERGROUND | STATUS3_ON_AIR | STATUS3_UNDERWATER | STATUS3_PHANTOM_FORCE) // Exception for Transform / Imposter -#define STATUS3_SEMI_INVULNERABLE (STATUS3_SEMI_INVULNERABLE_NO_COMMANDER | STATUS3_COMMANDER) -#define STATUS4_ELECTRIFIED (1 << 0) -#define STATUS4_MUD_SPORT (1 << 1) // Only used if B_SPORT_TURNS < GEN_6 -#define STATUS4_WATER_SPORT (1 << 2) // Only used if B_SPORT_TURNS < GEN_6 -#define STATUS4_INFINITE_CONFUSION (1 << 3) // Used for Berserk Gene -#define STATUS4_SALT_CURE (1 << 4) -#define STATUS4_SYRUP_BOMB (1 << 5) -#define STATUS4_GLAIVE_RUSH (1 << 6) +enum SemiInvulnerableState +{ + STATE_NONE, + STATE_UNDERGROUND, + STATE_UNDERWATER, + STATE_ON_AIR, + STATE_PHANTOM_FORCE, + STATE_SKY_DROP, + STATE_COMMANDER, +}; + +enum SemiInvulnerableExclusion +{ + CHECK_ALL, + EXCLUDE_COMMANDER, +}; #define HITMARKER_STRING_PRINTED (1 << 4) #define HITMARKER_IGNORE_BIDE (1 << 5) diff --git a/include/move.h b/include/move.h index 61483e402e..b1e8cba99f 100644 --- a/include/move.h +++ b/include/move.h @@ -489,7 +489,7 @@ static inline u32 GetMoveTwoTurnAttackStringId(u32 moveId) static inline u32 GetMoveTwoTurnAttackStatus(u32 moveId) { - return UNCOMPRESS_BITS(gMovesInfo[SanitizeMoveId(moveId)].argument.twoTurnAttack.status); + return gMovesInfo[SanitizeMoveId(moveId)].argument.twoTurnAttack.status; } static inline u32 GetMoveTwoTurnAttackWeather(u32 moveId) diff --git a/include/pokemon.h b/include/pokemon.h index f36f8ba7f5..cd7925cf14 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -381,12 +381,7 @@ struct BattlePokemon /*0x45*/ u32 experience; /*0x49*/ u32 personality; /*0x4D*/ u32 status1; - /*0x51*/ union { - struct { - u32 status2; // To be expanded to include Status3/4 - }; - struct Volatiles volatiles; - }; + /*0x51*/ struct Volatiles volatiles; /*0x5D*/ u32 otId; /*0x61*/ u8 metLevel; /*0x62*/ bool8 isShiny; diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index fc2ac90b1d..7a74e0d655 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -1083,7 +1083,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (IsPowderMove(move) && !IsAffectedByPowder(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef])) RETURN_SCORE_MINUS(10); - if (IsSemiInvulnerable(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && AI_IsFaster(battlerAtk, battlerDef, move, predictedMove, CONSIDER_PRIORITY)) + if (!BreaksThroughSemiInvulnerablity(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && AI_IsFaster(battlerAtk, battlerDef, move, predictedMove, CONSIDER_PRIORITY)) RETURN_SCORE_MINUS(10); if (IsTwoTurnNotSemiInvulnerableMove(battlerAtk, move) && CanTargetFaintAi(battlerDef, battlerAtk)) @@ -2363,7 +2363,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); // Don't Fly/dig/etc if opponent is going to fly/dig/etc after you if (BattlerWillFaintFromWeather(battlerAtk, aiData->abilities[battlerAtk]) - && GetMoveTwoTurnAttackStatus(move) == STATUS3_ON_AIR) + && GetMoveTwoTurnAttackStatus(move) == STATE_ON_AIR) ADJUST_SCORE(-10); // Attacker will faint while in the air break; case EFFECT_HEALING_WISH: //healing wish, lunar dance @@ -4524,7 +4524,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) || predictedEffect == EFFECT_MISTY_EXPLOSION || predictedEffect == EFFECT_PROTECT)) ADJUST_SCORE(GOOD_EFFECT); - else if (predictedEffect == EFFECT_SEMI_INVULNERABLE && !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE)) + else if (predictedEffect == EFFECT_SEMI_INVULNERABLE && !IsSemiInvulnerable(battlerDef, CHECK_ALL)) ADJUST_SCORE(GOOD_EFFECT); } break; diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 526c81c7ca..fe3bb5a5ed 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -482,7 +482,7 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler) u32 opposingBattler = GetOppositeBattler(battler); u32 incomingMove = GetIncomingMove(battler, opposingBattler, gAiLogicData); u32 incomingType = CheckDynamicMoveType(GetBattlerMon(opposingBattler), incomingMove, opposingBattler, MON_IN_BATTLE); - bool32 isOpposingBattlerChargingOrInvulnerable = (IsSemiInvulnerable(opposingBattler, incomingMove) || IsTwoTurnNotSemiInvulnerableMove(opposingBattler, incomingMove)); + bool32 isOpposingBattlerChargingOrInvulnerable = !BreaksThroughSemiInvulnerablity(opposingBattler, incomingMove) || IsTwoTurnNotSemiInvulnerableMove(opposingBattler, incomingMove); s32 i, j; if (!(gAiThinkingStruct->aiFlags[GetThinkingBattler(battler)] & AI_FLAG_SMART_SWITCHING)) @@ -615,7 +615,7 @@ static bool32 ShouldSwitchIfOpponentChargingOrInvulnerable(u32 battler) u32 opposingBattler = GetOppositeBattler(battler); u32 incomingMove = GetIncomingMove(battler, opposingBattler, gAiLogicData); - bool32 isOpposingBattlerChargingOrInvulnerable = (IsSemiInvulnerable(opposingBattler, incomingMove) || IsTwoTurnNotSemiInvulnerableMove(opposingBattler, incomingMove)); + bool32 isOpposingBattlerChargingOrInvulnerable = !BreaksThroughSemiInvulnerablity(opposingBattler, incomingMove) || IsTwoTurnNotSemiInvulnerableMove(opposingBattler, incomingMove); if (IsDoubleBattle() || !(gAiThinkingStruct->aiFlags[GetThinkingBattler(battler)] & AI_FLAG_SMART_SWITCHING)) return FALSE; @@ -2436,7 +2436,7 @@ static bool32 ShouldUseItem(u32 battler) // If teaming up with player and Pokemon is on the right, or Pokemon is currently held by Sky Drop if ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && GetBattlerPosition(battler) == B_POSITION_PLAYER_RIGHT) - || gStatuses3[battler] & STATUS3_SKY_DROPPED) + || gBattleMons[battler].volatiles.semiInvulnerable == STATE_SKY_DROP) return FALSE; if (gStatuses3[battler] & STATUS3_EMBARGO) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index b4e0cbaaf4..a15fafc897 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -457,7 +457,9 @@ bool32 IsBattlerTrapped(u32 battlerAtk, u32 battlerDef) return TRUE; if (gBattleMons[battlerDef].volatiles.escapePrevention) return TRUE; - if (gStatuses3[battlerDef] & (STATUS3_ROOTED | STATUS3_SKY_DROPPED)) + if (gBattleMons[battlerDef].volatiles.semiInvulnerable == STATE_SKY_DROP) + return TRUE; + if (gStatuses3[battlerDef] & STATUS3_ROOTED) return TRUE; if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK) return TRUE; @@ -1860,60 +1862,6 @@ bool32 IsMoveRedirectionPrevented(u32 battlerAtk, u32 move, u32 atkAbility) return FALSE; } -bool32 IsSemiInvulnerable(u32 battlerDef, u32 move) -{ - if (gStatuses3[battlerDef] & STATUS3_PHANTOM_FORCE) - return TRUE; - else if (gBattleStruct->battlerState[battlerDef].commandingDondozo) - return TRUE; - else if (!MoveDamagesAirborne(move) && gStatuses3[battlerDef] & STATUS3_ON_AIR) - return TRUE; - else if (!MoveDamagesUnderWater(move) && gStatuses3[battlerDef] & STATUS3_UNDERWATER) - return TRUE; - else if (!MoveDamagesUnderground(move) && gStatuses3[battlerDef] & STATUS3_UNDERGROUND) - return TRUE; - else - return FALSE; -} - -bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move) -{ - u32 weather; - if (IsSemiInvulnerable(battlerDef, move)) - return FALSE; - - //TODO - anticipate protect move? - - // always hits - if (gStatuses3[battlerDef] & STATUS3_ALWAYS_HITS || gDisableStructs[battlerDef].battlerWithSureHit == battlerAtk) - return TRUE; - - if (gAiLogicData->abilities[battlerDef] == ABILITY_NO_GUARD || gAiLogicData->abilities[battlerAtk] == ABILITY_NO_GUARD) - return TRUE; - - u32 nonVolatileStatus = GetMoveNonVolatileStatus(move); - if (B_TOXIC_NEVER_MISS >= GEN_6 - && nonVolatileStatus == MOVE_EFFECT_TOXIC - && IS_BATTLER_OF_TYPE(battlerAtk, TYPE_POISON)) - return TRUE; - - // discouraged from hitting - weather = AI_GetWeather(); - if ((weather & B_WEATHER_SUN) && MoveHas50AccuracyInSun(move)) - return FALSE; - - if ((weather & B_WEATHER_RAIN) && MoveAlwaysHitsInRain(move)) - return TRUE; - if ((weather & B_WEATHER_ICY_ANY) && MoveAlwaysHitsInHailSnow(move)) - return TRUE; - if (B_MINIMIZE_DMG_ACC >= GEN_6 && (gStatuses3[battlerDef] & STATUS3_MINIMIZED) && MoveIncreasesPowerToMinimizedTargets(move)) - return TRUE; - if (GetMoveAccuracy(move) == 0) - return TRUE; - - return FALSE; -} - bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbility, u32 move) { enum ItemHoldEffect holdEffect = gAiLogicData->holdEffects[battlerDef]; @@ -1972,8 +1920,8 @@ bool32 IsBattlerDamagedByStatus(u32 battler) || gBattleMons[battler].volatiles.wrapped || gBattleMons[battler].volatiles.nightmare || gBattleMons[battler].volatiles.cursed + || gBattleMons[battler].volatiles.saltCure || gStatuses3[battler] & (STATUS3_PERISH_SONG | STATUS3_LEECHSEED) - || gStatuses4[battler] & (STATUS4_SALT_CURE) || gSideStatuses[GetBattlerSide(battler)] & (SIDE_STATUS_SEA_OF_FIRE | SIDE_STATUS_DAMAGE_NON_TYPES); } @@ -2980,7 +2928,8 @@ static u32 GetWeatherDamage(u32 battlerId) if (weather & B_WEATHER_SANDSTORM) { if (BattlerAffectedBySandstorm(battlerId, ability) - && !(gStatuses3[battlerId] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) + && gBattleMons[battlerId].volatiles.semiInvulnerable != STATE_UNDERGROUND + && gBattleMons[battlerId].volatiles.semiInvulnerable != STATE_UNDERWATER && holdEffect != HOLD_EFFECT_SAFETY_GOGGLES) { damage = GetNonDynamaxMaxHP(battlerId) / 16; @@ -2991,7 +2940,8 @@ static u32 GetWeatherDamage(u32 battlerId) if ((weather & B_WEATHER_HAIL) && ability != ABILITY_ICE_BODY) { if (BattlerAffectedByHail(battlerId, ability) - && !(gStatuses3[battlerId] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) + && gBattleMons[battlerId].volatiles.semiInvulnerable != STATE_UNDERGROUND + && gBattleMons[battlerId].volatiles.semiInvulnerable != STATE_UNDERWATER && holdEffect != HOLD_EFFECT_SAFETY_GOGGLES) { damage = GetNonDynamaxMaxHP(battlerId) / 16; diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index fccbfb1b64..12bd7859b9 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -6871,7 +6871,7 @@ static void SwapBattlerMoveData(u32 battler1, u32 battler2) SWAP(gBattleStruct->moveTarget[battler1], gBattleStruct->moveTarget[battler2], temp); SWAP(gMoveSelectionCursor[battler1], gMoveSelectionCursor[battler2], temp); SWAP(gLockedMoves[battler1], gLockedMoves[battler2], temp); - + // update last moves SWAP(gLastPrintedMoves[battler1], gLastPrintedMoves[battler2], temp); SWAP(gLastMoves[battler1], gLastMoves[battler2], temp); @@ -6907,10 +6907,9 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId) SWAP(gTransformedPersonalities[battlerAtk], gTransformedPersonalities[battlerPartner], temp); SWAP(gTransformedShininess[battlerAtk], gTransformedShininess[battlerPartner], temp); SWAP(gStatuses3[battlerAtk], gStatuses3[battlerPartner], temp); - SWAP(gStatuses4[battlerAtk], gStatuses4[battlerPartner], temp); - + SwapBattlerMoveData(battlerAtk, battlerPartner); - + // Swap turn order, so that all the battlers take action SWAP(gChosenActionByBattler[battlerAtk], gChosenActionByBattler[battlerPartner], temp); for (i = 0; i < gBattlersCount; i++) diff --git a/src/battle_debug.c b/src/battle_debug.c index 6b8998de8f..a991ac341a 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -106,7 +106,6 @@ enum LIST_ITEM_STATUS1, LIST_ITEM_VOLATILE, LIST_ITEM_STATUS3, - LIST_ITEM_STATUS4, LIST_ITEM_HAZARDS, LIST_ITEM_SIDE_STATUS, LIST_ITEM_AI, @@ -147,8 +146,6 @@ enum LIST_STATUS3_LEECH_SEEDED, LIST_STATUS3_ALWAYS_HITS, LIST_STATUS3_PERISH_SONG, - LIST_STATUS3_ON_AIR, - LIST_STATUS3_UNDERGROUND, LIST_STATUS3_MINIMIZED, LIST_STATUS3_CHARGED_UP, LIST_STATUS3_ROOTED, @@ -157,7 +154,6 @@ enum LIST_STATUS3_GRUDGE, LIST_STATUS3_GASTRO_ACID, LIST_STATUS3_EMBARGO, - LIST_STATUS3_UNDERWATER, LIST_STATUS3_SMACKED_DOWN, LIST_STATUS3_TELEKINESIS, LIST_STATUS3_MIRACLE_EYED, @@ -168,14 +164,6 @@ enum LIST_STATUS3_POWER_TRICK, }; -enum -{ - LIST_STATUS4_ELECTRIFIED, - LIST_STATUS4_SALT_CURE, - LIST_STATUS4_SYRUP_BOMB, - LIST_STATUS4_GLAIVE_RUSH, -}; - enum { LIST_SIDE_STICKY_WEB, @@ -314,16 +302,6 @@ static const struct BitfieldInfo sStatus3Bitfield[] = {/*Power Trick*/ 1, 30}, }; -static const struct BitfieldInfo sStatus4Bitfield[] = -{ - {/*Electrified*/ 1, 0}, - {/*Mud Sport*/ 1, 1}, - {/*Water Sport*/ 1, 2}, - {/*Salt Cure*/ 1, 4}, - {/*Syrup Bomb*/ 1, 5}, - {/*Glaive Rush*/ 1, 6}, -}; - static const struct BitfieldInfo sAIBitfield[] = { {/*Check Bad Move*/ 1, 0}, @@ -369,7 +347,6 @@ static const struct ListMenuItem sMainListItems[] = {COMPOUND_STRING("Status1"), LIST_ITEM_STATUS1}, {COMPOUND_STRING("Volatiles"), LIST_ITEM_VOLATILE}, {COMPOUND_STRING("Status3"), LIST_ITEM_STATUS3}, - {COMPOUND_STRING("Status4"), LIST_ITEM_STATUS4}, {COMPOUND_STRING("Hazards"), LIST_ITEM_HAZARDS}, {COMPOUND_STRING("Side Status"), LIST_ITEM_SIDE_STATUS}, {COMPOUND_STRING("AI"), LIST_ITEM_AI}, @@ -405,21 +382,26 @@ static const struct ListMenuItem sStatus1ListItems[] = static const struct ListMenuItem sVolatileStatusListItems[] = { - {COMPOUND_STRING("Confusion"), VOLATILE_CONFUSION}, - {COMPOUND_STRING("Flinched"), VOLATILE_FLINCHED}, - {COMPOUND_STRING("Torment"), VOLATILE_TORMENT}, - {COMPOUND_STRING("Powder"), VOLATILE_POWDER}, - {COMPOUND_STRING("DefenseCurl"), VOLATILE_DEFENSE_CURL}, - {COMPOUND_STRING("Recharge"), VOLATILE_RECHARGE}, - {COMPOUND_STRING("Rage"), VOLATILE_RAGE}, - {COMPOUND_STRING("DestinyBond"), VOLATILE_DESTINY_BOND}, - {COMPOUND_STRING("EscapePrevention"), VOLATILE_ESCAPE_PREVENTION}, - {COMPOUND_STRING("Cursed"), VOLATILE_CURSED}, - {COMPOUND_STRING("Foresight"), VOLATILE_FORESIGHT}, - {COMPOUND_STRING("DragonCheer"), VOLATILE_DRAGON_CHEER}, - {COMPOUND_STRING("FocusEnergy"), VOLATILE_FOCUS_ENERGY}, - {COMPOUND_STRING("MudSport"), VOLATILE_MUD_SPORT}, - {COMPOUND_STRING("WaterSport"), VOLATILE_WATER_SPORT}, + {COMPOUND_STRING("Confusion"), VOLATILE_CONFUSION}, + {COMPOUND_STRING("Flinched"), VOLATILE_FLINCHED}, + {COMPOUND_STRING("Torment"), VOLATILE_TORMENT}, + {COMPOUND_STRING("Powder"), VOLATILE_POWDER}, + {COMPOUND_STRING("DefenseCurl"), VOLATILE_DEFENSE_CURL}, + {COMPOUND_STRING("Recharge"), VOLATILE_RECHARGE}, + {COMPOUND_STRING("Rage"), VOLATILE_RAGE}, + {COMPOUND_STRING("DestinyBond"), VOLATILE_DESTINY_BOND}, + {COMPOUND_STRING("EscapePrevention"), VOLATILE_ESCAPE_PREVENTION}, + {COMPOUND_STRING("Cursed"), VOLATILE_CURSED}, + {COMPOUND_STRING("Foresight"), VOLATILE_FORESIGHT}, + {COMPOUND_STRING("DragonCheer"), VOLATILE_DRAGON_CHEER}, + {COMPOUND_STRING("FocusEnergy"), VOLATILE_FOCUS_ENERGY}, + {COMPOUND_STRING("Electrified"), VOLATILE_ELECTRIFIED}, + {COMPOUND_STRING("MudSport"), VOLATILE_MUD_SPORT}, + {COMPOUND_STRING("WaterSport"), VOLATILE_WATER_SPORT}, + {COMPOUND_STRING("Infinite Confusion"), VOLATILE_INFINITE_CONFUSION}, + {COMPOUND_STRING("Salt Cure"), VOLATILE_SALT_CURE}, + {COMPOUND_STRING("Syrup Bomb"), VOLATILE_SYRUP_BOMB}, + {COMPOUND_STRING("Glaive Rush"), VOLATILE_GLAIVE_RUSH}, }; static const struct ListMenuItem sStatus3ListItems[] = @@ -428,8 +410,6 @@ static const struct ListMenuItem sStatus3ListItems[] = {COMPOUND_STRING("Leech Seeded"), LIST_STATUS3_LEECH_SEEDED}, {COMPOUND_STRING("Always Hits"), LIST_STATUS3_ALWAYS_HITS}, {COMPOUND_STRING("Perish Song"), LIST_STATUS3_PERISH_SONG}, - {COMPOUND_STRING("On Air"), LIST_STATUS3_ON_AIR}, - {COMPOUND_STRING("Underground"), LIST_STATUS3_UNDERGROUND}, {COMPOUND_STRING("Minimized"), LIST_STATUS3_MINIMIZED}, {COMPOUND_STRING("Charged Up"), LIST_STATUS3_CHARGED_UP}, {COMPOUND_STRING("Rooted"), LIST_STATUS3_ROOTED}, @@ -438,7 +418,6 @@ static const struct ListMenuItem sStatus3ListItems[] = {COMPOUND_STRING("Grudge"), LIST_STATUS3_GRUDGE}, {COMPOUND_STRING("Gastro Acid"), LIST_STATUS3_GASTRO_ACID}, {COMPOUND_STRING("Embargo"), LIST_STATUS3_EMBARGO}, - {COMPOUND_STRING("Underwater"), LIST_STATUS3_UNDERWATER}, {COMPOUND_STRING("Smacked Down"), LIST_STATUS3_SMACKED_DOWN}, {COMPOUND_STRING("Telekinesis"), LIST_STATUS3_TELEKINESIS}, {COMPOUND_STRING("Miracle Eyed"), LIST_STATUS3_MIRACLE_EYED}, @@ -449,14 +428,6 @@ static const struct ListMenuItem sStatus3ListItems[] = {COMPOUND_STRING("Power Trick"), LIST_STATUS3_POWER_TRICK}, }; -static const struct ListMenuItem sStatus4ListItems[] = -{ - {COMPOUND_STRING("Electrified"), LIST_STATUS4_ELECTRIFIED}, - {COMPOUND_STRING("Salt Cure"), LIST_STATUS4_SALT_CURE}, - {COMPOUND_STRING("Syrup Bomb"), LIST_STATUS4_SYRUP_BOMB}, - {COMPOUND_STRING("Glaive Rush"), LIST_STATUS4_GLAIVE_RUSH}, -}; - static const struct ListMenuItem sHazardsListItems[] = { {COMPOUND_STRING("Spikes"), LIST_SIDE_SPIKES}, @@ -822,7 +793,7 @@ static void PutMovesPointsText(struct BattleDebugMenu *data) AddTextPrinterParameterized(data->aiMovesWindowId, FONT_NORMAL, COMPOUND_STRING("Chosen move: "), 74, 64, 0, NULL); AddTextPrinterParameterized(data->aiMovesWindowId, FONT_NORMAL, GetMoveName(gBattleMons[data->aiBattlerId].moves[chosenMoveIndex]), 74 + 68, 64, 0, NULL); } - + CopyWindowToVram(data->aiMovesWindowId, COPYWIN_FULL); Free(text); } @@ -1437,11 +1408,6 @@ static void CreateSecondaryListMenu(struct BattleDebugMenu *data) itemsCount = ARRAY_COUNT(sStatus3ListItems); data->bitfield = sStatus3Bitfield; break; - case LIST_ITEM_STATUS4: - listTemplate.items = sStatus4ListItems; - itemsCount = ARRAY_COUNT(sStatus4ListItems); - data->bitfield = sStatus4Bitfield; - break; case LIST_ITEM_AI: listTemplate.items = sAIListItems; itemsCount = ARRAY_COUNT(sAIListItems); @@ -2084,11 +2050,6 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data) data->modifyArrows.currValue = GetBitfieldValue(gStatuses3[data->battlerId], data->bitfield[data->currentSecondaryListItemId].currBit, data->bitfield[data->currentSecondaryListItemId].bitsCount); data->modifyArrows.typeOfVal = VAL_BITFIELD_32; goto CASE_ITEM_STATUS; - case LIST_ITEM_STATUS4: - data->modifyArrows.modifiedValPtr = &gStatuses4[data->battlerId]; - data->modifyArrows.currValue = GetBitfieldValue(gStatuses4[data->battlerId], data->bitfield[data->currentSecondaryListItemId].currBit, data->bitfield[data->currentSecondaryListItemId].bitsCount); - data->modifyArrows.typeOfVal = VAL_BITFIELD_32; - goto CASE_ITEM_STATUS; case LIST_ITEM_AI: data->modifyArrows.modifiedValPtr = &gAiThinkingStruct->aiFlags[data->battlerId]; data->modifyArrows.currValue = GetBitfieldValue(gAiThinkingStruct->aiFlags[data->battlerId], data->bitfield[data->currentSecondaryListItemId].currBit, data->bitfield[data->currentSecondaryListItemId].bitsCount); diff --git a/src/battle_end_turn.c b/src/battle_end_turn.c index a33aa25cc4..87ed8542a7 100644 --- a/src/battle_end_turn.c +++ b/src/battle_end_turn.c @@ -232,9 +232,10 @@ static bool32 HandleEndTurnWeatherDamage(u32 battler) && ability != ABILITY_SAND_FORCE && ability != ABILITY_SAND_RUSH && ability != ABILITY_OVERCOAT - && !IS_BATTLER_ANY_TYPE(gBattlerAttacker, TYPE_ROCK, TYPE_GROUND, TYPE_STEEL) - && !(gStatuses3[gBattlerAttacker] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) - && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES + && !IS_BATTLER_ANY_TYPE(battler, TYPE_ROCK, TYPE_GROUND, TYPE_STEEL) + && gBattleMons[battler].volatiles.semiInvulnerable != STATE_UNDERGROUND + && gBattleMons[battler].volatiles.semiInvulnerable != STATE_UNDERWATER + && GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES && !IsAbilityAndRecord(battler, ability, ABILITY_MAGIC_GUARD)) { gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16; @@ -257,7 +258,8 @@ static bool32 HandleEndTurnWeatherDamage(u32 battler) if (ability != ABILITY_SNOW_CLOAK && ability != ABILITY_OVERCOAT && !IS_BATTLER_OF_TYPE(battler, TYPE_ICE) - && !(gStatuses3[battler] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) + && gBattleMons[battler].volatiles.semiInvulnerable != STATE_UNDERGROUND + && gBattleMons[battler].volatiles.semiInvulnerable != STATE_UNDERWATER && GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES && !IsAbilityAndRecord(battler, ability, ABILITY_MAGIC_GUARD)) { @@ -306,7 +308,7 @@ static bool32 HandleEndTurnEmergencyExit(u32 battler) && (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER)) && !(gBattleTypeFlags & BATTLE_TYPE_ARENA) && CountUsablePartyMons(battler) > 0 - && !(gStatuses3[battler] & STATUS3_SKY_DROPPED)) // Not currently held by Sky Drop + && gBattleMons[battler].volatiles.semiInvulnerable != STATE_SKY_DROP) // Not currently held by Sky Drop { gBattlerAbility = battler; gLastUsedAbility = ability; @@ -458,7 +460,7 @@ static bool32 HandleEndTurnFirstEventBlock(u32 battler) gBattleStruct->eventBlockCounter++; break; case FIRST_EVENT_BLOCK_THRASH: - if (gBattleMons[battler].volatiles.lockConfusionTurns && !(gStatuses3[battler] & STATUS3_SKY_DROPPED)) + if (gBattleMons[battler].volatiles.lockConfusionTurns && gBattleMons[battler].volatiles.semiInvulnerable != STATE_SKY_DROP) { gBattleMons[battler].volatiles.lockConfusionTurns--; if (WasUnableToUseMove(battler)) @@ -484,7 +486,8 @@ static bool32 HandleEndTurnFirstEventBlock(u32 battler) if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerAlive(battler) && !IsBattlerAtMaxHp(battler) - && !(gStatuses3[battler] & (STATUS3_SEMI_INVULNERABLE | STATUS3_HEAL_BLOCK)) + && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK) + && !IsSemiInvulnerable(battler, CHECK_ALL) && IsBattlerGrounded(battler)) { gBattlerAttacker = battler; @@ -795,7 +798,7 @@ static bool32 HandleEndTurnSaltCure(u32 battler) gBattleStruct->turnEffectsBattlerId++; - if (gStatuses4[battler] & STATUS4_SALT_CURE + if (gBattleMons[battler].volatiles.saltCure && IsBattlerAlive(battler) && !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD)) { @@ -836,10 +839,10 @@ static bool32 HandleEndTurnSyrupBomb(u32 battler) gBattleStruct->turnEffectsBattlerId++; - if ((gStatuses4[battler] & STATUS4_SYRUP_BOMB) && (IsBattlerAlive(battler))) + if (gBattleMons[battler].volatiles.syrupBomb && (IsBattlerAlive(battler))) { if (gDisableStructs[battler].syrupBombTimer > 0 && --gDisableStructs[battler].syrupBombTimer == 0) - gStatuses4[battler] &= ~STATUS4_SYRUP_BOMB; + gBattleMons[battler].volatiles.syrupBomb = FALSE; PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_SYRUP_BOMB); gBattlescriptCurrInstr = BattleScript_SyrupBombEndTurn; BattleScriptExecute(gBattlescriptCurrInstr); diff --git a/src/battle_main.c b/src/battle_main.c index 2b3edabad2..cd9544ef28 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -194,7 +194,6 @@ EWRAM_DATA u8 gBideTarget[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u32 gSideStatuses[NUM_BATTLE_SIDES] = {0}; EWRAM_DATA struct SideTimer gSideTimers[NUM_BATTLE_SIDES] = {0}; EWRAM_DATA u32 gStatuses3[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u32 gStatuses4[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u16 gPauseCounterBattle = 0; EWRAM_DATA u16 gPaydayMoney = 0; @@ -3028,7 +3027,6 @@ static void BattleStartClearSetData(void) for (i = 0; i < MAX_BATTLERS_COUNT; i++) { gStatuses3[i] = 0; - gStatuses4[i] = 0; gDisableStructs[i].isFirstTurn = 2; gLastMoves[i] = MOVE_NONE; gLastLandedMoves[i] = MOVE_NONE; @@ -3174,7 +3172,6 @@ void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy) gStatuses3[battler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED | STATUS3_GASTRO_ACID | STATUS3_EMBARGO | STATUS3_TELEKINESIS | STATUS3_MAGNET_RISE | STATUS3_HEAL_BLOCK | STATUS3_AQUA_RING | STATUS3_POWER_TRICK); - gStatuses4[battler] &= STATUS4_INFINITE_CONFUSION; for (i = 0; i < gBattlersCount; i++) { if (!IsBattlerAlly(battler, i) @@ -3191,7 +3188,6 @@ void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy) else { gStatuses3[battler] = 0; - gStatuses4[battler] = 0; } for (i = 0; i < gBattlersCount; i++) @@ -3200,8 +3196,8 @@ void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy) gBattleMons[i].volatiles.infatuation = 0; if (gBattleMons[i].volatiles.wrapped && gBattleStruct->wrappedBy[i] == battler) gBattleMons[i].volatiles.wrapped = FALSE; - if ((gStatuses4[i] & STATUS4_SYRUP_BOMB) && gBattleStruct->stickySyrupdBy[i] == battler) - gStatuses4[i] &= ~STATUS4_SYRUP_BOMB; + if (gBattleMons[i].volatiles.syrupBomb && gBattleStruct->stickySyrupdBy[i] == battler) + gBattleMons[i].volatiles.syrupBomb = FALSE; } gActionSelectionCursor[battler] = 0; @@ -3308,7 +3304,6 @@ const u8* FaintClearSetData(u32 battler) memset(&gBattleMons[battler].volatiles, 0, sizeof(struct Volatiles)); gStatuses3[battler] &= STATUS3_GASTRO_ACID; // Edge case: Keep Gastro Acid if pokemon's ability can have effect after fainting, for example Innards Out. - gStatuses4[battler] = 0; for (i = 0; i < gBattlersCount; i++) { @@ -3318,8 +3313,8 @@ const u8* FaintClearSetData(u32 battler) gBattleMons[i].volatiles.infatuation = 0; if (gBattleMons[i].volatiles.wrapped && gBattleStruct->wrappedBy[i] == battler) gBattleMons[i].volatiles.wrapped = FALSE; - if ((gStatuses4[i] & STATUS4_SYRUP_BOMB) && gBattleStruct->stickySyrupdBy[i] == battler) - gStatuses4[i] &= ~STATUS4_SYRUP_BOMB; + if (gBattleMons[i].volatiles.syrupBomb && gBattleStruct->stickySyrupdBy[i] == battler) + gBattleMons[i].volatiles.syrupBomb = FALSE; } gActionSelectionCursor[battler] = 0; @@ -3410,10 +3405,10 @@ const u8* FaintClearSetData(u32 battler) gBattleStruct->skyDropTargets[otherSkyDropper] = SKY_DROP_NO_TARGET; // If the other Pokemon involved in this Sky Drop was the target, not the attacker - if (gStatuses3[otherSkyDropper] & STATUS3_SKY_DROPPED) + if (gBattleMons[otherSkyDropper].volatiles.semiInvulnerable == STATE_SKY_DROP) { // Release the target and take them out of the semi-invulnerable state - gStatuses3[otherSkyDropper] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + gBattleMons[otherSkyDropper].volatiles.semiInvulnerable = STATE_NONE; // Make the target's sprite visible gSprites[gBattlerSpriteIds[otherSkyDropper]].invisible = FALSE; @@ -4019,7 +4014,7 @@ void BattleTurnPassed(void) gChosenActionByBattler[i] = B_ACTION_NONE; gChosenMoveByBattler[i] = MOVE_NONE; gBattleStruct->monToSwitchIntoId[i] = PARTY_SIZE; - gStatuses4[i] &= ~STATUS4_ELECTRIFIED; + gBattleMons[i].volatiles.electrified = FALSE; gBattleMons[i].volatiles.flinched = FALSE; gBattleMons[i].volatiles.powder = FALSE; @@ -4308,7 +4303,7 @@ static void HandleTurnActionSelectionState(void) | BATTLE_TYPE_RECORDED_LINK)) && !gTestRunnerEnabled) // Or if currently held by Sky Drop - || gStatuses3[battler] & STATUS3_SKY_DROPPED) + || gBattleMons[battler].volatiles.semiInvulnerable == STATE_SKY_DROP) { RecordedBattle_ClearBattlerAction(battler, 1); gSelectionBattleScripts[battler] = BattleScript_ActionSelectionItemsCantBeUsed; @@ -5133,7 +5128,7 @@ static void TurnValuesCleanUp(bool8 var0) if (gDisableStructs[i].substituteHP == 0) gBattleMons[i].volatiles.substitute = FALSE; - if (!(gStatuses3[i] & STATUS3_COMMANDER)) + if (gBattleMons[i].volatiles.semiInvulnerable != STATE_COMMANDER) gBattleStruct->battlerState[i].commandingDondozo = FALSE; gSpecialStatuses[i].parentalBondState = PARENTAL_BOND_OFF; @@ -6083,7 +6078,8 @@ void SetTypeBeforeUsingMove(u32 move, u32 battler) gBattleStruct->dynamicMoveType = moveType | F_DYNAMIC_TYPE_SET; moveType = GetBattleMoveType(move); - if ((gFieldStatuses & STATUS_FIELD_ION_DELUGE && moveType == TYPE_NORMAL) || gStatuses4[battler] & STATUS4_ELECTRIFIED) + if ((gFieldStatuses & STATUS_FIELD_ION_DELUGE && moveType == TYPE_NORMAL) + || gBattleMons[battler].volatiles.electrified) gBattleStruct->dynamicMoveType = TYPE_ELECTRIC | F_DYNAMIC_TYPE_SET; // Check if a gem should activate. diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 162e55dba9..965745608c 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -407,7 +407,7 @@ static void Cmd_jumpifabilitypresent(void); static void Cmd_endselectionscript(void); static void Cmd_playanimation(void); static void Cmd_playanimation_var(void); -static void Cmd_unused_0x47(void); +static void Cmd_jumpfifsemiinvulnerable(void); static void Cmd_unused_0x48(void); static void Cmd_moveend(void); static void Cmd_sethealblock(void); @@ -666,7 +666,7 @@ void (*const gBattleScriptingCommandsTable[])(void) = Cmd_endselectionscript, //0x44 Cmd_playanimation, //0x45 Cmd_playanimation_var, //0x46 - Cmd_unused_0x47, //0x47 + Cmd_jumpfifsemiinvulnerable, //0x47 Cmd_unused_0x48, //0x48 Cmd_moveend, //0x49 Cmd_sethealblock, //0x4A @@ -1079,7 +1079,7 @@ bool32 EmergencyExitCanBeTriggered(u32 battler) && (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER)) && !(gBattleTypeFlags & BATTLE_TYPE_ARENA) && CountUsablePartyMons(battler) > 0 - && !(gStatuses3[battler] & STATUS3_SKY_DROPPED)) + && gBattleMons[battler].volatiles.semiInvulnerable != STATE_SKY_DROP) return TRUE; return FALSE; @@ -1366,7 +1366,7 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u { if (gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker) gBattlescriptCurrInstr = nextInstr; - else if (gStatuses3[gBattlerTarget] & (STATUS3_SEMI_INVULNERABLE)) + else if (IsSemiInvulnerable(gBattlerTarget, CHECK_ALL)) gBattlescriptCurrInstr = failInstr; else if (!JumpIfMoveAffectedByProtect(gCurrentMove, gBattlerTarget, TRUE, failInstr)) gBattlescriptCurrInstr = nextInstr; @@ -3372,7 +3372,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai break; case MOVE_EFFECT_FLAME_BURST: if (IsBattlerAlive(BATTLE_PARTNER(gBattlerTarget)) - && !(gStatuses3[BATTLE_PARTNER(gBattlerTarget)] & STATUS3_SEMI_INVULNERABLE) + && !IsSemiInvulnerable(BATTLE_PARTNER(gBattlerTarget), CHECK_ALL) && GetBattlerAbility(BATTLE_PARTNER(gBattlerTarget)) != ABILITY_MAGIC_GUARD) { gBattleScripting.battler = i = BATTLE_PARTNER(gBattlerTarget); @@ -3513,11 +3513,11 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai } break; case MOVE_EFFECT_SYRUP_BOMB: - if (!(gStatuses4[gEffectBattler] & STATUS4_SYRUP_BOMB)) + if (!gBattleMons[gEffectBattler].volatiles.syrupBomb) { struct Pokemon *mon = GetBattlerMon(gBattlerAttacker); - gStatuses4[gEffectBattler] |= STATUS4_SYRUP_BOMB; + gBattleMons[gEffectBattler].volatiles.syrupBomb = TRUE; gDisableStructs[gEffectBattler].syrupBombTimer = 3; gDisableStructs[gEffectBattler].syrupBombIsShiny = IsMonShiny(mon); gBattleStruct->stickySyrupdBy[gEffectBattler] = gBattlerAttacker; @@ -3655,9 +3655,9 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai } break; case MOVE_EFFECT_SALT_CURE: - if (!(gStatuses4[gBattlerTarget] & STATUS4_SALT_CURE)) + if (!gBattleMons[gBattlerTarget].volatiles.saltCure) { - gStatuses4[gBattlerTarget] |= STATUS4_SALT_CURE; + gBattleMons[gBattlerTarget].volatiles.saltCure = TRUE; BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_MoveEffectSaltCure; } @@ -5455,7 +5455,7 @@ static void PlayAnimation(u32 battler, u8 animId, const u16 *argPtr, const u8 *n MarkBattlerForControllerExec(battler); gBattlescriptCurrInstr = nextInstr; } - else if (gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE) + else if (IsSemiInvulnerable(battler, CHECK_ALL)) { gBattlescriptCurrInstr = nextInstr; } @@ -5484,8 +5484,15 @@ static void Cmd_playanimation_var(void) PlayAnimation(battler, *(cmd->animIdPtr), cmd->argPtr, cmd->nextInstr); } -static void Cmd_unused_0x47(void) +static void Cmd_jumpfifsemiinvulnerable(void) { + CMD_ARGS(u8 battler, u8 state, const u8 *jumpInstr); + u32 battler = GetBattlerForBattleScript(cmd->battler); + + if (gBattleMons[battler].volatiles.semiInvulnerable == cmd->state) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_unused_0x48(void) @@ -5764,7 +5771,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect) if (IsBattlerTurnDamaged(gBattlerTarget) && IsBattlerAlive(gBattlerTarget) && IsBattlerAlive(gBattlerAttacker) - && !(gStatuses3[BATTLE_PARTNER(gBattlerTarget)] & STATUS3_COMMANDER)) + && gBattleMons[BATTLE_PARTNER(gBattlerTarget)].volatiles.semiInvulnerable != STATE_COMMANDER) { u32 targetAbility = GetBattlerAbility(gBattlerTarget); if (targetAbility == ABILITY_GUARD_DOG) @@ -5796,8 +5803,9 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect) && IsBattlerAlive(gBattlerTarget) && !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) { + gBattleMons[gBattlerTarget].volatiles.semiInvulnerable = STATE_NONE; gStatuses3[gBattlerTarget] |= STATUS3_SMACKED_DOWN; - gStatuses3[gBattlerTarget] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR); + gStatuses3[gBattlerTarget] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS); BattleScriptCall(BattleScript_MoveEffectSmackDown); effect = TRUE; } @@ -6156,7 +6164,7 @@ static void Cmd_moveend(void) gBattleScripting.moveendState++; break; case MOVEEND_ATTACKER_INVISIBLE: // make attacker sprite invisible - if (gStatuses3[gBattlerAttacker] & (STATUS3_SEMI_INVULNERABLE) + if (IsSemiInvulnerable(gBattlerAttacker, CHECK_ALL) && gHitMarker & (HITMARKER_NO_ANIMATIONS | HITMARKER_DISABLE_ANIMATION)) { BtlController_EmitSpriteInvisibility(gBattlerAttacker, B_COMM_TO_CONTROLLER, TRUE); @@ -6168,12 +6176,12 @@ static void Cmd_moveend(void) break; case MOVEEND_ATTACKER_VISIBLE: // make attacker sprite visible if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT - || !(gStatuses3[gBattlerAttacker] & (STATUS3_SEMI_INVULNERABLE)) + || !IsSemiInvulnerable(gBattlerAttacker, CHECK_ALL) || WasUnableToUseMove(gBattlerAttacker)) { BtlController_EmitSpriteInvisibility(gBattlerAttacker, B_COMM_TO_CONTROLLER, FALSE); MarkBattlerForControllerExec(gBattlerAttacker); - gStatuses3[gBattlerAttacker] &= ~STATUS3_SEMI_INVULNERABLE; + gBattleMons[gBattlerAttacker].volatiles.semiInvulnerable = STATE_NONE; gSpecialStatuses[gBattlerAttacker].restoredBattlerSprite = TRUE; gBattleScripting.moveendState++; return; @@ -6182,11 +6190,11 @@ static void Cmd_moveend(void) break; case MOVEEND_TARGET_VISIBLE: // make target sprite visible if (!gSpecialStatuses[gBattlerTarget].restoredBattlerSprite && gBattlerTarget < gBattlersCount - && !(gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE)) + && !IsSemiInvulnerable(gBattlerTarget, CHECK_ALL)) { BtlController_EmitSpriteInvisibility(gBattlerTarget, B_COMM_TO_CONTROLLER, FALSE); MarkBattlerForControllerExec(gBattlerTarget); - gStatuses3[gBattlerTarget] &= ~STATUS3_SEMI_INVULNERABLE; + gBattleMons[gBattlerTarget].volatiles.semiInvulnerable = STATE_NONE; gBattleScripting.moveendState++; return; } @@ -6927,7 +6935,7 @@ static void Cmd_moveend(void) u32 partner = BATTLE_PARTNER(i); gBattleStruct->battlerState[i].commanderSpecies = SPECIES_NONE; if (IsBattlerAlive(partner)) - gStatuses3[partner] &= ~STATUS3_COMMANDER; + gBattleMons[partner].volatiles.semiInvulnerable = STATE_NONE; } } @@ -8468,7 +8476,7 @@ static void Cmd_statusanimation(void) { u32 battler = GetBattlerForBattleScript(cmd->battler), statusFlag = (cmd->isVolatile || cmd->status) ? cmd->status : gBattleMons[battler].status1; - if (!(gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE) + if (!IsSemiInvulnerable(battler, CHECK_ALL) && gDisableStructs[battler].substituteHP == 0 && !(gHitMarker & (HITMARKER_NO_ANIMATIONS | HITMARKER_DISABLE_ANIMATION))) { @@ -9322,7 +9330,7 @@ static bool32 IsRototillerAffected(u32 battler) return FALSE; // Only grounded battlers affected if (!IS_BATTLER_OF_TYPE(battler, TYPE_GRASS)) return FALSE; // Only grass types affected - if (gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE) + if (IsSemiInvulnerable(battler, CHECK_ALL)) return FALSE; // Rototiller doesn't affected semi-invulnerable battlers if (BlocksPrankster(MOVE_ROTOTILLER, gBattlerAttacker, battler, FALSE)) return FALSE; @@ -9352,7 +9360,7 @@ static bool32 IsTeatimeAffected(u32 battler) { if (GetItemPocket(gBattleMons[battler].item) != POCKET_BERRIES) return FALSE; // Only berries - if (gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE) + if (IsSemiInvulnerable(battler, CHECK_ALL)) return FALSE; // Teatime doesn't affected semi-invulnerable battlers return TRUE; } @@ -11151,7 +11159,7 @@ static void Cmd_transformdataexecution(void) gBattlescriptCurrInstr = cmd->nextInstr; if (gBattleMons[gBattlerTarget].volatiles.transformed || gBattleStruct->illusion[gBattlerTarget].state == ILLUSION_ON - || gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE_NO_COMMANDER) + || IsSemiInvulnerable(gBattlerTarget, EXCLUDE_COMMANDER)) { gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_FAILED; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TRANSFORM_FAILED; @@ -11552,7 +11560,7 @@ static void Cmd_settypetorandomresistance(void) { gBattlescriptCurrInstr = cmd->failInstr; } - else if (IsSemiInvulnerable(gBattlerTarget, gCurrentMove)) + else if (!BreaksThroughSemiInvulnerablity(gBattlerTarget, gCurrentMove)) { gBattlescriptCurrInstr = cmd->failInstr; } @@ -11705,7 +11713,7 @@ static void Cmd_trychoosesleeptalkmove(void) gCalledMove = gBattleMons[gBattlerAttacker].moves[movePosition]; } gCurrMovePos = movePosition; - gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; + gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); gBattlescriptCurrInstr = cmd->failInstr; } @@ -12005,7 +12013,7 @@ static void Cmd_trysetperishsong(void) if (gStatuses3[i] & STATUS3_PERISH_SONG || GetBattlerAbility(i) == ABILITY_SOUNDPROOF || BlocksPrankster(gCurrentMove, gBattlerAttacker, i, TRUE) - || gStatuses3[i] & STATUS3_COMMANDER) + || gBattleMons[i].volatiles.semiInvulnerable == STATE_COMMANDER) { notAffectedCount++; } @@ -12557,9 +12565,9 @@ static void Cmd_setsemiinvulnerablebit(void) { u32 semiInvulnerableEffect = GetMoveTwoTurnAttackStatus(gCurrentMove); if (cmd->clear) - gStatuses3[gBattlerAttacker] &= ~semiInvulnerableEffect; + gBattleMons[gBattlerAttacker].volatiles.semiInvulnerable = STATE_NONE; else - gStatuses3[gBattlerAttacker] |= semiInvulnerableEffect; + gBattleMons[gBattlerAttacker].volatiles.semiInvulnerable = semiInvulnerableEffect; } gBattlescriptCurrInstr = cmd->nextInstr; @@ -12618,7 +12626,7 @@ static void Cmd_trymemento(void) if (B_MEMENTO_FAIL >= GEN_4 && (gBattleCommunication[MISS_TYPE] == B_MSG_PROTECTED - || gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE + || IsSemiInvulnerable(gBattlerTarget, CHECK_ALL) || IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove) || DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))) { @@ -15094,7 +15102,7 @@ void BS_ItemCureStatus(void) if (GetItemStatus1Mask(gLastUsedItem) & STATUS1_SLEEP) gBattleMons[battler].volatiles.nightmare = FALSE; if (ItemHasVolatileFlag(gLastUsedItem, VOLATILE_CONFUSION)) - gStatuses4[battler] &= ~STATUS4_INFINITE_CONFUSION; + gBattleMons[battler].volatiles.infiniteConfusion = FALSE; } if (statusChanged) @@ -15234,15 +15242,6 @@ void BS_JumpIfElectricAbilityAffected(void) gBattlescriptCurrInstr = cmd->nextInstr; } -void BS_ApplySaltCure(void) -{ - NATIVE_ARGS(u8 battler); - - u8 battler = GetBattlerForBattleScript(cmd->battler); - gStatuses4[battler] |= STATUS4_SALT_CURE; - gBattlescriptCurrInstr = cmd->nextInstr; -} - void BS_SetTerrain(void) { NATIVE_ARGS(const u8 *jumpInstr); @@ -15362,7 +15361,7 @@ void BS_TrySetOctolock(void) void BS_SetGlaiveRush(void) { NATIVE_ARGS(); - gStatuses4[gBattlerAttacker] |= STATUS4_GLAIVE_RUSH; + gBattleMons[gBattlerAttacker].volatiles.glaiveRush = TRUE; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -15985,7 +15984,7 @@ void BS_TeatimeInvul(void) NATIVE_ARGS(u8 battler, const u8 *jumpInstr); u32 battler = GetBattlerForBattleScript(cmd->battler); - if (GetItemPocket(gBattleMons[battler].item) == POCKET_BERRIES && !(gStatuses3[gBattlerTarget] & (STATUS3_SEMI_INVULNERABLE))) + if (GetItemPocket(gBattleMons[battler].item) == POCKET_BERRIES && !IsSemiInvulnerable(gBattlerTarget, CHECK_ALL)) gBattlescriptCurrInstr = cmd->nextInstr; else gBattlescriptCurrInstr = cmd->jumpInstr; @@ -16107,7 +16106,7 @@ void BS_JumpIfCommanderActive(void) if (gBattleStruct->battlerState[gBattlerTarget].commanderSpecies != SPECIES_NONE) gBattlescriptCurrInstr = cmd->jumpInstr; - else if (gStatuses3[gBattlerTarget] & STATUS3_COMMANDER) + else if (gBattleMons[gBattlerTarget].volatiles.semiInvulnerable == STATE_COMMANDER) gBattlescriptCurrInstr = cmd->jumpInstr; else gBattlescriptCurrInstr = cmd->nextInstr; @@ -16887,10 +16886,11 @@ void BS_GravityOnAirborneMons(void) { NATIVE_ARGS(); // Cancel all multiturn moves of IN_AIR Pokemon except those being targeted by Sky Drop. - if (gStatuses3[gBattlerTarget] & STATUS3_ON_AIR && !(gStatuses3[gBattlerTarget] & STATUS3_SKY_DROPPED)) + if (gBattleMons[gBattlerTarget].volatiles.semiInvulnerable == STATE_ON_AIR) CancelMultiTurnMoves(gBattlerTarget, SKY_DROP_GRAVITY_ON_AIRBORNE); - gStatuses3[gBattlerTarget] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR | STATUS3_SKY_DROPPED); + gBattleMons[gBattlerTarget].volatiles.semiInvulnerable = STATE_NONE; + gStatuses3[gBattlerTarget] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS); gBattlescriptCurrInstr = cmd->nextInstr; } @@ -17460,7 +17460,7 @@ void BS_TryElectrify(void) } else { - gStatuses4[gBattlerTarget] |= STATUS4_ELECTRIFIED; + gBattleMons[gBattlerTarget].volatiles.electrified = TRUE; gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -17964,7 +17964,7 @@ void BS_JumpIfUnder200(void) void BS_SetSkyDrop(void) { NATIVE_ARGS(); - gStatuses3[gBattlerTarget] |= (STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + gBattleMons[gBattlerTarget].volatiles.semiInvulnerable = STATE_SKY_DROP; /* skyDropTargets holds the information of who is in a particular instance of Sky Drop. This is needed in the case that multiple Pokemon use Sky Drop in the same turn or if the target of a Sky Drop faints while in the air.*/ @@ -17998,7 +17998,7 @@ void BS_ClearSkyDrop(void) { gBattleStruct->skyDropTargets[gBattlerAttacker] = SKY_DROP_NO_TARGET; gBattleStruct->skyDropTargets[gBattlerTarget] = SKY_DROP_NO_TARGET; - gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + gBattleMons[gBattlerTarget].volatiles.semiInvulnerable = STATE_NONE; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -18010,7 +18010,7 @@ void BS_ClearSkyDrop(void) void BS_SkyDropYawn(void) { NATIVE_ARGS(); - if (gBattleStruct->skyDropTargets[gEffectBattler] != SKY_DROP_NO_TARGET && !(gStatuses3[gEffectBattler] & STATUS3_SKY_DROPPED)) + if (gBattleStruct->skyDropTargets[gEffectBattler] != SKY_DROP_NO_TARGET && gBattleMons[gEffectBattler].volatiles.semiInvulnerable != STATE_SKY_DROP) { // Set the target of Sky Drop as gEffectBattler gEffectBattler = gBattleStruct->skyDropTargets[gEffectBattler]; diff --git a/src/battle_util.c b/src/battle_util.c index caa4be0191..bc5eafc56f 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1047,7 +1047,7 @@ const u8 *CheckSkyDropState(u32 battler, enum SkyDropState skyDropState) const u8 *result = NULL; u8 otherSkyDropper = gBattleStruct->skyDropTargets[battler]; - gStatuses3[otherSkyDropper] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + gBattleMons[battler].volatiles.semiInvulnerable = STATE_NONE; // Makes both attacker and target's sprites visible gSprites[gBattlerSpriteIds[battler]].invisible = FALSE; @@ -1075,9 +1075,9 @@ const u8 *CheckSkyDropState(u32 battler, enum SkyDropState skyDropState) } else if (skyDropState == SKY_DROP_GRAVITY_ON_AIRBORNE) { - // Reapplying STATUS3_SKY_DROPPED allows for avoiding unecessary messages when Gravity is applied to the target. + // Reapplying STATE_SKY_DROPPED allows for avoiding unecessary messages when Gravity is applied to the target. gBattleStruct->skyDropTargets[battler] = SKY_DROP_RELEASED_TARGET; - gStatuses3[otherSkyDropper] |= STATUS3_SKY_DROPPED; + gBattleMons[otherSkyDropper].volatiles.semiInvulnerable = STATE_SKY_DROP; } else if (skyDropState == SKY_DROP_CANCEL_MULTI_TURN_MOVES) { @@ -1121,10 +1121,10 @@ const u8 *CancelMultiTurnMoves(u32 battler, enum SkyDropState skyDropState) } // Clear battler's semi-invulnerable bits if they are not held by Sky Drop. - if (!(gStatuses3[battler] & STATUS3_SKY_DROPPED)) - gStatuses3[battler] &= ~(STATUS3_SEMI_INVULNERABLE); + if (gBattleMons[battler].volatiles.semiInvulnerable != STATE_SKY_DROP) + gBattleMons[battler].volatiles.semiInvulnerable = STATE_NONE; - if (gBattleStruct->skyDropTargets[battler] != SKY_DROP_NO_TARGET && !(gStatuses3[battler] & STATUS3_SKY_DROPPED)) + if (gBattleStruct->skyDropTargets[battler] != SKY_DROP_NO_TARGET && gBattleMons[battler].volatiles.semiInvulnerable != STATE_SKY_DROP) result = CheckSkyDropState(battler, skyDropState); gDisableStructs[battler].rolloutTimer = 0; @@ -1893,7 +1893,7 @@ static enum MoveCanceller CancellerFlags(void) { gBattleMons[gBattlerAttacker].volatiles.destinyBond = FALSE; gStatuses3[gBattlerAttacker] &= ~STATUS3_GRUDGE; - gStatuses4[gBattlerAttacker] &= ~STATUS4_GLAIVE_RUSH; + gBattleMons[gBattlerAttacker].volatiles.glaiveRush = FALSE; return MOVE_STEP_SUCCESS; } @@ -1907,7 +1907,7 @@ static enum MoveCanceller CancellerStanceChangeOne(void) static enum MoveCanceller CancellerSkyDrop(void) { // If Pokemon is being held in Sky Drop - if (gStatuses3[gBattlerAttacker] & STATUS3_SKY_DROPPED) + if (gBattleMons[gBattlerAttacker].volatiles.semiInvulnerable == STATE_SKY_DROP) { gBattlescriptCurrInstr = BattleScript_MoveEnd; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; @@ -2157,7 +2157,7 @@ static enum MoveCanceller CancellerConfused(void) if (gBattleMons[gBattlerAttacker].volatiles.confusionTurns) { - if (!(gStatuses4[gBattlerAttacker] & STATUS4_INFINITE_CONFUSION)) + if (!gBattleMons[gBattlerAttacker].volatiles.infiniteConfusion) gBattleMons[gBattlerAttacker].volatiles.confusionTurns--; if (gBattleMons[gBattlerAttacker].volatiles.confusionTurns) { @@ -3577,7 +3577,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && !gBattleMons[diagonalBattler].volatiles.transformed && !gBattleMons[battler].volatiles.transformed && gBattleStruct->illusion[diagonalBattler].state != ILLUSION_ON - && !(gStatuses3[diagonalBattler] & STATUS3_SEMI_INVULNERABLE_NO_COMMANDER)) + && !IsSemiInvulnerable(diagonalBattler, EXCLUDE_COMMANDER)) { SaveBattlerAttacker(gBattlerAttacker); SaveBattlerTarget(gBattlerTarget); @@ -4169,9 +4169,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 gBattlerAttacker = partner; gBattleStruct->battlerState[battler].commandingDondozo = TRUE; gBattleStruct->battlerState[partner].commanderSpecies = gBattleMons[battler].species; - gStatuses3[battler] |= STATUS3_COMMANDER; - if (gBattleMons[battler].volatiles.confusionTurns > 0 - && !(gStatuses4[battler] & STATUS4_INFINITE_CONFUSION)) + gBattleMons[battler].volatiles.semiInvulnerable = STATE_COMMANDER; + if (gBattleMons[battler].volatiles.confusionTurns > 0 && !gBattleMons[battler].volatiles.infiniteConfusion) gBattleMons[battler].volatiles.confusionTurns--; BtlController_EmitSpriteInvisibility(battler, B_COMM_TO_CONTROLLER, TRUE); MarkBattlerForControllerExec(battler); @@ -4212,7 +4211,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITY_ICE_BODY: if (IsBattlerWeatherAffected(battler, B_WEATHER_HAIL | B_WEATHER_SNOW) && !IsBattlerAtMaxHp(battler) - && !(gStatuses3[battler] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) + && gBattleMons[battler].volatiles.semiInvulnerable != STATE_UNDERGROUND + && gBattleMons[battler].volatiles.semiInvulnerable != STATE_UNDERWATER && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)) { BattleScriptPushCursorAndCallback(BattleScript_IceBodyHeal); @@ -4985,7 +4985,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 break; case ABILITY_GULP_MISSILE: if ((gBattleMons[gBattlerAttacker].species == SPECIES_CRAMORANT) - && ((gCurrentMove == MOVE_SURF && IsBattlerTurnDamaged(gBattlerTarget)) || gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER) + && ((gCurrentMove == MOVE_SURF && IsBattlerTurnDamaged(gBattlerTarget)) || gBattleMons[gBattlerAttacker].volatiles.semiInvulnerable == STATE_UNDERWATER) && TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_HP_PERCENT)) { gBattleScripting.battler = gBattlerAttacker; @@ -5506,7 +5506,7 @@ bool32 CanBattlerEscape(u32 battler) // no ability check return FALSE; else if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK) return FALSE; - else if (gStatuses3[battler] & STATUS3_SKY_DROPPED) + else if (gBattleMons[battler].volatiles.semiInvulnerable == STATE_SKY_DROP) return FALSE; else return TRUE; @@ -5531,7 +5531,7 @@ bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag) { if (!(gFieldStatuses & terrainFlag)) return FALSE; - else if (gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE) + if (IsSemiInvulnerable(battler, CHECK_ALL)) return FALSE; return IsBattlerGrounded(battler); @@ -6066,7 +6066,7 @@ enum ItemEffect TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 item static enum ItemEffect ConsumeBerserkGene(u32 battler, enum ItemCaseId caseID) { if (CanBeInfinitelyConfused(battler)) - gStatuses4[battler] |= STATUS4_INFINITE_CONFUSION; + gBattleMons[battler].volatiles.infiniteConfusion = TRUE; BufferStatChange(battler, STAT_ATK, STRINGID_STATROSE); gBattlerAttacker = gEffectBattler = battler; @@ -7300,8 +7300,8 @@ void ClearVariousBattlerFlags(u32 battler) { gDisableStructs[battler].furyCutterCounter = 0; gBattleMons[battler].volatiles.destinyBond = FALSE; + gBattleMons[battler].volatiles.glaiveRush = FALSE; gStatuses3[battler] &= ~STATUS3_GRUDGE; - gStatuses4[battler] &= ~ STATUS4_GLAIVE_RUSH; } void HandleAction_RunBattleScript(void) // identical to RunBattleScriptCommands @@ -8286,7 +8286,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageContext *ctx) break; case EFFECT_MAGNITUDE: case EFFECT_EARTHQUAKE: - if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE)) + if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && !IsSemiInvulnerable(battlerDef, CHECK_ALL)) modifier = uq4_12_multiply(modifier, UQ_4_12(0.5)); break; case EFFECT_KNOCK_OFF: @@ -9077,7 +9077,7 @@ static inline uq4_12_t GetCriticalModifier(bool32 isCrit) static inline uq4_12_t GetGlaiveRushModifier(u32 battlerDef) { - if (gStatuses4[battlerDef] & STATUS4_GLAIVE_RUSH) + if (gBattleMons[battlerDef].volatiles.glaiveRush) return UQ_4_12(2.0); return UQ_4_12(1.0); } @@ -9102,21 +9102,21 @@ static inline uq4_12_t GetMinimizeModifier(u32 move, u32 battlerDef) static inline uq4_12_t GetUndergroundModifier(u32 move, u32 battlerDef) { - if (MoveDamagesUnderground(move) && gStatuses3[battlerDef] & STATUS3_UNDERGROUND) + if (MoveDamagesUnderground(move) && gBattleMons[battlerDef].volatiles.semiInvulnerable == STATE_UNDERGROUND) return UQ_4_12(2.0); return UQ_4_12(1.0); } static inline uq4_12_t GetDiveModifier(u32 move, u32 battlerDef) { - if (MoveDamagesUnderWater(move) && gStatuses3[battlerDef] & STATUS3_UNDERWATER) + if (MoveDamagesUnderWater(move) && gBattleMons[battlerDef].volatiles.semiInvulnerable == STATE_UNDERWATER) return UQ_4_12(2.0); return UQ_4_12(1.0); } static inline uq4_12_t GetAirborneModifier(u32 move, u32 battlerDef) { - if (MoveDamagesAirborneDoubleDamage(move) && gStatuses3[battlerDef] & STATUS3_ON_AIR) + if (MoveDamagesAirborneDoubleDamage(move) && gBattleMons[battlerDef].volatiles.semiInvulnerable == STATE_ON_AIR) return UQ_4_12(2.0); return UQ_4_12(1.0); } @@ -9934,7 +9934,7 @@ bool32 CanMegaEvolve(u32 battler) return FALSE; // Check if battler is currently held by Sky Drop. - if (gStatuses3[battler] & STATUS3_SKY_DROPPED) + if (gBattleMons[battler].volatiles.semiInvulnerable == STATE_SKY_DROP) return FALSE; // Check if battler is holding a Z-Crystal. @@ -9972,7 +9972,7 @@ bool32 CanUltraBurst(u32 battler) return FALSE; // Check if mon is currently held by Sky Drop - if (gStatuses3[battler] & STATUS3_SKY_DROPPED) + if (gBattleMons[battler].volatiles.semiInvulnerable == STATE_SKY_DROP) return FALSE; // Check if there is an entry in the form change table for Ultra Burst and battler is holding a Z-Crystal. @@ -10784,7 +10784,7 @@ bool32 BlocksPrankster(u16 move, u32 battlerPrankster, u32 battlerDef, bool32 ch return FALSE; if (!IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK)) return FALSE; - if (gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE) + if (IsSemiInvulnerable(battlerDef, CHECK_ALL)) return FALSE; return TRUE; @@ -10915,7 +10915,7 @@ void RecalcBattlerStats(u32 battler, struct Pokemon *mon, bool32 isDynamaxing) void RemoveConfusionStatus(u32 battler) { gBattleMons[battler].volatiles.confusionTurns = 0; - gStatuses4[battler] &= ~STATUS4_INFINITE_CONFUSION; + gBattleMons[battler].volatiles.infiniteConfusion = FALSE; } static bool32 CanBeInfinitelyConfused(u32 battler) @@ -11226,7 +11226,7 @@ bool32 TargetFullyImmuneToCurrMove(u32 battlerAtk, u32 battlerDef) u32 moveType = GetBattleMoveType(gCurrentMove); return ((CalcTypeEffectivenessMultiplierHelper(gCurrentMove, moveType, battlerAtk, battlerDef, GetBattlerAbility(battlerAtk), GetBattlerAbility(battlerDef), FALSE) == UQ_4_12(0.0)) || IsBattlerProtected(battlerAtk, battlerDef, gCurrentMove) - || IsSemiInvulnerable(battlerDef, gCurrentMove) + || !BreaksThroughSemiInvulnerablity(battlerDef, gCurrentMove) || DoesBattlerHaveAbilityImmunity(battlerAtk, battlerDef, moveType)); } @@ -11614,13 +11614,13 @@ bool32 CanMoveSkipAccuracyCalc(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u if ((gStatuses3[battlerDef] & STATUS3_ALWAYS_HITS && gDisableStructs[battlerDef].battlerWithSureHit == battlerAtk) || (B_TOXIC_NEVER_MISS >= GEN_6 && nonVolatileStatus == MOVE_EFFECT_TOXIC && IS_BATTLER_OF_TYPE(battlerAtk, TYPE_POISON)) - || gStatuses4[battlerDef] & STATUS4_GLAIVE_RUSH) + || gBattleMons[battlerDef].volatiles.glaiveRush) { effect = TRUE; } // If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits. else if (abilityAtk == ABILITY_NO_GUARD - && !(gStatuses3[battlerDef] & STATUS3_COMMANDER) + && gBattleMons[battlerDef].volatiles.semiInvulnerable != STATE_COMMANDER && (moveEffect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[battlerDef] == SKY_DROP_NO_TARGET)) { effect = TRUE; @@ -11635,7 +11635,7 @@ bool32 CanMoveSkipAccuracyCalc(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u } // If the target is under the effects of Telekinesis, and the move isn't a OH-KO move, move hits. else if (gStatuses3[battlerDef] & STATUS3_TELEKINESIS - && !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE) + && !IsSemiInvulnerable(battlerDef, CHECK_ALL) && moveEffect != EFFECT_OHKO && moveEffect != EFFECT_SHEER_COLD) { @@ -11645,15 +11645,11 @@ bool32 CanMoveSkipAccuracyCalc(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u { effect = TRUE; } - else if (GetActiveGimmick(battlerAtk) == GIMMICK_Z_MOVE && !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE)) + else if (GetActiveGimmick(battlerAtk) == GIMMICK_Z_MOVE && !IsSemiInvulnerable(battlerDef, CHECK_ALL)) { effect = TRUE; } - else if ((gStatuses3[battlerDef] & STATUS3_COMMANDER) - || (gStatuses3[battlerDef] & STATUS3_PHANTOM_FORCE) - || ((gStatuses3[battlerDef] & STATUS3_ON_AIR) && !(MoveDamagesAirborne(move) || MoveDamagesAirborneDoubleDamage(move))) - || ((gStatuses3[battlerDef] & STATUS3_UNDERGROUND) && !MoveDamagesUnderground(move)) - || ((gStatuses3[battlerDef] & STATUS3_UNDERWATER) && !MoveDamagesUnderWater(move))) + else if (!BreaksThroughSemiInvulnerablity(battlerDef, move)) { if (option == RUN_SCRIPT) { @@ -11813,3 +11809,32 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u return calc; } + +bool32 IsSemiInvulnerable(u32 battler, enum SemiInvulnerableExclusion excludeCommander) +{ + if (gBattleMons[battler].volatiles.semiInvulnerable == STATE_COMMANDER) + return excludeCommander != EXCLUDE_COMMANDER; + return gBattleMons[battler].volatiles.semiInvulnerable != STATE_NONE; +} + +bool32 BreaksThroughSemiInvulnerablity(u32 battler, u32 move) +{ + switch (gBattleMons[battler].volatiles.semiInvulnerable) + { + case STATE_UNDERGROUND: + return MoveDamagesUnderground(move); + case STATE_UNDERWATER: + return MoveDamagesUnderWater(move); + case STATE_ON_AIR: + case STATE_SKY_DROP: + return MoveDamagesAirborne(move) || MoveDamagesAirborneDoubleDamage(move); + case STATE_PHANTOM_FORCE: + return FALSE; + case STATE_COMMANDER: + return FALSE; + case STATE_NONE: + return TRUE; + } + + return FALSE; +} diff --git a/src/data/moves_info.h b/src/data/moves_info.h index 4edf88f17a..a4cff9c375 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -604,7 +604,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .assistBanned = TRUE, - .argument.twoTurnAttack = { .stringId = STRINGID_PKMNFLEWHIGH, .status = COMPRESS_BITS(STATUS3_ON_AIR) }, + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNFLEWHIGH, .status = STATE_ON_AIR }, .contestEffect = CONTEST_EFFECT_AVOID_STARTLE, .contestCategory = CONTEST_CATEGORY_SMART, .contestComboStarterId = 0, @@ -2461,7 +2461,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] = .instructBanned = TRUE, .assistBanned = TRUE, .skyBattleBanned = TRUE, - .argument.twoTurnAttack = { .stringId = STRINGID_PKMNDUGHOLE, .status = COMPRESS_BITS(STATUS3_UNDERGROUND) }, + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNDUGHOLE, .status = STATE_UNDERGROUND }, .contestEffect = CONTEST_EFFECT_AVOID_STARTLE, .contestCategory = CONTEST_CATEGORY_SMART, .contestComboStarterId = 0, @@ -7715,7 +7715,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] = .instructBanned = TRUE, .assistBanned = TRUE, .skyBattleBanned = TRUE, - .argument.twoTurnAttack = { .stringId = STRINGID_PKMNHIDUNDERWATER, .status = COMPRESS_BITS(STATUS3_UNDERWATER) }, + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNHIDUNDERWATER, .status = STATE_UNDERWATER }, .contestEffect = CONTEST_EFFECT_AVOID_STARTLE_ONCE, .contestCategory = CONTEST_CATEGORY_BEAUTY, .contestComboStarterId = COMBO_STARTER_DIVE, @@ -8974,7 +8974,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .assistBanned = TRUE, - .argument.twoTurnAttack = { .stringId = STRINGID_PKMNSPRANGUP, .status = COMPRESS_BITS(STATUS3_ON_AIR) }, + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNSPRANGUP, .status = STATE_ON_AIR }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_PARALYSIS, .chance = 30, @@ -12100,7 +12100,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .assistBanned = TRUE, - .argument.twoTurnAttack = { .stringId = STRINGID_VANISHEDINSTANTLY, .status = COMPRESS_BITS(STATUS3_PHANTOM_FORCE) }, + .argument.twoTurnAttack = { .stringId = STRINGID_VANISHEDINSTANTLY, .status = STATE_PHANTOM_FORCE }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_FEINT, }), @@ -13065,7 +13065,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .assistBanned = TRUE, - .argument.twoTurnAttack = { .stringId = STRINGID_PKMNTOOKTARGETHIGH, .status = COMPRESS_BITS(STATUS3_ON_AIR) }, + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNTOOKTARGETHIGH, .status = STATE_ON_AIR }, .contestEffect = CONTEST_EFFECT_AVOID_STARTLE, .contestCategory = CONTEST_CATEGORY_SMART, .contestComboStarterId = 0, @@ -14505,7 +14505,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .assistBanned = TRUE, - .argument.twoTurnAttack = { .stringId = STRINGID_VANISHEDINSTANTLY, .status = COMPRESS_BITS(STATUS3_PHANTOM_FORCE) }, + .argument.twoTurnAttack = { .stringId = STRINGID_VANISHEDINSTANTLY, .status = STATE_PHANTOM_FORCE }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_FEINT, }), diff --git a/src/item_use.c b/src/item_use.c index 328a258f2e..af1395f011 100644 --- a/src/item_use.c +++ b/src/item_use.c @@ -1110,7 +1110,7 @@ static u32 GetBallThrowableState(void) return BALL_THROW_UNABLE_TWO_MONS; else if (IsPlayerPartyAndPokemonStorageFull() == TRUE) return BALL_THROW_UNABLE_NO_ROOM; - else if (B_SEMI_INVULNERABLE_CATCH >= GEN_4 && (gStatuses3[GetCatchingBattler()] & STATUS3_SEMI_INVULNERABLE)) + else if (B_SEMI_INVULNERABLE_CATCH >= GEN_4 && IsSemiInvulnerable(GetCatchingBattler(), CHECK_ALL)) return BALL_THROW_UNABLE_SEMI_INVULNERABLE; else if (FlagGet(B_FLAG_NO_CATCHING)) return BALL_THROW_UNABLE_DISABLED_FLAG; diff --git a/test/battle/hold_effect/berserk_gene.c b/test/battle/hold_effect/berserk_gene.c index bbeb356701..5331f57849 100644 --- a/test/battle/hold_effect/berserk_gene.c +++ b/test/battle/hold_effect/berserk_gene.c @@ -213,7 +213,7 @@ SINGLE_BATTLE_TEST("Berserk Gene causes infinite confusion") // check if bit is TURN {} } SCENE { } THEN { - EXPECT(gStatuses4[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)] & STATUS4_INFINITE_CONFUSION); + EXPECT(gBattleMons[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)].volatiles.infiniteConfusion); } } diff --git a/test/battle/move_effect/semi_invulnerable.c b/test/battle/move_effect/semi_invulnerable.c index 331413121c..66086ca458 100644 --- a/test/battle/move_effect/semi_invulnerable.c +++ b/test/battle/move_effect/semi_invulnerable.c @@ -4,17 +4,17 @@ ASSUMPTIONS { ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE); - ASSUME(GetMoveTwoTurnAttackStatus(MOVE_FLY) == STATUS3_ON_AIR); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_FLY) == STATE_ON_AIR); ASSUME(GetMoveEffect(MOVE_DIG) == EFFECT_SEMI_INVULNERABLE); - ASSUME(GetMoveTwoTurnAttackStatus(MOVE_DIG) == STATUS3_UNDERGROUND); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_DIG) == STATE_UNDERGROUND); ASSUME(GetMoveEffect(MOVE_BOUNCE) == EFFECT_SEMI_INVULNERABLE); - ASSUME(GetMoveTwoTurnAttackStatus(MOVE_BOUNCE) == STATUS3_ON_AIR); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_BOUNCE) == STATE_ON_AIR); ASSUME(GetMoveEffect(MOVE_DIVE) == EFFECT_SEMI_INVULNERABLE); - ASSUME(GetMoveTwoTurnAttackStatus(MOVE_DIVE) == STATUS3_UNDERWATER); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_DIVE) == STATE_UNDERWATER); ASSUME(GetMoveEffect(MOVE_PHANTOM_FORCE) == EFFECT_SEMI_INVULNERABLE); - ASSUME(GetMoveTwoTurnAttackStatus(MOVE_PHANTOM_FORCE) == STATUS3_PHANTOM_FORCE); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_PHANTOM_FORCE) == STATE_PHANTOM_FORCE); ASSUME(GetMoveEffect(MOVE_SHADOW_FORCE) == EFFECT_SEMI_INVULNERABLE); - ASSUME(GetMoveTwoTurnAttackStatus(MOVE_SHADOW_FORCE) == STATUS3_PHANTOM_FORCE); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_SHADOW_FORCE) == STATE_PHANTOM_FORCE); } SINGLE_BATTLE_TEST("Semi-invulnerable moves make the user semi-invulnerable turn 1, then strike turn 2") diff --git a/test/battle/move_effects_combined/hurricane.c b/test/battle/move_effects_combined/hurricane.c index 91a3435cf4..96773ce585 100644 --- a/test/battle/move_effects_combined/hurricane.c +++ b/test/battle/move_effects_combined/hurricane.c @@ -41,9 +41,9 @@ SINGLE_BATTLE_TEST("Hurricane can hit airborne targets (Fly, Bounce)") PARAMETRIZE { move = MOVE_BOUNCE; } GIVEN { ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE); - ASSUME(GetMoveTwoTurnAttackStatus(MOVE_FLY) == STATUS3_ON_AIR); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_FLY) == STATE_ON_AIR); ASSUME(GetMoveEffect(MOVE_BOUNCE) == EFFECT_SEMI_INVULNERABLE); - ASSUME(GetMoveTwoTurnAttackStatus(MOVE_BOUNCE) == STATUS3_ON_AIR); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_BOUNCE) == STATE_ON_AIR); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Moves(move); } } WHEN { @@ -59,7 +59,7 @@ DOUBLE_BATTLE_TEST("Hurricane can hit airborne targets (Sky Drop)") { GIVEN { ASSUME(GetMoveEffect(MOVE_SKY_DROP) == EFFECT_SKY_DROP); - ASSUME(GetMoveTwoTurnAttackStatus(MOVE_SKY_DROP) == STATUS3_ON_AIR); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_SKY_DROP) == STATE_ON_AIR); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);