Convert statuses3 to volatiles (#7514)

This commit is contained in:
Alex 2025-08-11 23:19:36 +02:00 committed by GitHub
parent 2469627c61
commit f4c91b5539
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 350 additions and 436 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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
{

View File

@ -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;
}

View File

@ -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))

View File

@ -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))

View File

@ -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];

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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++)
{

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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;
}