From f4c91b5539be83cb7d658bc8d77f475368a2ddc2 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Mon, 11 Aug 2025 23:19:36 +0200 Subject: [PATCH] Convert statuses3 to volatiles (#7514) --- asm/macros/battle_script.inc | 24 ++--- data/battle_scripts_1.s | 33 +++--- include/battle.h | 1 - include/battle_util.h | 2 +- include/constants/battle.h | 116 ++++++++++----------- src/battle_ai_field_statuses.c | 25 +++-- src/battle_ai_main.c | 90 +++++++++-------- src/battle_ai_switch_items.c | 16 +-- src/battle_ai_util.c | 45 +++++---- src/battle_anim_effects_1.c | 1 - src/battle_debug.c | 81 ++++----------- src/battle_end_turn.c | 59 +++++------ src/battle_main.c | 26 ++--- src/battle_script_commands.c | 179 ++++++++++++++------------------- src/battle_tv.c | 2 +- src/battle_util.c | 82 +++++++-------- src/item_use.c | 4 +- 17 files changed, 350 insertions(+), 436 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 9dd0479c92..2d70c5e722 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -187,12 +187,8 @@ .4byte \jumpInstr .endm - .macro jumpifstatus3condition battler:req, flags:req, jumpIfTrue:req, jumpInstr:req + .macro unused_0x21 .byte 0x21 - .byte \battler - .4byte \flags - .byte \jumpIfTrue - .4byte \jumpInstr .endm .macro jumpbasedontype battler:req, type:req, jumpIfType:req, jumpInstr:req @@ -738,9 +734,8 @@ .4byte \jumpInstr .endm - .macro setmiracleeye failInstr:req + .macro unused_0x83 .byte 0x83 - .4byte \failInstr .endm .macro jumpifuproarwakes jumpInstr:req @@ -1085,7 +1080,7 @@ tryfiretwoturnmovenowbyeffect \battler, FALSE, \jumpInstr .endm - .macro setminimize + .macro unused_0xC7 .byte 0xc7 .endm @@ -1191,9 +1186,10 @@ .4byte \failInstr .endm - .macro setuserstatus3 flags:req, failInstr:req + .macro trysetvolatile battler:req, _volatile:req, failInstr:req .byte 0xdd - .4byte \flags + .byte \battler + .byte \_volatile .4byte \failInstr .endm @@ -1884,14 +1880,6 @@ jumpifhalfword CMP_NOT_EQUAL, gChosenMove, \move, \jumpInstr .endm - .macro jumpifstatus3 battler:req, flags:req, jumpInstr:req - jumpifstatus3condition \battler, \flags, FALSE, \jumpInstr - .endm - - .macro jumpifnostatus3 battler:req, flags:req, jumpInstr:req - jumpifstatus3condition \battler, \flags, TRUE, \jumpInstr - .endm - .macro jumpifmovehadnoeffect jumpInstr:req jumpifmoveresultflags MOVE_RESULT_NO_EFFECT, \jumpInstr .endm diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 248d79714d..b7b4ec99cd 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -1182,7 +1182,7 @@ BattleScript_StrengthSapAnimation: @ Drain HP without lowering a stat BattleScript_StrengthSapHp: jumpifability BS_TARGET, ABILITY_LIQUID_OOZE, BattleScript_StrengthSapManipulateDmg - jumpifstatus3 BS_ATTACKER, STATUS3_HEAL_BLOCK, BattleScript_MoveEnd + jumpifvolatile BS_ATTACKER, VOLATILE_HEAL_BLOCK, BattleScript_MoveEnd jumpiffullhp BS_ATTACKER, BattleScript_MoveEnd BattleScript_StrengthSapManipulateDmg: manipulatedamage DMG_BIG_ROOT @@ -1240,7 +1240,7 @@ BattleScript_EffectLaserFocus:: attackcanceler attackstring ppreduce - setuserstatus3 STATUS3_LASER_FOCUS, BattleScript_ButItFailed + trysetvolatile BS_ATTACKER, VOLATILE_LASER_FOCUS, BattleScript_ButItFailed attackanimation waitanimation printstring STRINGID_LASERFOCUS @@ -2189,8 +2189,8 @@ BattleScript_EffectHealPulse:: attackcanceler attackstring ppreduce - jumpifstatus3 BS_ATTACKER, STATUS3_HEAL_BLOCK, BattleScript_MoveUsedHealBlockPrevents @ stops pollen puff - jumpifstatus3 BS_TARGET, STATUS3_HEAL_BLOCK, BattleScript_MoveUsedHealBlockPrevents + jumpifvolatile BS_ATTACKER, VOLATILE_HEAL_BLOCK, BattleScript_MoveUsedHealBlockPrevents @ stops pollen puff + jumpifvolatile BS_TARGET, VOLATILE_HEAL_BLOCK, BattleScript_MoveUsedHealBlockPrevents accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON jumpifsubstituteblocks BattleScript_ButItFailed tryhealpulse BattleScript_AlreadyAtFullHp @@ -2485,9 +2485,9 @@ BattleScript_EffectMagnetRise:: attackcanceler attackstring ppreduce - jumpifstatus3 BS_ATTACKER, STATUS3_ROOTED, BattleScript_ButItFailed - jumpifstatus3 BS_ATTACKER, STATUS3_SMACKED_DOWN, BattleScript_ButItFailed - setuserstatus3 STATUS3_MAGNET_RISE, BattleScript_ButItFailed + jumpifvolatile BS_ATTACKER, VOLATILE_ROOT, BattleScript_ButItFailed + jumpifvolatile BS_ATTACKER, VOLATILE_SMACK_DOWN, BattleScript_ButItFailed + trysetvolatile BS_ATTACKER, VOLATILE_MAGNET_RISE, BattleScript_ButItFailed attackanimation waitanimation printstring STRINGID_PKMNLEVITATEDONELECTROMAGNETISM @@ -2535,7 +2535,7 @@ BattleScript_EffectAquaRing:: attackcanceler attackstring ppreduce - setuserstatus3 STATUS3_AQUA_RING, BattleScript_ButItFailed + setvolatile BS_ATTACKER, VOLATILE_AQUA_RING attackanimation waitanimation printstring STRINGID_PKMNSURROUNDEDWITHVEILOFWATER @@ -2596,7 +2596,7 @@ BattleScript_EffectMiracleEye:: accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring ppreduce - setmiracleeye BattleScript_ButItFailed + setvolatile BS_TARGET, VOLATILE_MIRACLE_EYE goto BattleScript_IdentifiedFoe BattleScript_EffectGravity:: @@ -2614,7 +2614,8 @@ BattleScript_EffectGravitySuccess:: BattleScript_GravityLoop: movevaluescleanup jumpfifsemiinvulnerable BS_TARGET, STATE_ON_AIR, BattleScript_GravityLoopDrop - jumpifstatus3 BS_TARGET, STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS, BattleScript_GravityLoopDrop + jumpifvolatile BS_TARGET, VOLATILE_MAGNET_RISE, BattleScript_GravityLoopDrop + jumpifvolatile BS_TARGET, VOLATILE_TELEKINESIS, BattleScript_GravityLoopDrop goto BattleScript_GravityLoopEnd BattleScript_GravityLoopDrop: gravityonairbornemons @@ -2726,7 +2727,7 @@ BattleScript_EffectNaturalGift:: jumpifnotberry BS_ATTACKER, BattleScript_ButItFailed jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_MAGIC_ROOM, BattleScript_ButItFailed jumpifability BS_ATTACKER, ABILITY_KLUTZ, BattleScript_ButItFailed - jumpifstatus3 BS_ATTACKER, STATUS3_EMBARGO, BattleScript_ButItFailed + jumpifvolatile BS_ATTACKER, VOLATILE_EMBARGO, BattleScript_ButItFailed accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE call BattleScript_HitFromCritCalc @@ -3063,7 +3064,7 @@ BattleScript_EffectRoar:: jumpifcommanderactive BattleScript_ButItFailed jumpifability BS_TARGET, ABILITY_GUARD_DOG, BattleScript_ButItFailed jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut - jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted + jumpifvolatile BS_TARGET, VOLATILE_ROOT, BattleScript_PrintMonIsRooted jumpiftargetdynamaxed BattleScript_RoarBlockedByDynamax accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE @@ -3787,7 +3788,7 @@ BattleScript_NightmareWorked:: BattleScript_EffectMinimize:: attackcanceler - setminimize + setvolatile BS_ATTACKER, VOLATILE_MINIMIZE .if B_MINIMIZE_EVASION >= GEN_5 setstatchanger STAT_EVASION, 2, FALSE .else @@ -4697,7 +4698,7 @@ BattleScript_EffectIngrain:: attackcanceler attackstring ppreduce - setuserstatus3 STATUS3_ROOTED, BattleScript_ButItFailed + trysetvolatile BS_ATTACKER, VOLATILE_ROOT, BattleScript_ButItFailed attackanimation waitanimation printstring STRINGID_PKMNPLANTEDROOTS @@ -4846,7 +4847,7 @@ BattleScript_EffectGrudge:: attackcanceler attackstring ppreduce - setuserstatus3 STATUS3_GRUDGE, BattleScript_ButItFailed + trysetvolatile BS_ATTACKER, VOLATILE_GRUDGE, BattleScript_ButItFailed attackanimation waitanimation printstring STRINGID_PKMNWANTSGRUDGE @@ -9061,7 +9062,7 @@ BattleScript_RedCardActivates:: printstring STRINGID_REDCARDACTIVATE waitmessage B_WAIT_TIME_LONG swapattackerwithtarget - jumpifstatus3 BS_EFFECT_BATTLER, STATUS3_ROOTED, BattleScript_RedCardIngrain + jumpifvolatile BS_EFFECT_BATTLER, VOLATILE_ROOT, BattleScript_RedCardIngrain jumpifability BS_EFFECT_BATTLER, ABILITY_SUCTION_CUPS, BattleScript_RedCardSuctionCups jumpiftargetdynamaxed BattleScript_RedCardDynamaxed removeitem BS_SCRIPTING diff --git a/include/battle.h b/include/battle.h index 086eb68f51..e1cc318b25 100644 --- a/include/battle.h +++ b/include/battle.h @@ -1074,7 +1074,6 @@ extern u32 gHitMarker; 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 struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT]; extern u16 gPauseCounterBattle; extern u16 gPaydayMoney; diff --git a/include/battle_util.h b/include/battle_util.h index 8f38e0f572..0c486f4a3a 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -394,7 +394,7 @@ bool32 HadMoreThanHalfHpNowDoesnt(u32 battler); void UpdateStallMons(void); bool32 TryRestoreHPBerries(u32 battler, enum ItemCaseId caseId); bool32 TrySwitchInEjectPack(enum ItemCaseId caseID); -u32 GetMonVolatile(u32 battler, enum Volatile _volatile); +u32 GetBattlerVolatile(u32 battler, enum Volatile _volatile); void SetMonVolatile(u32 battler, enum Volatile _volatile, u32 newValue); u32 TryBoosterEnergy(u32 battler, u32 ability, enum ItemCaseId caseID); bool32 ItemHealMonVolatile(u32 battler, u16 itemId); diff --git a/include/constants/battle.h b/include/constants/battle.h index 148438237b..0f83eaecae 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -144,39 +144,59 @@ enum VolatileFlags /* Volatile status ailments * These are removed after exiting the battle or switching - * Enum, Type Type, max value, flags */ + * Enum, Type Type, max value, flags */ #define VOLATILE_DEFINITIONS(F) \ - F(VOLATILE_CONFUSION, confusionTurns, (u32, 6), V_BATON_PASSABLE) \ - F(VOLATILE_FLINCHED, flinched, (u32, 1)) \ - F(VOLATILE_UPROAR, uproarTurns, (u32, 5)) \ - F(VOLATILE_TORMENT, torment, (u32, 1)) \ - F(VOLATILE_BIDE, bideTurns, (u32, 3)) \ - F(VOLATILE_LOCK_CONFUSE, lockConfusionTurns, (u32, 3)) \ - F(VOLATILE_MULTIPLETURNS, multipleTurns, (u32, 1)) \ - F(VOLATILE_WRAPPED, wrapped, (u32, 1)) \ - F(VOLATILE_POWDER, powder, (u32, 1)) \ - F(VOLATILE_UNUSED, padding, (u32, 1)) \ - F(VOLATILE_INFATUATION, infatuation, (enum BattlerId, MAX_BITS(4))) \ - F(VOLATILE_DEFENSE_CURL, defenseCurl, (u32, 1)) \ - F(VOLATILE_TRANSFORMED, transformed, (u32, 1)) \ - F(VOLATILE_RECHARGE, recharge, (u32, 1)) \ - F(VOLATILE_RAGE, rage, (u32, 1)) \ - F(VOLATILE_SUBSTITUTE, substitute, (u32, 1), V_BATON_PASSABLE) \ - F(VOLATILE_DESTINY_BOND, destinyBond, (u32, 1)) \ - F(VOLATILE_ESCAPE_PREVENTION, escapePrevention, (u32, 1), V_BATON_PASSABLE) \ - F(VOLATILE_NIGHTMARE, nightmare, (u32, 1)) \ - F(VOLATILE_CURSED, cursed, (u32, 1), V_BATON_PASSABLE) \ - 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_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)) + F(VOLATILE_CONFUSION, confusionTurns, (u32, 6), V_BATON_PASSABLE) \ + F(VOLATILE_FLINCHED, flinched, (u32, 1)) \ + F(VOLATILE_UPROAR, uproarTurns, (u32, 5)) \ + F(VOLATILE_TORMENT, torment, (u32, 1)) \ + F(VOLATILE_BIDE, bideTurns, (u32, 3)) \ + F(VOLATILE_LOCK_CONFUSE, lockConfusionTurns, (u32, 3)) \ + F(VOLATILE_MULTIPLETURNS, multipleTurns, (u32, 1)) \ + F(VOLATILE_WRAPPED, wrapped, (u32, 1)) \ + F(VOLATILE_POWDER, powder, (u32, 1)) \ + F(VOLATILE_UNUSED, padding, (u32, 1)) \ + F(VOLATILE_INFATUATION, infatuation, (enum BattlerId, MAX_BITS(4))) \ + F(VOLATILE_DEFENSE_CURL, defenseCurl, (u32, 1)) \ + F(VOLATILE_TRANSFORMED, transformed, (u32, 1)) \ + F(VOLATILE_RECHARGE, recharge, (u32, 1)) \ + F(VOLATILE_RAGE, rage, (u32, 1)) \ + F(VOLATILE_SUBSTITUTE, substitute, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_DESTINY_BOND, destinyBond, (u32, 1)) \ + F(VOLATILE_ESCAPE_PREVENTION, escapePrevention, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_NIGHTMARE, nightmare, (u32, 1)) \ + F(VOLATILE_CURSED, cursed, (u32, 1), V_BATON_PASSABLE) \ + 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_INFINITE_CONFUSION, infiniteConfusion, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_SALT_CURE, saltCure, (u32, 1)) \ + F(VOLATILE_SYRUP_BOMB, syrupBomb, (u32, 1)) \ + F(VOLATILE_GLAIVE_RUSH, glaiveRush, (u32, 1)) \ + F(VOLATILE_LEECH_SEED, leechSeed, (enum BattlerId, MAX_BITS(4)), V_BATON_PASSABLE) \ + F(VOLATILE_LOCK_ON, lockOn, (u32, 2), V_BATON_PASSABLE) \ + F(VOLATILE_PERISH_SONG, perishSong, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_MINIMIZE, minimize, (u32, 1)) \ + F(VOLATILE_CHARGE, charge, (u32, 1)) \ + F(VOLATILE_ROOT, root, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_YAWN, yawn, (u32, 2)) \ + F(VOLATILE_IMPRISON, imprison, (u32, 1)) \ + F(VOLATILE_GRUDGE, grudge, (u32, 1)) \ + F(VOLATILE_GASTRO_ACID, gastroAcid, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_EMBARGO, embargo, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_SMACK_DOWN, smackDown, (u32, 1)) \ + F(VOLATILE_TELEKINESIS, telekinesis, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_MIRACLE_EYE, miracleEye, (u32, 1)) \ + F(VOLATILE_MAGNET_RISE, magnetRise, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_HEAL_BLOCK, healBlock, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_AQUA_RING, aquaRing, (u32, 1), V_BATON_PASSABLE) \ + F(VOLATILE_LASER_FOCUS, laserFocus, (u32, 1)) \ + F(VOLATILE_POWER_TRICK, powerTrick, (u32, 1), V_BATON_PASSABLE) + /* 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) @@ -193,37 +213,7 @@ enum Volatile // Helper macros #define INFATUATED_WITH(battler) (battler + 1) - -#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_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) -#define STATUS3_YAWN (1 << 11 | 1 << 12) // Number of turns to sleep -#define STATUS3_YAWN_TURN(num) (((num) << 11) & STATUS3_YAWN) -#define STATUS3_IMPRISONED_OTHERS (1 << 13) -#define STATUS3_GRUDGE (1 << 14) -#define STATUS3_UNUSED_15 (1 << 15) -#define STATUS3_GASTRO_ACID (1 << 16) -#define STATUS3_EMBARGO (1 << 17) -#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_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 LEECHSEEDED_BY(battler) (battler + 1) enum SemiInvulnerableState { diff --git a/src/battle_ai_field_statuses.c b/src/battle_ai_field_statuses.c index d85df3e74a..423910a0e5 100644 --- a/src/battle_ai_field_statuses.c +++ b/src/battle_ai_field_statuses.c @@ -227,9 +227,9 @@ static enum FieldEffectOutcome BenefitsFromSun(u32 battler) return FIELD_EFFECT_NEUTRAL; } - if (DoesAbilityBenefitFromWeather(ability, B_WEATHER_SUN) - || HasLightSensitiveMove(battler) - || HasDamagingMoveOfType(battler, TYPE_FIRE) + if (DoesAbilityBenefitFromWeather(ability, B_WEATHER_SUN) + || HasLightSensitiveMove(battler) + || HasDamagingMoveOfType(battler, TYPE_FIRE) || HasMoveWithEffect(battler, EFFECT_HYDRO_STEAM)) return FIELD_EFFECT_POSITIVE; @@ -248,8 +248,8 @@ static enum FieldEffectOutcome BenefitsFromSandstorm(u32 battler) if (gAiLogicData->holdEffects[battler] == HOLD_EFFECT_SAFETY_GOGGLES || IS_BATTLER_ANY_TYPE(battler, TYPE_ROCK, TYPE_GROUND, TYPE_STEEL)) { - if (!(IS_BATTLER_ANY_TYPE(FOE(battler), TYPE_ROCK, TYPE_GROUND, TYPE_STEEL)) - || gAiLogicData->holdEffects[FOE(battler)] == HOLD_EFFECT_SAFETY_GOGGLES + if (!(IS_BATTLER_ANY_TYPE(FOE(battler), TYPE_ROCK, TYPE_GROUND, TYPE_STEEL)) + || gAiLogicData->holdEffects[FOE(battler)] == HOLD_EFFECT_SAFETY_GOGGLES || DoesAbilityBenefitFromWeather(gAiLogicData->abilities[FOE(battler)], B_WEATHER_SANDSTORM)) return FIELD_EFFECT_POSITIVE; else @@ -285,7 +285,7 @@ static enum FieldEffectOutcome BenefitsFromRain(u32 battler) { if (gAiLogicData->holdEffects[battler] == HOLD_EFFECT_UTILITY_UMBRELLA) return FIELD_EFFECT_NEUTRAL; - + if (DoesAbilityBenefitFromWeather(gAiLogicData->abilities[battler], B_WEATHER_RAIN) || HasMoveWithFlag(battler, MoveAlwaysHitsInRain) || HasDamagingMoveOfType(battler, TYPE_WATER)) @@ -316,8 +316,8 @@ static enum FieldEffectOutcome BenefitsFromElectricTerrain(u32 battler) if (grounded && HasBattlerSideMoveWithAdditionalEffect(FOE(battler), MOVE_EFFECT_SLEEP)) return FIELD_EFFECT_POSITIVE; - if (grounded && ((gBattleMons[battler].status1 & STATUS1_SLEEP) - || (gStatuses3[battler] & STATUS3_YAWN) + if (grounded && ((gBattleMons[battler].status1 & STATUS1_SLEEP) + || gBattleMons[battler].volatiles.yawn || HasDamagingMoveOfType(battler, TYPE_ELECTRIC))) return FIELD_EFFECT_POSITIVE; @@ -382,8 +382,7 @@ static enum FieldEffectOutcome BenefitsFromMistyTerrain(u32 battler) && (HasNonVolatileMoveEffect(FOE(battler), MOVE_EFFECT_SLEEP) || HasNonVolatileMoveEffect(BATTLE_PARTNER(FOE(battler)), MOVE_EFFECT_SLEEP))) return FIELD_EFFECT_POSITIVE; - if (grounded && ((gBattleMons[battler].status1 & STATUS1_SLEEP) - || (gStatuses3[battler] & STATUS3_YAWN))) + if (grounded && (gBattleMons[battler].status1 & STATUS1_SLEEP || gBattleMons[battler].volatiles.yawn)) return FIELD_EFFECT_POSITIVE; return FIELD_EFFECT_NEUTRAL; @@ -407,7 +406,7 @@ static enum FieldEffectOutcome BenefitsFromPsychicTerrain(u32 battler) if (grounded || allyGrounded) { // harass priority - if (HasBattlerSideAbility(FOE(battler), ABILITY_GALE_WINGS, gAiLogicData) + if (HasBattlerSideAbility(FOE(battler), ABILITY_GALE_WINGS, gAiLogicData) || HasBattlerSideAbility(FOE(battler), ABILITY_TRIAGE, gAiLogicData) || HasBattlerSideAbility(FOE(battler), ABILITY_PRANKSTER, gAiLogicData)) return FIELD_EFFECT_POSITIVE; @@ -419,7 +418,7 @@ static enum FieldEffectOutcome BenefitsFromPsychicTerrain(u32 battler) if (HasBattlerSideMoveWithEffect(FOE(battler), EFFECT_EXPANDING_FORCE)) return FIELD_EFFECT_NEGATIVE; - if (HasBattlerSideAbility(battler, ABILITY_GALE_WINGS, gAiLogicData) + if (HasBattlerSideAbility(battler, ABILITY_GALE_WINGS, gAiLogicData) || HasBattlerSideAbility(battler, ABILITY_TRIAGE, gAiLogicData) || HasBattlerSideAbility(battler, ABILITY_PRANKSTER, gAiLogicData)) return FIELD_EFFECT_NEGATIVE; @@ -436,7 +435,7 @@ static enum FieldEffectOutcome BenefitsFromTrickRoom(u32 battler) return FIELD_EFFECT_POSITIVE; // If we tie, we shouldn't change trick room state. else if (GetBattlerSideSpeedAverage(battler) == GetBattlerSideSpeedAverage(FOE(battler))) - return FIELD_EFFECT_NEUTRAL; + return FIELD_EFFECT_NEUTRAL; else return FIELD_EFFECT_NEGATIVE; } diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 6d7f4ed09d..430412966b 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -1281,7 +1281,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (gDisableStructs[battlerAtk].throatChopTimer > gBattleTurnCounter && IsSoundMove(move)) return 0; // Can't even select move at all // heal block check - if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(battlerAtk, move)) + if (gBattleMons[battlerAtk].volatiles.healBlock && IsHealBlockPreventingMove(battlerAtk, move)) return 0; // Can't even select heal blocked move // primal weather check @@ -1432,7 +1432,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } break; case EFFECT_CHARGE: - if (gStatuses3[battlerAtk] & STATUS3_CHARGED_UP) + if (gBattleMons[battlerAtk].volatiles.charge) ADJUST_SCORE(-20); else if (!HasMoveWithType(battlerAtk, TYPE_ELECTRIC)) ADJUST_SCORE(-10); @@ -1761,7 +1761,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-8); break; case EFFECT_LEECH_SEED: - if (gStatuses3[battlerDef] & STATUS3_LEECHSEED + if (gBattleMons[battlerDef].volatiles.leechSeed || IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS) || DoesPartnerHaveSameMoveEffect(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove)) ADJUST_SCORE(-10); @@ -1891,9 +1891,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); //Don't wipe your team if you're going to lose } else if ((!IsBattlerAlive(FOE(battlerAtk)) || aiData->abilities[FOE(battlerAtk)] == ABILITY_SOUNDPROOF - || gStatuses3[FOE(battlerAtk)] & STATUS3_PERISH_SONG) + || gBattleMons[FOE(battlerAtk)].volatiles.perishSong) && (!IsBattlerAlive(BATTLE_PARTNER(FOE(battlerAtk))) || aiData->abilities[BATTLE_PARTNER(FOE(battlerAtk))] == ABILITY_SOUNDPROOF - || gStatuses3[BATTLE_PARTNER(FOE(battlerAtk))] & STATUS3_PERISH_SONG)) + || gBattleMons[BATTLE_PARTNER(FOE(battlerAtk))].volatiles.perishSong)) { ADJUST_SCORE(-10); //Both enemies are perish songed } @@ -1908,7 +1908,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) && CountUsablePartyMons(battlerDef) >= 1) ADJUST_SCORE(-10); - if (gStatuses3[FOE(battlerAtk)] & STATUS3_PERISH_SONG || aiData->abilities[FOE(battlerAtk)] == ABILITY_SOUNDPROOF) + if (gBattleMons[FOE(battlerAtk)].volatiles.perishSong || aiData->abilities[FOE(battlerAtk)] == ABILITY_SOUNDPROOF) ADJUST_SCORE(-10); } break; @@ -1954,8 +1954,11 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (CountUsablePartyMons(battlerAtk) == 0) ADJUST_SCORE(-10); else if (gBattleMons[battlerAtk].volatiles.substitute - || (gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_AQUA_RING | STATUS3_MAGNET_RISE | STATUS3_POWER_TRICK)) - || AnyStatIsRaised(battlerAtk)) + || gBattleMons[battlerAtk].volatiles.powerTrick + || gBattleMons[battlerAtk].volatiles.magnetRise + || gBattleMons[battlerAtk].volatiles.aquaRing + || gBattleMons[battlerAtk].volatiles.root + || AnyStatIsRaised(battlerAtk)) break; else ADJUST_SCORE(-6); @@ -2044,11 +2047,11 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); break; case EFFECT_INGRAIN: - if (gStatuses3[battlerAtk] & STATUS3_ROOTED) + if (gBattleMons[battlerAtk].volatiles.root) ADJUST_SCORE(-10); break; case EFFECT_AQUA_RING: - if (gStatuses3[battlerAtk] & STATUS3_AQUA_RING) + if (gBattleMons[battlerAtk].volatiles.aquaRing) ADJUST_SCORE(-10); break; case EFFECT_RECYCLE: @@ -2056,7 +2059,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); break; case EFFECT_IMPRISON: - if (gStatuses3[battlerAtk] & STATUS3_IMPRISONED_OTHERS) + if (gBattleMons[battlerAtk].volatiles.imprison) ADJUST_SCORE(-10); break; case EFFECT_REFRESH: @@ -2128,7 +2131,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); // don't scare away pokemon twice else if (aiData->hpPercents[battlerDef] < 10 && GetBattlerSecondaryDamage(battlerDef)) ADJUST_SCORE(-10); // don't blow away mon that will faint soon - else if (gStatuses3[battlerDef] & STATUS3_PERISH_SONG) + else if (gBattleMons[battlerDef].volatiles.perishSong) ADJUST_SCORE(-10); break; case EFFECT_CONVERSION: @@ -2200,14 +2203,14 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) //TODO break; case EFFECT_LOCK_ON: - if (gStatuses3[battlerDef] & STATUS3_ALWAYS_HITS + if (gBattleMons[battlerDef].volatiles.lockOn || aiData->abilities[battlerAtk] == ABILITY_NO_GUARD || aiData->abilities[battlerDef] == ABILITY_NO_GUARD || DoesPartnerHaveSameMoveEffect(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove)) ADJUST_SCORE(-10); break; case EFFECT_LASER_FOCUS: - if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS) + if (gBattleMons[battlerDef].volatiles.laserFocus) ADJUST_SCORE(-10); else if (aiData->abilities[battlerDef] == ABILITY_SHELL_ARMOR || aiData->abilities[battlerDef] == ABILITY_BATTLE_ARMOR) ADJUST_SCORE(-8); @@ -2312,7 +2315,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } break; case EFFECT_MIRACLE_EYE: - if (gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED) + if (gBattleMons[battlerDef].volatiles.miracleEye) ADJUST_SCORE(-10); if (gBattleMons[battlerDef].statStages[STAT_EVASION] <= 4 @@ -2431,7 +2434,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); break; case EFFECT_YAWN: - if (gStatuses3[battlerDef] & STATUS3_YAWN) + if (gBattleMons[battlerDef].volatiles.yawn) ADJUST_SCORE(-10); else if (!AI_CanPutToSleep(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, aiData->partnerMove)) ADJUST_SCORE(-10); @@ -2651,7 +2654,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_EMBARGO: if (!IsBattlerItemEnabled(battlerAtk) - || gStatuses3[battlerDef] & STATUS3_EMBARGO + || gBattleMons[battlerDef].volatiles.embargo || PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove)) ADJUST_SCORE(-10); break; @@ -2661,15 +2664,17 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); break; case EFFECT_TELEKINESIS: - if (gStatuses3[battlerDef] & (STATUS3_TELEKINESIS | STATUS3_ROOTED | STATUS3_SMACKED_DOWN) - || gFieldStatuses & STATUS_FIELD_GRAVITY - || aiData->holdEffects[battlerDef] == HOLD_EFFECT_IRON_BALL - || IsTelekinesisBannedSpecies(gBattleMons[battlerDef].species) - || PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove)) + if (gBattleMons[battlerDef].volatiles.telekinesis + || gBattleMons[battlerDef].volatiles.root + || gBattleMons[battlerDef].volatiles.smackDown + || gFieldStatuses & STATUS_FIELD_GRAVITY + || aiData->holdEffects[battlerDef] == HOLD_EFFECT_IRON_BALL + || IsTelekinesisBannedSpecies(gBattleMons[battlerDef].species) + || PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove)) ADJUST_SCORE(-10); break; case EFFECT_HEAL_BLOCK: - if (gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK + if (gBattleMons[battlerDef].volatiles.healBlock || PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove)) ADJUST_SCORE(-10); break; @@ -2698,7 +2703,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_HIT_ENEMY_HEAL_ALLY: // pollen puff if (IsTargetingPartner(battlerAtk, battlerDef)) { - if (gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK) + if (gBattleMons[battlerDef].volatiles.healBlock) return 0; // cannot even select if (AI_BattlerAtMaxHp(battlerDef)) ADJUST_SCORE(-10); @@ -2806,9 +2811,11 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_MAGNET_RISE: if (gFieldStatuses & STATUS_FIELD_GRAVITY - || gDisableStructs[battlerAtk].magnetRiseTimer > gBattleTurnCounter + || gDisableStructs[battlerAtk].magnetRiseTimer > gBattleTurnCounter || aiData->holdEffects[battlerAtk] == HOLD_EFFECT_IRON_BALL - || gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_MAGNET_RISE | STATUS3_SMACKED_DOWN) + || gBattleMons[battlerAtk].volatiles.smackDown + || gBattleMons[battlerAtk].volatiles.root + || gBattleMons[battlerAtk].volatiles.magnetRise || !IsBattlerGrounded(battlerAtk)) ADJUST_SCORE(-10); break; @@ -4205,7 +4212,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) case EFFECT_SHEER_COLD: if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX) break; - else if (gStatuses3[battlerAtk] & STATUS3_ALWAYS_HITS) + else if (gBattleMons[battlerAtk].volatiles.lockOn) ADJUST_SCORE(BEST_EFFECT); break; case EFFECT_MEAN_LOOK: @@ -4237,7 +4244,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) break; case EFFECT_LEECH_SEED: if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS) - || gStatuses3[battlerDef] & STATUS3_LEECHSEED + || gBattleMons[battlerDef].volatiles.leechSeed || HasMoveWithEffect(battlerDef, EFFECT_RAPID_SPIN) || aiData->abilities[battlerDef] == ABILITY_LIQUID_OOZE || aiData->abilities[battlerDef] == ABILITY_MAGIC_GUARD) @@ -4286,7 +4293,10 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) break; case EFFECT_BATON_PASS: if ((gAiLogicData->shouldSwitch & (1u << battlerAtk)) && (gBattleMons[battlerAtk].volatiles.substitute - || (gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_AQUA_RING | STATUS3_MAGNET_RISE | STATUS3_POWER_TRICK)) + || gBattleMons[battlerAtk].volatiles.powerTrick + || gBattleMons[battlerAtk].volatiles.magnetRise + || gBattleMons[battlerAtk].volatiles.aquaRing + || gBattleMons[battlerAtk].volatiles.root || AnyStatIsRaised(battlerAtk))) ADJUST_SCORE(BEST_EFFECT); break; @@ -4940,9 +4950,9 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_POWER_TRICK: - if (!(gStatuses3[battlerAtk] & STATUS3_POWER_TRICK) - && gBattleMons[battlerAtk].defense > gBattleMons[battlerAtk].attack - && HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_PHYSICAL)) + if (!gBattleMons[battlerAtk].volatiles.powerTrick + && gBattleMons[battlerAtk].defense > gBattleMons[battlerAtk].attack + && HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_PHYSICAL)) ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_HEART_SWAP: @@ -5016,7 +5026,7 @@ case EFFECT_GUARD_SPLIT: if (ShouldSetFieldStatus(battlerAtk, STATUS_FIELD_ELECTRIC_TERRAIN)) { ADJUST_SCORE(GOOD_EFFECT); - if (gStatuses3[battlerAtk] & STATUS3_YAWN && IsBattlerGrounded(battlerAtk)) + if (gBattleMons[battlerAtk].volatiles.yawn && IsBattlerGrounded(battlerAtk)) ADJUST_SCORE(BEST_EFFECT); if (aiData->holdEffects[battlerAtk] == HOLD_EFFECT_TERRAIN_EXTENDER || HasBattlerSideMoveWithEffect(battlerAtk, EFFECT_TERRAIN_PULSE)) ADJUST_SCORE(WEAK_EFFECT); @@ -5026,7 +5036,7 @@ case EFFECT_GUARD_SPLIT: if (ShouldSetFieldStatus(battlerAtk, STATUS_FIELD_MISTY_TERRAIN)) { ADJUST_SCORE(GOOD_EFFECT); - if (gStatuses3[battlerAtk] & STATUS3_YAWN && IsBattlerGrounded(battlerAtk)) + if (gBattleMons[battlerAtk].volatiles.yawn && IsBattlerGrounded(battlerAtk)) ADJUST_SCORE(BEST_EFFECT); if (aiData->holdEffects[battlerAtk] == HOLD_EFFECT_TERRAIN_EXTENDER || HasBattlerSideMoveWithEffect(battlerAtk, EFFECT_TERRAIN_PULSE)) ADJUST_SCORE(WEAK_EFFECT); @@ -5266,7 +5276,7 @@ case EFFECT_GUARD_SPLIT: break; case EFFECT_RAPID_SPIN: if ((AreAnyHazardsOnSide(GetBattlerSide(battlerAtk)) && CountUsablePartyMons(battlerAtk) != 0) - || (gStatuses3[battlerAtk] & STATUS3_LEECHSEED || gBattleMons[battlerAtk].volatiles.wrapped)) + || (gBattleMons[battlerAtk].volatiles.leechSeed || gBattleMons[battlerAtk].volatiles.wrapped)) ADJUST_SCORE(GOOD_EFFECT); break; case EFFECT_SPECTRAL_THIEF: @@ -5806,11 +5816,11 @@ static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u32 move, s32 scor switch (effect) { case EFFECT_INGRAIN: - if (!(gStatuses3[battlerAtk] & STATUS3_ROOTED)) + if (!gBattleMons[battlerAtk].volatiles.root) ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_AQUA_RING: - if (!(gStatuses3[battlerAtk] & STATUS3_AQUA_RING)) + if (!gBattleMons[battlerAtk].volatiles.aquaRing) ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_PROTECT: @@ -5820,9 +5830,9 @@ static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u32 move, s32 scor ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_BATON_PASS: - if (gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_AQUA_RING)) + if (gBattleMons[battlerAtk].volatiles.root || gBattleMons[battlerAtk].volatiles.aquaRing) ADJUST_SCORE(DECENT_EFFECT); - if (gStatuses3[battlerAtk] & STATUS3_LEECHSEED) + if (gBattleMons[battlerAtk].volatiles.leechSeed) ADJUST_SCORE(-3); ADJUST_SCORE(CountPositiveStatStages(battlerAtk) - CountNegativeStatStages(battlerAtk)); break; @@ -5848,7 +5858,7 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) || (moveType == TYPE_GROUND && gAiLogicData->abilities[BATTLE_PARTNER(battlerAtk)] == ABILITY_EARTH_EATER) || (moveType == TYPE_WATER && (gAiLogicData->abilities[BATTLE_PARTNER(battlerAtk)] == ABILITY_DRY_SKIN || gAiLogicData->abilities[BATTLE_PARTNER(battlerAtk)] == ABILITY_WATER_ABSORB))) { - if (gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK) + if (gBattleMons[battlerDef].volatiles.healBlock) return 0; if (CanTargetFaintAi(FOE(battlerAtk), BATTLE_PARTNER(battlerAtk)) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 6f470d3c84..c11f448645 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -675,7 +675,7 @@ static bool32 ShouldSwitchIfBadlyStatused(u32 battler) bool32 hasStatRaised = AnyStatIsRaised(battler); //Perish Song - if (gStatuses3[battler] & STATUS3_PERISH_SONG + if (gBattleMons[battler].volatiles.perishSong && gDisableStructs[battler].perishSongTimer == 0 && monAbility != ABILITY_SOUNDPROOF && RandomPercentage(RNG_AI_SWITCH_PERISH_SONG, GetSwitchChance(SHOULD_SWITCH_PERISH_SONG))) @@ -684,7 +684,7 @@ static bool32 ShouldSwitchIfBadlyStatused(u32 battler) if (gAiThinkingStruct->aiFlags[battler] & AI_FLAG_SMART_SWITCHING) { //Yawn - if (gStatuses3[battler] & STATUS3_YAWN + if (gBattleMons[battler].volatiles.yawn && CanBeSlept(battler, battler, monAbility, BLOCKED_BY_SLEEP_CLAUSE) // TODO: ask for help from pawwkie && gBattleMons[battler].hp > gBattleMons[battler].maxHP / 3 && RandomPercentage(RNG_AI_SWITCH_YAWN, GetSwitchChance(SHOULD_SWITCH_YAWN))) @@ -719,7 +719,7 @@ static bool32 ShouldSwitchIfBadlyStatused(u32 battler) && gAiLogicData->abilities[opposingBattler] != ABILITY_MINDS_EYE && (GetGenConfig(GEN_ILLUMINATE_EFFECT) >= GEN_9 && gAiLogicData->abilities[opposingBattler] != ABILITY_ILLUMINATE) && !gBattleMons[battler].volatiles.foresight - && !(gStatuses3[battler] & STATUS3_MIRACLE_EYED)) + && !gBattleMons[battler].volatiles.miracleEye) switchMon = FALSE; if (switchMon) @@ -749,7 +749,7 @@ static bool32 ShouldSwitchIfBadlyStatused(u32 battler) return SetSwitchinAndSwitch(battler, PARTY_SIZE); //Leech Seed - if (gStatuses3[battler] & STATUS3_LEECHSEED + if (gBattleMons[battler].volatiles.leechSeed && (hasStatRaised ? RandomPercentage(RNG_AI_SWITCH_SEEDED, GetSwitchChance(SHOULD_SWITCH_SEEDED_STATS_RAISED)) : RandomPercentage(RNG_AI_SWITCH_SEEDED, GetSwitchChance(SHOULD_SWITCH_SEEDED)))) return SetSwitchinAndSwitch(battler, PARTY_SIZE); } @@ -770,7 +770,7 @@ static bool32 ShouldSwitchIfAbilityBenefit(u32 battler) bool32 hasStatRaised = AnyStatIsRaised(battler); //Check if ability is blocked - if (gStatuses3[battler] & STATUS3_GASTRO_ACID + if (gBattleMons[battler].volatiles.gastroAcid || IsNeutralizingGasOnField()) return FALSE; @@ -1109,7 +1109,7 @@ bool32 ShouldSwitch(u32 battler) return FALSE; if (gBattleMons[battler].volatiles.escapePrevention) return FALSE; - if (gStatuses3[battler] & STATUS3_ROOTED) + if (gBattleMons[battler].volatiles.root) return FALSE; if (IsAbilityPreventingEscape(battler)) return FALSE; @@ -1260,7 +1260,7 @@ void ModifySwitchAfterMoveScoring(u32 battler) return; if (gBattleMons[battler].volatiles.escapePrevention) return; - if (gStatuses3[battler] & STATUS3_ROOTED) + if (gBattleMons[battler].volatiles.root) return; if (IsAbilityPreventingEscape(battler)) return; @@ -2425,7 +2425,7 @@ static bool32 ShouldUseItem(u32 battler) || gBattleMons[battler].volatiles.semiInvulnerable == STATE_SKY_DROP) return FALSE; - if (gStatuses3[battler] & STATUS3_EMBARGO) + if (gBattleMons[battler].volatiles.embargo) return FALSE; if (AiExpectsToFaintPlayer(battler)) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index e044f7b3e9..8fe1067a19 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -467,7 +467,7 @@ bool32 IsBattlerTrapped(u32 battlerAtk, u32 battlerDef) return TRUE; if (gBattleMons[battlerDef].volatiles.semiInvulnerable == STATE_SKY_DROP) return TRUE; - if (gStatuses3[battlerDef] & STATUS3_ROOTED) + if (gBattleMons[battlerDef].volatiles.root) return TRUE; if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK) return TRUE; @@ -1632,11 +1632,11 @@ enum ItemHoldEffect AI_DecideHoldEffectForTurn(u32 battlerId) if (gAiThinkingStruct->aiFlags[battlerId] & AI_FLAG_NEGATE_UNAWARE) return holdEffect; - if (gStatuses3[battlerId] & STATUS3_EMBARGO) + if (gBattleMons[battlerId].volatiles.embargo) return HOLD_EFFECT_NONE; if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM) return HOLD_EFFECT_NONE; - if (gAiLogicData->abilities[battlerId] == ABILITY_KLUTZ && !(gStatuses3[battlerId] & STATUS3_GASTRO_ACID)) + if (gAiLogicData->abilities[battlerId] == ABILITY_KLUTZ && !gBattleMons[battlerId].volatiles.gastroAcid) return HOLD_EFFECT_NONE; return holdEffect; @@ -1890,7 +1890,7 @@ bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbil if (!DoesBattlerIgnoreAbilityChecks(battlerAtk, atkAbility, move) && defAbility == ABILITY_STURDY) return FALSE; - if ((((gStatuses3[battlerDef] & STATUS3_ALWAYS_HITS) + if (((gBattleMons[battlerDef].volatiles.lockOn && gDisableStructs[battlerDef].battlerWithSureHit == battlerAtk) || atkAbility == ABILITY_NO_GUARD || defAbility == ABILITY_NO_GUARD) && gBattleMons[battlerAtk].level >= gBattleMons[battlerDef].level) @@ -1935,7 +1935,8 @@ bool32 IsBattlerDamagedByStatus(u32 battler) || gBattleMons[battler].volatiles.nightmare || gBattleMons[battler].volatiles.cursed || gBattleMons[battler].volatiles.saltCure - || gStatuses3[battler] & (STATUS3_PERISH_SONG | STATUS3_LEECHSEED) + || gBattleMons[battler].volatiles.leechSeed + || gBattleMons[battler].volatiles.perishSong || gSideStatuses[GetBattlerSide(battler)] & (SIDE_STATUS_SEA_OF_FIRE | SIDE_STATUS_DAMAGE_NON_TYPES); } @@ -2087,9 +2088,9 @@ u32 IncreaseStatDownScore(u32 battlerAtk, u32 battlerDef, u32 stat) case STAT_ACC: if (gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY) tempScore += WEAK_EFFECT; - if (gStatuses3[battlerDef] & STATUS3_LEECHSEED) + if (gBattleMons[battlerDef].volatiles.leechSeed) tempScore += WEAK_EFFECT; - if (gStatuses3[battlerDef] & STATUS3_ROOTED) + if (gBattleMons[battlerDef].volatiles.root) tempScore += WEAK_EFFECT; if (gBattleMons[battlerDef].volatiles.cursed) tempScore += WEAK_EFFECT; @@ -2097,9 +2098,9 @@ u32 IncreaseStatDownScore(u32 battlerAtk, u32 battlerDef, u32 stat) case STAT_EVASION: if (gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY) tempScore += WEAK_EFFECT; - if (gStatuses3[battlerDef] & STATUS3_LEECHSEED) + if (gBattleMons[battlerDef].volatiles.leechSeed) tempScore += WEAK_EFFECT; - if (gStatuses3[battlerDef] & STATUS3_ROOTED) + if (gBattleMons[battlerDef].volatiles.root) tempScore += WEAK_EFFECT; if (gBattleMons[battlerDef].volatiles.cursed) tempScore += WEAK_EFFECT; @@ -2864,13 +2865,13 @@ bool32 IsTwoTurnNotSemiInvulnerableMove(u32 battlerAtk, u32 move) } } -static u32 GetLeechSeedDamage(u32 battlerId) +static u32 GetLeechSeedDamage(u32 battler) { u32 damage = 0; - if ((gStatuses3[battlerId] & STATUS3_LEECHSEED) - && gBattleMons[gStatuses3[battlerId] & STATUS3_LEECHSEED_BATTLER].hp != 0) + u32 leechSeeder = gBattleMons[battler].volatiles.leechSeed; + if (leechSeeder && gBattleMons[leechSeeder - 1].hp != 0) { - damage = GetNonDynamaxMaxHP(battlerId) / 8; + damage = GetNonDynamaxMaxHP(battler) / 8; if (damage == 0) damage = 1; } @@ -3714,7 +3715,7 @@ bool32 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, u32 move, s32 damage) // using item or user goes first s32 healDmg = (GetMoveAbsorbPercentage(move) * damage) / 100; - if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK) + if (gBattleMons[battlerAtk].volatiles.healBlock) healDmg = 0; if (CanTargetFaintAi(battlerDef, battlerAtk) @@ -3739,7 +3740,7 @@ bool32 ShouldRecover(u32 battlerAtk, u32 battlerDef, u32 move, u32 healPercent) u32 healAmount = (healPercent * maxHP) / 100; if (healAmount > maxHP) healAmount = maxHP; - if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK) + if (gBattleMons[battlerAtk].volatiles.healBlock) healAmount = 0; if (AI_IsFaster(battlerAtk, battlerDef, move, GetIncomingMove(battlerAtk, battlerDef, gAiLogicData), CONSIDER_PRIORITY)) { @@ -3800,7 +3801,7 @@ bool32 ShouldSetScreen(u32 battlerAtk, u32 battlerDef, enum BattleMoveEffects mo bool32 IsBattle1v1() { if (IsDoubleBattle() - && ((IsBattlerAlive(B_POSITION_PLAYER_LEFT) && IsBattlerAlive(B_POSITION_PLAYER_RIGHT)) + && ((IsBattlerAlive(B_POSITION_PLAYER_LEFT) && IsBattlerAlive(B_POSITION_PLAYER_RIGHT)) || (IsBattlerAlive(B_POSITION_OPPONENT_LEFT) && IsBattlerAlive(B_POSITION_OPPONENT_RIGHT)))) return FALSE; return TRUE; @@ -5154,9 +5155,9 @@ void IncreaseTidyUpScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) if (gBattleMons[battlerDef].volatiles.substitute) ADJUST_SCORE_PTR(GOOD_EFFECT); - if (gStatuses3[battlerAtk] & STATUS3_LEECHSEED) + if (gBattleMons[battlerAtk].volatiles.leechSeed) ADJUST_SCORE_PTR(DECENT_EFFECT); - if (gStatuses3[battlerDef] & STATUS3_LEECHSEED) + if (gBattleMons[battlerDef].volatiles.leechSeed) ADJUST_SCORE_PTR(-2); } @@ -5209,7 +5210,7 @@ u32 IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, u32 move) scoreIncrease += BEST_EFFECT; } - if (gStatuses3[battlerDef] & STATUS3_PERISH_SONG) + if (gBattleMons[battlerDef].volatiles.perishSong) scoreIncrease += GOOD_EFFECT; if (gBattleMons[battlerDef].status1 & STATUS1_SLEEP) @@ -5250,9 +5251,9 @@ bool32 IsBattlerItemEnabled(u32 battler) return TRUE; if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM) return FALSE; - if (gStatuses3[battler] & STATUS3_EMBARGO) + if (gBattleMons[battler].volatiles.embargo) return FALSE; - if (gBattleMons[battler].ability == ABILITY_KLUTZ && !(gStatuses3[battler] & STATUS3_GASTRO_ACID)) + if (gBattleMons[battler].ability == ABILITY_KLUTZ && !gBattleMons[battler].volatiles.gastroAcid) return FALSE; return TRUE; } @@ -5393,7 +5394,7 @@ bool32 CanEffectChangeAbility(u32 battlerAtk, u32 battlerDef, u32 effect, struct } } - if (gStatuses3[battlerDef] & STATUS3_GASTRO_ACID) + if (gBattleMons[battlerDef].volatiles.gastroAcid) return FALSE; u32 atkAbility = aiData->abilities[battlerAtk]; diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index 12bd7859b9..e49c9f2003 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -6906,7 +6906,6 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId) SWAP(gBattleSpritesDataPtr->battlerData[battlerAtk].invisible, gBattleSpritesDataPtr->battlerData[battlerPartner].invisible, temp); SWAP(gTransformedPersonalities[battlerAtk], gTransformedPersonalities[battlerPartner], temp); SWAP(gTransformedShininess[battlerAtk], gTransformedShininess[battlerPartner], temp); - SWAP(gStatuses3[battlerAtk], gStatuses3[battlerPartner], temp); SwapBattlerMoveData(battlerAtk, battlerPartner); diff --git a/src/battle_debug.c b/src/battle_debug.c index a991ac341a..149cb4065c 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -105,7 +105,6 @@ enum LIST_ITEM_STAT_STAGES, LIST_ITEM_STATUS1, LIST_ITEM_VOLATILE, - LIST_ITEM_STATUS3, LIST_ITEM_HAZARDS, LIST_ITEM_SIDE_STATUS, LIST_ITEM_AI, @@ -140,30 +139,6 @@ enum LIST_STATUS1_FROSTBITE, }; -enum -{ - LIST_STATUS3_LEECH_SEED_HEALER, - LIST_STATUS3_LEECH_SEEDED, - LIST_STATUS3_ALWAYS_HITS, - LIST_STATUS3_PERISH_SONG, - LIST_STATUS3_MINIMIZED, - LIST_STATUS3_CHARGED_UP, - LIST_STATUS3_ROOTED, - LIST_STATUS3_YAWN, - LIST_STATUS3_IMPRISONED_OTHERS, - LIST_STATUS3_GRUDGE, - LIST_STATUS3_GASTRO_ACID, - LIST_STATUS3_EMBARGO, - LIST_STATUS3_SMACKED_DOWN, - LIST_STATUS3_TELEKINESIS, - LIST_STATUS3_MIRACLE_EYED, - LIST_STATUS3_MAGNET_RISE, - LIST_STATUS3_HEAL_BLOCK, - LIST_STATUS3_AQUA_RING, - LIST_STATUS3_LASER_FOCUS, - LIST_STATUS3_POWER_TRICK, -}; - enum { LIST_SIDE_STICKY_WEB, @@ -346,7 +321,6 @@ static const struct ListMenuItem sMainListItems[] = {COMPOUND_STRING("Stat Stages"), LIST_ITEM_STAT_STAGES}, {COMPOUND_STRING("Status1"), LIST_ITEM_STATUS1}, {COMPOUND_STRING("Volatiles"), LIST_ITEM_VOLATILE}, - {COMPOUND_STRING("Status3"), LIST_ITEM_STATUS3}, {COMPOUND_STRING("Hazards"), LIST_ITEM_HAZARDS}, {COMPOUND_STRING("Side Status"), LIST_ITEM_SIDE_STATUS}, {COMPOUND_STRING("AI"), LIST_ITEM_AI}, @@ -402,30 +376,25 @@ static const struct ListMenuItem sVolatileStatusListItems[] = {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[] = -{ - {COMPOUND_STRING("Leech Seed Healer"), LIST_STATUS3_LEECH_SEED_HEALER}, - {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("Minimized"), LIST_STATUS3_MINIMIZED}, - {COMPOUND_STRING("Charged Up"), LIST_STATUS3_CHARGED_UP}, - {COMPOUND_STRING("Rooted"), LIST_STATUS3_ROOTED}, - {COMPOUND_STRING("Yawn"), LIST_STATUS3_YAWN}, - {COMPOUND_STRING("Imprisoned Others"), LIST_STATUS3_IMPRISONED_OTHERS}, - {COMPOUND_STRING("Grudge"), LIST_STATUS3_GRUDGE}, - {COMPOUND_STRING("Gastro Acid"), LIST_STATUS3_GASTRO_ACID}, - {COMPOUND_STRING("Embargo"), LIST_STATUS3_EMBARGO}, - {COMPOUND_STRING("Smacked Down"), LIST_STATUS3_SMACKED_DOWN}, - {COMPOUND_STRING("Telekinesis"), LIST_STATUS3_TELEKINESIS}, - {COMPOUND_STRING("Miracle Eyed"), LIST_STATUS3_MIRACLE_EYED}, - {COMPOUND_STRING("Magnet Rise"), LIST_STATUS3_MAGNET_RISE}, - {COMPOUND_STRING("Heal Block"), LIST_STATUS3_HEAL_BLOCK}, - {COMPOUND_STRING("Aqua Ring"), LIST_STATUS3_AQUA_RING}, - {COMPOUND_STRING("Laser Focus"), LIST_STATUS3_LASER_FOCUS}, - {COMPOUND_STRING("Power Trick"), LIST_STATUS3_POWER_TRICK}, + {COMPOUND_STRING("Leech Seed"), VOLATILE_LEECH_SEED}, + {COMPOUND_STRING("Lock On"), VOLATILE_LOCK_ON}, + {COMPOUND_STRING("Perish Song"), VOLATILE_PERISH_SONG}, + {COMPOUND_STRING("Minimize"), VOLATILE_MINIMIZE}, + {COMPOUND_STRING("Charge"), VOLATILE_CHARGE}, + {COMPOUND_STRING("Root"), VOLATILE_ROOT}, + {COMPOUND_STRING("Yawn"), VOLATILE_YAWN}, + {COMPOUND_STRING("Imprison"), VOLATILE_IMPRISON}, + {COMPOUND_STRING("Grudge"), VOLATILE_GRUDGE}, + {COMPOUND_STRING("Gastro Acid"), VOLATILE_GASTRO_ACID}, + {COMPOUND_STRING("Embargo"), VOLATILE_EMBARGO}, + {COMPOUND_STRING("Smack Down"), VOLATILE_SMACK_DOWN}, + {COMPOUND_STRING("Telekinesis"), VOLATILE_TELEKINESIS}, + {COMPOUND_STRING("Miracle Eye"), VOLATILE_MIRACLE_EYE}, + {COMPOUND_STRING("Magnet Rise"), VOLATILE_MAGNET_RISE}, + {COMPOUND_STRING("Heal Block"), VOLATILE_HEAL_BLOCK}, + {COMPOUND_STRING("Aqua Ring"), VOLATILE_AQUA_RING}, + {COMPOUND_STRING("Laser Focus"), VOLATILE_LASER_FOCUS}, + {COMPOUND_STRING("Power Trick"), VOLATILE_POWER_TRICK}, }; static const struct ListMenuItem sHazardsListItems[] = @@ -1403,11 +1372,6 @@ static void CreateSecondaryListMenu(struct BattleDebugMenu *data) listTemplate.items = sVolatileStatusListItems; itemsCount = ARRAY_COUNT(sVolatileStatusListItems); break; - case LIST_ITEM_STATUS3: - listTemplate.items = sStatus3ListItems; - itemsCount = ARRAY_COUNT(sStatus3ListItems); - data->bitfield = sStatus3Bitfield; - break; case LIST_ITEM_AI: listTemplate.items = sAIListItems; itemsCount = ARRAY_COUNT(sAIListItems); @@ -2024,7 +1988,7 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data) data->modifyArrows.typeOfVal = VAL_BITFIELD_32; goto CASE_ITEM_STATUS; case LIST_ITEM_VOLATILE: - data->modifyArrows.currValue = GetMonVolatile(data->battlerId, data->currentSecondaryListItemId); + data->modifyArrows.currValue = GetBattlerVolatile(data->battlerId, data->currentSecondaryListItemId); data->modifyArrows.typeOfVal = VAL_VOLATILE; data->modifyArrows.minValue = 0; #define UNPACK_VOLATILE_MAX_SIZE(_enum, _fieldName, _typeMaxValue, ...) case _enum: data->modifyArrows.maxValue = min(MAX_u16, GET_VOLATILE_MAXIMUM(_typeMaxValue)); break; @@ -2045,11 +2009,6 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data) } data->modifyArrows.maxDigits = MAX_DIGITS(data->modifyArrows.maxValue); break; - case LIST_ITEM_STATUS3: - data->modifyArrows.modifiedValPtr = &gStatuses3[data->battlerId]; - 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_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 87ed8542a7..c39e4e114a 100644 --- a/src/battle_end_turn.c +++ b/src/battle_end_turn.c @@ -163,14 +163,14 @@ static bool32 HandleEndTurnVarious(u32 battler) for (i = 0; i < gBattlersCount; i++) { - if (gStatuses3[i] & STATUS3_ALWAYS_HITS) - gStatuses3[i] -= STATUS3_ALWAYS_HITS_TURN(1); + if (gBattleMons[i].volatiles.lockOn > 0) + gBattleMons[i].volatiles.lockOn--; if (gDisableStructs[i].chargeTimer && --gDisableStructs[i].chargeTimer == 0) - gStatuses3[i] &= ~STATUS3_CHARGED_UP; + gBattleMons[i].volatiles.charge = FALSE; - if (gStatuses3[i] & STATUS3_LASER_FOCUS && gDisableStructs[i].laserFocusTimer == gBattleTurnCounter) - gStatuses3[i] &= ~STATUS3_LASER_FOCUS; + if (gBattleMons[i].volatiles.laserFocus && gDisableStructs[i].laserFocusTimer == gBattleTurnCounter) + gBattleMons[i].volatiles.laserFocus = FALSE; gBattleStruct->hpBefore[i] = gBattleMons[i].hp; } @@ -409,7 +409,7 @@ static bool32 HandleEndTurnWish(u32 battler) } gBattleStruct->moveDamage[battler] *= -1; - if (gStatuses3[battler] & STATUS3_HEAL_BLOCK) + if (gBattleMons[battler].volatiles.healBlock) BattleScriptExecute(BattleScript_WishButHealBlocked); else if (gBattleMons[battler].hp == gBattleMons[battler].maxHP) BattleScriptExecute(BattleScript_WishButFullHp); @@ -486,7 +486,7 @@ static bool32 HandleEndTurnFirstEventBlock(u32 battler) if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerAlive(battler) && !IsBattlerAtMaxHp(battler) - && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK) + && !gBattleMons[battler].volatiles.healBlock && !IsSemiInvulnerable(battler, CHECK_ALL) && IsBattlerGrounded(battler)) { @@ -542,8 +542,8 @@ static bool32 HandleEndTurnAquaRing(u32 battler) gBattleStruct->turnEffectsBattlerId++; - if (gStatuses3[battler] & STATUS3_AQUA_RING - && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK) + if (gBattleMons[battler].volatiles.aquaRing + && !gBattleMons[battler].volatiles.healBlock && !IsBattlerAtMaxHp(battler) && IsBattlerAlive(battler)) { @@ -561,8 +561,8 @@ static bool32 HandleEndTurnIngrain(u32 battler) gBattleStruct->turnEffectsBattlerId++; - if (gStatuses3[battler] & STATUS3_ROOTED - && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK) + if (gBattleMons[battler].volatiles.root + && !gBattleMons[battler].volatiles.healBlock && !IsBattlerAtMaxHp(battler) && IsBattlerAlive(battler)) { @@ -580,12 +580,12 @@ static bool32 HandleEndTurnLeechSeed(u32 battler) gBattleStruct->turnEffectsBattlerId++; - if (gStatuses3[battler] & STATUS3_LEECHSEED - && IsBattlerAlive(gStatuses3[battler] & STATUS3_LEECHSEED_BATTLER) + if (gBattleMons[battler].volatiles.leechSeed + && IsBattlerAlive(gBattleMons[battler].volatiles.leechSeed - 1) && IsBattlerAlive(battler) && !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD)) { - gBattlerTarget = gStatuses3[battler] & STATUS3_LEECHSEED_BATTLER; // Notice gBattlerTarget is actually the HP receiver. + gBattlerTarget = gBattleMons[battler].volatiles.leechSeed - 1; // leech seed receiver gBattleScripting.animArg1 = gBattlerTarget; gBattleScripting.animArg2 = gBattlerAttacker; gBattleStruct->moveDamage[gBattlerAttacker] = max(1, GetNonDynamaxMaxHP(battler) / 8); @@ -597,7 +597,7 @@ static bool32 HandleEndTurnLeechSeed(u32 battler) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_OOZE; BattleScriptExecute(BattleScript_LeechSeedTurnDrainLiquidOoze); } - else if (gStatuses3[gBattlerTarget] & STATUS3_HEAL_BLOCK) + else if (gBattleMons[gBattlerTarget].volatiles.healBlock) { BattleScriptExecute(BattleScript_LeechSeedTurnDrainHealBlock); } @@ -626,7 +626,7 @@ static bool32 HandleEndTurnPoison(u32 battler) { if (ability == ABILITY_POISON_HEAL) { - if (!IsBattlerAtMaxHp(battler) && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)) + if (!IsBattlerAtMaxHp(battler) && !gBattleMons[battler].volatiles.healBlock) { gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8; if (gBattleStruct->moveDamage[battler] == 0) @@ -946,9 +946,9 @@ static bool32 HandleEndTurnMagnetRise(u32 battler) gBattleStruct->turnEffectsBattlerId++; - if (gStatuses3[battler] & STATUS3_MAGNET_RISE && gDisableStructs[battler].magnetRiseTimer == gBattleTurnCounter) + if (gBattleMons[battler].volatiles.magnetRise && gDisableStructs[battler].magnetRiseTimer == gBattleTurnCounter) { - gStatuses3[battler] &= ~STATUS3_MAGNET_RISE; + gBattleMons[battler].volatiles.magnetRise = FALSE; BattleScriptExecute(BattleScript_BufferEndTurn); PREPARE_STRING_BUFFER(gBattleTextBuff1, STRINGID_ELECTROMAGNETISM); effect = TRUE; @@ -963,9 +963,9 @@ static bool32 HandleEndTurnTelekinesis(u32 battler) gBattleStruct->turnEffectsBattlerId++; - if (gStatuses3[battler] & STATUS3_TELEKINESIS && gDisableStructs[battler].telekinesisTimer == gBattleTurnCounter) + if (gBattleMons[battler].volatiles.telekinesis && gDisableStructs[battler].telekinesisTimer == gBattleTurnCounter) { - gStatuses3[battler] &= ~STATUS3_TELEKINESIS; + gBattleMons[battler].volatiles.telekinesis = FALSE; BattleScriptExecute(BattleScript_TelekinesisEndTurn); effect = TRUE; } @@ -979,9 +979,9 @@ static bool32 HandleEndTurnHealBlock(u32 battler) gBattleStruct->turnEffectsBattlerId++; - if (gStatuses3[battler] & STATUS3_HEAL_BLOCK && gDisableStructs[battler].healBlockTimer == gBattleTurnCounter) + if (gBattleMons[battler].volatiles.healBlock && gDisableStructs[battler].healBlockTimer == gBattleTurnCounter) { - gStatuses3[battler] &= ~STATUS3_HEAL_BLOCK; + gBattleMons[battler].volatiles.healBlock = FALSE; BattleScriptExecute(BattleScript_BufferEndTurn); PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_HEAL_BLOCK); effect = TRUE; @@ -996,9 +996,9 @@ static bool32 HandleEndTurnEmbargo(u32 battler) gBattleStruct->turnEffectsBattlerId++; - if (gStatuses3[battler] & STATUS3_EMBARGO && gDisableStructs[battler].embargoTimer == gBattleTurnCounter) + if (gBattleMons[battler].volatiles.embargo && gDisableStructs[battler].embargoTimer == gBattleTurnCounter) { - gStatuses3[battler] &= ~STATUS3_EMBARGO; + gBattleMons[battler].volatiles.embargo = FALSE; BattleScriptExecute(BattleScript_EmbargoEndTurn); effect = TRUE; } @@ -1014,10 +1014,11 @@ static bool32 HandleEndTurnYawn(u32 battler) gBattleStruct->turnEffectsBattlerId++; - if (gStatuses3[battler] & STATUS3_YAWN) + if (gBattleMons[battler].volatiles.yawn > 0) { - gStatuses3[battler] -= STATUS3_YAWN_TURN(1); - if (!(gStatuses3[battler] & STATUS3_YAWN) && !(gBattleMons[battler].status1 & STATUS1_ANY) + gBattleMons[battler].volatiles.yawn--; + if (!gBattleMons[battler].volatiles.yawn + && !(gBattleMons[battler].status1 & STATUS1_ANY) && ability != ABILITY_VITAL_SPIRIT && ability != ABILITY_INSOMNIA && !UproarWakeUpCheck(battler) @@ -1064,12 +1065,12 @@ static bool32 HandleEndTurnPerishSong(u32 battler) gBattleStruct->turnEffectsBattlerId++; - if (IsBattlerAlive(battler) && gStatuses3[battler] & STATUS3_PERISH_SONG) + if (IsBattlerAlive(battler) && gBattleMons[battler].volatiles.perishSong) { PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff1, 1, gDisableStructs[battler].perishSongTimer); if (gDisableStructs[battler].perishSongTimer == 0) { - gStatuses3[battler] &= ~STATUS3_PERISH_SONG; + gBattleMons[battler].volatiles.perishSong = FALSE; gBattleStruct->moveDamage[battler] = gBattleMons[battler].hp; BattleScriptExecute(BattleScript_PerishSongTakesLife); } diff --git a/src/battle_main.c b/src/battle_main.c index ac60bab82a..b5bba9eebe 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -193,7 +193,6 @@ EWRAM_DATA u32 gHitMarker = 0; 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 struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u16 gPauseCounterBattle = 0; EWRAM_DATA u16 gPaydayMoney = 0; @@ -3025,7 +3024,6 @@ static void BattleStartClearSetData(void) for (i = 0; i < MAX_BATTLERS_COUNT; i++) { - gStatuses3[i] = 0; gDisableStructs[i].isFirstTurn = 2; gLastMoves[i] = MOVE_NONE; gLastLandedMoves[i] = MOVE_NONE; @@ -3148,9 +3146,9 @@ void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy) { if (gBattleMons[i].volatiles.escapePrevention && gDisableStructs[i].battlerPreventingEscape == battler) gBattleMons[i].volatiles.escapePrevention = FALSE; - if ((gStatuses3[i] & STATUS3_ALWAYS_HITS) && gDisableStructs[i].battlerWithSureHit == battler) + if (gBattleMons[i].volatiles.lockOn && gDisableStructs[i].battlerWithSureHit == battler) { - gStatuses3[i] &= ~STATUS3_ALWAYS_HITS; + gBattleMons[i].volatiles.lockOn = 0; gDisableStructs[i].battlerWithSureHit = 0; } } @@ -3168,26 +3166,19 @@ void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy) * gBattleMons[battler].volatiles.escapePrevention = volatilesCopy->escapePrevention; * ...etc */ - 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); + for (i = 0; i < gBattlersCount; i++) { if (!IsBattlerAlly(battler, i) - && (gStatuses3[i] & STATUS3_ALWAYS_HITS) != 0 + && gBattleMons[i].volatiles.lockOn != 0 && (gDisableStructs[i].battlerWithSureHit == battler)) { - gStatuses3[i] &= ~STATUS3_ALWAYS_HITS; - gStatuses3[i] |= STATUS3_ALWAYS_HITS_TURN(2); + gBattleMons[i].volatiles.lockOn = 0; } } - if (gStatuses3[battler] & STATUS3_POWER_TRICK) + if (gBattleMons[battler].volatiles.powerTrick) SWAP(gBattleMons[battler].attack, gBattleMons[battler].defense, i); } - else - { - gStatuses3[battler] = 0; - } for (i = 0; i < gBattlersCount; i++) { @@ -3301,8 +3292,11 @@ const u8* FaintClearSetData(u32 battler) for (i = 0; i < NUM_BATTLE_STATS; i++) gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE; + bool32 keepGastroAcid = FALSE; + if (gBattleMons[battler].volatiles.gastroAcid) + keepGastroAcid = TRUE; 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. + gBattleMons[battler].volatiles.gastroAcid = keepGastroAcid; // Edge case: Keep Gastro Acid if pokemon's ability can have effect after fainting, for example Innards Out. for (i = 0; i < gBattlersCount; i++) { diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 8bd6d3ab6a..86cb831bb0 100755 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -369,7 +369,7 @@ static void Cmd_jumpifvolatile(void); static void Cmd_jumpifability(void); static void Cmd_jumpifsideaffecting(void); static void Cmd_jumpifstat(void); -static void Cmd_jumpifstatus3condition(void); +static void Cmd_unused_0x21(void); static void Cmd_jumpbasedontype(void); static void Cmd_getexp(void); static void Cmd_checkteamslost(void); @@ -467,7 +467,7 @@ static void Cmd_setseeded(void); static void Cmd_manipulatedamage(void); static void Cmd_trysetrest(void); static void Cmd_jumpifnotfirstturn(void); -static void Cmd_setmiracleeye(void); +static void Cmd_unused_0x83(void); static void Cmd_jumpifuproarwakes(void); static void Cmd_stockpile(void); static void Cmd_stockpiletobasedamage(void); @@ -535,7 +535,7 @@ static void Cmd_trysetfutureattack(void); static void Cmd_trydobeatup(void); static void Cmd_setsemiinvulnerablebit(void); static void Cmd_tryfiretwoturnmovenowbyeffect(void); -static void Cmd_setminimize(void); +static void Cmd_unused_0xC7(void); static void Cmd_unused_c8(void); static void Cmd_trymemento(void); static void Cmd_setforcedtarget(void); @@ -557,7 +557,7 @@ static void Cmd_setroom(void); static void Cmd_tryswapabilities(void); static void Cmd_tryimprison(void); static void Cmd_setstealthrock(void); -static void Cmd_setuserstatus3(void); +static void Cmd_trysetvolatile(void); static void Cmd_assistattackselect(void); static void Cmd_trysetmagiccoat(void); static void Cmd_trysetsnatch(void); @@ -628,7 +628,7 @@ void (*const gBattleScriptingCommandsTable[])(void) = Cmd_jumpifability, //0x1E Cmd_jumpifsideaffecting, //0x1F Cmd_jumpifstat, //0x20 - Cmd_jumpifstatus3condition, //0x21 + Cmd_unused_0x21, //0x21 Cmd_jumpbasedontype, //0x22 Cmd_getexp, //0x23 Cmd_checkteamslost, //0x24 @@ -726,7 +726,7 @@ void (*const gBattleScriptingCommandsTable[])(void) = Cmd_manipulatedamage, //0x80 Cmd_trysetrest, //0x81 Cmd_jumpifnotfirstturn, //0x82 - Cmd_setmiracleeye, //0x83 + Cmd_unused_0x83, //0x83 Cmd_jumpifuproarwakes, //0x84 Cmd_stockpile, //0x85 Cmd_stockpiletobasedamage, //0x86 @@ -794,7 +794,7 @@ void (*const gBattleScriptingCommandsTable[])(void) = Cmd_trydobeatup, //0xC4 Cmd_setsemiinvulnerablebit, //0xC5 Cmd_tryfiretwoturnmovenowbyeffect, //0xC6 - Cmd_setminimize, //0xC7 + Cmd_unused_0xC7, //0xC7 Cmd_unused_c8, //0xC8 Cmd_trymemento, //0xC9 Cmd_setforcedtarget, //0xCA @@ -816,7 +816,7 @@ void (*const gBattleScriptingCommandsTable[])(void) = Cmd_tryswapabilities, //0xDA Cmd_tryimprison, //0xDB Cmd_setstealthrock, //0xDC - Cmd_setuserstatus3, //0xDD + Cmd_trysetvolatile, //0xDD Cmd_assistattackselect, //0xDE Cmd_trysetmagiccoat, //0xDF Cmd_trysetsnatch, //0xE0 @@ -1364,7 +1364,7 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u if (move == NO_ACC_CALC_CHECK_LOCK_ON) { - if (gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker) + if (gBattleMons[gBattlerTarget].volatiles.lockOn && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker) gBattlescriptCurrInstr = nextInstr; else if (IsSemiInvulnerable(gBattlerTarget, CHECK_ALL)) gBattlescriptCurrInstr = failInstr; @@ -1621,7 +1621,7 @@ s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordA { critChance = CRITICAL_HIT_BLOCKED; } - else if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS + else if (gBattleMons[battlerAtk].volatiles.laserFocus || MoveAlwaysCrits(move) || (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)) { @@ -1704,7 +1704,7 @@ s32 CalcCritChanceStageGen1(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec } // Guaranteed crits - else if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS + else if (gBattleMons[battlerAtk].volatiles.laserFocus || MoveAlwaysCrits(move) || (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)) { @@ -3565,9 +3565,9 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_AromaVeilProtectsRet; } - else if (!(gStatuses3[gEffectBattler] & STATUS3_HEAL_BLOCK)) + else if (!gBattleMons[gEffectBattler].volatiles.healBlock) { - gStatuses3[gEffectBattler] |= STATUS3_HEAL_BLOCK; + gBattleMons[gEffectBattler].volatiles.healBlock = TRUE; gDisableStructs[gEffectBattler].healBlockTimer = gBattleTurnCounter + 2; BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_EffectPsychicNoise; @@ -3637,10 +3637,9 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai gBattlescriptCurrInstr = BattleScript_MoveEffectHaze; break; case MOVE_EFFECT_LEECH_SEED: - if (!IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) && !(gStatuses3[gBattlerTarget] & STATUS3_LEECHSEED)) + if (!IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) && !gBattleMons[gBattlerTarget].volatiles.leechSeed) { - gStatuses3[gBattlerTarget] |= gBattlerAttacker; - gStatuses3[gBattlerTarget] |= STATUS3_LEECHSEED; + gBattleMons[gBattlerTarget].volatiles.leechSeed = LEECHSEEDED_BY(gBattlerAttacker); BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_MoveEffectLeechSeed; } @@ -3944,11 +3943,11 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai } case MOVE_EFFECT_YAWN_FOE: { - if (!(gStatuses3[gBattlerTarget] & STATUS3_YAWN) + if (gBattleMons[gBattlerTarget].volatiles.yawn == 0 && CanBeSlept(gBattlerTarget, gBattlerTarget, GetBattlerAbility(gBattlerTarget), BLOCKED_BY_SLEEP_CLAUSE) && RandomPercentage(RNG_G_MAX_SNOOZE, 50)) { - gStatuses3[gBattlerTarget] |= STATUS3_YAWN_TURN(2); + gBattleMons[gBattlerTarget].volatiles.yawn = 2; BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_EffectYawnSuccess; } @@ -4248,7 +4247,7 @@ static void Cmd_tryfaintmon(void) gBattleStruct->moveDamage[destinyBondBattler] = gBattleMons[destinyBondBattler].hp; gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife; } - if ((gStatuses3[gBattlerTarget] & STATUS3_GRUDGE) + if (gBattleMons[gBattlerTarget].volatiles.grudge && !(gHitMarker & HITMARKER_GRUDGE) && !IsBattlerAlly(gBattlerAttacker, gBattlerTarget) && IsBattlerAlive(gBattlerAttacker) @@ -4340,7 +4339,7 @@ static void Cmd_jumpifvolatile(void) u8 battler = GetBattlerForBattleScript(cmd->battler); const u8 *jumpInstr = cmd->jumpInstr; - if (GetMonVolatile(battler, cmd->_volatile) && IsBattlerAlive(battler)) + if (GetBattlerVolatile(battler, cmd->_volatile) != 0 && IsBattlerAlive(battler)) gBattlescriptCurrInstr = jumpInstr; else gBattlescriptCurrInstr = cmd->nextInstr; @@ -4422,25 +4421,8 @@ static void Cmd_jumpifstat(void) gBattlescriptCurrInstr = cmd->nextInstr; } -static void Cmd_jumpifstatus3condition(void) +static void Cmd_unused_0x21(void) { - CMD_ARGS(u8 battler, u32 flags, bool8 jumpIfTrue, const u8 *jumpInstr); - - u32 battler = GetBattlerForBattleScript(cmd->battler); - if (cmd->jumpIfTrue) - { - if ((gStatuses3[battler] & cmd->flags) != 0) - gBattlescriptCurrInstr = cmd->nextInstr; - else - gBattlescriptCurrInstr = cmd->jumpInstr; - } - else - { - if ((gStatuses3[battler] & cmd->flags) != 0) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - } } static void Cmd_jumpbasedontype(void) @@ -4772,7 +4754,7 @@ static void Cmd_getexp(void) if (battler != 0xFF) { CopyMonLevelAndBaseStatsToBattleMon(battler, &gPlayerParty[*expMonId]); - if (gStatuses3[battler] & STATUS3_POWER_TRICK) + if (gBattleMons[battler].volatiles.powerTrick) SWAP(gBattleMons[battler].attack, gBattleMons[battler].defense, temp); } @@ -5786,7 +5768,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect) { BattleScriptCall(BattleScript_AbilityPreventsPhasingOutRet); } - else if (gStatuses3[gBattlerTarget] & STATUS3_ROOTED) + else if (gBattleMons[gBattlerTarget].volatiles.root) { BattleScriptCall(BattleScript_PrintMonIsRootedRet); } @@ -5808,9 +5790,10 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect) && IsBattlerAlive(gBattlerTarget) && !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) { + gBattleMons[gBattlerTarget].volatiles.smackDown = TRUE; + gBattleMons[gBattlerTarget].volatiles.telekinesis = FALSE; + gBattleMons[gBattlerTarget].volatiles.magnetRise = FALSE; gBattleMons[gBattlerTarget].volatiles.semiInvulnerable = STATE_NONE; - gStatuses3[gBattlerTarget] |= STATUS3_SMACKED_DOWN; - gStatuses3[gBattlerTarget] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS); BattleScriptCall(BattleScript_MoveEffectSmackDown); effect = TRUE; } @@ -6067,7 +6050,7 @@ static void Cmd_moveend(void) { case EFFECT_ABSORB: case EFFECT_DREAM_EATER: - if (!(gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK) + if (!gBattleMons[gBattlerAttacker].volatiles.healBlock && gBattleStruct->moveDamage[gBattlerTarget] > 0 && IsBattlerAlive(gBattlerAttacker)) { @@ -6927,7 +6910,7 @@ static void Cmd_moveend(void) if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE) SetActiveGimmick(gBattlerAttacker, GIMMICK_NONE); if (B_CHARGE >= GEN_9 && moveType == TYPE_ELECTRIC && (IsBattlerTurnDamaged(gBattlerTarget) || gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)) - gStatuses3[gBattlerAttacker] &= ~(STATUS3_CHARGED_UP); + gBattleMons[gBattlerAttacker].volatiles.charge = FALSE; // check if Stellar type boost should be used up if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA && GetBattlerTeraType(gBattlerAttacker) == TYPE_STELLAR @@ -7040,13 +7023,13 @@ static void Cmd_sethealblock(void) { CMD_ARGS(const u8 *failInstr); - if (gStatuses3[gBattlerTarget] & STATUS3_HEAL_BLOCK) + if (gBattleMons[gBattlerTarget].volatiles.healBlock) { gBattlescriptCurrInstr = cmd->failInstr; } else { - gStatuses3[gBattlerTarget] |= STATUS3_HEAL_BLOCK; + gBattleMons[gBattlerTarget].volatiles.healBlock = TRUE; gDisableStructs[gBattlerTarget].healBlockTimer = gBattleTurnCounter + 5; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -8583,7 +8566,7 @@ static bool32 TryCheekPouch(u32 battler, u32 itemId) { if (GetItemPocket(itemId) == POCKET_BERRIES && GetBattlerAbility(battler) == ABILITY_CHEEK_POUCH - && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK) + && !gBattleMons[battler].volatiles.healBlock && GetBattlerPartyState(battler)->ateBerry && !IsBattlerAtMaxHp(battler)) { @@ -9769,7 +9752,7 @@ static void Cmd_setseeded(void) { CMD_ARGS(); - if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT || gStatuses3[gBattlerTarget] & STATUS3_LEECHSEED) + if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT || gBattleMons[gBattlerTarget].volatiles.leechSeed) { gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_MISS; @@ -9781,8 +9764,7 @@ static void Cmd_setseeded(void) } else { - gStatuses3[gBattlerTarget] |= gBattlerAttacker; - gStatuses3[gBattlerTarget] |= STATUS3_LEECHSEED; + gBattleMons[gBattlerTarget].volatiles.leechSeed = LEECHSEEDED_BY(gBattlerAttacker); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_SET; } @@ -9864,19 +9846,8 @@ static void Cmd_jumpifnotfirstturn(void) gBattlescriptCurrInstr = jumpInstr; } -static void Cmd_setmiracleeye(void) +static void Cmd_unused_0x83(void) { - CMD_ARGS(const u8 *failInstr); - - if (!(gStatuses3[gBattlerTarget] & STATUS3_MIRACLE_EYED)) - { - gStatuses3[gBattlerTarget] |= STATUS3_MIRACLE_EYED; - gBattlescriptCurrInstr = cmd->nextInstr; - } - else - { - gBattlescriptCurrInstr = cmd->failInstr; - } } bool8 UproarWakeUpCheck(u8 battler) @@ -10953,7 +10924,7 @@ static void Cmd_tryKO(void) else { if (gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level - && ((gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS + && ((gBattleMons[gBattlerTarget].volatiles.lockOn && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker) || IsAbilityAndRecord(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), ABILITY_NO_GUARD) || IsAbilityAndRecord(gBattlerTarget, targetAbility, ABILITY_NO_GUARD))) @@ -11625,9 +11596,7 @@ static void Cmd_settypetorandomresistance(void) static void Cmd_setalwayshitflag(void) { CMD_ARGS(); - - gStatuses3[gBattlerTarget] &= ~STATUS3_ALWAYS_HITS; - gStatuses3[gBattlerTarget] |= STATUS3_ALWAYS_HITS_TURN(2); + gBattleMons[gBattlerTarget].volatiles.lockOn = 2; gDisableStructs[gBattlerTarget].battlerWithSureHit = gBattlerAttacker; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -12021,7 +11990,7 @@ static void Cmd_trysetperishsong(void) for (i = 0; i < gBattlersCount; i++) { - if (gStatuses3[i] & STATUS3_PERISH_SONG + if (gBattleMons[i].volatiles.perishSong || GetBattlerAbility(i) == ABILITY_SOUNDPROOF || BlocksPrankster(gCurrentMove, gBattlerAttacker, i, TRUE) || gBattleMons[i].volatiles.semiInvulnerable == STATE_COMMANDER) @@ -12030,7 +11999,7 @@ static void Cmd_trysetperishsong(void) } else { - gStatuses3[i] |= STATUS3_PERISH_SONG; + gBattleMons[i].volatiles.perishSong = TRUE; gDisableStructs[i].perishSongTimer = 3; } } @@ -12111,13 +12080,13 @@ static void Cmd_setembargo(void) { CMD_ARGS(const u8 *failInstr); - if (gStatuses3[gBattlerTarget] & STATUS3_EMBARGO) + if (gBattleMons[gBattlerTarget].volatiles.embargo) { gBattlescriptCurrInstr = cmd->failInstr; } else { - gStatuses3[gBattlerTarget] |= STATUS3_EMBARGO; + gBattleMons[gBattlerTarget].volatiles.embargo = TRUE; gDisableStructs[gBattlerTarget].embargoTimer = gBattleTurnCounter + 5; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -12355,10 +12324,9 @@ static void Cmd_rapidspinfree(void) PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleStruct->wrappedMove[gBattlerAttacker]); BattleScriptCall(BattleScript_WrapFree); } - else if (gStatuses3[gBattlerAttacker] & STATUS3_LEECHSEED) + else if (gBattleMons[gBattlerAttacker].volatiles.leechSeed) { - gStatuses3[gBattlerAttacker] &= ~STATUS3_LEECHSEED; - gStatuses3[gBattlerAttacker] &= ~STATUS3_LEECHSEED_BATTLER; + gBattleMons[gBattlerAttacker].volatiles.leechSeed = 0; BattleScriptCall(BattleScript_LeechSeedFree); } else if (AreAnyHazardsOnSide(atkSide)) @@ -12617,14 +12585,8 @@ static void Cmd_tryfiretwoturnmovenowbyeffect(void) gBattlescriptCurrInstr = cmd->nextInstr; } -static void Cmd_setminimize(void) +static void Cmd_unused_0xC7(void) { - CMD_ARGS(); - - if (gHitMarker & HITMARKER_OBEYS) - gStatuses3[gBattlerAttacker] |= STATUS3_MINIMIZED; - - gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_unused_c8(void) @@ -12678,7 +12640,7 @@ static void Cmd_setcharge(void) CMD_ARGS(u8 battler); u8 battler = GetBattlerForBattleScript(cmd->battler); - gStatuses3[battler] |= STATUS3_CHARGED_UP; + gBattleMons[battler].volatiles.charge = TRUE; if (B_CHARGE < GEN_9) gDisableStructs[battler].chargeTimer = 2; else @@ -12968,7 +12930,7 @@ static void Cmd_trywish(void) { CMD_ARGS(const u8 *failInstr); - if (gStatuses3[gBattlerTarget] & STATUS3_HEAL_BLOCK) + if (gBattleMons[gBattlerTarget].volatiles.healBlock) { gBattlescriptCurrInstr = cmd->failInstr; } @@ -13002,6 +12964,7 @@ static void Cmd_settoxicspikes(void) } } +// TODO: possible failing bug for when gastro acid is already active static void Cmd_setgastroacid(void) { CMD_ARGS(const u8 *failInstr); @@ -13015,7 +12978,7 @@ static void Cmd_setgastroacid(void) if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS) gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE; - gStatuses3[gBattlerTarget] |= STATUS3_GASTRO_ACID; + gBattleMons[gBattlerTarget].volatiles.gastroAcid = TRUE; gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -13024,7 +12987,7 @@ static void Cmd_setyawn(void) { CMD_ARGS(const u8 *failInstr); - if (gStatuses3[gBattlerTarget] & STATUS3_YAWN + if (gBattleMons[gBattlerTarget].volatiles.yawn || gBattleMons[gBattlerTarget].status1 & STATUS1_ANY) { gBattlescriptCurrInstr = cmd->failInstr; @@ -13043,7 +13006,7 @@ static void Cmd_setyawn(void) } else { - gStatuses3[gBattlerTarget] |= STATUS3_YAWN_TURN(2); + gBattleMons[gBattlerTarget].volatiles.yawn = 2; gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -13139,13 +13102,13 @@ static void Cmd_tryimprison(void) { CMD_ARGS(const u8 *failInstr); - if ((gStatuses3[gBattlerAttacker] & STATUS3_IMPRISONED_OTHERS)) + if (gBattleMons[gBattlerAttacker].volatiles.imprison) { gBattlescriptCurrInstr = cmd->failInstr; } else if (B_IMPRISON >= GEN_5) { - gStatuses3[gBattlerAttacker] |= STATUS3_IMPRISONED_OTHERS; + gBattleMons[gBattlerAttacker].volatiles.imprison = TRUE; gBattlescriptCurrInstr = cmd->nextInstr; } else @@ -13171,7 +13134,7 @@ static void Cmd_tryimprison(void) } if (attackerMoveId != MAX_MON_MOVES) { - gStatuses3[gBattlerAttacker] |= STATUS3_IMPRISONED_OTHERS; + gBattleMons[gBattlerAttacker].volatiles.imprison = TRUE; gBattlescriptCurrInstr = cmd->nextInstr; break; } @@ -13198,23 +13161,30 @@ static void Cmd_setstealthrock(void) } } -static void Cmd_setuserstatus3(void) +static void Cmd_trysetvolatile(void) { - CMD_ARGS(u32 flags, const u8 *failInstr); + CMD_ARGS(u8 battler, u8 _volatile, const u8 *failInstr); - u32 flags = cmd->flags; + u32 battler = GetBattlerForBattleScript(cmd->battler); - if (gStatuses3[gBattlerAttacker] & flags) + if (GetBattlerVolatile(battler, cmd->_volatile) != 0) { gBattlescriptCurrInstr = cmd->failInstr; } else { - gStatuses3[gBattlerAttacker] |= flags; - if (flags & STATUS3_MAGNET_RISE) - gDisableStructs[gBattlerAttacker].magnetRiseTimer = gBattleTurnCounter + 5; - if (flags & STATUS3_LASER_FOCUS) - gDisableStructs[gBattlerAttacker].laserFocusTimer = gBattleTurnCounter + 2; + SetMonVolatile(battler, cmd->_volatile, TRUE); + switch (cmd->_volatile) + { + case VOLATILE_MAGNET_RISE: + gDisableStructs[battler].magnetRiseTimer = gBattleTurnCounter + 5; + break; + case VOLATILE_LASER_FOCUS: + gDisableStructs[battler].laserFocusTimer = gBattleTurnCounter + 2; + break; + default: + break; + } gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -14459,7 +14429,9 @@ static void Cmd_settelekinesis(void) { CMD_ARGS(const u8 *failInstr); - if (gStatuses3[gBattlerTarget] & (STATUS3_TELEKINESIS | STATUS3_ROOTED | STATUS3_SMACKED_DOWN) + if (gBattleMons[gBattlerTarget].volatiles.telekinesis + || gBattleMons[gBattlerTarget].volatiles.root + || gBattleMons[gBattlerTarget].volatiles.smackDown || gFieldStatuses & STATUS_FIELD_GRAVITY || IsTelekinesisBannedSpecies(gBattleMons[gBattlerTarget].species)) { @@ -14467,7 +14439,7 @@ static void Cmd_settelekinesis(void) } else { - gStatuses3[gBattlerTarget] |= STATUS3_TELEKINESIS; + gBattleMons[gBattlerTarget].volatiles.telekinesis = TRUE; gDisableStructs[gBattlerTarget].telekinesisTimer = gBattleTurnCounter + 3; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -16901,7 +16873,8 @@ void BS_GravityOnAirborneMons(void) CancelMultiTurnMoves(gBattlerTarget, SKY_DROP_GRAVITY_ON_AIRBORNE); gBattleMons[gBattlerTarget].volatiles.semiInvulnerable = STATE_NONE; - gStatuses3[gBattlerTarget] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS); + gBattleMons[gBattlerTarget].volatiles.magnetRise = FALSE; + gBattleMons[gBattlerTarget].volatiles.telekinesis = FALSE; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -17674,7 +17647,7 @@ void BS_PowerTrick(void) { NATIVE_ARGS(); u32 temp; - gStatuses3[gBattlerAttacker] ^= STATUS3_POWER_TRICK; + gBattleMons[gBattlerAttacker].volatiles.powerTrick = !gBattleMons[gBattlerAttacker].volatiles.powerTrick; SWAP(gBattleMons[gBattlerAttacker].attack, gBattleMons[gBattlerAttacker].defense, temp); gBattlescriptCurrInstr = cmd->nextInstr; } @@ -18297,9 +18270,9 @@ void BS_CureCertainStatuses(void) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_TORMENT; } // Check heal block - if (gStatuses3[gBattlerTarget] & STATUS3_HEAL_BLOCK) + if (gBattleMons[gBattlerTarget].volatiles.healBlock) { - gStatuses3[gBattlerTarget] &= ~(STATUS3_HEAL_BLOCK); + gBattleMons[gBattlerTarget].volatiles.healBlock = FALSE; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_HEALBLOCK; } // Check disable diff --git a/src/battle_tv.c b/src/battle_tv.c index e23712beab..6504a3cc43 100644 --- a/src/battle_tv.c +++ b/src/battle_tv.c @@ -591,7 +591,7 @@ void BattleTv_SetDataBasedOnMove(u16 move, u16 weatherFlags, struct DisableStruc tvPtr->side[atkSide].usedMoveSlot = moveSlot; AddMovePoints(PTS_MOVE_EFFECT, moveSlot, move, 0); AddPointsBasedOnWeather(weatherFlags, move, moveSlot); - if (gStatuses3[gBattlerAttacker] & STATUS3_CHARGED_UP) + if (gBattleMons[gBattlerAttacker].volatiles.charge) AddMovePoints(PTS_ELECTRIC, move, moveSlot, 0); if (move == MOVE_WISH) diff --git a/src/battle_util.c b/src/battle_util.c index 13f830d953..8eb6a89bc1 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1281,7 +1281,7 @@ static bool32 IsGravityPreventingMove(u32 move) bool32 IsHealBlockPreventingMove(u32 battler, u32 move) { - if (!(gStatuses3[battler] & STATUS3_HEAL_BLOCK)) + if (!gBattleMons[battler].volatiles.healBlock) return FALSE; return IsHealingMove(move); @@ -1656,7 +1656,7 @@ u8 GetImprisonedMovesCount(u32 battler, u16 move) for (i = 0; i < gBattlersCount; i++) { - if (battlerSide != GetBattlerSide(i) && gStatuses3[i] & STATUS3_IMPRISONED_OTHERS) + if (battlerSide != GetBattlerSide(i) && gBattleMons[i].volatiles.imprison) { s32 j; for (j = 0; j < MAX_MON_MOVES; j++) @@ -1892,7 +1892,7 @@ void SetAtkCancellerForCalledMove(void) static enum MoveCanceller CancellerFlags(void) { gBattleMons[gBattlerAttacker].volatiles.destinyBond = FALSE; - gStatuses3[gBattlerAttacker] &= ~STATUS3_GRUDGE; + gBattleMons[gBattlerAttacker].volatiles.grudge = FALSE; gBattleMons[gBattlerAttacker].volatiles.glaiveRush = FALSE; return MOVE_STEP_SUCCESS; } @@ -2095,7 +2095,7 @@ static enum MoveCanceller CancellerDisabled(void) static enum MoveCanceller CancellerVolatileBlocked(void) { - if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(gBattlerAttacker, gCurrentMove)) + if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gBattleMons[gBattlerAttacker].volatiles.healBlock && IsHealBlockPreventingMove(gBattlerAttacker, gCurrentMove)) { gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE; gBattleScripting.battler = gBattlerAttacker; @@ -3173,7 +3173,7 @@ bool32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 return FALSE; case MOVE_ABSORBED_BY_DRAIN_HP_ABILITY: gBattleStruct->pledgeMove = FALSE; - if (IsBattlerAtMaxHp(battlerDef) || (B_HEAL_BLOCKING >= GEN_5 && gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK)) + if (IsBattlerAtMaxHp(battlerDef) || (B_HEAL_BLOCKING >= GEN_5 && gBattleMons[battlerDef].volatiles.healBlock)) { if ((gProtectStructs[battlerAtk].notFirstStrike)) battleScript = BattleScript_MonMadeMoveUseless; @@ -4096,7 +4096,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!gSpecialStatuses[battler].switchInAbilityDone && IsDoubleBattle() - && !(gStatuses3[partner] & STATUS3_HEAL_BLOCK) + && !gBattleMons[partner].volatiles.healBlock && gBattleMons[partner].hp < gBattleMons[partner].maxHP && IsBattlerAlive(partner)) { @@ -4213,7 +4213,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && !IsBattlerAtMaxHp(battler) && gBattleMons[battler].volatiles.semiInvulnerable != STATE_UNDERGROUND && gBattleMons[battler].volatiles.semiInvulnerable != STATE_UNDERWATER - && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)) + && !gBattleMons[battler].volatiles.healBlock) { BattleScriptPushCursorAndCallback(BattleScript_IceBodyHeal); gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16; @@ -4230,7 +4230,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITY_RAIN_DISH: if (IsBattlerWeatherAffected(battler, B_WEATHER_RAIN) && !IsBattlerAtMaxHp(battler) - && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)) + && !gBattleMons[battler].volatiles.healBlock) { BattleScriptPushCursorAndCallback(BattleScript_RainDishActivates); gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (gLastUsedAbility == ABILITY_RAIN_DISH ? 16 : 8); @@ -4832,14 +4832,14 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && IsBattlerTurnDamaged(gBattlerTarget) && IsBattlerAlive(battler) && !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker, TRUE), move) - && !(gStatuses3[gBattlerAttacker] & STATUS3_PERISH_SONG)) + && !gBattleMons[gBattlerAttacker].volatiles.perishSong) { - if (!(gStatuses3[battler] & STATUS3_PERISH_SONG)) + if (!gBattleMons[battler].volatiles.perishSong) { - gStatuses3[battler] |= STATUS3_PERISH_SONG; + gBattleMons[battler].volatiles.perishSong = TRUE; gDisableStructs[battler].perishSongTimer = 3; } - gStatuses3[gBattlerAttacker] |= STATUS3_PERISH_SONG; + gBattleMons[gBattlerAttacker].volatiles.perishSong = TRUE; gDisableStructs[gBattlerAttacker].perishSongTimer = 3; BattleScriptCall(BattleScript_PerishBodyActivates); effect++; @@ -5339,7 +5339,7 @@ bool32 IsNeutralizingGasOnField(void) for (i = 0; i < gBattlersCount; i++) { - if (IsBattlerAlive(i) && gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !(gStatuses3[i] & STATUS3_GASTRO_ACID)) + if (IsBattlerAlive(i) && gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !gBattleMons[i].volatiles.gastroAcid) return TRUE; } @@ -5348,7 +5348,7 @@ bool32 IsNeutralizingGasOnField(void) bool32 IsMoldBreakerTypeAbility(u32 battler, u32 ability) { - if (gStatuses3[battler] & STATUS3_GASTRO_ACID) + if (gBattleMons[battler].volatiles.gastroAcid) return FALSE; if (ability == ABILITY_MOLD_BREAKER @@ -5400,7 +5400,7 @@ u32 GetBattlerAbilityInternal(u32 battler, u32 ignoreMoldBreaker, u32 noAbilityS { // Edge case: pokemon under the effect of gastro acid transforms into a pokemon with Comatose (Todo: verify how other unsuppressable abilities behave) if (gBattleMons[battler].volatiles.transformed - && gStatuses3[battler] & STATUS3_GASTRO_ACID + && gBattleMons[battler].volatiles.gastroAcid && gBattleMons[battler].ability == ABILITY_COMATOSE) return ABILITY_NONE; @@ -5410,7 +5410,7 @@ u32 GetBattlerAbilityInternal(u32 battler, u32 ignoreMoldBreaker, u32 noAbilityS return gBattleMons[battler].ability; } - if (gStatuses3[battler] & STATUS3_GASTRO_ACID) + if (gBattleMons[battler].volatiles.gastroAcid) return ABILITY_NONE; if (!hasAbilityShield @@ -5502,7 +5502,7 @@ bool32 CanBattlerEscape(u32 battler) // no ability check return FALSE; else if (gBattleMons[battler].volatiles.wrapped) return FALSE; - else if (gStatuses3[battler] & STATUS3_ROOTED) + else if (gBattleMons[battler].volatiles.root) return FALSE; else if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK) return FALSE; @@ -5875,7 +5875,7 @@ bool32 HasEnoughHpToEatBerry(u32 battler, u32 hpFraction, u32 itemId) static enum ItemEffect HealConfuseBerry(u32 battler, u32 itemId, u32 flavorId, enum ItemCaseId caseID) { if (HasEnoughHpToEatBerry(battler, (B_CONFUSE_BERRIES_HEAL >= GEN_7 ? 4 : 2), itemId) - && (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))) + && (B_HEAL_BLOCKING < GEN_5 || !gBattleMons[battler].volatiles.healBlock)) { PREPARE_FLAVOR_BUFFER(gBattleTextBuff1, flavorId); @@ -6003,7 +6003,7 @@ static enum ItemEffect TrySetEnigmaBerry(u32 battler) && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && ((IsBattlerTurnDamaged(battler) && gBattleStruct->moveResultFlags[battler] & MOVE_RESULT_SUPER_EFFECTIVE) || gBattleScripting.overrideBerryRequirements) && !(gBattleScripting.overrideBerryRequirements && gBattleMons[battler].hp == gBattleMons[battler].maxHP) - && (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))) + && (B_HEAL_BLOCKING < GEN_5 || !gBattleMons[battler].volatiles.healBlock)) { gBattleScripting.battler = battler; gBattleStruct->moveDamage[battler] = (gBattleMons[battler].maxHP * 25 / 100) * -1; @@ -6125,7 +6125,7 @@ static u32 ItemRestorePp(u32 battler, u32 itemId, enum ItemCaseId caseID) static u32 ItemHealHp(u32 battler, u32 itemId, enum ItemCaseId caseID, bool32 percentHeal) { if (!(gBattleScripting.overrideBerryRequirements && gBattleMons[battler].hp == gBattleMons[battler].maxHP) - && (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)) + && (B_HEAL_BLOCKING < GEN_5 || !gBattleMons[battler].volatiles.healBlock) && HasEnoughHpToEatBerry(battler, 2, itemId)) { if (percentHeal) @@ -6196,9 +6196,9 @@ static bool32 GetMentalHerbEffect(u32 battler) ret = TRUE; } // Check heal block - if (gStatuses3[battler] & STATUS3_HEAL_BLOCK) + if (gBattleMons[battler].volatiles.healBlock) { - gStatuses3[battler] &= ~STATUS3_HEAL_BLOCK; + gBattleMons[battler].volatiles.healBlock = FALSE; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_HEALBLOCK; ret = TRUE; } @@ -6789,7 +6789,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler) case HOLD_EFFECT_LEFTOVERS: LEFTOVERS: if (gBattleMons[battler].hp < gBattleMons[battler].maxHP - && (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))) + && (B_HEAL_BLOCKING < GEN_5 || !gBattleMons[battler].volatiles.healBlock)) { gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16; if (gBattleStruct->moveDamage[battler] == 0) @@ -7025,7 +7025,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler) && IsBattlerAlive(gBattlerAttacker) && GetMoveEffect(gCurrentMove) != EFFECT_FUTURE_SIGHT && GetMoveEffect(gCurrentMove) != EFFECT_PAIN_SPLIT - && (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))) + && (B_HEAL_BLOCKING < GEN_5 || !gBattleMons[battler].volatiles.healBlock)) { gLastUsedItem = atkItem; gPotentialItemEffectBattler = gBattlerAttacker; @@ -7299,7 +7299,7 @@ void ClearVariousBattlerFlags(u32 battler) gDisableStructs[battler].furyCutterCounter = 0; gBattleMons[battler].volatiles.destinyBond = FALSE; gBattleMons[battler].volatiles.glaiveRush = FALSE; - gStatuses3[battler] &= ~STATUS3_GRUDGE; + gBattleMons[battler].volatiles.grudge = FALSE; } void HandleAction_RunBattleScript(void) // identical to RunBattleScriptCommands @@ -7539,11 +7539,11 @@ enum ItemHoldEffect GetBattlerHoldEffectInternal(u32 battler, bool32 checkNegati { if (checkNegating) { - if (gStatuses3[battler] & STATUS3_EMBARGO) + if (gBattleMons[battler].volatiles.embargo) return HOLD_EFFECT_NONE; if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM) return HOLD_EFFECT_NONE; - if (checkAbility && GetBattlerAbility(battler) == ABILITY_KLUTZ && !(gStatuses3[battler] & STATUS3_GASTRO_ACID)) + if (checkAbility && GetBattlerAbility(battler) == ABILITY_KLUTZ && !gBattleMons[battler].volatiles.gastroAcid) return HOLD_EFFECT_NONE; } @@ -7708,13 +7708,13 @@ static bool32 IsBattlerGroundedInverseCheck(u32 battler, enum InverseBattleCheck return TRUE; if (gFieldStatuses & STATUS_FIELD_GRAVITY) return TRUE; - if (B_ROOTED_GROUNDING >= GEN_4 && gStatuses3[battler] & STATUS3_ROOTED) + if (B_ROOTED_GROUNDING >= GEN_4 && gBattleMons[battler].volatiles.root) return TRUE; - if (gStatuses3[battler] & STATUS3_SMACKED_DOWN) + if (gBattleMons[battler].volatiles.smackDown) return TRUE; - if (gStatuses3[battler] & STATUS3_TELEKINESIS) + if (gBattleMons[battler].volatiles.telekinesis) return FALSE; - if (gStatuses3[battler] & STATUS3_MAGNET_RISE) + if (gBattleMons[battler].volatiles.magnetRise) return FALSE; if (holdEffect == HOLD_EFFECT_AIR_BALLOON) return FALSE; @@ -8300,7 +8300,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageContext *ctx) modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); if (gSpecialStatuses[battlerAtk].gemBoost) modifier = uq4_12_multiply(modifier, uq4_12_add(UQ_4_12(1.0), PercentToUQ4_12(gSpecialStatuses[battlerAtk].gemParam))); - if (gStatuses3[battlerAtk] & STATUS3_CHARGED_UP && moveType == TYPE_ELECTRIC) + if (gBattleMons[battlerAtk].volatiles.charge && moveType == TYPE_ELECTRIC) modifier = uq4_12_multiply(modifier, UQ_4_12(2.0)); if (GetMoveEffect(gChosenMove) == EFFECT_ME_FIRST) modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); @@ -9091,7 +9091,7 @@ static inline uq4_12_t GetZMaxMoveAgainstProtectionModifier(struct DamageContext static inline uq4_12_t GetMinimizeModifier(u32 move, u32 battlerDef) { - if (MoveIncreasesPowerToMinimizedTargets(move) && gStatuses3[battlerDef] & STATUS3_MINIMIZED) + if (MoveIncreasesPowerToMinimizedTargets(move) && gBattleMons[battlerDef].volatiles.minimize) return UQ_4_12(2.0); return UQ_4_12(1.0); } @@ -9569,7 +9569,7 @@ static inline void MulByTypeEffectiveness(struct DamageContext *ctx, uq4_12_t *m RecordAbilityBattle(ctx->battlerAtk, ctx->abilityAtk); } - if (ctx->moveType == TYPE_PSYCHIC && defType == TYPE_DARK && gStatuses3[ctx->battlerDef] & STATUS3_MIRACLE_EYED && mod == UQ_4_12(0.0)) + if (ctx->moveType == TYPE_PSYCHIC && defType == TYPE_DARK && gBattleMons[ctx->battlerDef].volatiles.miracleEye && mod == UQ_4_12(0.0)) mod = UQ_4_12(1.0); if (GetMoveEffect(ctx->move) == EFFECT_SUPER_EFFECTIVE_ON_ARG && defType == GetMoveArgType(ctx->move)) mod = UQ_4_12(2.0); @@ -10524,7 +10524,7 @@ bool32 CanFling(u32 battler) if (item == ITEM_NONE || (B_KLUTZ_FLING_INTERACTION >= GEN_5 && GetBattlerAbility(battler) == ABILITY_KLUTZ) || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM - || gStatuses3[battler] & STATUS3_EMBARGO + || gBattleMons[battler].volatiles.embargo || GetFlingPowerFromItemId(item) == 0 || !CanBattlerGetOrLoseItem(battler, item)) return FALSE; @@ -10843,7 +10843,7 @@ bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, u16 move) { if (GetMoveEffect(move) == EFFECT_HIT_ENEMY_HEAL_ALLY && IsBattlerAlly(battlerAtk, battlerDef) - && gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK) + && gBattleMons[battlerAtk].volatiles.healBlock) return FALSE; // Pokémon affected by Heal Block cannot target allies with Pollen Puff if (IsBattlerAlly(battlerAtk, battlerDef) && (GetActiveGimmick(battlerAtk) == GIMMICK_DYNAMAX || IsGimmickSelected(battlerAtk, GIMMICK_DYNAMAX))) @@ -11468,7 +11468,7 @@ bool32 TrySwitchInEjectPack(enum ItemCaseId caseID) // Gets the value of a volatile status flag for a certain battler // Primarily used for the debug menu and scripts. Outside of it explicit references are preferred -u32 GetMonVolatile(u32 battler, enum Volatile _volatile) +u32 GetBattlerVolatile(u32 battler, enum Volatile _volatile) { switch (_volatile) { @@ -11608,7 +11608,7 @@ bool32 CanMoveSkipAccuracyCalc(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u enum BattleMoveEffects moveEffect = GetMoveEffect(move); u32 nonVolatileStatus = GetMoveNonVolatileStatus(move); - if ((gStatuses3[battlerDef] & STATUS3_ALWAYS_HITS && gDisableStructs[battlerDef].battlerWithSureHit == battlerAtk) + if ((gBattleMons[battlerDef].volatiles.lockOn && gDisableStructs[battlerDef].battlerWithSureHit == battlerAtk) || (B_TOXIC_NEVER_MISS >= GEN_6 && nonVolatileStatus == MOVE_EFFECT_TOXIC && IS_BATTLER_OF_TYPE(battlerAtk, TYPE_POISON)) || gBattleMons[battlerDef].volatiles.glaiveRush) { @@ -11630,7 +11630,7 @@ bool32 CanMoveSkipAccuracyCalc(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u ability = ABILITY_NO_GUARD; } // 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 + else if (gBattleMons[battlerDef].volatiles.telekinesis && !IsSemiInvulnerable(battlerDef, CHECK_ALL) && moveEffect != EFFECT_OHKO && moveEffect != EFFECT_SHEER_COLD) @@ -11658,7 +11658,7 @@ bool32 CanMoveSkipAccuracyCalc(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u } } else if (B_MINIMIZE_DMG_ACC >= GEN_6 - && (gStatuses3[battlerDef] & STATUS3_MINIMIZED) + && gBattleMons[battlerDef].volatiles.minimize && MoveIncreasesPowerToMinimizedTargets(move)) { effect = TRUE; @@ -11703,7 +11703,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u if (defAbility == ABILITY_UNAWARE) accStage = DEFAULT_STAT_STAGE; - if (gBattleMons[battlerDef].volatiles.foresight || gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED) + if (gBattleMons[battlerDef].volatiles.foresight || gBattleMons[battlerDef].volatiles.miracleEye) buff = accStage; else buff = accStage + DEFAULT_STAT_STAGE - evasionStage; diff --git a/src/item_use.c b/src/item_use.c index 5895016399..a086737bd9 100644 --- a/src/item_use.c +++ b/src/item_use.c @@ -1244,8 +1244,8 @@ bool32 CannotUseItemsInBattle(u16 itemId, struct Pokemon *mon) u16 hp = GetMonData(mon, MON_DATA_HP); // Embargo Check - if ((gPartyMenu.slotId == 0 && gStatuses3[B_POSITION_PLAYER_LEFT] & STATUS3_EMBARGO) - || (gPartyMenu.slotId == 1 && gStatuses3[B_POSITION_PLAYER_RIGHT] & STATUS3_EMBARGO)) + if ((gPartyMenu.slotId == 0 && gBattleMons[B_POSITION_PLAYER_LEFT].volatiles.embargo) + || (gPartyMenu.slotId == 1 && gBattleMons[B_POSITION_PLAYER_RIGHT].volatiles.embargo)) { return TRUE; }