mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-03-21 18:04:50 -05:00
Replaces STATUS2 usage with volatiles in code (#7262)
Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com>
This commit is contained in:
parent
9228826ae1
commit
a1e67572b6
|
|
@ -596,27 +596,15 @@
|
|||
.byte \notChosenMove
|
||||
.endm
|
||||
|
||||
.macro statusanimation battler:req
|
||||
.macro statusanimation battler:req, status=0, isVolatile=FALSE
|
||||
.byte 0x64
|
||||
.byte \battler
|
||||
.endm
|
||||
|
||||
.macro status2animation battler:req, status2:req
|
||||
.byte 0x65
|
||||
.byte \battler
|
||||
.4byte \status2
|
||||
.endm
|
||||
|
||||
.macro setmoveeffect effect:req
|
||||
sethword sMOVE_EFFECT, \effect
|
||||
sethword sSAVED_MOVE_EFFECT, \effect
|
||||
.endm
|
||||
|
||||
.macro chosenstatusanimation battler:req, isStatus2:req, status:req
|
||||
.byte 0x66
|
||||
.byte \battler
|
||||
.byte \isStatus2
|
||||
.4byte \status
|
||||
.byte \isVolatile
|
||||
.endm
|
||||
|
||||
.macro volatileanimation battler:req, volatile:req
|
||||
statusanimation \battler, \volatile, TRUE
|
||||
.endm
|
||||
|
||||
.macro yesnobox
|
||||
|
|
@ -979,8 +967,11 @@
|
|||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro setforesight
|
||||
.macro setvolatile battler:req, volatile:req, value=TRUE
|
||||
.byte 0xb1
|
||||
.byte \battler
|
||||
.byte \volatile
|
||||
.byte \value
|
||||
.endm
|
||||
|
||||
.macro trysetperishsong failInstr:req
|
||||
|
|
@ -1041,10 +1032,6 @@
|
|||
.byte 0xbe
|
||||
.endm
|
||||
|
||||
.macro setdefensecurlbit
|
||||
.byte 0xbf
|
||||
.endm
|
||||
|
||||
.macro recoverbasedonsunlight failInstr:req
|
||||
.byte 0xc0
|
||||
.4byte \failInstr
|
||||
|
|
@ -2094,10 +2081,6 @@
|
|||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro setpowder battler:req
|
||||
various \battler, VARIOUS_SET_POWDER
|
||||
.endm
|
||||
|
||||
.macro bringdownairbornebattler battler:req
|
||||
various \battler, VARIOUS_GRAVITY_ON_AIRBORNE_MONS
|
||||
.endm
|
||||
|
|
@ -2353,12 +2336,9 @@
|
|||
setbyte sSTATCHANGER, \stat | \stages << 3 | \down << 7
|
||||
.endm
|
||||
|
||||
.macro chosenstatus1animation battler:req, status:req
|
||||
chosenstatusanimation \battler, 0x0, \status
|
||||
.endm
|
||||
|
||||
.macro chosenstatus2animation battler:req, status:req
|
||||
chosenstatusanimation \battler, 0x1, \status
|
||||
.macro setmoveeffect effect:req
|
||||
sethword sMOVE_EFFECT, \effect
|
||||
sethword sSAVED_MOVE_EFFECT, \effect
|
||||
.endm
|
||||
|
||||
.macro sethword dst:req, value:req
|
||||
|
|
|
|||
|
|
@ -1329,7 +1329,7 @@ BattleScript_EffectPowder::
|
|||
attackstring
|
||||
ppreduce
|
||||
jumpifvolatile BS_TARGET, VOLATILE_POWDER, BattleScript_ButItFailed
|
||||
setpowder BS_TARGET
|
||||
setvolatile BS_TARGET, VOLATILE_POWDER
|
||||
attackanimation
|
||||
waitanimation
|
||||
printstring STRINGID_COVEREDINPOWDER
|
||||
|
|
@ -3929,7 +3929,7 @@ BattleScript_EffectForesight::
|
|||
ppreduce
|
||||
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
|
||||
jumpifvolatile BS_TARGET, VOLATILE_FORESIGHT, BattleScript_ButItFailed
|
||||
setforesight
|
||||
setvolatile BS_TARGET, VOLATILE_FORESIGHT
|
||||
BattleScript_IdentifiedFoe:
|
||||
attackanimation
|
||||
waitanimation
|
||||
|
|
@ -4026,7 +4026,7 @@ BattleScript_TryDestinyKnotTarget:
|
|||
infatuatewithbattler BS_TARGET, BS_ATTACKER
|
||||
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT
|
||||
waitanimation
|
||||
status2animation BS_TARGET, STATUS2_INFATUATION
|
||||
volatileanimation BS_TARGET, VOLATILE_INFATUATION
|
||||
waitanimation
|
||||
printstring STRINGID_DESTINYKNOTACTIVATES
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
|
|
@ -4038,7 +4038,7 @@ BattleScript_TryDestinyKnotAttacker:
|
|||
infatuatewithbattler BS_ATTACKER, BS_TARGET
|
||||
playanimation BS_TARGET, B_ANIM_HELD_ITEM_EFFECT
|
||||
waitanimation
|
||||
status2animation BS_ATTACKER, STATUS2_INFATUATION
|
||||
volatileanimation BS_ATTACKER, VOLATILE_INFATUATION
|
||||
waitanimation
|
||||
printstring STRINGID_DESTINYKNOTACTIVATES
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
|
|
@ -4332,7 +4332,7 @@ BattleScript_EffectDefenseCurl::
|
|||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
setdefensecurlbit
|
||||
setvolatile BS_TARGET, VOLATILE_DEFENSE_CURL
|
||||
setstatchanger STAT_DEF, 1, FALSE
|
||||
statbuffchange BS_ATTACKER, STAT_CHANGE_ALLOW_PTR | STAT_CHANGE_ONLY_CHECKING, BattleScript_DefenseCurlDoStatUpAnim
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_StatUpPrintString
|
||||
|
|
@ -6866,7 +6866,7 @@ BattleScript_PrintUproarOverTurns::
|
|||
end2
|
||||
|
||||
BattleScript_ThrashConfuses::
|
||||
chosenstatus2animation BS_ATTACKER, STATUS2_CONFUSION
|
||||
volatileanimation BS_ATTACKER, VOLATILE_CONFUSION
|
||||
printstring STRINGID_PKMNFATIGUECONFUSION
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
|
|
@ -6874,7 +6874,7 @@ BattleScript_ThrashConfuses::
|
|||
BattleScript_MoveUsedIsConfused::
|
||||
printstring STRINGID_PKMNISCONFUSED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
status2animation BS_ATTACKER, STATUS2_CONFUSION
|
||||
volatileanimation BS_ATTACKER, VOLATILE_CONFUSION
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, FALSE, BattleScript_MoveUsedIsConfusedRet
|
||||
BattleScript_DoSelfConfusionDmg::
|
||||
cancelmultiturnmoves BS_ATTACKER
|
||||
|
|
@ -6900,7 +6900,7 @@ BattleScript_MoveUsedPowder::
|
|||
ppreduce
|
||||
pause B_WAIT_TIME_SHORT
|
||||
cancelmultiturnmoves BS_ATTACKER
|
||||
status2animation BS_ATTACKER, STATUS2_POWDER
|
||||
volatileanimation BS_ATTACKER, VOLATILE_POWDER
|
||||
waitanimation
|
||||
effectivenesssound
|
||||
hitanimation BS_ATTACKER
|
||||
|
|
@ -6938,7 +6938,7 @@ BattleScript_WrapEnds::
|
|||
BattleScript_MoveUsedIsInLove::
|
||||
printstring STRINGID_PKMNINLOVE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
status2animation BS_ATTACKER, STATUS2_INFATUATION
|
||||
volatileanimation BS_ATTACKER, VOLATILE_INFATUATION
|
||||
return
|
||||
|
||||
BattleScript_MoveUsedIsInLoveCantAttack::
|
||||
|
|
@ -6949,13 +6949,13 @@ BattleScript_MoveUsedIsInLoveCantAttack::
|
|||
BattleScript_NightmareTurnDmg::
|
||||
printstring STRINGID_PKMNLOCKEDINNIGHTMARE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
status2animation BS_ATTACKER, STATUS2_NIGHTMARE
|
||||
volatileanimation BS_ATTACKER, VOLATILE_NIGHTMARE
|
||||
goto BattleScript_DoTurnDmg
|
||||
|
||||
BattleScript_CurseTurnDmg::
|
||||
printstring STRINGID_PKMNAFFLICTEDBYCURSE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
status2animation BS_ATTACKER, STATUS2_CURSED
|
||||
volatileanimation BS_ATTACKER, VOLATILE_CURSED
|
||||
goto BattleScript_DoTurnDmg
|
||||
|
||||
BattleScript_TargetPRLZHeal::
|
||||
|
|
@ -7085,7 +7085,7 @@ BattleScript_MoveEffectWrap::
|
|||
return
|
||||
|
||||
BattleScript_MoveEffectConfusion::
|
||||
chosenstatus2animation BS_EFFECT_BATTLER, STATUS2_CONFUSION
|
||||
volatileanimation BS_EFFECT_BATTLER, VOLATILE_CONFUSION
|
||||
printstring STRINGID_PKMNWASCONFUSED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
|
@ -8195,7 +8195,7 @@ BattleScript_BanefulBunkerEffect::
|
|||
|
||||
BattleScript_CuteCharmActivates::
|
||||
call BattleScript_AbilityPopUp
|
||||
status2animation BS_ATTACKER, STATUS2_INFATUATION
|
||||
volatileanimation BS_ATTACKER, VOLATILE_INFATUATION
|
||||
printstring STRINGID_PKMNSXINFATUATEDY
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
call BattleScript_TryDestinyKnotTarget
|
||||
|
|
@ -9455,9 +9455,9 @@ BattleScript_EffectConfuseSide::
|
|||
BattleScript_ConfuseSideLoop:
|
||||
jumpifabsent BS_TARGET, BattleScript_ConfuseSideIncrement
|
||||
trysetconfusion BattleScript_ConfuseSideIncrement
|
||||
status2animation BS_EFFECT_BATTLER, STATUS2_CONFUSION
|
||||
volatileanimation BS_EFFECT_BATTLER, VOLATILE_CONFUSION
|
||||
BattleScript_ConfuseSidePrintMessage:
|
||||
printfromtable gStatus2StringIds
|
||||
printstring STRINGID_PKMNWASCONFUSED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_ConfuseSideIncrement:
|
||||
jumpifbytenotequal gBattlerTarget, sBATTLER, BattleScript_ConfuseSideEnd
|
||||
|
|
@ -9477,9 +9477,9 @@ BattleScript_EffectInfatuateSide::
|
|||
BattleScript_InfatuateSideLoop:
|
||||
jumpifabsent BS_TARGET, BattleScript_InfatuateSideIncrement
|
||||
trysetinfatuation BattleScript_InfatuateSideIncrement
|
||||
status2animation BS_EFFECT_BATTLER, STATUS2_INFATUATION
|
||||
volatileanimation BS_EFFECT_BATTLER, VOLATILE_INFATUATION
|
||||
BattleScript_InfatuateSidePrintMessage:
|
||||
printfromtable gStatus2StringIds
|
||||
printstring STRINGID_PKMNFELLINLOVE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_InfatuateSideIncrement:
|
||||
jumpifbytenotequal gBattlerTarget, sBATTLER, BattleScript_InfatuateSideEnd
|
||||
|
|
@ -9495,7 +9495,7 @@ BattleScript_TormentSideLoop:
|
|||
jumpifabsent BS_TARGET, BattleScript_TormentSideIncrement
|
||||
trysettorment BattleScript_TormentSideIncrement
|
||||
BattleScript_TormentSidePrintMessage:
|
||||
printfromtable gStatus2StringIds
|
||||
printstring STRINGID_PKMNSUBJECTEDTOTORMENT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_TormentSideIncrement:
|
||||
jumpifbytenotequal gBattlerTarget, sBATTLER, BattleScript_TormentSideEnd
|
||||
|
|
@ -9516,7 +9516,7 @@ BattleScript_MeanLookSideLoop:
|
|||
jumpifabsent BS_TARGET, BattleScript_MeanLookSideIncrement
|
||||
trysetescapeprevention BattleScript_MeanLookSideIncrement
|
||||
BattleScript_MeanLookSidePrintMessage:
|
||||
printfromtable gStatus2StringIds
|
||||
printstring STRINGID_TARGETCANTESCAPENOW
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_MeanLookSideIncrement:
|
||||
jumpifbytenotequal gBattlerTarget, sBATTLER, BattleScript_MeanLookSideEnd
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ void BS_TrySetOctolock(void)
|
|||
else
|
||||
{
|
||||
gDisableStructs[battler].octolock = TRUE;
|
||||
gBattleMons[battler].status2 |= STATUS2_ESCAPE_PREVENTION;
|
||||
gBattleMons[battler].volatiles.escapePrevention = TRUE;
|
||||
gDisableStructs[battler].battlerPreventingEscape = gBattlerAttacker;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
// Used to exclude moves learned temporarily by Transform or Mimic
|
||||
#define MOVE_IS_PERMANENT(battler, moveSlot) \
|
||||
(!(gBattleMons[battler].status2 & STATUS2_TRANSFORMED) \
|
||||
(!(gBattleMons[battler].volatiles.transformed) \
|
||||
&& !(gDisableStructs[battler].mimickedMoves & (1u << moveSlot)))
|
||||
|
||||
// Battle Actions
|
||||
|
|
|
|||
|
|
@ -301,8 +301,8 @@ void BtlController_EmitChooseItem(u32 battler, u32 bufferId, u8 *battlePartyOrde
|
|||
void BtlController_EmitChoosePokemon(u32 battler, u32 bufferId, u8 caseId, u8 slotId, u16 abilityId, u8 battlerPreventingSwitchout, u8 *data);
|
||||
void BtlController_EmitHealthBarUpdate(u32 battler, u32 bufferId, u16 hpValue);
|
||||
void BtlController_EmitExpUpdate(u32 battler, u32 bufferId, u8 partyId, s32 expPoints);
|
||||
void BtlController_EmitStatusIconUpdate(u32 battler, u32 bufferId, u32 status1, u32 status2);
|
||||
void BtlController_EmitStatusAnimation(u32 battler, u32 bufferId, bool8 status2, u32 status);
|
||||
void BtlController_EmitStatusIconUpdate(u32 battler, u32 bufferId, u32 status);
|
||||
void BtlController_EmitStatusAnimation(u32 battler, u32 bufferId, bool8 isVolatile, u32 status);
|
||||
void BtlController_EmitDataTransfer(u32 battler, u32 bufferId, u16 size, void *data);
|
||||
void BtlController_EmitTwoReturnValues(u32 battler, u32 bufferId, u8 ret8, u32 ret32);
|
||||
void BtlController_EmitChosenMonReturnValue(u32 battler, u32 bufferId, u8 partyId, u8 *battlePartyOrder);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ u16 ChooseMoveAndTargetInBattlePalace(u32 battler);
|
|||
void SpriteCB_WaitForBattlerBallReleaseAnim(struct Sprite *sprite);
|
||||
void SpriteCB_TrainerSlideIn(struct Sprite *sprite);
|
||||
void SpriteCB_TrainerSpawn(struct Sprite *sprite);
|
||||
void InitAndLaunchChosenStatusAnimation(u32 battler, bool32 isStatus2, u32 status);
|
||||
void InitAndLaunchChosenStatusAnimation(u32 battler, bool32 isVolatile, u32 status);
|
||||
bool8 TryHandleLaunchBattleTableAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId, u16 argument);
|
||||
void InitAndLaunchSpecialAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId);
|
||||
bool8 IsBattleSEPlaying(u8 battler);
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ void SpriteCB_TrainerThrowObject(struct Sprite *sprite);
|
|||
void AnimSetCenterToCornerVecX(struct Sprite *sprite);
|
||||
void BeginBattleIntroDummy(void);
|
||||
void BeginBattleIntro(void);
|
||||
void SwitchInClearSetData(u32 battler);
|
||||
void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy);
|
||||
const u8* FaintClearSetData(u32 battler);
|
||||
void BattleTurnPassed(void);
|
||||
u8 IsRunningFromBattleImpossible(u32 battler);
|
||||
|
|
|
|||
|
|
@ -392,9 +392,10 @@ 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);
|
||||
void SetMonVolatile(u32 battler, enum Volatile volatile, u32 newValue);
|
||||
u32 GetMonVolatile(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);
|
||||
void PushHazardTypeToQueue(u32 side, enum Hazards hazardType);
|
||||
bool32 IsHazardOnSide(u32 side, enum Hazards hazardType);
|
||||
bool32 AreAnyHazardsOnSide(u32 side);
|
||||
|
|
|
|||
|
|
@ -142,23 +142,21 @@ enum VolatileFlags
|
|||
V_BATON_PASSABLE = (1 << 0),
|
||||
};
|
||||
|
||||
// Volatile status ailments
|
||||
// These are removed after exiting the battle or switching
|
||||
/* Definitions with names e.g. "Confusion" are accessible in the debug menu
|
||||
* Enum, Type, (Field name, (optional)bitSize), Flags, (optional)(Debug menu header, (optional)max. value)
|
||||
*/
|
||||
/* Volatile status ailments
|
||||
* These are removed after exiting the battle or switching
|
||||
* Enum, Type Type, max value, flags */
|
||||
#define VOLATILE_DEFINITIONS(F) \
|
||||
F(VOLATILE_CONFUSION, confusionTurns, (u32, 3), V_BATON_PASSABLE) \
|
||||
F(VOLATILE_CONFUSION, confusionTurns, (u32, 6), V_BATON_PASSABLE) \
|
||||
F(VOLATILE_FLINCHED, flinched, (u32, 1)) \
|
||||
F(VOLATILE_UPROAR, uproarTurns, (u32, 3)) \
|
||||
F(VOLATILE_UPROAR, uproarTurns, (u32, 5)) \
|
||||
F(VOLATILE_TORMENT, torment, (u32, 1)) \
|
||||
F(VOLATILE_BIDE, bideTurns, (u32, 2)) \
|
||||
F(VOLATILE_LOCK_CONFUSE, lockConfusionTurns, (u32, 2)) \
|
||||
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, (u32, 4)) \
|
||||
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)) \
|
||||
|
|
@ -174,18 +172,22 @@ enum VolatileFlags
|
|||
F(VOLATILE_MUD_SPORT, mudSport, (u32, 1), V_BATON_PASSABLE) \
|
||||
F(VOLATILE_WATER_SPORT, waterSport, (u32, 1), V_BATON_PASSABLE)
|
||||
|
||||
/* Use within a macro to get the maximum allowed value for a volatile. Requires _typeBitSize and debug parameters as input. */
|
||||
#define GET_VOLATILE_MAXIMUM(_typeBitSize, ...) INVOKE_WITH_B(GET_VOLATILE_MAXIMUM_, _typeBitSize)
|
||||
#define GET_VOLATILE_MAXIMUM_(_type, ...) FIRST(__VA_OPT__(MAX_BITS(FIRST(__VA_ARGS__)),) MAX_BITS((sizeof(_type) * 8)))
|
||||
/* 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)
|
||||
#define GET_VOLATILE_MAXIMUM_(_type, ...) FIRST(__VA_OPT__(FIRST(__VA_ARGS__),) MAX_BITS((sizeof(_type) * 8)))
|
||||
|
||||
#define UNPACK_VOLATILE_ENUMS(_enum, ...) _enum,
|
||||
|
||||
enum Volatile
|
||||
{
|
||||
VOLATILE_NONE,
|
||||
VOLATILE_DEFINITIONS(UNPACK_VOLATILE_ENUMS)
|
||||
/* Expands to VOLATILE_CONFUSION, VOLATILE_FLINCHED, etc. */
|
||||
};
|
||||
|
||||
// Helper macros
|
||||
#define INFATUATED_WITH(battler) (battler + 1)
|
||||
|
||||
// Old flags
|
||||
#define STATUS2_CONFUSION (1 << 0 | 1 << 1 | 1 << 2)
|
||||
#define STATUS2_CONFUSION_TURN(num) ((num) << 0)
|
||||
|
|
|
|||
|
|
@ -149,7 +149,6 @@ enum CmdVarious
|
|||
VARIOUS_SET_AURORA_VEIL,
|
||||
VARIOUS_TRY_THIRD_TYPE,
|
||||
VARIOUS_ACUPRESSURE,
|
||||
VARIOUS_SET_POWDER,
|
||||
VARIOUS_GRAVITY_ON_AIRBORNE_MONS,
|
||||
VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS,
|
||||
VARIOUS_JUMP_IF_ROAR_FAILS,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define GUARD_ITEM_H
|
||||
|
||||
#include "constants/item.h"
|
||||
#include "constants/item_effects.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/moves.h"
|
||||
#include "constants/tms_hms.h"
|
||||
|
|
@ -187,7 +188,7 @@ u8 GetItemBattleUsage(u16 itemId);
|
|||
u32 GetItemSecondaryId(u32 itemId);
|
||||
u32 GetItemFlingPower(u32 itemId);
|
||||
u32 GetItemStatus1Mask(u16 itemId);
|
||||
u32 GetItemStatus2Mask(u16 itemId);
|
||||
bool32 ItemHasVolatileFlag(u16 itemId, enum Volatile volatile);
|
||||
u32 GetItemSellPrice(u32 itemId);
|
||||
|
||||
#endif // GUARD_ITEM_H
|
||||
|
|
|
|||
|
|
@ -120,42 +120,51 @@
|
|||
#define DEFAULT_3(_default, ...) DEFAULT(_default __VA_OPT__(, THIRD(__VA_ARGS__)))
|
||||
#define DEFAULT_4(_default, ...) DEFAULT(_default __VA_OPT__(, FOURTH(__VA_ARGS__)))
|
||||
|
||||
/* Simply a lists numbers 0-31, allows for word-spanning macros */
|
||||
#define BITS_32(F, ...) \
|
||||
F(0, __VA_ARGS__) \
|
||||
F(1, __VA_ARGS__) \
|
||||
F(2, __VA_ARGS__) \
|
||||
F(3, __VA_ARGS__) \
|
||||
F(4, __VA_ARGS__) \
|
||||
F(5, __VA_ARGS__) \
|
||||
F(6, __VA_ARGS__) \
|
||||
F(7, __VA_ARGS__) \
|
||||
F(8, __VA_ARGS__) \
|
||||
F(9, __VA_ARGS__) \
|
||||
F(10, __VA_ARGS__) \
|
||||
F(11, __VA_ARGS__) \
|
||||
F(12, __VA_ARGS__) \
|
||||
F(13, __VA_ARGS__) \
|
||||
F(14, __VA_ARGS__) \
|
||||
F(15, __VA_ARGS__) \
|
||||
F(16, __VA_ARGS__) \
|
||||
F(17, __VA_ARGS__) \
|
||||
F(18, __VA_ARGS__) \
|
||||
F(19, __VA_ARGS__) \
|
||||
F(20, __VA_ARGS__) \
|
||||
F(21, __VA_ARGS__) \
|
||||
F(22, __VA_ARGS__) \
|
||||
F(23, __VA_ARGS__) \
|
||||
F(24, __VA_ARGS__) \
|
||||
F(25, __VA_ARGS__) \
|
||||
F(26, __VA_ARGS__) \
|
||||
F(27, __VA_ARGS__) \
|
||||
F(28, __VA_ARGS__) \
|
||||
F(29, __VA_ARGS__) \
|
||||
F(30, __VA_ARGS__) \
|
||||
F(31, __VA_ARGS__)
|
||||
|
||||
/* Compares _n to 1 shifted by _b by _operation (==, <, > etc) */
|
||||
#define OP_BIT_SHIFT(_b, _n, _operation) (_n) _operation (1 << _b) ? _b :
|
||||
|
||||
/* (Credit to MGriffin) A rather monstrous way of finding the set bit in a word.
|
||||
Invalid input causes a compiler error. Sample: https://cexplore.karathan.at/z/x1hm7B */
|
||||
#define BIT_INDEX(n) \
|
||||
(n) == (1 << 0) ? 0 : \
|
||||
(n) == (1 << 1) ? 1 : \
|
||||
(n) == (1 << 2) ? 2 : \
|
||||
(n) == (1 << 3) ? 3 : \
|
||||
(n) == (1 << 4) ? 4 : \
|
||||
(n) == (1 << 5) ? 5 : \
|
||||
(n) == (1 << 6) ? 6 : \
|
||||
(n) == (1 << 7) ? 7 : \
|
||||
(n) == (1 << 8) ? 8 : \
|
||||
(n) == (1 << 9) ? 9 : \
|
||||
(n) == (1 << 10) ? 10 : \
|
||||
(n) == (1 << 11) ? 11 : \
|
||||
(n) == (1 << 12) ? 12 : \
|
||||
(n) == (1 << 13) ? 13 : \
|
||||
(n) == (1 << 14) ? 14 : \
|
||||
(n) == (1 << 15) ? 15 : \
|
||||
(n) == (1 << 16) ? 16 : \
|
||||
(n) == (1 << 17) ? 17 : \
|
||||
(n) == (1 << 18) ? 18 : \
|
||||
(n) == (1 << 19) ? 19 : \
|
||||
(n) == (1 << 20) ? 20 : \
|
||||
(n) == (1 << 21) ? 21 : \
|
||||
(n) == (1 << 22) ? 22 : \
|
||||
(n) == (1 << 23) ? 23 : \
|
||||
(n) == (1 << 24) ? 24 : \
|
||||
(n) == (1 << 25) ? 25 : \
|
||||
(n) == (1 << 26) ? 26 : \
|
||||
(n) == (1 << 27) ? 27 : \
|
||||
(n) == (1 << 28) ? 28 : \
|
||||
(n) == (1 << 29) ? 29 : \
|
||||
(n) == (1 << 30) ? 30 : \
|
||||
(n) == (1 << 31) ? 31 : \
|
||||
*(u32 *)NULL
|
||||
#define BIT_INDEX(_n) BITS_32(OP_BIT_SHIFT, _n, ==) *(u32 *)NULL
|
||||
|
||||
/* (Credit to MGriffin) A way to find the minimum required number of bits to
|
||||
store a number (max: 32). Sample: https://godbolt.org/z/xb4KdPMhT */
|
||||
#define BIT_SIZE(_n) (BITS_32(OP_BIT_SHIFT, _n, <) 32)
|
||||
|
||||
#define COMPRESS_BITS_0 0, 1
|
||||
#define COMPRESS_BITS_1 1, 1
|
||||
|
|
@ -167,11 +176,10 @@ Invalid input causes a compiler error. Sample: https://cexplore.karathan.at/z/x1
|
|||
#define COMPRESS_BITS_7 7, 1
|
||||
|
||||
/* Will try and compress a set bit (or up to three sequential bits) into a single byte
|
||||
Input must be of the form (upper << lower) where upper can be up to 3, lower up to 31 */
|
||||
Input must be of the form (upper << lower) where upper can be up to 7, lower up to 31 */
|
||||
#define COMPRESS_BITS(_val) COMPRESS_BITS_STEP_2 _val
|
||||
#define COMPRESS_BITS_STEP_2(_unpacked) COMPRESS_BITS_STEP_3(COMPRESS_BITS_## _unpacked)
|
||||
#define COMPRESS_BITS_STEP_3(...) COMPRESS_BITS_STEP_4(__VA_ARGS__)
|
||||
#define COMPRESS_BITS_STEP_4(upper, lower) (((upper % 8) << 5) + (BIT_INDEX(lower)))
|
||||
#define COMPRESS_BITS_STEP_2(_unpacked) INVOKE(COMPRESS_BITS_STEP_3, COMPRESS_BITS_## _unpacked)
|
||||
#define COMPRESS_BITS_STEP_3(upper, lower) (((upper % 8) << 5) + (BIT_INDEX(lower)))
|
||||
|
||||
/* Will read a compressed bit stored by COMPRESS_BIT into a single byte */
|
||||
#define UNCOMPRESS_BITS(compressed) ((compressed >> 5) << (compressed & 0x1F))
|
||||
|
|
|
|||
|
|
@ -310,8 +310,8 @@ enum {
|
|||
MON_SPR_GFX_MANAGERS_COUNT
|
||||
};
|
||||
|
||||
#define UNPACK_VOLATILE_STRUCT(_enum, _fieldName, _typeBitSize, ...) INVOKE(UNPACK_VOLATILE_STRUCT_, _fieldName, UNPACK_B(_typeBitSize));
|
||||
#define UNPACK_VOLATILE_STRUCT_(_fieldName, _type, ...) _type FIRST(__VA_OPT__(_fieldName:FIRST(__VA_ARGS__),) _fieldName)
|
||||
#define UNPACK_VOLATILE_STRUCT(_enum, _fieldName, _typeMaxValue, ...) INVOKE(UNPACK_VOLATILE_STRUCT_, _fieldName, UNPACK_B(_typeMaxValue));
|
||||
#define UNPACK_VOLATILE_STRUCT_(_fieldName, _type, ...) _type FIRST(__VA_OPT__(_fieldName:BIT_SIZE(FIRST(__VA_ARGS__)),) _fieldName)
|
||||
|
||||
struct Volatiles
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1653,19 +1653,21 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
// AI_CBM_HighRiskForDamage
|
||||
if (aiData->abilities[battlerDef] == ABILITY_WONDER_GUARD && effectiveness < UQ_4_12(2.0))
|
||||
ADJUST_SCORE(-10);
|
||||
if (HasDamagingMove(battlerDef) && !((gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE)
|
||||
if (HasDamagingMove(battlerDef) && !(gBattleMons[battlerAtk].volatiles.substitute
|
||||
|| IsBattlerIncapacitated(battlerDef, abilityDef)
|
||||
|| gBattleMons[battlerDef].volatiles.infatuation
|
||||
|| gBattleMons[battlerDef].volatiles.confusionTurns))
|
||||
ADJUST_SCORE(-10);
|
||||
if (HasMoveWithEffect(battlerAtk, EFFECT_SUBSTITUTE) && !(gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE))
|
||||
if (HasMoveWithEffect(battlerAtk, EFFECT_SUBSTITUTE) && !gBattleMons[battlerAtk].volatiles.substitute)
|
||||
ADJUST_SCORE(-10);
|
||||
if (HasNonVolatileMoveEffect(battlerAtk, MOVE_EFFECT_SLEEP) && ! (gBattleMons[battlerDef].status1 & STATUS1_SLEEP))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_COUNTER:
|
||||
case EFFECT_MIRROR_COAT:
|
||||
if (IsBattlerIncapacitated(battlerDef, aiData->abilities[battlerDef]) || gBattleMons[battlerDef].status2 & (STATUS2_INFATUATION | STATUS2_CONFUSION))
|
||||
if (IsBattlerIncapacitated(battlerDef, aiData->abilities[battlerDef])
|
||||
|| gBattleMons[battlerDef].volatiles.infatuation
|
||||
|| gBattleMons[battlerDef].volatiles.confusionTurns > 0)
|
||||
ADJUST_SCORE(-1);
|
||||
if ((predictedMove == MOVE_NONE || GetBattleMoveCategory(predictedMove) == DAMAGE_CATEGORY_STATUS
|
||||
|| DoesSubstituteBlockMove(battlerAtk, BATTLE_PARTNER(battlerDef), predictedMove))
|
||||
|
|
@ -1717,7 +1719,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_FOCUS_ENERGY:
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY_ANY)
|
||||
if (gBattleMons[battlerAtk].volatiles.dragonCheer || gBattleMons[battlerAtk].volatiles.focusEnergy)
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_CONFUSE:
|
||||
|
|
@ -1727,7 +1729,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_SUBSTITUTE:
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE || aiData->abilities[battlerDef] == ABILITY_INFILTRATOR)
|
||||
if (gBattleMons[battlerAtk].volatiles.substitute || aiData->abilities[battlerDef] == ABILITY_INFILTRATOR)
|
||||
ADJUST_SCORE(-8);
|
||||
else if (aiData->hpPercents[battlerAtk] <= 25)
|
||||
ADJUST_SCORE(-10);
|
||||
|
|
@ -1737,7 +1739,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
case EFFECT_SHED_TAIL:
|
||||
if (CountUsablePartyMons(battlerAtk) == 0)
|
||||
ADJUST_SCORE(-10);
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE || aiData->abilities[battlerDef] == ABILITY_INFILTRATOR)
|
||||
if (gBattleMons[battlerAtk].volatiles.substitute || aiData->abilities[battlerDef] == ABILITY_INFILTRATOR)
|
||||
ADJUST_SCORE(-8);
|
||||
else if (aiData->hpPercents[battlerAtk] <= 50)
|
||||
ADJUST_SCORE(-10);
|
||||
|
|
@ -1808,7 +1810,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_NIGHTMARE:
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_NIGHTMARE)
|
||||
if (gBattleMons[battlerDef].volatiles.nightmare)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (!AI_IsBattlerAsleepOrComatose(battlerDef))
|
||||
ADJUST_SCORE(-8);
|
||||
|
|
@ -1818,7 +1820,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
case EFFECT_CURSE:
|
||||
if (IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GHOST))
|
||||
{
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_CURSED
|
||||
if (gBattleMons[battlerDef].volatiles.cursed
|
||||
|| DoesPartnerHaveSameMoveEffect(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
else if (aiData->hpPercents[battlerAtk] <= 50)
|
||||
|
|
@ -1857,7 +1859,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
ADJUST_SCORE(-10); // only one mon needs to set up Sticky Web
|
||||
break;
|
||||
case EFFECT_FORESIGHT:
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_FORESIGHT)
|
||||
if (gBattleMons[battlerDef].volatiles.foresight)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (gBattleMons[battlerDef].statStages[STAT_EVASION] <= 4
|
||||
|| !(IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST))
|
||||
|
|
@ -1945,7 +1947,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
case EFFECT_BATON_PASS:
|
||||
if (CountUsablePartyMons(battlerAtk) == 0)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE
|
||||
else if (gBattleMons[battlerAtk].volatiles.substitute
|
||||
|| (gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_AQUA_RING | STATUS3_MAGNET_RISE | STATUS3_POWER_TRICK))
|
||||
|| AnyStatIsRaised(battlerAtk))
|
||||
break;
|
||||
|
|
@ -2005,7 +2007,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
case EFFECT_TORMENT:
|
||||
if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (gBattleMons[battlerDef].status2 & STATUS2_TORMENT
|
||||
else if (gBattleMons[battlerDef].volatiles.torment
|
||||
|| DoesPartnerHaveSameMoveEffect(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove))
|
||||
{
|
||||
ADJUST_SCORE(-10);
|
||||
|
|
@ -2162,8 +2164,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
ADJUST_SCORE(-6);
|
||||
break;
|
||||
case EFFECT_TRANSFORM:
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_TRANSFORMED
|
||||
|| (gBattleMons[battlerDef].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE))) //Leave out Illusion b/c AI is supposed to be fooled
|
||||
if (gBattleMons[battlerAtk].volatiles.transformed
|
||||
|| gBattleMons[battlerDef].volatiles.transformed
|
||||
|| gBattleMons[battlerDef].volatiles.substitute) //Leave out Illusion b/c AI is supposed to be fooled
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_SPITE:
|
||||
|
|
@ -2206,7 +2209,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
case EFFECT_DESTINY_BOND:
|
||||
if (DoesDestinyBondFail(battlerAtk))
|
||||
ADJUST_SCORE(-10);
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_DESTINY_BOND)
|
||||
if (gBattleMons[battlerDef].volatiles.destinyBond)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX)
|
||||
ADJUST_SCORE(-10);
|
||||
|
|
@ -2703,7 +2706,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
|| MoveHasAdditionalEffectSelf(instructedMove, MOVE_EFFECT_RECHARGE)
|
||||
|| IsZMove(instructedMove)
|
||||
|| (gLockedMoves[battlerDef] != 0 && gLockedMoves[battlerDef] != 0xFFFF)
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_MULTIPLETURNS
|
||||
|| gBattleMons[battlerDef].volatiles.multipleTurns
|
||||
|| PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove))
|
||||
{
|
||||
ADJUST_SCORE(-10);
|
||||
|
|
@ -2975,7 +2978,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
ADJUST_SCORE(-7);
|
||||
break;
|
||||
case EFFECT_PERISH_SONG:
|
||||
if (!(gBattleMons[battlerDef].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED)))
|
||||
if (!(gBattleMons[battlerDef].volatiles.escapePrevention || gBattleMons[battlerDef].volatiles.wrapped))
|
||||
{
|
||||
if (IsTrappingMove(aiData->partnerMove) || predictedMove == MOVE_INGRAIN)
|
||||
ADJUST_SCORE(WEAK_EFFECT);
|
||||
|
|
@ -3038,7 +3041,9 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
}
|
||||
break;
|
||||
case EFFECT_DRAGON_CHEER:
|
||||
if (gBattleMons[battlerAtkPartner].status2 & STATUS2_FOCUS_ENERGY_ANY || !HasDamagingMove(battlerAtkPartner))
|
||||
if (gBattleMons[battlerAtkPartner].volatiles.dragonCheer
|
||||
|| gBattleMons[battlerAtkPartner].volatiles.focusEnergy
|
||||
|| !HasDamagingMove(battlerAtkPartner))
|
||||
ADJUST_SCORE(-5);
|
||||
else if (atkPartnerHoldEffect == HOLD_EFFECT_SCOPE_LENS
|
||||
|| IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_DRAGON)
|
||||
|
|
@ -4147,7 +4152,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
|||
}
|
||||
break;
|
||||
case EFFECT_BATON_PASS:
|
||||
if ((gAiLogicData->shouldSwitch & (1u << battlerAtk)) && (gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE
|
||||
if ((gAiLogicData->shouldSwitch & (1u << battlerAtk)) && (gBattleMons[battlerAtk].volatiles.substitute
|
||||
|| (gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_AQUA_RING | STATUS3_MAGNET_RISE | STATUS3_POWER_TRICK))
|
||||
|| AnyStatIsRaised(battlerAtk)))
|
||||
ADJUST_SCORE(BEST_EFFECT);
|
||||
|
|
@ -4411,7 +4416,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
|||
}
|
||||
break;
|
||||
case EFFECT_DEFENSE_CURL:
|
||||
if (HasMoveWithEffect(battlerAtk, EFFECT_ROLLOUT) && !(gBattleMons[battlerAtk].status2 & STATUS2_DEFENSE_CURL))
|
||||
if (HasMoveWithEffect(battlerAtk, EFFECT_ROLLOUT) && !gBattleMons[battlerAtk].volatiles.defenseCurl)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
ADJUST_SCORE(IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_DEF));
|
||||
break;
|
||||
|
|
@ -4456,7 +4461,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
|||
&& BattlerWillFaintFromSecondaryDamage(battlerDef, aiData->abilities[battlerDef]))
|
||||
break; // Don't use if the attract won't have a change to activate
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_ANY
|
||||
|| (gBattleMons[battlerDef].status2 & STATUS2_CONFUSION)
|
||||
|| gBattleMons[battlerDef].volatiles.confusionTurns > 0
|
||||
|| (!AI_CanBattlerEscape(battlerDef) && IsBattlerTrapped(battlerAtk, battlerDef)))
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
else
|
||||
|
|
@ -5049,7 +5054,7 @@ case EFFECT_GUARD_SPLIT:
|
|||
break;
|
||||
case EFFECT_RAPID_SPIN:
|
||||
if ((AreAnyHazardsOnSide(GetBattlerSide(battlerAtk)) && CountUsablePartyMons(battlerAtk) != 0)
|
||||
|| (gStatuses3[battlerAtk] & STATUS3_LEECHSEED || gBattleMons[battlerAtk].status2 & STATUS2_WRAPPED))
|
||||
|| (gStatuses3[battlerAtk] & STATUS3_LEECHSEED || gBattleMons[battlerAtk].volatiles.wrapped))
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
case EFFECT_SPECTRAL_THIEF:
|
||||
ADJUST_SCORE(AI_ShouldCopyStatChanges(battlerAtk, battlerDef));
|
||||
|
|
@ -5204,13 +5209,13 @@ case EFFECT_GUARD_SPLIT:
|
|||
score += AI_TryToClearStats(battlerAtk, battlerDef, FALSE);
|
||||
break;
|
||||
case MOVE_EFFECT_BUG_BITE: // And pluck
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_SUBSTITUTE || aiData->abilities[battlerDef] == ABILITY_STICKY_HOLD)
|
||||
if (gBattleMons[battlerDef].volatiles.substitute || aiData->abilities[battlerDef] == ABILITY_STICKY_HOLD)
|
||||
break;
|
||||
else if (GetItemPocket(aiData->items[battlerDef]) == POCKET_BERRIES)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case MOVE_EFFECT_INCINERATE:
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_SUBSTITUTE || aiData->abilities[battlerDef] == ABILITY_STICKY_HOLD)
|
||||
if (gBattleMons[battlerDef].volatiles.substitute || aiData->abilities[battlerDef] == ABILITY_STICKY_HOLD)
|
||||
break;
|
||||
else if (GetItemPocket(aiData->items[battlerDef]) == POCKET_BERRIES || aiData->holdEffects[battlerDef] == HOLD_EFFECT_GEMS)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
|
|
@ -5949,9 +5954,10 @@ static s32 AI_PredictSwitch(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
{
|
||||
if (aiData->abilities[battlerDef] == ABILITY_WONDER_GUARD && effectiveness < UQ_4_12(2.0))
|
||||
ADJUST_SCORE(10);
|
||||
if (HasDamagingMove(battlerDef) && !((gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE)
|
||||
if (HasDamagingMove(battlerDef) && !(gBattleMons[battlerAtk].volatiles.substitute
|
||||
|| IsBattlerIncapacitated(battlerDef, aiData->abilities[battlerDef])
|
||||
|| gBattleMons[battlerDef].status2 & (STATUS2_INFATUATION | STATUS2_CONFUSION)))
|
||||
|| gBattleMons[battlerDef].volatiles.infatuation
|
||||
|| gBattleMons[battlerDef].volatiles.confusionTurns > 0))
|
||||
ADJUST_SCORE(10);
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -692,7 +692,7 @@ static bool32 ShouldSwitchIfBadlyStatused(u32 battler)
|
|||
&& gAiLogicData->abilities[opposingBattler] != ABILITY_KEEN_EYE
|
||||
&& gAiLogicData->abilities[opposingBattler] != ABILITY_MINDS_EYE
|
||||
&& (B_ILLUMINATE_EFFECT >= GEN_9 && gAiLogicData->abilities[opposingBattler] != ABILITY_ILLUMINATE)
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_FORESIGHT)
|
||||
&& !gBattleMons[battler].volatiles.foresight
|
||||
&& !(gStatuses3[battler] & STATUS3_MIRACLE_EYED))
|
||||
switchMon = FALSE;
|
||||
|
||||
|
|
@ -713,12 +713,12 @@ static bool32 ShouldSwitchIfBadlyStatused(u32 battler)
|
|||
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
|
||||
|
||||
//Cursed
|
||||
if (gBattleMons[battler].status2 & STATUS2_CURSED
|
||||
if (gBattleMons[battler].volatiles.cursed
|
||||
&& (hasStatRaised ? RandomPercentage(RNG_AI_SWITCH_CURSED, GetSwitchChance(SHOULD_SWITCH_CURSED_STATS_RAISED)) : RandomPercentage(RNG_AI_SWITCH_CURSED, GetSwitchChance(SHOULD_SWITCH_CURSED))))
|
||||
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
|
||||
|
||||
//Nightmare
|
||||
if (gBattleMons[battler].status2 & STATUS2_NIGHTMARE
|
||||
if (gBattleMons[battler].volatiles.nightmare
|
||||
&& (hasStatRaised ? RandomPercentage(RNG_AI_SWITCH_NIGHTMARE, GetSwitchChance(SHOULD_SWITCH_NIGHTMARE_STATS_RAISED)) : RandomPercentage(RNG_AI_SWITCH_NIGHTMARE, GetSwitchChance(SHOULD_SWITCH_NIGHTMARE))))
|
||||
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
|
||||
|
||||
|
|
@ -729,7 +729,7 @@ static bool32 ShouldSwitchIfBadlyStatused(u32 battler)
|
|||
}
|
||||
|
||||
// Infatuation
|
||||
if (gBattleMons[battler].status2 & STATUS2_INFATUATION
|
||||
if (gBattleMons[battler].volatiles.infatuation
|
||||
&& !AiExpectsToFaintPlayer(battler)
|
||||
&& gAiLogicData->mostSuitableMonId[battler] != PARTY_SIZE
|
||||
&& RandomPercentage(RNG_AI_SWITCH_INFATUATION, GetSwitchChance(SHOULD_SWITCH_INFATUATION)))
|
||||
|
|
@ -1079,7 +1079,9 @@ bool32 ShouldSwitch(u32 battler)
|
|||
s32 i;
|
||||
s32 availableToSwitch;
|
||||
|
||||
if (gBattleMons[battler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION))
|
||||
if (gBattleMons[battler].volatiles.wrapped)
|
||||
return FALSE;
|
||||
if (gBattleMons[battler].volatiles.escapePrevention)
|
||||
return FALSE;
|
||||
if (gStatuses3[battler] & STATUS3_ROOTED)
|
||||
return FALSE;
|
||||
|
|
@ -1228,7 +1230,9 @@ void ModifySwitchAfterMoveScoring(u32 battler)
|
|||
s32 i;
|
||||
s32 availableToSwitch;
|
||||
|
||||
if (gBattleMons[battler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION))
|
||||
if (gBattleMons[battler].volatiles.wrapped)
|
||||
return;
|
||||
if (gBattleMons[battler].volatiles.escapePrevention)
|
||||
return;
|
||||
if (gStatuses3[battler] & STATUS3_ROOTED)
|
||||
return;
|
||||
|
|
@ -2405,7 +2409,7 @@ static bool32 ShouldUseItem(u32 battler)
|
|||
shouldUse = TRUE;
|
||||
if (itemEffects[3] & ITEM3_PARALYSIS && gBattleMons[battler].status1 & STATUS1_PARALYSIS)
|
||||
shouldUse = TRUE;
|
||||
if (itemEffects[3] & ITEM3_CONFUSION && gBattleMons[battler].status2 & STATUS2_CONFUSION)
|
||||
if (itemEffects[3] & ITEM3_CONFUSION && gBattleMons[battler].volatiles.confusionTurns > 0)
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
case EFFECT_ITEM_INCREASE_STAT:
|
||||
|
|
@ -2417,7 +2421,8 @@ static bool32 ShouldUseItem(u32 battler)
|
|||
break;
|
||||
case EFFECT_ITEM_SET_FOCUS_ENERGY:
|
||||
if (!gDisableStructs[battler].isFirstTurn
|
||||
|| gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY
|
||||
|| gBattleMons[battler].volatiles.dragonCheer
|
||||
|| gBattleMons[battler].volatiles.focusEnergy
|
||||
|| AI_OpponentCanFaintAiWithMod(battler, 0))
|
||||
break;
|
||||
shouldUse = TRUE;
|
||||
|
|
|
|||
|
|
@ -373,7 +373,9 @@ bool32 AI_CanBattlerEscape(u32 battler)
|
|||
|
||||
bool32 IsBattlerTrapped(u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
if (gBattleMons[battlerDef].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED))
|
||||
if (gBattleMons[battlerDef].volatiles.wrapped)
|
||||
return TRUE;
|
||||
if (gBattleMons[battlerDef].volatiles.escapePrevention)
|
||||
return TRUE;
|
||||
if (gStatuses3[battlerDef] & (STATUS3_ROOTED | STATUS3_SKY_DROPPED))
|
||||
return TRUE;
|
||||
|
|
@ -1880,7 +1882,9 @@ bool32 ShouldSetSnow(u32 battler, u32 ability, enum ItemHoldEffect holdEffect)
|
|||
bool32 IsBattlerDamagedByStatus(u32 battler)
|
||||
{
|
||||
return gBattleMons[battler].status1 & STATUS1_DAMAGING
|
||||
|| gBattleMons[battler].status2 & (STATUS2_WRAPPED | STATUS2_NIGHTMARE | STATUS2_CURSED)
|
||||
|| gBattleMons[battler].volatiles.wrapped
|
||||
|| gBattleMons[battler].volatiles.nightmare
|
||||
|| gBattleMons[battler].volatiles.cursed
|
||||
|| gStatuses3[battler] & (STATUS3_PERISH_SONG | STATUS3_LEECHSEED)
|
||||
|| gStatuses4[battler] & (STATUS4_SALT_CURE)
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & (SIDE_STATUS_SEA_OF_FIRE | SIDE_STATUS_DAMAGE_NON_TYPES);
|
||||
|
|
@ -2028,7 +2032,7 @@ u32 IncreaseStatDownScore(u32 battlerAtk, u32 battlerDef, u32 stat)
|
|||
tempScore += WEAK_EFFECT;
|
||||
if (gStatuses3[battlerDef] & STATUS3_ROOTED)
|
||||
tempScore += WEAK_EFFECT;
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_CURSED)
|
||||
if (gBattleMons[battlerDef].volatiles.cursed)
|
||||
tempScore += WEAK_EFFECT;
|
||||
break;
|
||||
case STAT_EVASION:
|
||||
|
|
@ -2038,7 +2042,7 @@ u32 IncreaseStatDownScore(u32 battlerAtk, u32 battlerDef, u32 stat)
|
|||
tempScore += WEAK_EFFECT;
|
||||
if (gStatuses3[battlerDef] & STATUS3_ROOTED)
|
||||
tempScore += WEAK_EFFECT;
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_CURSED)
|
||||
if (gBattleMons[battlerDef].volatiles.cursed)
|
||||
tempScore += WEAK_EFFECT;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2801,7 +2805,7 @@ static u32 GetLeechSeedDamage(u32 battlerId)
|
|||
static u32 GetNightmareDamage(u32 battlerId)
|
||||
{
|
||||
u32 damage = 0;
|
||||
if ((gBattleMons[battlerId].status2 & STATUS2_NIGHTMARE) && gBattleMons[battlerId].status1 & STATUS1_SLEEP)
|
||||
if (gBattleMons[battlerId].volatiles.nightmare && gBattleMons[battlerId].status1 & STATUS1_SLEEP)
|
||||
{
|
||||
damage = GetNonDynamaxMaxHP(battlerId) / 4;
|
||||
if (damage == 0)
|
||||
|
|
@ -2813,7 +2817,7 @@ static u32 GetNightmareDamage(u32 battlerId)
|
|||
static u32 GetCurseDamage(u32 battlerId)
|
||||
{
|
||||
u32 damage = 0;
|
||||
if (gBattleMons[battlerId].status2 & STATUS2_CURSED)
|
||||
if (gBattleMons[battlerId].volatiles.cursed)
|
||||
{
|
||||
damage = GetNonDynamaxMaxHP(battlerId) / 4;
|
||||
if (damage == 0)
|
||||
|
|
@ -2827,7 +2831,7 @@ static u32 GetTrapDamage(u32 battlerId)
|
|||
// ai has no knowledge about turns remaining
|
||||
u32 damage = 0;
|
||||
enum ItemHoldEffect holdEffect = gAiLogicData->holdEffects[gBattleStruct->wrappedBy[battlerId]];
|
||||
if (gBattleMons[battlerId].status2 & STATUS2_WRAPPED)
|
||||
if (gBattleMons[battlerId].volatiles.wrapped)
|
||||
{
|
||||
if (holdEffect == HOLD_EFFECT_BINDING_BAND)
|
||||
damage = GetNonDynamaxMaxHP(battlerId) / (B_BINDING_DAMAGE >= GEN_6 ? 6 : 8);
|
||||
|
|
@ -3233,7 +3237,7 @@ bool32 IsBattlerIncapacitated(u32 battler, u32 ability)
|
|||
if (gBattleMons[battler].status1 & STATUS1_SLEEP && !HasMoveWithEffect(battler, EFFECT_SLEEP_TALK))
|
||||
return TRUE;
|
||||
|
||||
if (gBattleMons[battler].status2 & STATUS2_RECHARGE || (ability == ABILITY_TRUANT && gDisableStructs[battler].truantCounter != 0))
|
||||
if (gBattleMons[battler].volatiles.recharge || (ability == ABILITY_TRUANT && gDisableStructs[battler].truantCounter != 0))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
|
|
@ -3372,7 +3376,7 @@ bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move,
|
|||
|
||||
bool32 AI_CanBeConfused(u32 battlerAtk, u32 battlerDef, u32 move, u32 ability)
|
||||
{
|
||||
if ((gBattleMons[battlerDef].status2 & STATUS2_CONFUSION)
|
||||
if (gBattleMons[battlerDef].volatiles.confusionTurns > 0
|
||||
|| (ability == ABILITY_OWN_TEMPO && !DoesBattlerIgnoreAbilityChecks(battlerAtk, gAiLogicData->abilities[battlerAtk], move))
|
||||
|| IsBattlerTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN)
|
||||
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
||||
|
|
@ -3421,7 +3425,7 @@ bool32 AI_CanGiveFrostbite(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 b
|
|||
|
||||
bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, u32 defAbility)
|
||||
{
|
||||
if ((gBattleMons[battlerDef].status2 & STATUS2_INFATUATION)
|
||||
if (gBattleMons[battlerDef].volatiles.infatuation
|
||||
|| gAiLogicData->effectiveness[battlerAtk][battlerDef][gAiThinkingStruct->movesetIndex] == UQ_4_12(0.0)
|
||||
|| defAbility == ABILITY_OBLIVIOUS
|
||||
|| !AreBattlersOfOppositeGender(battlerAtk, battlerDef)
|
||||
|
|
@ -3441,8 +3445,8 @@ u32 ShouldTryToFlinch(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbi
|
|||
}
|
||||
else if ((atkAbility == ABILITY_SERENE_GRACE
|
||||
|| gBattleMons[battlerDef].status1 & STATUS1_PARALYSIS
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_INFATUATION
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_CONFUSION)
|
||||
|| gBattleMons[battlerDef].volatiles.infatuation
|
||||
|| gBattleMons[battlerDef].volatiles.confusionTurns > 0)
|
||||
|| ((AI_IsFaster(battlerAtk, battlerDef, move)) && CanTargetFaintAi(battlerDef, battlerAtk)))
|
||||
{
|
||||
return 2; // good idea to flinch
|
||||
|
|
@ -4357,8 +4361,8 @@ void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
|
|||
if ((defSpeed >= atkSpeed && defSpeed / 2 < atkSpeed) // You'll go first after paralyzing foe
|
||||
|| IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PARALYSIS)
|
||||
|| (HasMoveWithMoveEffectExcept(battlerAtk, MOVE_EFFECT_FLINCH, EFFECT_FIRST_TURN_ONLY)) // filter out Fake Out
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_INFATUATION
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_CONFUSION)
|
||||
|| gBattleMons[battlerDef].volatiles.infatuation
|
||||
|| gBattleMons[battlerDef].volatiles.confusionTurns > 0)
|
||||
ADJUST_SCORE_PTR(GOOD_EFFECT);
|
||||
else
|
||||
ADJUST_SCORE_PTR(DECENT_EFFECT);
|
||||
|
|
@ -4396,7 +4400,7 @@ void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score
|
|||
&& gAiLogicData->holdEffects[battlerDef] != HOLD_EFFECT_CURE_STATUS)
|
||||
{
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_PARALYSIS
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_INFATUATION
|
||||
|| gBattleMons[battlerDef].volatiles.infatuation
|
||||
|| (gAiLogicData->abilities[battlerAtk] == ABILITY_SERENE_GRACE && HasMoveWithMoveEffectExcept(battlerAtk, MOVE_EFFECT_FLINCH, EFFECT_FIRST_TURN_ONLY)))
|
||||
ADJUST_SCORE_PTR(GOOD_EFFECT);
|
||||
else
|
||||
|
|
@ -4801,9 +4805,9 @@ void IncreaseTidyUpScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
|
|||
if (AreAnyHazardsOnSide(GetBattlerSide(battlerDef)) && CountUsablePartyMons(battlerDef) != 0)
|
||||
ADJUST_SCORE_PTR(-2);
|
||||
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE && AI_IsFaster(battlerAtk, battlerDef, move))
|
||||
if (gBattleMons[battlerAtk].volatiles.substitute && AI_IsFaster(battlerAtk, battlerDef, move))
|
||||
ADJUST_SCORE_PTR(-10);
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_SUBSTITUTE)
|
||||
if (gBattleMons[battlerDef].volatiles.substitute)
|
||||
ADJUST_SCORE_PTR(GOOD_EFFECT);
|
||||
|
||||
if (gStatuses3[battlerAtk] & STATUS3_LEECHSEED)
|
||||
|
|
|
|||
|
|
@ -1025,7 +1025,7 @@ void HandleMoveSwitching(u32 battler)
|
|||
gBattleMons[battler].pp[i] = moveInfo->currentPp[i];
|
||||
}
|
||||
|
||||
if (!(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
|
||||
if (!(gBattleMons[battler].volatiles.transformed))
|
||||
{
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1043,24 +1043,20 @@ void BtlController_EmitExpUpdate(u32 battler, u32 bufferId, u8 partyId, s32 expP
|
|||
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 6);
|
||||
}
|
||||
|
||||
void BtlController_EmitStatusIconUpdate(u32 battler, u32 bufferId, u32 status1, u32 status2)
|
||||
void BtlController_EmitStatusIconUpdate(u32 battler, u32 bufferId, u32 status)
|
||||
{
|
||||
gBattleResources->transferBuffer[0] = CONTROLLER_STATUSICONUPDATE;
|
||||
gBattleResources->transferBuffer[1] = status1;
|
||||
gBattleResources->transferBuffer[2] = (status1 & 0x0000FF00) >> 8;
|
||||
gBattleResources->transferBuffer[3] = (status1 & 0x00FF0000) >> 16;
|
||||
gBattleResources->transferBuffer[4] = (status1 & 0xFF000000) >> 24;
|
||||
gBattleResources->transferBuffer[5] = status2;
|
||||
gBattleResources->transferBuffer[6] = (status2 & 0x0000FF00) >> 8;
|
||||
gBattleResources->transferBuffer[7] = (status2 & 0x00FF0000) >> 16;
|
||||
gBattleResources->transferBuffer[8] = (status2 & 0xFF000000) >> 24;
|
||||
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 9);
|
||||
gBattleResources->transferBuffer[1] = status;
|
||||
gBattleResources->transferBuffer[2] = (status & 0x0000FF00) >> 8;
|
||||
gBattleResources->transferBuffer[3] = (status & 0x00FF0000) >> 16;
|
||||
gBattleResources->transferBuffer[4] = (status & 0xFF000000) >> 24;
|
||||
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 5);
|
||||
}
|
||||
|
||||
void BtlController_EmitStatusAnimation(u32 battler, u32 bufferId, bool8 status2, u32 status)
|
||||
void BtlController_EmitStatusAnimation(u32 battler, u32 bufferId, bool8 isVolatile, u32 status)
|
||||
{
|
||||
gBattleResources->transferBuffer[0] = CONTROLLER_STATUSANIMATION;
|
||||
gBattleResources->transferBuffer[1] = status2;
|
||||
gBattleResources->transferBuffer[1] = isVolatile;
|
||||
gBattleResources->transferBuffer[2] = status;
|
||||
gBattleResources->transferBuffer[3] = (status & 0x0000FF00) >> 8;
|
||||
gBattleResources->transferBuffer[4] = (status & 0x00FF0000) >> 16;
|
||||
|
|
|
|||
|
|
@ -1668,13 +1668,13 @@ static void UpdateBattlerValue(struct BattleDebugMenu *data)
|
|||
if (data->modifyArrows.currValue)
|
||||
{
|
||||
if (IsBattlerAlive(BATTLE_OPPOSITE(data->battlerId)))
|
||||
gBattleMons[data->battlerId].status2 |= STATUS2_INFATUATED_WITH(BATTLE_OPPOSITE(data->battlerId));
|
||||
gBattleMons[data->battlerId].volatiles.infatuation = INFATUATED_WITH(BATTLE_OPPOSITE(data->battlerId));
|
||||
else
|
||||
gBattleMons[data->battlerId].status2 |= STATUS2_INFATUATED_WITH(BATTLE_PARTNER(BATTLE_OPPOSITE(data->battlerId)));
|
||||
gBattleMons[data->battlerId].volatiles.infatuation = INFATUATED_WITH(BATTLE_PARTNER(BATTLE_OPPOSITE(data->battlerId)));
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[data->battlerId].status2 &= ~STATUS2_INFATUATION;
|
||||
gBattleMons[data->battlerId].volatiles.infatuation = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2034,7 +2034,7 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data)
|
|||
data->modifyArrows.maxDigits = 1;
|
||||
data->modifyArrows.modifiedValPtr = NULL;
|
||||
data->modifyArrows.typeOfVal = VAR_IN_LOVE;
|
||||
data->modifyArrows.currValue = (gBattleMons[data->battlerId].status2 & STATUS2_INFATUATION) != 0;
|
||||
data->modifyArrows.currValue = gBattleMons[data->battlerId].volatiles.infatuation;
|
||||
}
|
||||
break;
|
||||
case LIST_ITEM_STATUS1:
|
||||
|
|
@ -2046,7 +2046,7 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data)
|
|||
data->modifyArrows.currValue = GetMonVolatile(data->battlerId, data->currentSecondaryListItemId);
|
||||
data->modifyArrows.typeOfVal = VAL_VOLATILE;
|
||||
data->modifyArrows.minValue = 0;
|
||||
#define UNPACK_VOLATILE_MAX_SIZE(_enum, _fieldName, _typeBitSize, ...) case _enum: data->modifyArrows.maxValue = min(MAX_u16, GET_VOLATILE_MAXIMUM(_typeBitSize)); break;
|
||||
#define UNPACK_VOLATILE_MAX_SIZE(_enum, _fieldName, _typeMaxValue, ...) case _enum: data->modifyArrows.maxValue = min(MAX_u16, GET_VOLATILE_MAXIMUM(_typeMaxValue)); break;
|
||||
switch (data->currentSecondaryListItemId)
|
||||
{
|
||||
VOLATILE_DEFINITIONS(UNPACK_VOLATILE_MAX_SIZE)
|
||||
|
|
|
|||
|
|
@ -181,14 +181,14 @@ void ActivateDynamax(u32 battler)
|
|||
gBattleStruct->dynamax.dynamaxTurns[battler] = gBattleTurnCounter + DYNAMAX_TURNS_COUNT;
|
||||
|
||||
// Substitute is removed upon Dynamaxing.
|
||||
gBattleMons[battler].status2 &= ~STATUS2_SUBSTITUTE;
|
||||
gBattleMons[battler].volatiles.substitute = FALSE;
|
||||
ClearBehindSubstituteBit(battler);
|
||||
|
||||
// Choiced Moves are reset upon Dynamaxing.
|
||||
gBattleStruct->choicedMove[battler] = MOVE_NONE;
|
||||
|
||||
// Try Gigantamax form change.
|
||||
if (!(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)) // Ditto cannot Gigantamax.
|
||||
if (!gBattleMons[battler].volatiles.transformed) // Ditto cannot Gigantamax.
|
||||
TryBattleFormChange(battler, FORM_CHANGE_BATTLE_GIGANTAMAX);
|
||||
|
||||
BattleScriptExecute(BattleScript_DynamaxBegins);
|
||||
|
|
|
|||
|
|
@ -458,21 +458,21 @@ static bool32 HandleEndTurnFirstEventBlock(u32 battler)
|
|||
gBattleStruct->eventBlockCounter++;
|
||||
break;
|
||||
case FIRST_EVENT_BLOCK_THRASH:
|
||||
if (gBattleMons[battler].status2 & STATUS2_LOCK_CONFUSE && !(gStatuses3[battler] & STATUS3_SKY_DROPPED))
|
||||
if (gBattleMons[battler].volatiles.lockConfusionTurns && !(gStatuses3[battler] & STATUS3_SKY_DROPPED))
|
||||
{
|
||||
gBattleMons[battler].status2 -= STATUS2_LOCK_CONFUSE_TURN(1);
|
||||
gBattleMons[battler].volatiles.lockConfusionTurns--;
|
||||
if (WasUnableToUseMove(battler))
|
||||
{
|
||||
CancelMultiTurnMoves(battler, SKY_DROP_IGNORE);
|
||||
}
|
||||
else if (!(gBattleMons[battler].status2 & STATUS2_LOCK_CONFUSE) && (gBattleMons[battler].status2 & STATUS2_MULTIPLETURNS))
|
||||
else if (!gBattleMons[battler].volatiles.lockConfusionTurns && gBattleMons[battler].volatiles.multipleTurns)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~STATUS2_MULTIPLETURNS;
|
||||
if (!(gBattleMons[battler].status2 & STATUS2_CONFUSION))
|
||||
gBattleMons[battler].volatiles.multipleTurns = FALSE;
|
||||
if (!gBattleMons[battler].volatiles.confusionTurns)
|
||||
{
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_CONFUSION;
|
||||
SetMoveEffect(battler, battler, TRUE, FALSE);
|
||||
if (gBattleMons[battler].status2 & STATUS2_CONFUSION)
|
||||
if (gBattleMons[battler].volatiles.confusionTurns)
|
||||
BattleScriptExecute(BattleScript_ThrashConfuses);
|
||||
effect = TRUE;
|
||||
}
|
||||
|
|
@ -705,7 +705,7 @@ static bool32 HandleEndTurnNightmare(u32 battler)
|
|||
|
||||
gBattleStruct->turnEffectsBattlerId++;
|
||||
|
||||
if (gBattleMons[battler].status2 & STATUS2_NIGHTMARE
|
||||
if (gBattleMons[battler].volatiles.nightmare
|
||||
&& IsBattlerAlive(battler)
|
||||
&& !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD))
|
||||
{
|
||||
|
|
@ -719,7 +719,7 @@ static bool32 HandleEndTurnNightmare(u32 battler)
|
|||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[battler].volatiles.nightmare = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -732,7 +732,7 @@ static bool32 HandleEndTurnCurse(u32 battler)
|
|||
|
||||
gBattleStruct->turnEffectsBattlerId++;
|
||||
|
||||
if (gBattleMons[battler].status2 & STATUS2_CURSED
|
||||
if (gBattleMons[battler].volatiles.cursed
|
||||
&& IsBattlerAlive(battler)
|
||||
&& !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD))
|
||||
{
|
||||
|
|
@ -752,7 +752,7 @@ static bool32 HandleEndTurnWrap(u32 battler)
|
|||
|
||||
gBattleStruct->turnEffectsBattlerId++;
|
||||
|
||||
if (gBattleMons[battler].status2 & STATUS2_WRAPPED && IsBattlerAlive(battler))
|
||||
if (gBattleMons[battler].volatiles.wrapped && IsBattlerAlive(battler))
|
||||
{
|
||||
if (--gDisableStructs[battler].wrapTurns != 0)
|
||||
{
|
||||
|
|
@ -773,7 +773,7 @@ static bool32 HandleEndTurnWrap(u32 battler)
|
|||
}
|
||||
else // broke free
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~STATUS2_WRAPPED;
|
||||
gBattleMons[battler].volatiles.wrapped = FALSE;
|
||||
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleStruct->wrappedMove[battler]);
|
||||
BattleScriptExecute(BattleScript_WrapEnds);
|
||||
}
|
||||
|
|
@ -867,7 +867,7 @@ static bool32 HandleEndTurnTorment(u32 battler)
|
|||
|
||||
if (gDisableStructs[battler].tormentTimer == gBattleTurnCounter)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~STATUS2_TORMENT;
|
||||
gBattleMons[battler].volatiles.torment = FALSE;
|
||||
BattleScriptExecute(BattleScript_TormentEnds);
|
||||
effect = TRUE;
|
||||
}
|
||||
|
|
@ -1349,7 +1349,7 @@ static bool32 HandleEndTurnThirdEventBlock(u32 battler)
|
|||
switch (gBattleStruct->eventBlockCounter)
|
||||
{
|
||||
case THIRD_EVENT_BLOCK_UPROAR:
|
||||
if (gBattleMons[battler].status2 & STATUS2_UPROAR)
|
||||
if (gBattleMons[battler].volatiles.uproarTurns)
|
||||
{
|
||||
for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++)
|
||||
{
|
||||
|
|
@ -1357,7 +1357,7 @@ static bool32 HandleEndTurnThirdEventBlock(u32 battler)
|
|||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF)
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP;
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[gBattlerAttacker].volatiles.nightmare = FALSE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||||
BattleScriptExecute(BattleScript_MonWokeUpInUproar);
|
||||
BtlController_EmitSetMonData(gBattlerAttacker, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBattlerAttacker].status1);
|
||||
|
|
@ -1372,16 +1372,16 @@ static bool32 HandleEndTurnThirdEventBlock(u32 battler)
|
|||
else
|
||||
{
|
||||
gBattlerAttacker = battler;
|
||||
gBattleMons[battler].status2 -= STATUS2_UPROAR_TURN(1); // uproar timer goes down
|
||||
gBattleMons[battler].volatiles.uproarTurns--; // uproar timer goes down
|
||||
if (WasUnableToUseMove(battler))
|
||||
{
|
||||
CancelMultiTurnMoves(battler, SKY_DROP_IGNORE);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_UPROAR_ENDS;
|
||||
}
|
||||
else if (gBattleMons[battler].status2 & STATUS2_UPROAR)
|
||||
else if (gBattleMons[battler].volatiles.uproarTurns)
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_UPROAR_CONTINUES;
|
||||
gBattleMons[battler].status2 |= STATUS2_MULTIPLETURNS;
|
||||
gBattleMons[battler].volatiles.multipleTurns = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -459,10 +459,10 @@ static void SpriteCB_TrainerSlideVertical(struct Sprite *sprite)
|
|||
|
||||
#undef sSpeedX
|
||||
|
||||
void InitAndLaunchChosenStatusAnimation(u32 battler, bool32 isStatus2, u32 status)
|
||||
void InitAndLaunchChosenStatusAnimation(u32 battler, bool32 isVolatile, u32 status)
|
||||
{
|
||||
gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = 1;
|
||||
if (!isStatus2)
|
||||
if (!isVolatile)
|
||||
{
|
||||
if (status == STATUS1_FREEZE || status == STATUS1_FROSTBITE)
|
||||
LaunchStatusAnimation(battler, B_ANIM_STATUS_FRZ);
|
||||
|
|
@ -479,13 +479,13 @@ void InitAndLaunchChosenStatusAnimation(u32 battler, bool32 isStatus2, u32 statu
|
|||
}
|
||||
else
|
||||
{
|
||||
if (status & STATUS2_INFATUATION)
|
||||
if (status == VOLATILE_INFATUATION)
|
||||
LaunchStatusAnimation(battler, B_ANIM_STATUS_INFATUATION);
|
||||
else if (status & STATUS2_CONFUSION)
|
||||
else if (status == VOLATILE_CONFUSION)
|
||||
LaunchStatusAnimation(battler, B_ANIM_STATUS_CONFUSION);
|
||||
else if (status & STATUS2_CURSED)
|
||||
else if (status == VOLATILE_CURSED)
|
||||
LaunchStatusAnimation(battler, B_ANIM_STATUS_CURSED);
|
||||
else if (status & STATUS2_NIGHTMARE)
|
||||
else if (status == VOLATILE_NIGHTMARE)
|
||||
LaunchStatusAnimation(battler, B_ANIM_STATUS_NIGHTMARE);
|
||||
else // no animation
|
||||
gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = 0;
|
||||
|
|
|
|||
|
|
@ -3117,14 +3117,13 @@ static void BattleStartClearSetData(void)
|
|||
}
|
||||
}
|
||||
|
||||
#define UNPACK_VOLATILE_BATON_PASSABLES(_enum, _fieldName, _typeBitSize, ...) __VA_OPT__(if ((FIRST(__VA_ARGS__)) & V_BATON_PASSABLE) gBattleMons[battler].volatiles._fieldName = volatilesCopy._fieldName;)
|
||||
#define UNPACK_VOLATILE_BATON_PASSABLES(_enum, _fieldName, _typeMaxValue, ...) __VA_OPT__(if ((FIRST(__VA_ARGS__)) & V_BATON_PASSABLE) gBattleMons[battler].volatiles._fieldName = volatilesCopy->_fieldName;)
|
||||
|
||||
void SwitchInClearSetData(u32 battler)
|
||||
void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy)
|
||||
{
|
||||
s32 i;
|
||||
enum BattleMoveEffects effect = GetMoveEffect(gCurrentMove);
|
||||
struct DisableStruct disableStructCopy = gDisableStructs[battler];
|
||||
struct Volatiles volatilesCopy = gBattleMons[battler].volatiles;
|
||||
|
||||
ClearIllusionMon(battler);
|
||||
if (effect != EFFECT_BATON_PASS)
|
||||
|
|
@ -3133,8 +3132,8 @@ void SwitchInClearSetData(u32 battler)
|
|||
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == battler)
|
||||
gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION;
|
||||
if (gBattleMons[i].volatiles.escapePrevention && gDisableStructs[i].battlerPreventingEscape == battler)
|
||||
gBattleMons[i].volatiles.escapePrevention = FALSE;
|
||||
if ((gStatuses3[i] & STATUS3_ALWAYS_HITS) && gDisableStructs[i].battlerWithSureHit == battler)
|
||||
{
|
||||
gStatuses3[i] &= ~STATUS3_ALWAYS_HITS;
|
||||
|
|
@ -3142,15 +3141,17 @@ void SwitchInClearSetData(u32 battler)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear volatiles - reapply some if Baton Pass was used
|
||||
memset(&gBattleMons[battler].volatiles, 0, sizeof(struct Volatiles));
|
||||
if (effect == EFFECT_BATON_PASS)
|
||||
{
|
||||
// Transfer Baton Passable volatile statuses
|
||||
memset(&gBattleMons[battler].volatiles, 0, sizeof(struct Volatiles));
|
||||
VOLATILE_DEFINITIONS(UNPACK_VOLATILE_BATON_PASSABLES)
|
||||
/* Expands to the following (compiler removes `if` statements):
|
||||
* gBattleMons[battler].volatiles.confusionTurns = volatilesCopy.confusionTurns;
|
||||
* gBattleMons[battler].volatiles.substitute = volatilesCopy.substitute;
|
||||
* gBattleMons[battler].volatiles.escapePrevention = volatilesCopy.escapePrevention;
|
||||
* gBattleMons[battler].volatiles.confusionTurns = volatilesCopy->confusionTurns;
|
||||
* gBattleMons[battler].volatiles.substitute = volatilesCopy->substitute;
|
||||
* gBattleMons[battler].volatiles.escapePrevention = volatilesCopy->escapePrevention;
|
||||
* ...etc
|
||||
*/
|
||||
gStatuses3[battler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED
|
||||
|
|
@ -3172,17 +3173,16 @@ void SwitchInClearSetData(u32 battler)
|
|||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[battler].status2 = 0;
|
||||
gStatuses3[battler] = 0;
|
||||
gStatuses4[battler] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleMons[i].status2 & STATUS2_INFATUATED_WITH(battler))
|
||||
gBattleMons[i].status2 &= ~STATUS2_INFATUATED_WITH(battler);
|
||||
if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && gBattleStruct->wrappedBy[i] == battler)
|
||||
gBattleMons[i].status2 &= ~STATUS2_WRAPPED;
|
||||
if (gBattleMons[i].volatiles.infatuation == INFATUATED_WITH(battler))
|
||||
gBattleMons[i].volatiles.infatuation = 0;
|
||||
if (gBattleMons[i].volatiles.wrapped && gBattleStruct->wrappedBy[i] == battler)
|
||||
gBattleMons[i].volatiles.wrapped = FALSE;
|
||||
if ((gStatuses4[i] & STATUS4_SYRUP_BOMB) && gBattleStruct->stickySyrupdBy[i] == battler)
|
||||
gStatuses4[i] &= ~STATUS4_SYRUP_BOMB;
|
||||
}
|
||||
|
|
@ -3203,7 +3203,7 @@ void SwitchInClearSetData(u32 battler)
|
|||
}
|
||||
else if (effect == EFFECT_SHED_TAIL)
|
||||
{
|
||||
gBattleMons[battler].status2 |= STATUS2_SUBSTITUTE;
|
||||
gBattleMons[battler].volatiles.substitute = TRUE;
|
||||
gDisableStructs[battler].substituteHP = disableStructCopy.substituteHP;
|
||||
}
|
||||
|
||||
|
|
@ -3289,18 +3289,18 @@ const u8* FaintClearSetData(u32 battler)
|
|||
for (i = 0; i < NUM_BATTLE_STATS; i++)
|
||||
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
|
||||
|
||||
gBattleMons[battler].status2 = 0;
|
||||
memset(&gBattleMons[battler].volatiles, 0, sizeof(struct Volatiles));
|
||||
gStatuses3[battler] &= STATUS3_GASTRO_ACID; // Edge case: Keep Gastro Acid if pokemon's ability can have effect after fainting, for example Innards Out.
|
||||
gStatuses4[battler] = 0;
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == battler)
|
||||
gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION;
|
||||
if (gBattleMons[i].status2 & STATUS2_INFATUATED_WITH(battler))
|
||||
gBattleMons[i].status2 &= ~STATUS2_INFATUATED_WITH(battler);
|
||||
if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && gBattleStruct->wrappedBy[i] == battler)
|
||||
gBattleMons[i].status2 &= ~STATUS2_WRAPPED;
|
||||
if (gBattleMons[i].volatiles.escapePrevention && gDisableStructs[i].battlerPreventingEscape == battler)
|
||||
gBattleMons[i].volatiles.escapePrevention = FALSE;
|
||||
if (gBattleMons[i].volatiles.infatuation == INFATUATED_WITH(battler))
|
||||
gBattleMons[i].volatiles.infatuation = 0;
|
||||
if (gBattleMons[i].volatiles.wrapped && gBattleStruct->wrappedBy[i] == battler)
|
||||
gBattleMons[i].volatiles.wrapped = FALSE;
|
||||
if ((gStatuses4[i] & STATUS4_SYRUP_BOMB) && gBattleStruct->stickySyrupdBy[i] == battler)
|
||||
gStatuses4[i] &= ~STATUS4_SYRUP_BOMB;
|
||||
}
|
||||
|
|
@ -3403,17 +3403,17 @@ const u8* FaintClearSetData(u32 battler)
|
|||
|
||||
// If the target was sky dropped in the middle of using Outrage/Petal Dance/Thrash,
|
||||
// confuse them upon release and print "confused via fatigue" message and animation.
|
||||
if (gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE)
|
||||
if (gBattleMons[otherSkyDropper].volatiles.lockConfusionTurns)
|
||||
{
|
||||
gBattleMons[otherSkyDropper].status2 &= ~(STATUS2_LOCK_CONFUSE);
|
||||
gBattleMons[otherSkyDropper].volatiles.lockConfusionTurns = 0;
|
||||
|
||||
// If the released mon can be confused, do so.
|
||||
// Don't use CanBeConfused here, since it can cause issues in edge cases.
|
||||
if (!(GetBattlerAbility(otherSkyDropper) == ABILITY_OWN_TEMPO
|
||||
|| gBattleMons[otherSkyDropper].status2 & STATUS2_CONFUSION
|
||||
|| gBattleMons[otherSkyDropper].volatiles.confusionTurns
|
||||
|| IsBattlerTerrainAffected(otherSkyDropper, STATUS_FIELD_MISTY_TERRAIN)))
|
||||
{
|
||||
gBattleMons[otherSkyDropper].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
|
||||
gBattleMons[otherSkyDropper].volatiles.confusionTurns = ((Random()) % 4) + 2;
|
||||
gBattlerAttacker = otherSkyDropper;
|
||||
result = BattleScript_ThrashConfuses;
|
||||
}
|
||||
|
|
@ -3476,7 +3476,7 @@ static void DoBattleIntro(void)
|
|||
gBattleMons[battler].types[2] = TYPE_MYSTERY;
|
||||
gBattleMons[battler].ability = GetAbilityBySpecies(gBattleMons[battler].species, gBattleMons[battler].abilityNum);
|
||||
gBattleStruct->hpOnSwitchout[GetBattlerSide(battler)] = gBattleMons[battler].hp;
|
||||
gBattleMons[battler].status2 = 0;
|
||||
memset(&gBattleMons[battler].volatiles, 0, sizeof(struct Volatiles));
|
||||
for (i = 0; i < NUM_BATTLE_STATS; i++)
|
||||
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
|
||||
#if TESTING
|
||||
|
|
@ -3905,7 +3905,7 @@ static void TryDoEventsBeforeFirstTurn(void)
|
|||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
gBattleMons[i].status2 &= ~STATUS2_FLINCHED;
|
||||
gBattleMons[i].volatiles.flinched = FALSE;
|
||||
// Record party slots of player's mons that appeared in battle
|
||||
if (!BattlerHasAi(i))
|
||||
gBattleStruct->appearedInBattle |= 1u << gBattlerPartyIndexes[i];
|
||||
|
|
@ -3945,8 +3945,8 @@ static void HandleEndTurn_ContinueBattle(void)
|
|||
gBattleCommunication[i] = 0;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
gBattleMons[i].status2 &= ~STATUS2_FLINCHED;
|
||||
if ((gBattleMons[i].status1 & STATUS1_SLEEP) && (gBattleMons[i].status2 & STATUS2_MULTIPLETURNS))
|
||||
gBattleMons[i].volatiles.flinched = FALSE;
|
||||
if ((gBattleMons[i].status1 & STATUS1_SLEEP) && (gBattleMons[i].volatiles.multipleTurns))
|
||||
CancelMultiTurnMoves(i, SKY_DROP_IGNORE);
|
||||
}
|
||||
gBattleStruct->eventBlockCounter = 0;
|
||||
|
|
@ -4003,8 +4003,8 @@ void BattleTurnPassed(void)
|
|||
gChosenMoveByBattler[i] = MOVE_NONE;
|
||||
gBattleStruct->monToSwitchIntoId[i] = PARTY_SIZE;
|
||||
gStatuses4[i] &= ~STATUS4_ELECTRIFIED;
|
||||
gBattleMons[i].status2 &= ~STATUS2_FLINCHED;
|
||||
gBattleMons[i].status2 &= ~STATUS2_POWDER;
|
||||
gBattleMons[i].volatiles.flinched = FALSE;
|
||||
gBattleMons[i].volatiles.powder = FALSE;
|
||||
|
||||
if (gBattleStruct->battlerState[i].stompingTantrumTimer > 0)
|
||||
gBattleStruct->battlerState[i].stompingTantrumTimer--;
|
||||
|
|
@ -4192,8 +4192,8 @@ static void HandleTurnActionSelectionState(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (gBattleMons[battler].status2 & STATUS2_MULTIPLETURNS
|
||||
|| gBattleMons[battler].status2 & STATUS2_RECHARGE)
|
||||
if (gBattleMons[battler].volatiles.multipleTurns
|
||||
|| gBattleMons[battler].volatiles.recharge)
|
||||
{
|
||||
gChosenActionByBattler[battler] = B_ACTION_USE_MOVE;
|
||||
gBattleCommunication[battler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
|
||||
|
|
@ -4347,8 +4347,8 @@ static void HandleTurnActionSelectionState(void)
|
|||
gBattleCommunication[battler] = STATE_WAIT_SET_BEFORE_ACTION;
|
||||
gBattleCommunication[GetPartnerBattler(battler)] = STATE_BEFORE_ACTION_CHOSEN;
|
||||
RecordedBattle_ClearBattlerAction(battler, 1);
|
||||
if (gBattleMons[GetPartnerBattler(battler)].status2 & STATUS2_MULTIPLETURNS
|
||||
|| gBattleMons[GetPartnerBattler(battler)].status2 & STATUS2_RECHARGE)
|
||||
if (gBattleMons[GetPartnerBattler(battler)].volatiles.multipleTurns
|
||||
|| gBattleMons[GetPartnerBattler(battler)].volatiles.recharge)
|
||||
{
|
||||
BtlController_EmitEndBounceEffect(battler, B_COMM_TO_CONTROLLER);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
|
|
@ -4740,9 +4740,9 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, enum ItemHoldEffect h
|
|||
speed *= 2;
|
||||
else if (ability == ABILITY_SLOW_START && gDisableStructs[battler].slowStartTimer != 0)
|
||||
speed /= 2;
|
||||
else if (ability == ABILITY_PROTOSYNTHESIS && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED) && ((gBattleWeather & B_WEATHER_SUN && HasWeatherEffect()) || gDisableStructs[battler].boosterEnergyActivated))
|
||||
else if (ability == ABILITY_PROTOSYNTHESIS && !(gBattleMons[battler].volatiles.transformed) && ((gBattleWeather & B_WEATHER_SUN && HasWeatherEffect()) || gDisableStructs[battler].boosterEnergyActivated))
|
||||
speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed;
|
||||
else if (ability == ABILITY_QUARK_DRIVE && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED) && (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gDisableStructs[battler].boosterEnergyActivated))
|
||||
else if (ability == ABILITY_QUARK_DRIVE && !(gBattleMons[battler].volatiles.transformed) && (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gDisableStructs[battler].boosterEnergyActivated))
|
||||
speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed;
|
||||
else if (ability == ABILITY_UNBURDEN && gDisableStructs[battler].unburdenActive)
|
||||
speed *= 2;
|
||||
|
|
@ -4762,7 +4762,7 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, enum ItemHoldEffect h
|
|||
speed /= 2;
|
||||
else if (holdEffect == HOLD_EFFECT_CHOICE_SCARF && GetActiveGimmick(battler) != GIMMICK_DYNAMAX)
|
||||
speed = (speed * 150) / 100;
|
||||
else if (holdEffect == HOLD_EFFECT_QUICK_POWDER && gBattleMons[battler].species == SPECIES_DITTO && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
|
||||
else if (holdEffect == HOLD_EFFECT_QUICK_POWDER && gBattleMons[battler].species == SPECIES_DITTO && !(gBattleMons[battler].volatiles.transformed))
|
||||
speed *= 2;
|
||||
|
||||
// various effects
|
||||
|
|
@ -5108,13 +5108,13 @@ static void TurnValuesCleanUp(bool8 var0)
|
|||
{
|
||||
gDisableStructs[i].rechargeTimer--;
|
||||
if (gDisableStructs[i].rechargeTimer == 0)
|
||||
gBattleMons[i].status2 &= ~STATUS2_RECHARGE;
|
||||
gBattleMons[i].volatiles.recharge = FALSE;
|
||||
}
|
||||
gBattleStruct->battlerState[i].canPickupItem = FALSE;
|
||||
}
|
||||
|
||||
if (gDisableStructs[i].substituteHP == 0)
|
||||
gBattleMons[i].status2 &= ~STATUS2_SUBSTITUTE;
|
||||
gBattleMons[i].volatiles.substitute = FALSE;
|
||||
|
||||
if (!(gStatuses3[i] & STATUS3_COMMANDER))
|
||||
gBattleStruct->battlerState[i].commandingDondozo = FALSE;
|
||||
|
|
|
|||
|
|
@ -1379,11 +1379,6 @@ const u16 gStatusConditionsStringIds[] =
|
|||
STRINGID_PKMNWASPOISONED, STRINGID_PKMNBADLYPOISONED, STRINGID_PKMNWASBURNED, STRINGID_PKMNWASPARALYZED, STRINGID_PKMNFELLASLEEP, STRINGID_PKMNGOTFROSTBITE
|
||||
};
|
||||
|
||||
const u16 gStatus2StringIds[] =
|
||||
{
|
||||
STRINGID_PKMNWASCONFUSED, STRINGID_PKMNFELLINLOVE, STRINGID_TARGETCANTESCAPENOW, STRINGID_PKMNSUBJECTEDTOTORMENT
|
||||
};
|
||||
|
||||
const u16 gDamageNonTypesStartStringIds[] =
|
||||
{
|
||||
[B_MSG_TRAPPED_WITH_VINES] = STRINGID_TEAMTRAPPEDWITHVINES,
|
||||
|
|
|
|||
|
|
@ -449,8 +449,8 @@ static void Cmd_drawpartystatussummary(void);
|
|||
static void Cmd_hidepartystatussummary(void);
|
||||
static void Cmd_jumptocalledmove(void);
|
||||
static void Cmd_statusanimation(void);
|
||||
static void Cmd_status2animation(void);
|
||||
static void Cmd_chosenstatusanimation(void);
|
||||
static void Cmd_unused_0x65(void);
|
||||
static void Cmd_unused_0x66(void);
|
||||
static void Cmd_yesnobox(void);
|
||||
static void Cmd_cancelallactions(void);
|
||||
static void Cmd_setgravity(void);
|
||||
|
|
@ -525,7 +525,7 @@ static void Cmd_tryspiteppreduce(void);
|
|||
static void Cmd_healpartystatus(void);
|
||||
static void Cmd_cursetarget(void);
|
||||
static void Cmd_trysetspikes(void);
|
||||
static void Cmd_setforesight(void);
|
||||
static void Cmd_setvolatile(void);
|
||||
static void Cmd_trysetperishsong(void);
|
||||
static void Cmd_handlerollout(void);
|
||||
static void Cmd_jumpifconfusedandstatmaxed(void);
|
||||
|
|
@ -539,7 +539,7 @@ static void Cmd_tryrestorehpberry(void);
|
|||
static void Cmd_halvehp(void);
|
||||
static void Cmd_copyfoestats(void);
|
||||
static void Cmd_rapidspinfree(void);
|
||||
static void Cmd_setdefensecurlbit(void);
|
||||
static void Cmd_unused_0xBF(void);
|
||||
static void Cmd_recoverbasedonsunlight(void);
|
||||
static void Cmd_setstickyweb(void);
|
||||
static void Cmd_selectfirstvalidtarget(void);
|
||||
|
|
@ -708,8 +708,8 @@ void (*const gBattleScriptingCommandsTable[])(void) =
|
|||
Cmd_hidepartystatussummary, //0x62
|
||||
Cmd_jumptocalledmove, //0x63
|
||||
Cmd_statusanimation, //0x64
|
||||
Cmd_status2animation, //0x65
|
||||
Cmd_chosenstatusanimation, //0x66
|
||||
Cmd_unused_0x65, //0x65
|
||||
Cmd_unused_0x66, //0x66
|
||||
Cmd_yesnobox, //0x67
|
||||
Cmd_cancelallactions, //0x68
|
||||
Cmd_setgravity, //0x69
|
||||
|
|
@ -784,7 +784,7 @@ void (*const gBattleScriptingCommandsTable[])(void) =
|
|||
Cmd_healpartystatus, //0xAE
|
||||
Cmd_cursetarget, //0xAF
|
||||
Cmd_trysetspikes, //0xB0
|
||||
Cmd_setforesight, //0xB1
|
||||
Cmd_setvolatile, //0xB1
|
||||
Cmd_trysetperishsong, //0xB2
|
||||
Cmd_handlerollout, //0xB3
|
||||
Cmd_jumpifconfusedandstatmaxed, //0xB4
|
||||
|
|
@ -798,7 +798,7 @@ void (*const gBattleScriptingCommandsTable[])(void) =
|
|||
Cmd_halvehp, //0xBC
|
||||
Cmd_copyfoestats, //0xBD
|
||||
Cmd_rapidspinfree, //0xBE
|
||||
Cmd_setdefensecurlbit, //0xBF
|
||||
Cmd_unused_0xBF, //0xBF
|
||||
Cmd_recoverbasedonsunlight, //0xC0
|
||||
Cmd_setstickyweb, //0xC1
|
||||
Cmd_selectfirstvalidtarget, //0xC2
|
||||
|
|
@ -1137,9 +1137,9 @@ u32 NumAffectedSpreadMoveTargets(void)
|
|||
|
||||
u32 NumFaintedBattlersByAttacker(u32 battlerAtk)
|
||||
{
|
||||
u32 numMonsFainted = 0;
|
||||
u32 battler, numMonsFainted = 0;
|
||||
|
||||
for (u32 battler = 0; battler < gBattlersCount; battler++)
|
||||
for (battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
if (battler == battlerAtk)
|
||||
continue;
|
||||
|
|
@ -1268,7 +1268,7 @@ static void Cmd_attackcanceler(void)
|
|||
|
||||
if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE
|
||||
&& !(gHitMarker & (HITMARKER_ALLOW_NO_PP | HITMARKER_NO_ATTACKSTRING | HITMARKER_NO_PPDEDUCT))
|
||||
&& !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
|
||||
&& !(gBattleMons[gBattlerAttacker].volatiles.multipleTurns))
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_NoPPForMove;
|
||||
gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
|
||||
|
|
@ -1279,7 +1279,7 @@ static void Cmd_attackcanceler(void)
|
|||
|
||||
// Check if no available target present on the field or if Sky Battles ban the move
|
||||
if ((NoTargetPresent(gBattlerAttacker, gCurrentMove)
|
||||
&& (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
|
||||
&& (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].volatiles.multipleTurns)))
|
||||
|| (IsMoveNotAllowedInSkyBattles(gCurrentMove)))
|
||||
{
|
||||
gBattleStruct->noTargetPresent = TRUE;
|
||||
|
|
@ -1289,7 +1289,7 @@ static void Cmd_attackcanceler(void)
|
|||
else
|
||||
gBattlescriptCurrInstr = BattleScript_FailedFromAtkString;
|
||||
|
||||
if (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
|
||||
if (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].volatiles.multipleTurns))
|
||||
CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1354,7 +1354,8 @@ static void Cmd_attackcanceler(void)
|
|||
return;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < gBattlersCount; i++)
|
||||
u32 i;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if ((gProtectStructs[gBattlerByTurnOrder[i]].stealMove) && MoveCanBeSnatched(gCurrentMove))
|
||||
{
|
||||
|
|
@ -1382,7 +1383,7 @@ static void Cmd_attackcanceler(void)
|
|||
}
|
||||
else if (IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove)
|
||||
&& (effect != EFFECT_CURSE || IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
|
||||
&& (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
|
||||
&& (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].volatiles.multipleTurns))
|
||||
&& effect != EFFECT_SUCKER_PUNCH
|
||||
&& effect != EFFECT_COUNTER
|
||||
&& effect != EFFECT_UPPER_HAND)
|
||||
|
|
@ -1504,13 +1505,14 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u
|
|||
}
|
||||
else
|
||||
{
|
||||
u32 numTargets = 0;
|
||||
u32 numMisses = 0;
|
||||
u32 moveType = GetBattleMoveType(move);
|
||||
u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, move);
|
||||
u32 battlerDef,
|
||||
numTargets = 0,
|
||||
numMisses = 0,
|
||||
moveType = GetBattleMoveType(move),
|
||||
moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, move);
|
||||
bool32 calcSpreadMove = IsSpreadMove(moveTarget) && !IsBattleMoveStatus(move);
|
||||
|
||||
for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
||||
for (battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
||||
{
|
||||
if (gBattleStruct->calculatedSpreadMoveAccuracy)
|
||||
break;
|
||||
|
|
@ -1624,7 +1626,7 @@ static void Cmd_ppreduce(void)
|
|||
if (gBattleControllerExecFlags)
|
||||
return;
|
||||
|
||||
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)
|
||||
if (gBattleMons[gBattlerAttacker].volatiles.multipleTurns)
|
||||
gHitMarker |= HITMARKER_NO_PPDEDUCT;
|
||||
|
||||
if (moveTarget == MOVE_TARGET_BOTH
|
||||
|
|
@ -1739,8 +1741,8 @@ s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordA
|
|||
}
|
||||
else
|
||||
{
|
||||
critChance = 2 * ((gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY) != 0)
|
||||
+ 1 * ((gBattleMons[battlerAtk].status2 & STATUS2_DRAGON_CHEER) != 0)
|
||||
critChance = 2 * (gBattleMons[battlerAtk].volatiles.focusEnergy != 0)
|
||||
+ 1 * (gBattleMons[battlerAtk].volatiles.dragonCheer != 0)
|
||||
+ GetMoveCriticalHitStage(move)
|
||||
+ GetHoldEffectCritChanceIncrease(battlerAtk, holdEffectAtk)
|
||||
+ 2 * (B_AFFECTION_MECHANICS == TRUE && GetBattlerAffectionHearts(battlerAtk) == AFFECTION_FIVE_HEARTS)
|
||||
|
|
@ -1789,9 +1791,9 @@ s32 CalcCritChanceStageGen1(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec
|
|||
if (bonusCritStage > 0)
|
||||
critChance *= bonusCritStage;
|
||||
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY)
|
||||
if (gBattleMons[battlerAtk].volatiles.focusEnergy)
|
||||
critChance *= 4;
|
||||
else if (gBattleMons[battlerAtk].status2 & STATUS2_DRAGON_CHEER)
|
||||
else if (gBattleMons[battlerAtk].volatiles.dragonCheer)
|
||||
critChance *= 2;
|
||||
|
||||
if (holdEffectCritStage > 0)
|
||||
|
|
@ -1836,14 +1838,15 @@ static void Cmd_critcalc(void)
|
|||
{
|
||||
CMD_ARGS();
|
||||
|
||||
u32 partySlot = gBattlerPartyIndexes[gBattlerAttacker];
|
||||
u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
|
||||
u32 partySlot = gBattlerPartyIndexes[gBattlerAttacker],
|
||||
moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove),
|
||||
abilityAtk = GetBattlerAbility(gBattlerAttacker),
|
||||
battlerDef;
|
||||
bool32 calcSpreadMoveDamage = IsSpreadMove(moveTarget) && !IsBattleMoveStatus(gCurrentMove);
|
||||
u32 abilityAtk = GetBattlerAbility(gBattlerAttacker);
|
||||
enum ItemHoldEffect holdEffectAtk = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
|
||||
gPotentialItemEffectBattler = gBattlerAttacker;
|
||||
|
||||
for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
||||
for (battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
||||
{
|
||||
if (gBattleStruct->calculatedDamageDone)
|
||||
break;
|
||||
|
|
@ -2120,7 +2123,7 @@ static inline bool32 DoesBattlerNegateDamage(u32 battler)
|
|||
u32 species = gBattleMons[battler].species;
|
||||
u32 ability = GetBattlerAbility(battler);
|
||||
|
||||
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
if (gBattleMons[battler].volatiles.transformed)
|
||||
return FALSE;
|
||||
if (ability == ABILITY_DISGUISE && species == SPECIES_MIMIKYU)
|
||||
return TRUE;
|
||||
|
|
@ -2307,7 +2310,7 @@ static void Cmd_attackanimation(void)
|
|||
if (!(moveResultFlags & MOVE_RESULT_NO_EFFECT))
|
||||
{
|
||||
u32 multihit;
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_SUBSTITUTE)
|
||||
if (gBattleMons[gBattlerTarget].volatiles.substitute)
|
||||
{
|
||||
multihit = gMultiHitCounter;
|
||||
}
|
||||
|
|
@ -3138,20 +3141,20 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||
break;
|
||||
case MOVE_EFFECT_CONFUSION:
|
||||
if (!CanBeConfused(gEffectBattler)
|
||||
|| gBattleMons[gEffectBattler].status2 & STATUS2_CONFUSION
|
||||
|| gBattleMons[gEffectBattler].volatiles.confusionTurns
|
||||
|| (gSideStatuses[GetBattlerSide(gEffectBattler)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT) && !primary))
|
||||
{
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gEffectBattler].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); // 2-5 turns
|
||||
gBattleMons[gEffectBattler].volatiles.confusionTurns = ((Random()) % 4) + 2; // 2-5 turns
|
||||
|
||||
// If the confusion is activating due to being released from Sky Drop, go to "confused due to fatigue" script.
|
||||
// Otherwise, do normal confusion script.
|
||||
if (GetMoveEffect(gCurrentMove) == EFFECT_SKY_DROP)
|
||||
{
|
||||
gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE);
|
||||
gBattleMons[gEffectBattler].volatiles.lockConfusionTurns = 0;
|
||||
gBattlerAttacker = gEffectBattler;
|
||||
gBattlescriptCurrInstr = BattleScript_ThrashConfuses;
|
||||
}
|
||||
|
|
@ -3179,14 +3182,14 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
}
|
||||
else if (gBattleMons[gEffectBattler].status2 & STATUS2_FLINCHED)
|
||||
else if (gBattleMons[gEffectBattler].volatiles.flinched)
|
||||
{
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
else if (GetBattlerTurnOrderNum(gEffectBattler) > gCurrentTurnActionNumber
|
||||
&& !(GetActiveGimmick(gEffectBattler) == GIMMICK_DYNAMAX))
|
||||
{
|
||||
gBattleMons[gEffectBattler].status2 |= STATUS2_FLINCHED;
|
||||
gBattleMons[gEffectBattler].volatiles.flinched = TRUE;
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
else
|
||||
|
|
@ -3195,11 +3198,11 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||
}
|
||||
break;
|
||||
case MOVE_EFFECT_UPROAR:
|
||||
if (!(gBattleMons[gEffectBattler].status2 & STATUS2_UPROAR))
|
||||
if (!gBattleMons[gEffectBattler].volatiles.uproarTurns)
|
||||
{
|
||||
gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS;
|
||||
gBattleMons[gEffectBattler].volatiles.multipleTurns = TRUE;
|
||||
gLockedMoves[gEffectBattler] = gCurrentMove;
|
||||
gBattleMons[gEffectBattler].status2 |= STATUS2_UPROAR_TURN(B_UPROAR_TURNS >= GEN_5 ? 3 : (Random() & 3) + 2);
|
||||
gBattleMons[gEffectBattler].volatiles.uproarTurns = B_UPROAR_TURNS >= GEN_5 ? 3 : (Random() & 3) + 2;
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectUproar;
|
||||
|
|
@ -3260,13 +3263,13 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||
}
|
||||
break;
|
||||
case MOVE_EFFECT_WRAP:
|
||||
if (gBattleMons[gEffectBattler].status2 & STATUS2_WRAPPED)
|
||||
if (gBattleMons[gEffectBattler].volatiles.wrapped)
|
||||
{
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gEffectBattler].status2 |= STATUS2_WRAPPED;
|
||||
gBattleMons[gEffectBattler].volatiles.wrapped = TRUE;
|
||||
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_GRIP_CLAW)
|
||||
gDisableStructs[gEffectBattler].wrapTurns = B_BINDING_TURNS >= GEN_5 ? 7 : 5;
|
||||
else
|
||||
|
|
@ -3401,13 +3404,13 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||
if (B_SKIP_RECHARGE == GEN_1 && !IsBattlerAlive(gBattlerTarget)) // Skip recharge if gen 1 and foe is KO'd
|
||||
break;
|
||||
|
||||
gBattleMons[gEffectBattler].status2 |= STATUS2_RECHARGE;
|
||||
gBattleMons[gEffectBattler].volatiles.recharge = TRUE;
|
||||
gDisableStructs[gEffectBattler].rechargeTimer = 2;
|
||||
gLockedMoves[gEffectBattler] = gCurrentMove;
|
||||
gBattlescriptCurrInstr++;
|
||||
break;
|
||||
case MOVE_EFFECT_RAGE:
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_RAGE;
|
||||
gBattleMons[gBattlerAttacker].volatiles.rage = TRUE;
|
||||
gBattlescriptCurrInstr++;
|
||||
break;
|
||||
case MOVE_EFFECT_STEAL_ITEM:
|
||||
|
|
@ -3440,15 +3443,15 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||
}
|
||||
break;
|
||||
case MOVE_EFFECT_PREVENT_ESCAPE:
|
||||
if (!(gBattleMons[gBattlerTarget].status2 & STATUS2_ESCAPE_PREVENTION))
|
||||
if (!gBattleMons[gBattlerTarget].volatiles.escapePrevention)
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_ESCAPE_PREVENTION;
|
||||
gBattleMons[gBattlerTarget].volatiles.escapePrevention = TRUE;
|
||||
gDisableStructs[gBattlerTarget].battlerPreventingEscape = gBattlerAttacker;
|
||||
}
|
||||
gBattlescriptCurrInstr++;
|
||||
break;
|
||||
case MOVE_EFFECT_NIGHTMARE:
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_NIGHTMARE;
|
||||
gBattleMons[gBattlerTarget].volatiles.nightmare = TRUE;
|
||||
gBattlescriptCurrInstr++;
|
||||
break;
|
||||
case MOVE_EFFECT_ALL_STATS_UP:
|
||||
|
|
@ -3484,15 +3487,15 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||
break;
|
||||
case MOVE_EFFECT_THRASH:
|
||||
// Petal Dance doesn't lock mons that copy the move with Dancer
|
||||
if (gSpecialStatuses[gEffectBattler].dancerUsedMove || gBattleMons[gEffectBattler].status2 & STATUS2_LOCK_CONFUSE)
|
||||
if (gSpecialStatuses[gEffectBattler].dancerUsedMove || gBattleMons[gEffectBattler].volatiles.lockConfusionTurns)
|
||||
{
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS;
|
||||
gBattleMons[gEffectBattler].volatiles.multipleTurns = TRUE;
|
||||
gLockedMoves[gEffectBattler] = gCurrentMove;
|
||||
gBattleMons[gEffectBattler].status2 |= STATUS2_LOCK_CONFUSE_TURN(RandomUniform(RNG_RAMPAGE_TURNS, 2, 3));
|
||||
gBattleMons[gEffectBattler].volatiles.lockConfusionTurns = RandomUniform(RNG_RAMPAGE_TURNS, 2, 3);
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_CLEAR_SMOG:
|
||||
|
|
@ -3597,19 +3600,19 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||
}
|
||||
break;
|
||||
case MOVE_EFFECT_TRAP_BOTH:
|
||||
if (!(gBattleMons[gBattlerTarget].status2 & STATUS2_ESCAPE_PREVENTION) && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_ESCAPE_PREVENTION))
|
||||
if (!(gBattleMons[gBattlerTarget].volatiles.escapePrevention || gBattleMons[gBattlerAttacker].volatiles.escapePrevention))
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_BothCanNoLongerEscape;
|
||||
}
|
||||
if (!(gBattleMons[gBattlerTarget].status2 & STATUS2_ESCAPE_PREVENTION))
|
||||
if (!gBattleMons[gBattlerTarget].volatiles.escapePrevention)
|
||||
gDisableStructs[gBattlerTarget].battlerPreventingEscape = gBattlerAttacker;
|
||||
|
||||
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_ESCAPE_PREVENTION))
|
||||
if (!gBattleMons[gBattlerAttacker].volatiles.escapePrevention)
|
||||
gDisableStructs[gBattlerAttacker].battlerPreventingEscape = gBattlerTarget;
|
||||
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_ESCAPE_PREVENTION;
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_ESCAPE_PREVENTION;
|
||||
gBattleMons[gBattlerTarget].volatiles.escapePrevention = TRUE;
|
||||
gBattleMons[gBattlerAttacker].volatiles.escapePrevention = TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_REMOVE_ARG_TYPE:
|
||||
{
|
||||
|
|
@ -3893,7 +3896,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||
PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct)
|
||||
gBattleMons[gBattlerTarget].pp[i] -= ppToDeduct;
|
||||
if (!(gDisableStructs[gBattlerTarget].mimickedMoves & (1u << i))
|
||||
&& !(gBattleMons[gBattlerTarget].status2 & STATUS2_TRANSFORMED))
|
||||
&& !(gBattleMons[gBattlerTarget].volatiles.transformed))
|
||||
{
|
||||
BtlController_EmitSetMonData(gBattlerTarget, B_COMM_TO_CONTROLLER, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[gBattlerTarget].pp[i]), &gBattleMons[gBattlerTarget].pp[i]);
|
||||
MarkBattlerForControllerExec(gBattlerTarget);
|
||||
|
|
@ -4128,9 +4131,9 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||
{
|
||||
if (!IsBattlerAlly(battler, gBattlerTarget))
|
||||
continue;
|
||||
if (!(gBattleMons[battler].status2 & STATUS2_WRAPPED))
|
||||
if (!gBattleMons[battler].volatiles.wrapped)
|
||||
{
|
||||
gBattleMons[battler].status2 |= STATUS2_WRAPPED;
|
||||
gBattleMons[battler].volatiles.wrapped = TRUE;
|
||||
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_GRIP_CLAW)
|
||||
gDisableStructs[battler].wrapTurns = (B_BINDING_TURNS >= GEN_5) ? 7 : 5;
|
||||
else
|
||||
|
|
@ -4539,12 +4542,12 @@ static void Cmd_jumpifstatus(void)
|
|||
|
||||
static void Cmd_jumpifvolatile(void)
|
||||
{
|
||||
CMD_ARGS(u8 battler, u8 volatileStatus, const u8 *jumpInstr);
|
||||
CMD_ARGS(u8 battler, u8 _volatile, const u8 *jumpInstr);
|
||||
|
||||
u8 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
const u8 *jumpInstr = cmd->jumpInstr;
|
||||
|
||||
if (GetMonVolatile(battler, cmd->volatileStatus) && IsBattlerAlive(battler))
|
||||
if (GetMonVolatile(battler, cmd->_volatile) && IsBattlerAlive(battler))
|
||||
gBattlescriptCurrInstr = jumpInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
|
@ -6119,7 +6122,7 @@ static void Cmd_moveend(void)
|
|||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_RAGE: // rage check
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_RAGE
|
||||
if (gBattleMons[gBattlerTarget].volatiles.rage
|
||||
&& IsBattlerAlive(gBattlerTarget)
|
||||
&& gBattlerAttacker != gBattlerTarget
|
||||
&& !IsBattlerAlly(gBattlerAttacker, gBattlerTarget)
|
||||
|
|
@ -6313,7 +6316,7 @@ static void Cmd_moveend(void)
|
|||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gDisableStructs[i].substituteHP == 0)
|
||||
gBattleMons[i].status2 &= ~STATUS2_SUBSTITUTE;
|
||||
gBattleMons[i].volatiles.substitute = FALSE;
|
||||
}
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
|
|
@ -6348,7 +6351,7 @@ static void Cmd_moveend(void)
|
|||
if (!IsOnPlayerSide(gBattlerAttacker))
|
||||
UpdateStallMons();
|
||||
if ((gBattleStruct->moveResultFlags[gBattlerTarget] & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE))
|
||||
|| (gBattleMons[gBattlerAttacker].status2 & (STATUS2_FLINCHED))
|
||||
|| (gBattleMons[gBattlerAttacker].volatiles.flinched)
|
||||
|| gProtectStructs[gBattlerAttacker].nonVolatileStatusImmobility)
|
||||
gBattleStruct->battlerState[gBattlerAttacker].stompingTantrumTimer = 2;
|
||||
|
||||
|
|
@ -7050,7 +7053,7 @@ static void Cmd_moveend(void)
|
|||
if (B_RAMPAGE_CANCELLING >= GEN_5
|
||||
&& MoveHasAdditionalEffectSelf(gCurrentMove, MOVE_EFFECT_THRASH) // If we're rampaging
|
||||
&& gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT // And it is unusable
|
||||
&& (gBattleMons[gBattlerAttacker].status2 & STATUS2_LOCK_CONFUSE) != STATUS2_LOCK_CONFUSE_TURN(1)) // And won't end this turn
|
||||
&& gBattleMons[gBattlerAttacker].volatiles.lockConfusionTurns != 1) // And won't end this turn
|
||||
CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_IGNORE); // Cancel it
|
||||
|
||||
if (gBattleStruct->savedAttackerCount > 0)
|
||||
|
|
@ -7320,10 +7323,9 @@ static void Cmd_switchindataupdate(void)
|
|||
{
|
||||
gBattleMons[battler].statStages[i] = oldData.statStages[i];
|
||||
}
|
||||
gBattleMons[battler].status2 = oldData.status2;
|
||||
}
|
||||
|
||||
SwitchInClearSetData(battler);
|
||||
SwitchInClearSetData(battler, &oldData.volatiles);
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE
|
||||
&& gBattleMons[battler].maxHP / 2 >= gBattleMons[battler].hp
|
||||
|
|
@ -7843,7 +7845,7 @@ static void UpdateSentMonFlags(u32 battler)
|
|||
|
||||
static void SetDmgHazardsBattlescript(u8 battler, u8 multistringId)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~STATUS2_DESTINY_BOND;
|
||||
gBattleMons[battler].volatiles.destinyBond = FALSE;
|
||||
gHitMarker &= ~HITMARKER_DESTINYBOND;
|
||||
gBattleScripting.battler = battler;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = multistringId;
|
||||
|
|
@ -8220,7 +8222,7 @@ static void Cmd_handlelearnnewmove(void)
|
|||
u32 battler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
||||
|
||||
if (gBattlerPartyIndexes[battler] == monId
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
|
||||
&& !(gBattleMons[battler].volatiles.transformed))
|
||||
{
|
||||
GiveMoveToBattleMon(&gBattleMons[battler], learnMove);
|
||||
}
|
||||
|
|
@ -8228,7 +8230,7 @@ static void Cmd_handlelearnnewmove(void)
|
|||
{
|
||||
battler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
||||
if (gBattlerPartyIndexes[battler] == monId
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
|
||||
&& !(gBattleMons[battler].volatiles.transformed))
|
||||
{
|
||||
GiveMoveToBattleMon(&gBattleMons[battler], learnMove);
|
||||
}
|
||||
|
|
@ -8643,58 +8645,29 @@ static void Cmd_jumptocalledmove(void)
|
|||
|
||||
static void Cmd_statusanimation(void)
|
||||
{
|
||||
CMD_ARGS(u8 battler);
|
||||
CMD_ARGS(u8 battler, u32 status, bool8 isVolatile);
|
||||
|
||||
if (gBattleControllerExecFlags == 0)
|
||||
{
|
||||
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
u32 battler = GetBattlerForBattleScript(cmd->battler),
|
||||
statusFlag = (cmd->isVolatile || cmd->status) ? cmd->status : gBattleMons[battler].status1;
|
||||
if (!(gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE)
|
||||
&& gDisableStructs[battler].substituteHP == 0
|
||||
&& !(gHitMarker & (HITMARKER_NO_ANIMATIONS | HITMARKER_DISABLE_ANIMATION)))
|
||||
{
|
||||
BtlController_EmitStatusAnimation(battler, B_COMM_TO_CONTROLLER, FALSE, gBattleMons[battler].status1);
|
||||
BtlController_EmitStatusAnimation(battler, B_COMM_TO_CONTROLLER, cmd->isVolatile, statusFlag);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
}
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
||||
static void Cmd_status2animation(void)
|
||||
static void Cmd_unused_0x65(void)
|
||||
{
|
||||
CMD_ARGS(u8 battler, u32 status2);
|
||||
|
||||
if (gBattleControllerExecFlags == 0)
|
||||
{
|
||||
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
u32 status2ToAnim = cmd->status2;
|
||||
if (!(gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE)
|
||||
&& gDisableStructs[battler].substituteHP == 0
|
||||
&& !(gHitMarker & (HITMARKER_NO_ANIMATIONS | HITMARKER_DISABLE_ANIMATION)))
|
||||
{
|
||||
BtlController_EmitStatusAnimation(battler, B_COMM_TO_CONTROLLER, TRUE, gBattleMons[battler].status2 & status2ToAnim);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
}
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
||||
static void Cmd_chosenstatusanimation(void)
|
||||
static void Cmd_unused_0x66(void)
|
||||
{
|
||||
CMD_ARGS(u8 battler, bool8 isStatus2, u32 status);
|
||||
|
||||
if (gBattleControllerExecFlags == 0)
|
||||
{
|
||||
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
u32 wantedStatus = cmd->status;
|
||||
if (!(gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE)
|
||||
&& gDisableStructs[battler].substituteHP == 0
|
||||
&& !(gHitMarker & (HITMARKER_NO_ANIMATIONS | HITMARKER_DISABLE_ANIMATION)))
|
||||
{
|
||||
BtlController_EmitStatusAnimation(battler, B_COMM_TO_CONTROLLER, cmd->isStatus2, wantedStatus);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
}
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
||||
static void Cmd_yesnobox(void)
|
||||
|
|
@ -9454,13 +9427,13 @@ static bool32 TryTidyUpClear(u32 battlerAtk, bool32 clear)
|
|||
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
{
|
||||
if (gBattleMons[i].status2 & STATUS2_SUBSTITUTE)
|
||||
if (gBattleMons[i].volatiles.substitute)
|
||||
{
|
||||
if (clear)
|
||||
{
|
||||
gBattlerTarget = i;
|
||||
gDisableStructs[i].substituteHP = 0;
|
||||
gBattleMons[i].status2 &= ~STATUS2_SUBSTITUTE;
|
||||
gBattleMons[i].volatiles.substitute = FALSE;
|
||||
BattleScriptCall(BattleScript_SubstituteFade);
|
||||
}
|
||||
gBattlerAttacker = saveBattler;
|
||||
|
|
@ -9799,7 +9772,7 @@ static void Cmd_various(void)
|
|||
{
|
||||
VARIOUS_ARGS(u8 infatuateWith);
|
||||
gBattleScripting.battler = battler;
|
||||
gBattleMons[battler].status2 |= STATUS2_INFATUATED_WITH(GetBattlerForBattleScript(cmd->infatuateWith));
|
||||
gBattleMons[battler].volatiles.infatuation = INFATUATED_WITH(GetBattlerForBattleScript(cmd->infatuateWith));
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
return;
|
||||
}
|
||||
|
|
@ -9939,12 +9912,6 @@ static void Cmd_various(void)
|
|||
gStatuses3[battler] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR | STATUS3_SKY_DROPPED);
|
||||
break;
|
||||
}
|
||||
case VARIOUS_SET_POWDER:
|
||||
{
|
||||
VARIOUS_ARGS();
|
||||
gBattleMons[battler].status2 |= STATUS2_POWDER;
|
||||
break;
|
||||
}
|
||||
case VARIOUS_ACUPRESSURE:
|
||||
{
|
||||
VARIOUS_ARGS(const u8 *failInstr);
|
||||
|
|
@ -10953,10 +10920,10 @@ static void Cmd_various(void)
|
|||
gBattleStruct->skyDropTargets[gBattlerAttacker] = gBattlerTarget;
|
||||
gBattleStruct->skyDropTargets[gBattlerTarget] = gBattlerAttacker;
|
||||
|
||||
// End any multiturn effects caused by the target except STATUS2_LOCK_CONFUSE
|
||||
gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_MULTIPLETURNS);
|
||||
gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_UPROAR);
|
||||
gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_BIDE);
|
||||
// End any multiturn effects caused by the target except VOLATILE_LOCK_CONFUSE
|
||||
gBattleMons[gBattlerTarget].volatiles.multipleTurns = 0;
|
||||
gBattleMons[gBattlerTarget].volatiles.uproarTurns= 0;
|
||||
gBattleMons[gBattlerTarget].volatiles.bideTurns = 0;
|
||||
gDisableStructs[gBattlerTarget].rolloutTimer = 0;
|
||||
gDisableStructs[gBattlerTarget].furyCutterCounter = 0;
|
||||
|
||||
|
|
@ -10982,7 +10949,7 @@ static void Cmd_various(void)
|
|||
}
|
||||
|
||||
// Confuse target if they were in the middle of Petal Dance/Outrage/Thrash when targeted.
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_LOCK_CONFUSE)
|
||||
if (gBattleMons[gBattlerTarget].volatiles.lockConfusionTurns)
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_CONFUSION;
|
||||
return;
|
||||
}
|
||||
|
|
@ -10999,11 +10966,11 @@ static void Cmd_various(void)
|
|||
gBattleStruct->skyDropTargets[gEffectBattler] = SKY_DROP_NO_TARGET;
|
||||
|
||||
// If the target was in the middle of Outrage/Thrash/etc. when targeted by Sky Drop, confuse them on release and do proper animation
|
||||
if (gBattleMons[gEffectBattler].status2 & STATUS2_LOCK_CONFUSE && CanBeConfused(gEffectBattler))
|
||||
if (gBattleMons[gEffectBattler].volatiles.lockConfusionTurns && CanBeConfused(gEffectBattler))
|
||||
{
|
||||
gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE);
|
||||
gBattleMons[gEffectBattler].volatiles.lockConfusionTurns = 0;
|
||||
gBattlerAttacker = gEffectBattler;
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
|
||||
gBattleMons[gBattlerTarget].volatiles.confusionTurns = ((Random()) % 4) + 2;
|
||||
gBattlescriptCurrInstr = BattleScript_ThrashConfuses;
|
||||
return;
|
||||
}
|
||||
|
|
@ -11225,7 +11192,7 @@ static void Cmd_various(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!(gBattleMons[battler].status2 & STATUS2_ESCAPE_PREVENTION))
|
||||
if (!gBattleMons[battler].volatiles.escapePrevention)
|
||||
gDisableStructs[battler].noRetreat = TRUE;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
|
@ -11235,9 +11202,9 @@ static void Cmd_various(void)
|
|||
{
|
||||
VARIOUS_ARGS();
|
||||
// Check infatuation
|
||||
if (gBattleMons[battler].status2 & STATUS2_INFATUATION)
|
||||
if (gBattleMons[battler].volatiles.infatuation)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_INFATUATION);
|
||||
gBattleMons[battler].volatiles.infatuation = 0;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_INFATUATION; // STRINGID_TARGETGOTOVERINFATUATION
|
||||
StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn);
|
||||
}
|
||||
|
|
@ -11256,9 +11223,9 @@ static void Cmd_various(void)
|
|||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_ENCORE; // STRINGID_PKMNENCOREENDED
|
||||
}
|
||||
// Check torment
|
||||
if (gBattleMons[battler].status2 & STATUS2_TORMENT)
|
||||
if (gBattleMons[battler].volatiles.torment == TRUE)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_TORMENT);
|
||||
gBattleMons[battler].volatiles.torment = FALSE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_TORMENT;
|
||||
}
|
||||
// Check heal block
|
||||
|
|
@ -11673,7 +11640,7 @@ bool8 UproarWakeUpCheck(u8 battler)
|
|||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || hasSoundproof)
|
||||
if (!(gBattleMons[i].volatiles.uproarTurns) || hasSoundproof)
|
||||
continue;
|
||||
|
||||
gBattleScripting.battler = i;
|
||||
|
|
@ -12317,10 +12284,10 @@ static void Cmd_setbide(void)
|
|||
{
|
||||
CMD_ARGS();
|
||||
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_MULTIPLETURNS;
|
||||
gBattleMons[gBattlerAttacker].volatiles.multipleTurns = TRUE;
|
||||
gLockedMoves[gBattlerAttacker] = gCurrentMove;
|
||||
gBideDmg[gBattlerAttacker] = 0;
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_BIDE_TURN(2);
|
||||
gBattleMons[gBattlerAttacker].volatiles.bideTurns = 2;
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
|
@ -12838,14 +12805,14 @@ static void Cmd_tryinfatuating(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_INFATUATION
|
||||
if (gBattleMons[gBattlerTarget].volatiles.infatuation
|
||||
|| !AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_INFATUATED_WITH(gBattlerAttacker);
|
||||
gBattleMons[gBattlerTarget].volatiles.infatuation = INFATUATED_WITH(gBattlerAttacker);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
|
@ -12865,7 +12832,7 @@ static void Cmd_updatestatusicon(void)
|
|||
{
|
||||
if (!(gAbsentBattlerFlags & (1u << battler)))
|
||||
{
|
||||
BtlController_EmitStatusIconUpdate(battler, B_COMM_TO_CONTROLLER, gBattleMons[battler].status1, gBattleMons[battler].status2);
|
||||
BtlController_EmitStatusIconUpdate(battler, B_COMM_TO_CONTROLLER, gBattleMons[battler].status1);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
}
|
||||
}
|
||||
|
|
@ -12876,7 +12843,7 @@ static void Cmd_updatestatusicon(void)
|
|||
battler = gBattlerAttacker;
|
||||
if (!(gAbsentBattlerFlags & (1u << battler)))
|
||||
{
|
||||
BtlController_EmitStatusIconUpdate(battler, B_COMM_TO_CONTROLLER, gBattleMons[battler].status1, gBattleMons[battler].status2);
|
||||
BtlController_EmitStatusIconUpdate(battler, B_COMM_TO_CONTROLLER, gBattleMons[battler].status1);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
}
|
||||
if ((IsDoubleBattle()))
|
||||
|
|
@ -12884,7 +12851,7 @@ static void Cmd_updatestatusicon(void)
|
|||
battler = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker)));
|
||||
if (!(gAbsentBattlerFlags & (1u << battler)))
|
||||
{
|
||||
BtlController_EmitStatusIconUpdate(battler, B_COMM_TO_CONTROLLER, gBattleMons[battler].status1, gBattleMons[battler].status2);
|
||||
BtlController_EmitStatusIconUpdate(battler, B_COMM_TO_CONTROLLER, gBattleMons[battler].status1);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
}
|
||||
}
|
||||
|
|
@ -12893,7 +12860,7 @@ static void Cmd_updatestatusicon(void)
|
|||
else
|
||||
{
|
||||
battler = GetBattlerForBattleScript(cmd->battler);
|
||||
BtlController_EmitStatusIconUpdate(battler, B_COMM_TO_CONTROLLER, gBattleMons[battler].status1, gBattleMons[battler].status2);
|
||||
BtlController_EmitStatusIconUpdate(battler, B_COMM_TO_CONTROLLER, gBattleMons[battler].status1);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
|
@ -12924,22 +12891,22 @@ static void Cmd_setfocusenergy(void)
|
|||
enum BattleMoveEffects effect = GetMoveEffect(gCurrentMove);
|
||||
|
||||
if ((effect == EFFECT_DRAGON_CHEER && (!(IsDoubleBattle()) || (gAbsentBattlerFlags & (1u << battler))))
|
||||
|| gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY)
|
||||
|| gBattleMons[battler].volatiles.dragonCheer || gBattleMons[battler].volatiles.focusEnergy)
|
||||
{
|
||||
gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_FAILED;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FOCUS_ENERGY_FAILED;
|
||||
}
|
||||
else if (effect == EFFECT_DRAGON_CHEER && !IS_BATTLER_OF_TYPE(battler, TYPE_DRAGON))
|
||||
{
|
||||
gBattleMons[battler].status2 |= STATUS2_DRAGON_CHEER;
|
||||
gBattleMons[battler].volatiles.dragonCheer = TRUE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_GETTING_PUMPED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetGenConfig(GEN_CONFIG_FOCUS_ENERGY_CRIT_RATIO) >= GEN_3)
|
||||
gBattleMons[battler].status2 |= STATUS2_FOCUS_ENERGY;
|
||||
gBattleMons[battler].volatiles.focusEnergy = TRUE;
|
||||
else
|
||||
gBattleMons[battler].status2 |= STATUS2_DRAGON_CHEER;
|
||||
gBattleMons[battler].volatiles.dragonCheer = TRUE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_GETTING_PUMPED;
|
||||
}
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
|
@ -12951,7 +12918,7 @@ static void Cmd_transformdataexecution(void)
|
|||
|
||||
gChosenMove = MOVE_UNAVAILABLE;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_TRANSFORMED
|
||||
if (gBattleMons[gBattlerTarget].volatiles.transformed
|
||||
|| gBattleStruct->illusion[gBattlerTarget].state == ILLUSION_ON
|
||||
|| gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE_NO_COMMANDER)
|
||||
{
|
||||
|
|
@ -12964,7 +12931,7 @@ static void Cmd_transformdataexecution(void)
|
|||
u8 *battleMonAttacker, *battleMonTarget;
|
||||
u8 timesGotHit;
|
||||
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_TRANSFORMED;
|
||||
gBattleMons[gBattlerAttacker].volatiles.transformed = TRUE;
|
||||
gDisableStructs[gBattlerAttacker].disabledMove = MOVE_NONE;
|
||||
gDisableStructs[gBattlerAttacker].disableTimer = 0;
|
||||
gDisableStructs[gBattlerAttacker].transformedMonPersonality = gBattleMons[gBattlerTarget].personality;
|
||||
|
|
@ -13029,8 +12996,8 @@ static void Cmd_setsubstitute(void)
|
|||
if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = 1;
|
||||
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_SUBSTITUTE;
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_WRAPPED;
|
||||
gBattleMons[gBattlerAttacker].volatiles.substitute = TRUE;
|
||||
gBattleMons[gBattlerAttacker].volatiles.wrapped = FALSE;
|
||||
if (factor == 2)
|
||||
gDisableStructs[gBattlerAttacker].substituteHP = gBattleStruct->moveDamage[gBattlerAttacker] / 2;
|
||||
else
|
||||
|
|
@ -13047,7 +13014,7 @@ static void Cmd_mimicattackcopy(void)
|
|||
CMD_ARGS(const u8 *failInstr);
|
||||
|
||||
if ((IsMoveMimicBanned(gLastMoves[gBattlerTarget]))
|
||||
|| (gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED)
|
||||
|| (gBattleMons[gBattlerAttacker].volatiles.transformed)
|
||||
|| gLastMoves[gBattlerTarget] == MOVE_NONE
|
||||
|| gLastMoves[gBattlerTarget] == MOVE_UNAVAILABLE)
|
||||
{
|
||||
|
|
@ -13296,7 +13263,7 @@ static void Cmd_settypetorandomresistance(void)
|
|||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
else if (gBattleMoveEffects[GetMoveEffect(gLastLandedMoves[gBattlerAttacker])].twoTurnEffect
|
||||
&& gBattleMons[gLastHitBy[gBattlerAttacker]].status2 & STATUS2_MULTIPLETURNS)
|
||||
&& gBattleMons[gLastHitBy[gBattlerAttacker]].volatiles.multipleTurns)
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
|
|
@ -13422,7 +13389,7 @@ static void Cmd_copymovepermanently(void)
|
|||
|
||||
gChosenMove = MOVE_UNAVAILABLE;
|
||||
|
||||
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED)
|
||||
if (!(gBattleMons[gBattlerAttacker].volatiles.transformed)
|
||||
&& gLastPrintedMoves[gBattlerTarget] != MOVE_UNAVAILABLE
|
||||
&& !IsMoveSketchBanned(gLastPrintedMoves[gBattlerTarget]))
|
||||
{
|
||||
|
|
@ -13541,14 +13508,14 @@ static void Cmd_trysetdestinybond(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_DESTINY_BOND;
|
||||
gBattleMons[gBattlerAttacker].volatiles.destinyBond = TRUE;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
||||
static void TrySetDestinyBondToHappen(void)
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_DESTINY_BOND
|
||||
if (gBattleMons[gBattlerTarget].volatiles.destinyBond
|
||||
&& !IsBattlerAlly(gBattlerAttacker, gBattlerTarget)
|
||||
&& !(gHitMarker & HITMARKER_GRUDGE))
|
||||
{
|
||||
|
|
@ -13629,7 +13596,7 @@ static void Cmd_tryspiteppreduce(void)
|
|||
|
||||
// if (MOVE_IS_PERMANENT(gBattlerTarget, i)), but backwards
|
||||
if (!(gDisableStructs[gBattlerTarget].mimickedMoves & (1u << i))
|
||||
&& !(gBattleMons[gBattlerTarget].status2 & STATUS2_TRANSFORMED))
|
||||
&& !(gBattleMons[gBattlerTarget].volatiles.transformed))
|
||||
{
|
||||
BtlController_EmitSetMonData(gBattlerTarget, B_COMM_TO_CONTROLLER, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[gBattlerTarget].pp[i]), &gBattleMons[gBattlerTarget].pp[i]);
|
||||
MarkBattlerForControllerExec(gBattlerTarget);
|
||||
|
|
@ -13672,7 +13639,7 @@ static void Cmd_healpartystatus(void)
|
|||
else
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SOOTHING_AROMA;
|
||||
gBattleMons[gBattlerAttacker].status1 = 0;
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[gBattlerAttacker].volatiles.nightmare = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -13688,7 +13655,7 @@ static void Cmd_healpartystatus(void)
|
|||
|| !(isSoundMove && GetBattlerAbility(partner) == ABILITY_SOUNDPROOF))
|
||||
{
|
||||
gBattleMons[partner].status1 = 0;
|
||||
gBattleMons[partner].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[partner].volatiles.nightmare = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -13753,13 +13720,13 @@ static void Cmd_cursetarget(void)
|
|||
{
|
||||
CMD_ARGS(const u8 *failInstr);
|
||||
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_CURSED)
|
||||
if (gBattleMons[gBattlerTarget].volatiles.cursed)
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_CURSED;
|
||||
gBattleMons[gBattlerTarget].volatiles.cursed = TRUE;
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
|
||||
if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = 1;
|
||||
|
|
@ -13787,11 +13754,11 @@ static void Cmd_trysetspikes(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void Cmd_setforesight(void)
|
||||
static void Cmd_setvolatile(void)
|
||||
{
|
||||
CMD_ARGS();
|
||||
CMD_ARGS(u8 battler, u8 _volatile, u8 value);
|
||||
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_FORESIGHT;
|
||||
SetMonVolatile(GetBattlerForBattleScript(cmd->battler), cmd->_volatile, cmd->value);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
|
|
@ -13835,16 +13802,16 @@ static void Cmd_handlerollout(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)) // First hit.
|
||||
if (!(gBattleMons[gBattlerAttacker].volatiles.multipleTurns)) // First hit.
|
||||
{
|
||||
gDisableStructs[gBattlerAttacker].rolloutTimer = 5;
|
||||
gDisableStructs[gBattlerAttacker].rolloutTimerStartValue = 5;
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_MULTIPLETURNS;
|
||||
gBattleMons[gBattlerAttacker].volatiles.multipleTurns = TRUE;
|
||||
gLockedMoves[gBattlerAttacker] = gCurrentMove;
|
||||
}
|
||||
if (--gDisableStructs[gBattlerAttacker].rolloutTimer == 0) // Last hit.
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_MULTIPLETURNS;
|
||||
gBattleMons[gBattlerAttacker].volatiles.multipleTurns = FALSE;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
|
@ -13855,7 +13822,7 @@ static void Cmd_jumpifconfusedandstatmaxed(void)
|
|||
{
|
||||
CMD_ARGS(u8 stat, const u8 *jumpInstr);
|
||||
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_CONFUSION
|
||||
if (gBattleMons[gBattlerTarget].volatiles.confusionTurns > 0
|
||||
&& !CompareStat(gBattlerTarget, cmd->stat, MAX_STAT_STAGE, CMP_LESS_THAN))
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr; // Fails if we're confused AND stat cannot be raised
|
||||
else
|
||||
|
|
@ -14130,10 +14097,10 @@ static void Cmd_rapidspinfree(void)
|
|||
|
||||
u8 atkSide = GetBattlerSide(gBattlerAttacker);
|
||||
|
||||
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_WRAPPED)
|
||||
if (gBattleMons[gBattlerAttacker].volatiles.wrapped)
|
||||
{
|
||||
gBattleScripting.battler = gBattlerTarget;
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_WRAPPED;
|
||||
gBattleMons[gBattlerAttacker].volatiles.wrapped = FALSE;
|
||||
gBattlerTarget = gBattleStruct->wrappedBy[gBattlerAttacker];
|
||||
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleStruct->wrappedMove[gBattlerAttacker]);
|
||||
BattleScriptCall(BattleScript_WrapFree);
|
||||
|
|
@ -14163,12 +14130,8 @@ static void Cmd_rapidspinfree(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void Cmd_setdefensecurlbit(void)
|
||||
static void Cmd_unused_0xBF(void)
|
||||
{
|
||||
CMD_ARGS();
|
||||
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_DEFENSE_CURL;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
static void Cmd_recoverbasedonsunlight(void)
|
||||
|
|
@ -14536,14 +14499,14 @@ static void Cmd_settorment(void)
|
|||
{
|
||||
CMD_ARGS(const u8 *failInstr);
|
||||
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_TORMENT
|
||||
if (gBattleMons[gBattlerTarget].volatiles.torment == TRUE
|
||||
|| (GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_TORMENT;
|
||||
gBattleMons[gBattlerTarget].volatiles.torment = TRUE;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
|
@ -15300,7 +15263,7 @@ static void Cmd_settypebasedhalvers(void)
|
|||
|
||||
bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
{
|
||||
if (!(gBattleMons[battlerDef].status2 & STATUS2_SUBSTITUTE))
|
||||
if (!gBattleMons[battlerDef].volatiles.substitute)
|
||||
return FALSE;
|
||||
else if (MoveIgnoresSubstitute(move))
|
||||
return FALSE;
|
||||
|
|
@ -15313,7 +15276,7 @@ bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move)
|
|||
bool32 DoesDisguiseBlockMove(u32 battler, u32 move)
|
||||
{
|
||||
if (!(gBattleMons[battler].species == SPECIES_MIMIKYU_DISGUISED || gBattleMons[battler].species == SPECIES_MIMIKYU_TOTEM_DISGUISED)
|
||||
|| gBattleMons[battler].status2 & STATUS2_TRANSFORMED
|
||||
|| gBattleMons[battler].volatiles.transformed
|
||||
|| (!gProtectStructs[battler].confusionSelfDmg && (IsBattleMoveStatus(move) || gHitMarker & HITMARKER_PASSIVE_DAMAGE))
|
||||
|| gHitMarker & HITMARKER_IGNORE_DISGUISE
|
||||
|| !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_DISGUISE))
|
||||
|
|
@ -16881,34 +16844,23 @@ void BS_ItemCureStatus(void)
|
|||
{
|
||||
NATIVE_ARGS(const u8 *noStatusInstr);
|
||||
u32 battler = gBattlerAttacker;
|
||||
u32 previousStatus2 = 0;
|
||||
bool32 statusChanged = FALSE;
|
||||
struct Pokemon *party = GetBattlerParty(gBattlerAttacker);
|
||||
|
||||
// Heal Status2 conditions if battler is active.
|
||||
// Heal volatile conditions if battler is active.
|
||||
if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker])
|
||||
{
|
||||
previousStatus2 = gBattleMons[battler].status2;
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~GetItemStatus2Mask(gLastUsedItem);
|
||||
}
|
||||
statusChanged = ItemHealMonVolatile(battler, gLastUsedItem);
|
||||
else if (IsDoubleBattle()
|
||||
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
|
||||
{
|
||||
battler = BATTLE_PARTNER(gBattlerAttacker);
|
||||
previousStatus2 = gBattleMons[battler].status2;
|
||||
gBattleMons[battler].status2 &= ~GetItemStatus2Mask(gLastUsedItem);
|
||||
}
|
||||
|
||||
if (previousStatus2 != gBattleMons[battler].status2)
|
||||
statusChanged = TRUE;
|
||||
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
|
||||
statusChanged = ItemHealMonVolatile(BATTLE_PARTNER(gBattlerAttacker), gLastUsedItem);
|
||||
|
||||
// Heal Status1 conditions.
|
||||
if (!HealStatusConditions(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], GetItemStatus1Mask(gLastUsedItem), battler))
|
||||
{
|
||||
statusChanged = TRUE;
|
||||
if (GetItemStatus1Mask(gLastUsedItem) & STATUS1_SLEEP)
|
||||
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
|
||||
if (GetItemStatus2Mask(gLastUsedItem) & STATUS2_CONFUSION)
|
||||
gBattleMons[battler].volatiles.nightmare = FALSE;
|
||||
if (ItemHasVolatileFlag(gLastUsedItem, VOLATILE_CONFUSION))
|
||||
gStatuses4[battler] &= ~STATUS4_INFINITE_CONFUSION;
|
||||
}
|
||||
|
||||
|
|
@ -17168,7 +17120,7 @@ void BS_TrySetOctolock(void)
|
|||
else
|
||||
{
|
||||
gDisableStructs[battler].octolock = TRUE;
|
||||
gBattleMons[battler].status2 |= STATUS2_ESCAPE_PREVENTION;
|
||||
gBattleMons[battler].volatiles.escapePrevention = TRUE;
|
||||
gDisableStructs[battler].battlerPreventingEscape = gBattlerAttacker;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
|
@ -17962,7 +17914,7 @@ void BS_CheckPokeFlute(void)
|
|||
if (GetBattlerAbility(i) != ABILITY_SOUNDPROOF)
|
||||
{
|
||||
gBattleMons[i].status1 &= ~STATUS1_SLEEP;
|
||||
gBattleMons[i].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[i].volatiles.nightmare = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -18243,8 +18195,7 @@ void BS_TrySetConfusion(void)
|
|||
|
||||
if (CanBeConfused(gBattlerTarget))
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
gBattleMons[gBattlerTarget].volatiles.confusionTurns = ((Random()) % 4) + 2;
|
||||
gBattleCommunication[MULTIUSE_STATE] = 1;
|
||||
gEffectBattler = gBattlerTarget;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
|
@ -18259,13 +18210,12 @@ void BS_TrySetInfatuation(void)
|
|||
{
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
|
||||
if (!(gBattleMons[gBattlerTarget].status2 & STATUS2_INFATUATION)
|
||||
if (!gBattleMons[gBattlerTarget].volatiles.infatuation
|
||||
&& gBattleMons[gBattlerTarget].ability != ABILITY_OBLIVIOUS
|
||||
&& !IsAbilityOnSide(gBattlerTarget, ABILITY_AROMA_VEIL)
|
||||
&& AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget))
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_INFATUATED_WITH(gBattlerAttacker);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||||
gBattleMons[gBattlerTarget].volatiles.infatuation = INFATUATED_WITH(gBattlerAttacker);
|
||||
gBattleCommunication[MULTIUSE_STATE] = 2;
|
||||
gEffectBattler = gBattlerTarget;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
|
@ -18280,11 +18230,10 @@ void BS_TrySetEscapePrevention(void)
|
|||
{
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
|
||||
if (!(gBattleMons[gBattlerTarget].status2 & STATUS2_ESCAPE_PREVENTION))
|
||||
if (!gBattleMons[gBattlerTarget].volatiles.escapePrevention)
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_ESCAPE_PREVENTION;
|
||||
gBattleMons[gBattlerTarget].volatiles.escapePrevention = TRUE;
|
||||
gDisableStructs[gBattlerTarget].battlerPreventingEscape = gBattlerAttacker;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
||||
gEffectBattler = gBattlerTarget;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
|
@ -18298,12 +18247,11 @@ void BS_TrySetTorment(void)
|
|||
{
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
|
||||
if (!(gBattleMons[gBattlerTarget].status2 & STATUS2_TORMENT)
|
||||
if (!(gBattleMons[gBattlerTarget].volatiles.torment == TRUE)
|
||||
&& !IsAbilityOnSide(gBattlerTarget, ABILITY_AROMA_VEIL))
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_TORMENT;
|
||||
gBattleMons[gBattlerTarget].volatiles.torment = TRUE;
|
||||
gDisableStructs[gBattlerTarget].tormentTimer = gBattleTurnCounter + 3; // 3 turns excluding current turn
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
|
||||
gEffectBattler = gBattlerTarget;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ bool32 CanTerastallize(u32 battler)
|
|||
{
|
||||
enum ItemHoldEffect holdEffect = GetBattlerHoldEffect(battler, FALSE);
|
||||
|
||||
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED && GET_BASE_SPECIES_ID(gBattleMons[battler].species) == SPECIES_TERAPAGOS)
|
||||
if (gBattleMons[battler].volatiles.transformed && GET_BASE_SPECIES_ID(gBattleMons[battler].species) == SPECIES_TERAPAGOS)
|
||||
return FALSE;
|
||||
|
||||
// Prevents Zigzagoon from terastalizing in vanilla.
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ void HandleAction_UseMove(void)
|
|||
gHitMarker |= HITMARKER_NO_PPDEDUCT;
|
||||
gBattleStruct->moveTarget[gBattlerAttacker] = GetBattleMoveTarget(MOVE_STRUGGLE, NO_TARGET_OVERRIDE);
|
||||
}
|
||||
else if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS || gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE)
|
||||
else if (gBattleMons[gBattlerAttacker].volatiles.multipleTurns || gBattleMons[gBattlerAttacker].volatiles.recharge)
|
||||
{
|
||||
gCurrentMove = gChosenMove = gLockedMoves[gBattlerAttacker];
|
||||
}
|
||||
|
|
@ -1056,18 +1056,18 @@ const u8 *CheckSkyDropState(u32 battler, enum SkyDropState skyDropState)
|
|||
// If target was sky dropped in the middle of Outrage/Thrash/Petal Dance,
|
||||
// confuse them upon release and display "confused by fatigue" message & animation.
|
||||
// Don't do this if this CancelMultiTurnMoves is caused by falling asleep via Yawn.
|
||||
if (gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE && skyDropState != SKY_DROP_STATUS_YAWN)
|
||||
if (gBattleMons[otherSkyDropper].volatiles.lockConfusionTurns && skyDropState != SKY_DROP_STATUS_YAWN)
|
||||
{
|
||||
gBattleMons[otherSkyDropper].status2 &= ~(STATUS2_LOCK_CONFUSE);
|
||||
gBattleMons[otherSkyDropper].volatiles.lockConfusionTurns = 0;
|
||||
|
||||
// If the target can be confused, confuse them.
|
||||
// Don't use CanBeConfused, can cause issues in edge cases.
|
||||
if (!(gBattleMons[otherSkyDropper].status2 & STATUS2_CONFUSION
|
||||
if (!(gBattleMons[otherSkyDropper].volatiles.confusionTurns > 0
|
||||
|| IsAbilityAndRecord(otherSkyDropper, GetBattlerAbility(otherSkyDropper), ABILITY_OWN_TEMPO)
|
||||
|| IsBattlerTerrainAffected(otherSkyDropper, STATUS_FIELD_MISTY_TERRAIN)))
|
||||
{
|
||||
// Set confused status
|
||||
gBattleMons[otherSkyDropper].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
|
||||
gBattleMons[otherSkyDropper].volatiles.confusionTurns = ((Random()) % 4) + 2;
|
||||
|
||||
if (skyDropState == SKY_DROP_ATTACKCANCELLER_CHECK)
|
||||
{
|
||||
|
|
@ -1094,7 +1094,7 @@ const u8 *CheckSkyDropState(u32 battler, enum SkyDropState skyDropState)
|
|||
}
|
||||
|
||||
// Clear skyDropTargets data, unless this CancelMultiTurnMoves is caused by Yawn, attackcanceler, or VARIOUS_GRAVITY_ON_AIRBORNE_MONS
|
||||
if (!(gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[battler] < 4)
|
||||
if (!(gBattleMons[otherSkyDropper].volatiles.lockConfusionTurns) && gBattleStruct->skyDropTargets[battler] < 4)
|
||||
{
|
||||
gBattleStruct->skyDropTargets[battler] = SKY_DROP_NO_TARGET;
|
||||
gBattleStruct->skyDropTargets[otherSkyDropper] = SKY_DROP_NO_TARGET;
|
||||
|
|
@ -1106,18 +1106,18 @@ const u8 *CheckSkyDropState(u32 battler, enum SkyDropState skyDropState)
|
|||
const u8 *CancelMultiTurnMoves(u32 battler, enum SkyDropState skyDropState)
|
||||
{
|
||||
const u8 *result = NULL;
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_UPROAR);
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_BIDE);
|
||||
gBattleMons[battler].volatiles.uproarTurns = 0;
|
||||
gBattleMons[battler].volatiles.bideTurns = 0;
|
||||
|
||||
if (B_RAMPAGE_CANCELLING < GEN_5)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_MULTIPLETURNS);
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_LOCK_CONFUSE);
|
||||
gBattleMons[battler].volatiles.multipleTurns = 0;
|
||||
gBattleMons[battler].volatiles.lockConfusionTurns = 0;
|
||||
}
|
||||
else if (!(gBattleMons[battler].status2 & STATUS2_LOCK_CONFUSE)
|
||||
|| ((gBattleMons[battler].status2 & STATUS2_LOCK_CONFUSE) > STATUS2_LOCK_CONFUSE_TURN(1)))
|
||||
else if (!gBattleMons[battler].volatiles.lockConfusionTurns
|
||||
|| gBattleMons[battler].volatiles.lockConfusionTurns > 1)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_MULTIPLETURNS);
|
||||
gBattleMons[battler].volatiles.multipleTurns = 0;
|
||||
}
|
||||
|
||||
// Clear battler's semi-invulnerable bits if they are not held by Sky Drop.
|
||||
|
|
@ -1341,7 +1341,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
|
|||
}
|
||||
}
|
||||
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && move == gLastMoves[battler] && move != MOVE_STRUGGLE && (gBattleMons[battler].status2 & STATUS2_TORMENT))
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && move == gLastMoves[battler] && move != MOVE_STRUGGLE && (gBattleMons[battler].volatiles.torment == TRUE))
|
||||
{
|
||||
CancelMultiTurnMoves(battler, SKY_DROP_IGNORE);
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
|
|
@ -1588,7 +1588,7 @@ u32 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check)
|
|||
else if (check & MOVE_LIMITATION_DISABLED && move == gDisableStructs[battler].disabledMove)
|
||||
unusableMoves |= 1u << i;
|
||||
// Torment
|
||||
else if (check & MOVE_LIMITATION_TORMENTED && move == gLastMoves[battler] && gBattleMons[battler].status2 & STATUS2_TORMENT)
|
||||
else if (check & MOVE_LIMITATION_TORMENTED && move == gLastMoves[battler] && gBattleMons[battler].volatiles.torment == TRUE)
|
||||
unusableMoves |= 1u << i;
|
||||
// Taunt
|
||||
else if (check & MOVE_LIMITATION_TAUNT && gDisableStructs[battler].tauntTimer && IsBattleMoveStatus(move))
|
||||
|
|
@ -1849,8 +1849,8 @@ void TryClearRageAndFuryCutter(void)
|
|||
s32 i;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if ((gBattleMons[i].status2 & STATUS2_RAGE) && gChosenMoveByBattler[i] != MOVE_RAGE)
|
||||
gBattleMons[i].status2 &= ~STATUS2_RAGE;
|
||||
if (gBattleMons[i].volatiles.rage && gChosenMoveByBattler[i] != MOVE_RAGE)
|
||||
gBattleMons[i].volatiles.rage = FALSE;
|
||||
if (gDisableStructs[i].furyCutterCounter != 0 && gChosenMoveByBattler[i] != MOVE_FURY_CUTTER)
|
||||
gDisableStructs[i].furyCutterCounter = 0;
|
||||
}
|
||||
|
|
@ -1871,7 +1871,7 @@ static inline bool32 TryFormChangeBeforeMove(void)
|
|||
static inline bool32 TryActivatePowderStatus(u32 move)
|
||||
{
|
||||
u32 partnerMove = gBattleMons[BATTLE_PARTNER(gBattlerAttacker)].moves[gBattleStruct->chosenMovePositions[BATTLE_PARTNER(gBattlerAttacker)]];
|
||||
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_POWDER))
|
||||
if (!gBattleMons[gBattlerAttacker].volatiles.powder)
|
||||
return FALSE;
|
||||
if (GetBattleMoveType(move) == TYPE_FIRE && !gBattleStruct->pledgeMove)
|
||||
return TRUE;
|
||||
|
|
@ -1890,7 +1890,7 @@ void SetAtkCancellerForCalledMove(void)
|
|||
|
||||
static enum MoveCanceller CancellerFlags(void)
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_DESTINY_BOND;
|
||||
gBattleMons[gBattlerAttacker].volatiles.destinyBond = FALSE;
|
||||
gStatuses3[gBattlerAttacker] &= ~STATUS3_GRUDGE;
|
||||
gStatuses4[gBattlerAttacker] &= ~STATUS4_GLAIVE_RUSH;
|
||||
return MOVE_STEP_SUCCESS;
|
||||
|
|
@ -1917,9 +1917,9 @@ static enum MoveCanceller CancellerSkyDrop(void)
|
|||
|
||||
static enum MoveCanceller CancellerRecharge(void)
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE)
|
||||
if (gBattleMons[gBattlerAttacker].volatiles.recharge)
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RECHARGE;
|
||||
gBattleMons[gBattlerAttacker].volatiles.recharge = TRUE;
|
||||
gDisableStructs[gBattlerAttacker].rechargeTimer = 0;
|
||||
CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge;
|
||||
|
|
@ -1937,7 +1937,7 @@ static enum MoveCanceller CancellerAsleepOrFrozen(void)
|
|||
{
|
||||
TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), gBattlerPartyIndexes[gBattlerAttacker]);
|
||||
gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP;
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[gBattlerAttacker].volatiles.nightmare = FALSE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP_UPROAR;
|
||||
BattleScriptCall(BattleScript_MoveUsedWokeUp);
|
||||
return MOVE_STEP_REMOVES_STATUS;
|
||||
|
|
@ -1967,7 +1967,7 @@ static enum MoveCanceller CancellerAsleepOrFrozen(void)
|
|||
else
|
||||
{
|
||||
TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), gBattlerPartyIndexes[gBattlerAttacker]);
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[gBattlerAttacker].volatiles.nightmare = FALSE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP;
|
||||
BattleScriptCall(BattleScript_MoveUsedWokeUp);
|
||||
return MOVE_STEP_REMOVES_STATUS;
|
||||
|
|
@ -2067,7 +2067,7 @@ static enum MoveCanceller CancellerTruant(void)
|
|||
|
||||
static enum MoveCanceller CancellerFlinch(void)
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_FLINCHED)
|
||||
if (gBattleMons[gBattlerAttacker].volatiles.flinched)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE;
|
||||
CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK);
|
||||
|
|
@ -2154,11 +2154,11 @@ static enum MoveCanceller CancellerConfused(void)
|
|||
if (gBattleStruct->isAtkCancelerForCalledMove)
|
||||
return MOVE_STEP_SUCCESS;
|
||||
|
||||
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION)
|
||||
if (gBattleMons[gBattlerAttacker].volatiles.confusionTurns)
|
||||
{
|
||||
if (!(gStatuses4[gBattlerAttacker] & STATUS4_INFINITE_CONFUSION))
|
||||
gBattleMons[gBattlerAttacker].status2 -= STATUS2_CONFUSION_TURN(1);
|
||||
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION)
|
||||
gBattleMons[gBattlerAttacker].volatiles.confusionTurns--;
|
||||
if (gBattleMons[gBattlerAttacker].volatiles.confusionTurns)
|
||||
{
|
||||
// confusion dmg
|
||||
if (RandomPercentage(RNG_CONFUSION, (GetGenConfig(GEN_CONFIG_CONFUSION_SELF_DMG_CHANCE) >= GEN_7 ? 33 : 50)))
|
||||
|
|
@ -2212,9 +2212,9 @@ static enum MoveCanceller CancellerParalysed(void)
|
|||
|
||||
static enum MoveCanceller CancellerInfatuation(void)
|
||||
{
|
||||
if (!gBattleStruct->isAtkCancelerForCalledMove && gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION)
|
||||
if (!gBattleStruct->isAtkCancelerForCalledMove && gBattleMons[gBattlerAttacker].volatiles.infatuation)
|
||||
{
|
||||
gBattleScripting.battler = CountTrailingZeroBits((gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) >> 0x10);
|
||||
gBattleScripting.battler = gBattleMons[gBattlerAttacker].volatiles.infatuation - 1;
|
||||
if (!RandomPercentage(RNG_INFATUATION, 50))
|
||||
{
|
||||
BattleScriptCall(BattleScript_MoveUsedIsInLove);
|
||||
|
|
@ -2234,17 +2234,16 @@ static enum MoveCanceller CancellerInfatuation(void)
|
|||
|
||||
static enum MoveCanceller CancellerBide(void)
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE)
|
||||
if (gBattleMons[gBattlerAttacker].volatiles.bideTurns)
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status2 -= STATUS2_BIDE_TURN(1);
|
||||
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE)
|
||||
if (--gBattleMons[gBattlerAttacker].volatiles.bideTurns)
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_BideStoringEnergy;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is removed in FRLG and Emerald for some reason
|
||||
//gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_MULTIPLETURNS;
|
||||
//gBattleMons[gBattlerAttacker].volatiles.multipleTurns = FALSE;
|
||||
if (gBideDmg[gBattlerAttacker])
|
||||
{
|
||||
gCurrentMove = MOVE_BIDE;
|
||||
|
|
@ -2978,7 +2977,7 @@ bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 a
|
|||
case ABILITY_SOUNDPROOF:
|
||||
if (IsSoundMove(move) && !(GetBattlerMoveTargetType(battlerAtk, move) & MOVE_TARGET_USER))
|
||||
{
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_MULTIPLETURNS)
|
||||
if (gBattleMons[battlerAtk].volatiles.multipleTurns)
|
||||
gHitMarker |= HITMARKER_NO_PPDEDUCT;
|
||||
battleScriptBlocksMove = BattleScript_SoundproofProtected;
|
||||
}
|
||||
|
|
@ -2986,7 +2985,7 @@ bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 a
|
|||
case ABILITY_BULLETPROOF:
|
||||
if (IsBallisticMove(move))
|
||||
{
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_MULTIPLETURNS)
|
||||
if (gBattleMons[battlerAtk].volatiles.multipleTurns)
|
||||
gHitMarker |= HITMARKER_NO_PPDEDUCT;
|
||||
battleScriptBlocksMove = BattleScript_SoundproofProtected;
|
||||
}
|
||||
|
|
@ -2996,7 +2995,7 @@ bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 a
|
|||
case ABILITY_ARMOR_TAIL:
|
||||
if (atkPriority > 0 && !IsBattlerAlly(battlerAtk, battlerDef))
|
||||
{
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_MULTIPLETURNS)
|
||||
if (gBattleMons[battlerAtk].volatiles.multipleTurns)
|
||||
gHitMarker |= HITMARKER_NO_PPDEDUCT;
|
||||
battleScriptBlocksMove = BattleScript_DazzlingProtected;
|
||||
}
|
||||
|
|
@ -3041,7 +3040,7 @@ bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 a
|
|||
case ABILITY_DAZZLING:
|
||||
case ABILITY_QUEENLY_MAJESTY:
|
||||
case ABILITY_ARMOR_TAIL:
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_MULTIPLETURNS)
|
||||
if (gBattleMons[battlerAtk].volatiles.multipleTurns)
|
||||
gHitMarker |= HITMARKER_NO_PPDEDUCT;
|
||||
battlerAbility = partnerDef;
|
||||
battleScriptBlocksMove = BattleScript_DazzlingProtected;
|
||||
|
|
@ -3549,8 +3548,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
if (gDisableStructs[battler].isFirstTurn == 2
|
||||
&& !gDisableStructs[battler].overwrittenAbility
|
||||
&& IsBattlerAlive(diagonalBattler)
|
||||
&& !(gBattleMons[diagonalBattler].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE))
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
&& !gBattleMons[diagonalBattler].volatiles.substitute
|
||||
&& !gBattleMons[diagonalBattler].volatiles.transformed
|
||||
&& !gBattleMons[battler].volatiles.transformed
|
||||
&& gBattleStruct->illusion[diagonalBattler].state != ILLUSION_ON
|
||||
&& !(gStatuses3[diagonalBattler] & STATUS3_SEMI_INVULNERABLE_NO_COMMANDER))
|
||||
{
|
||||
|
|
@ -4124,7 +4124,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
case ABILITY_ICE_FACE:
|
||||
if (IsBattlerWeatherAffected(battler, B_WEATHER_HAIL | B_WEATHER_SNOW)
|
||||
&& gBattleMons[battler].species == SPECIES_EISCUE_NOICE
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
|
||||
&& !(gBattleMons[battler].volatiles.transformed))
|
||||
{
|
||||
// TODO: Convert this to a proper FORM_CHANGE type.
|
||||
gBattleMons[battler].species = SPECIES_EISCUE_ICE;
|
||||
|
|
@ -4147,9 +4147,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
gBattleStruct->battlerState[battler].commandingDondozo = TRUE;
|
||||
gBattleStruct->commanderActive[partner] = gBattleMons[battler].species;
|
||||
gStatuses3[battler] |= STATUS3_COMMANDER;
|
||||
if (gBattleMons[battler].status2 & STATUS2_CONFUSION
|
||||
if (gBattleMons[battler].volatiles.confusionTurns > 0
|
||||
&& !(gStatuses4[battler] & STATUS4_INFINITE_CONFUSION))
|
||||
gBattleMons[battler].status2 -= STATUS2_CONFUSION_TURN(1);
|
||||
gBattleMons[battler].volatiles.confusionTurns--;
|
||||
BtlController_EmitSpriteInvisibility(battler, B_COMM_TO_CONTROLLER, TRUE);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
BattleScriptPushCursorAndCallback(BattleScript_CommanderActivates);
|
||||
|
|
@ -4245,7 +4245,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
|
||||
|
||||
gBattleMons[battler].status1 = 0;
|
||||
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[battler].volatiles.nightmare = FALSE;
|
||||
gBattleScripting.battler = battler;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_ShedSkinActivates);
|
||||
BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battler].status1);
|
||||
|
|
@ -4363,7 +4363,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
}
|
||||
break;
|
||||
case ABILITY_HUNGER_SWITCH:
|
||||
if (!(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
if (!gBattleMons[battler].volatiles.transformed
|
||||
&& GetActiveGimmick(battler) != GIMMICK_TERA
|
||||
&& TryBattleFormChange(battler, FORM_CHANGE_BATTLE_TURN_END))
|
||||
{
|
||||
|
|
@ -4728,13 +4728,13 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||
&& IsBattlerAlive(gBattlerTarget)
|
||||
&& (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_CUTE_CHARM, 30) : RandomChance(RNG_CUTE_CHARM, 1, 3))
|
||||
&& !(gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION)
|
||||
&& !(gBattleMons[gBattlerAttacker].volatiles.infatuation)
|
||||
&& AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget)
|
||||
&& !IsAbilityAndRecord(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), ABILITY_OBLIVIOUS)
|
||||
&& !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker, TRUE), move)
|
||||
&& !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL))
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_INFATUATED_WITH(gBattlerTarget);
|
||||
gBattleMons[gBattlerAttacker].volatiles.infatuation = INFATUATED_WITH(gBattlerTarget);
|
||||
BattleScriptCall(BattleScript_CuteCharmActivates);
|
||||
effect++;
|
||||
}
|
||||
|
|
@ -5034,7 +5034,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
}
|
||||
break;
|
||||
case ABILITY_OWN_TEMPO:
|
||||
if (gBattleMons[battler].status2 & STATUS2_CONFUSION)
|
||||
if (gBattleMons[battler].volatiles.confusionTurns > 0)
|
||||
{
|
||||
StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn);
|
||||
effect = 2;
|
||||
|
|
@ -5052,7 +5052,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
|
||||
{
|
||||
TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
|
||||
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[battler].volatiles.nightmare = FALSE;
|
||||
StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
|
||||
effect = 1;
|
||||
}
|
||||
|
|
@ -5074,7 +5074,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
}
|
||||
break;
|
||||
case ABILITY_OBLIVIOUS:
|
||||
if (gBattleMons[battler].status2 & STATUS2_INFATUATION)
|
||||
if (gBattleMons[battler].volatiles.infatuation)
|
||||
effect = 3;
|
||||
else if (gDisableStructs[battler].tauntTimer != 0)
|
||||
effect = 4;
|
||||
|
|
@ -5094,7 +5094,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
BattleScriptCall(BattleScript_AbilityCuredStatus);
|
||||
break;
|
||||
case 3: // get rid of infatuation
|
||||
gBattleMons[battler].status2 &= ~STATUS2_INFATUATION;
|
||||
gBattleMons[battler].volatiles.infatuation = 0;
|
||||
BattleScriptCall(BattleScript_BattlerGotOverItsInfatuation);
|
||||
break;
|
||||
case 4: // get rid of taunt
|
||||
|
|
@ -5215,7 +5215,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
if (!gDisableStructs[battler].weatherAbilityDone
|
||||
&& battlerWeatherAffected
|
||||
&& gBattleMons[battler].species == SPECIES_EISCUE_NOICE
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
|
||||
&& !(gBattleMons[battler].volatiles.transformed))
|
||||
{
|
||||
// TODO: Convert this to a proper FORM_CHANGE type.
|
||||
gBattleScripting.battler = battler;
|
||||
|
|
@ -5229,7 +5229,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
case ABILITY_PROTOSYNTHESIS:
|
||||
if (!gDisableStructs[battler].weatherAbilityDone
|
||||
&& (gBattleWeather & B_WEATHER_SUN) && HasWeatherEffect()
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
&& !gBattleMons[battler].volatiles.transformed
|
||||
&& !gDisableStructs[battler].boosterEnergyActivated)
|
||||
{
|
||||
gDisableStructs[battler].weatherAbilityDone = TRUE;
|
||||
|
|
@ -5258,7 +5258,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
case ABILITY_QUARK_DRIVE:
|
||||
if (!gDisableStructs[battler].terrainAbilityDone
|
||||
&& gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
&& !gBattleMons[battler].volatiles.transformed
|
||||
&& !gDisableStructs[battler].boosterEnergyActivated)
|
||||
{
|
||||
gDisableStructs[battler].terrainAbilityDone = TRUE;
|
||||
|
|
@ -5358,7 +5358,7 @@ u32 GetBattlerAbilityInternal(u32 battler, u32 ignoreMoldBreaker, u32 noAbilityS
|
|||
if (abilityCantBeSuppressed)
|
||||
{
|
||||
// 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].status2 & STATUS2_TRANSFORMED
|
||||
if (gBattleMons[battler].volatiles.transformed
|
||||
&& gStatuses3[battler] & STATUS3_GASTRO_ACID
|
||||
&& gBattleMons[battler].ability == ABILITY_COMATOSE)
|
||||
return ABILITY_NONE;
|
||||
|
|
@ -5457,7 +5457,9 @@ bool32 CanBattlerEscape(u32 battler) // no ability check
|
|||
return TRUE;
|
||||
else if (B_GHOSTS_ESCAPE >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
|
||||
return TRUE;
|
||||
else if (gBattleMons[battler].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED))
|
||||
else if (gBattleMons[battler].volatiles.escapePrevention)
|
||||
return FALSE;
|
||||
else if (gBattleMons[battler].volatiles.wrapped)
|
||||
return FALSE;
|
||||
else if (gStatuses3[battler] & STATUS3_ROOTED)
|
||||
return FALSE;
|
||||
|
|
@ -5793,7 +5795,7 @@ static bool32 CanSleepDueToSleepClause(u32 battlerAtk, u32 battlerDef, enum Func
|
|||
|
||||
bool32 CanBeConfused(u32 battler)
|
||||
{
|
||||
if (gBattleMons[battler].status2 & STATUS2_CONFUSION
|
||||
if (gBattleMons[battler].volatiles.confusionTurns > 0
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_MISTY_TERRAIN)
|
||||
|| IsAbilityAndRecord(battler, GetBattlerAbility(battler),ABILITY_OWN_TEMPO))
|
||||
return FALSE;
|
||||
|
|
@ -6137,9 +6139,9 @@ static bool32 GetMentalHerbEffect(u32 battler)
|
|||
bool32 ret = FALSE;
|
||||
|
||||
// Check infatuation
|
||||
if (gBattleMons[battler].status2 & STATUS2_INFATUATION)
|
||||
if (gBattleMons[battler].volatiles.infatuation)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~STATUS2_INFATUATION;
|
||||
gBattleMons[battler].volatiles.infatuation = 0;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_INFATUATION; // STRINGID_TARGETGOTOVERINFATUATION
|
||||
StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn);
|
||||
ret = TRUE;
|
||||
|
|
@ -6163,9 +6165,9 @@ static bool32 GetMentalHerbEffect(u32 battler)
|
|||
ret = TRUE;
|
||||
}
|
||||
// Check torment
|
||||
if (gBattleMons[battler].status2 & STATUS2_TORMENT)
|
||||
if (gBattleMons[battler].volatiles.torment == TRUE)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~STATUS2_TORMENT;
|
||||
gBattleMons[battler].volatiles.torment = FALSE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_TORMENT;
|
||||
ret = TRUE;
|
||||
}
|
||||
|
|
@ -6209,7 +6211,7 @@ static u32 TryConsumeMirrorHerb(u32 battler, enum ItemCaseId caseID)
|
|||
|
||||
u32 TryBoosterEnergy(u32 battler, u32 ability, enum ItemCaseId caseID)
|
||||
{
|
||||
if (gDisableStructs[battler].boosterEnergyActivated || gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
if (gDisableStructs[battler].boosterEnergyActivated || gBattleMons[battler].volatiles.transformed)
|
||||
return ITEM_NO_EFFECT;
|
||||
|
||||
if (((ability == ABILITY_PROTOSYNTHESIS) && !((gBattleWeather & B_WEATHER_SUN) && HasWeatherEffect()))
|
||||
|
|
@ -6368,14 +6370,14 @@ static u8 ItemEffectMoveEnd(u32 battler, enum ItemHoldEffect holdEffect)
|
|||
if (gBattleMons[battler].status1 & STATUS1_SLEEP && !UnnerveOn(battler, gLastUsedItem))
|
||||
{
|
||||
gBattleMons[battler].status1 &= ~STATUS1_SLEEP;
|
||||
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[battler].volatiles.nightmare = FALSE;
|
||||
BattleScriptCall(BattleScript_BerryCureSlpRet);
|
||||
effect = ITEM_STATUS_CHANGE;
|
||||
TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
|
||||
}
|
||||
break;
|
||||
case HOLD_EFFECT_CURE_CONFUSION:
|
||||
if (gBattleMons[battler].status2 & STATUS2_CONFUSION && !UnnerveOn(battler, gLastUsedItem))
|
||||
if (gBattleMons[battler].volatiles.confusionTurns > 0 && !UnnerveOn(battler, gLastUsedItem))
|
||||
{
|
||||
RemoveConfusionStatus(battler);
|
||||
BattleScriptCall(BattleScript_BerryCureConfusionRet);
|
||||
|
|
@ -6392,14 +6394,14 @@ static u8 ItemEffectMoveEnd(u32 battler, enum ItemHoldEffect holdEffect)
|
|||
}
|
||||
break;
|
||||
case HOLD_EFFECT_CURE_STATUS:
|
||||
if ((gBattleMons[battler].status1 & STATUS1_ANY || gBattleMons[battler].status2 & STATUS2_CONFUSION) && !UnnerveOn(battler, gLastUsedItem))
|
||||
if ((gBattleMons[battler].status1 & STATUS1_ANY || gBattleMons[battler].volatiles.confusionTurns > 0) && !UnnerveOn(battler, gLastUsedItem))
|
||||
{
|
||||
if (gBattleMons[battler].status1 & STATUS1_PSN_ANY)
|
||||
StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn);
|
||||
|
||||
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[battler].volatiles.nightmare = FALSE;
|
||||
StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
|
||||
TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
|
||||
}
|
||||
|
|
@ -6413,7 +6415,7 @@ static u8 ItemEffectMoveEnd(u32 battler, enum ItemHoldEffect holdEffect)
|
|||
if (gBattleMons[battler].status1 & STATUS1_FREEZE || gBattleMons[battler].status1 & STATUS1_FROSTBITE)
|
||||
StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
|
||||
|
||||
if (gBattleMons[battler].status2 & STATUS2_CONFUSION)
|
||||
if (gBattleMons[battler].volatiles.confusionTurns > 0)
|
||||
StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn);
|
||||
|
||||
gBattleMons[battler].status1 = 0;
|
||||
|
|
@ -6425,10 +6427,10 @@ static u8 ItemEffectMoveEnd(u32 battler, enum ItemHoldEffect holdEffect)
|
|||
break;
|
||||
case HOLD_EFFECT_CRITICAL_UP: // lansat berry
|
||||
if (B_BERRIES_INSTANT >= GEN_4
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY)
|
||||
&& !(gBattleMons[battler].volatiles.dragonCheer || gBattleMons[battler].volatiles.focusEnergy)
|
||||
&& HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, gLastUsedItem), gLastUsedItem))
|
||||
{
|
||||
gBattleMons[battler].status2 |= STATUS2_FOCUS_ENERGY;
|
||||
gBattleMons[battler].volatiles.focusEnergy = TRUE;
|
||||
gBattleScripting.battler = battler;
|
||||
gPotentialItemEffectBattler = battler;
|
||||
BattleScriptCall(BattleScript_BerryFocusEnergyRet);
|
||||
|
|
@ -6453,7 +6455,7 @@ static inline bool32 TryCureStatus(u32 battler, enum ItemCaseId caseId)
|
|||
u32 effect = ITEM_NO_EFFECT;
|
||||
u32 string = 0;
|
||||
|
||||
if ((gBattleMons[battler].status1 & STATUS1_ANY || gBattleMons[battler].status2 & STATUS2_CONFUSION) && !UnnerveOn(battler, gLastUsedItem))
|
||||
if ((gBattleMons[battler].status1 & STATUS1_ANY || gBattleMons[battler].volatiles.confusionTurns > 0) && !UnnerveOn(battler, gLastUsedItem))
|
||||
{
|
||||
if (gBattleMons[battler].status1 & STATUS1_PSN_ANY)
|
||||
{
|
||||
|
|
@ -6462,7 +6464,7 @@ static inline bool32 TryCureStatus(u32 battler, enum ItemCaseId caseId)
|
|||
}
|
||||
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[battler].volatiles.nightmare = FALSE;
|
||||
StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
|
||||
string++;
|
||||
TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
|
||||
|
|
@ -6482,7 +6484,7 @@ static inline bool32 TryCureStatus(u32 battler, enum ItemCaseId caseId)
|
|||
StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
|
||||
string++;
|
||||
}
|
||||
if (gBattleMons[battler].status2 & STATUS2_CONFUSION)
|
||||
if (gBattleMons[battler].volatiles.confusionTurns > 0)
|
||||
{
|
||||
StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn);
|
||||
string++;
|
||||
|
|
@ -6585,10 +6587,10 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler)
|
|||
break;
|
||||
case HOLD_EFFECT_CRITICAL_UP:
|
||||
if (B_BERRIES_INSTANT >= GEN_4
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY)
|
||||
&& !(gBattleMons[battler].volatiles.dragonCheer || gBattleMons[battler].volatiles.focusEnergy)
|
||||
&& HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, gLastUsedItem), gLastUsedItem))
|
||||
{
|
||||
gBattleMons[battler].status2 |= STATUS2_FOCUS_ENERGY;
|
||||
gBattleMons[battler].volatiles.focusEnergy = TRUE;
|
||||
gBattleScripting.battler = battler;
|
||||
BattleScriptExecute(BattleScript_BerryFocusEnergyEnd2);
|
||||
effect = ITEM_EFFECT_OTHER;
|
||||
|
|
@ -6652,7 +6654,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler)
|
|||
&& !UnnerveOn(battler, gLastUsedItem))
|
||||
{
|
||||
gBattleMons[battler].status1 &= ~STATUS1_SLEEP;
|
||||
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[battler].volatiles.nightmare = FALSE;
|
||||
BattleScriptExecute(BattleScript_BerryCureSlpEnd2);
|
||||
effect = ITEM_STATUS_CHANGE;
|
||||
TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
|
||||
|
|
@ -6808,10 +6810,10 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler)
|
|||
effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, caseID);
|
||||
break;
|
||||
case HOLD_EFFECT_CRITICAL_UP:
|
||||
if (!(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY)
|
||||
if (!(gBattleMons[battler].volatiles.dragonCheer || gBattleMons[battler].volatiles.focusEnergy)
|
||||
&& HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, gLastUsedItem), gLastUsedItem))
|
||||
{
|
||||
gBattleMons[battler].status2 |= STATUS2_FOCUS_ENERGY;
|
||||
gBattleMons[battler].volatiles.focusEnergy = TRUE;
|
||||
gBattleScripting.battler = battler;
|
||||
BattleScriptExecute(BattleScript_BerryFocusEnergyEnd2);
|
||||
effect = ITEM_EFFECT_OTHER;
|
||||
|
|
@ -6862,14 +6864,14 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler)
|
|||
if (gBattleMons[battler].status1 & STATUS1_SLEEP && !UnnerveOn(battler, gLastUsedItem))
|
||||
{
|
||||
gBattleMons[battler].status1 &= ~STATUS1_SLEEP;
|
||||
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
|
||||
gBattleMons[battler].volatiles.nightmare = FALSE;
|
||||
BattleScriptExecute(BattleScript_BerryCureSlpEnd2);
|
||||
effect = ITEM_STATUS_CHANGE;
|
||||
TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
|
||||
}
|
||||
break;
|
||||
case HOLD_EFFECT_CURE_CONFUSION:
|
||||
if (gBattleMons[battler].status2 & STATUS2_CONFUSION && !UnnerveOn(battler, gLastUsedItem))
|
||||
if (gBattleMons[battler].volatiles.confusionTurns > 0 && !UnnerveOn(battler, gLastUsedItem))
|
||||
{
|
||||
RemoveConfusionStatus(battler);
|
||||
BattleScriptExecute(BattleScript_BerryCureConfusionEnd2);
|
||||
|
|
@ -7270,7 +7272,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler)
|
|||
void ClearVariousBattlerFlags(u32 battler)
|
||||
{
|
||||
gDisableStructs[battler].furyCutterCounter = 0;
|
||||
gBattleMons[battler].status2 &= ~STATUS2_DESTINY_BOND;
|
||||
gBattleMons[battler].volatiles.destinyBond = FALSE;
|
||||
gStatuses3[battler] &= ~STATUS3_GRUDGE;
|
||||
gStatuses4[battler] &= ~ STATUS4_GLAIVE_RUSH;
|
||||
}
|
||||
|
|
@ -7459,7 +7461,7 @@ u8 GetAttackerObedienceForAction()
|
|||
// is not obedient
|
||||
enum BattleMoveEffects moveEffect = GetMoveEffect(gCurrentMove);
|
||||
if (moveEffect == EFFECT_RAGE)
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RAGE;
|
||||
gBattleMons[gBattlerAttacker].volatiles.rage = FALSE;
|
||||
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (moveEffect == EFFECT_SNORE || moveEffect == EFFECT_SLEEP_TALK))
|
||||
return DISOBEYS_WHILE_ASLEEP;
|
||||
|
||||
|
|
@ -7485,7 +7487,7 @@ u8 GetAttackerObedienceForAction()
|
|||
// try putting asleep
|
||||
int i;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
if (gBattleMons[i].status2 & STATUS2_UPROAR)
|
||||
if (gBattleMons[i].volatiles.uproarTurns)
|
||||
break;
|
||||
if (i == gBattlersCount)
|
||||
return DISOBEYS_FALL_ASLEEP;
|
||||
|
|
@ -7895,7 +7897,7 @@ u32 CalcRolloutBasePower(u32 battlerAtk, u32 basePower, u32 rolloutTimer)
|
|||
u32 i;
|
||||
for (i = 1; i < (5 - rolloutTimer); i++)
|
||||
basePower *= 2;
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_DEFENSE_CURL)
|
||||
if (gBattleMons[battlerAtk].volatiles.defenseCurl)
|
||||
basePower *= 2;
|
||||
return basePower;
|
||||
}
|
||||
|
|
@ -8431,7 +8433,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageContext *ctx)
|
|||
u8 defHighestStat = GetHighestStatId(battlerDef);
|
||||
if (((ctx->weather & B_WEATHER_SUN && HasWeatherEffect()) || gDisableStructs[battlerDef].boosterEnergyActivated)
|
||||
&& ((IsBattleMovePhysical(move) && defHighestStat == STAT_DEF) || (IsBattleMoveSpecial(move) && defHighestStat == STAT_SPDEF))
|
||||
&& !(gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED))
|
||||
&& !(gBattleMons[battlerDef].volatiles.transformed))
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(0.7));
|
||||
}
|
||||
break;
|
||||
|
|
@ -8440,7 +8442,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageContext *ctx)
|
|||
u8 defHighestStat = GetHighestStatId(battlerDef);
|
||||
if ((gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gDisableStructs[battlerDef].boosterEnergyActivated)
|
||||
&& ((IsBattleMovePhysical(move) && defHighestStat == STAT_DEF) || (IsBattleMoveSpecial(move) && defHighestStat == STAT_SPDEF))
|
||||
&& !(gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED))
|
||||
&& !(gBattleMons[battlerDef].volatiles.transformed))
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(0.7));
|
||||
}
|
||||
break;
|
||||
|
|
@ -8683,7 +8685,7 @@ static inline u32 CalcAttackStat(struct DamageContext *ctx)
|
|||
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
|
||||
break;
|
||||
case ABILITY_PROTOSYNTHESIS:
|
||||
if (!(gBattleMons[battlerAtk].status2 & STATUS2_TRANSFORMED))
|
||||
if (!(gBattleMons[battlerAtk].volatiles.transformed))
|
||||
{
|
||||
u32 atkHighestStat = GetHighestStatId(battlerAtk);
|
||||
if (((ctx->weather & B_WEATHER_SUN) && HasWeatherEffect()) || gDisableStructs[battlerAtk].boosterEnergyActivated)
|
||||
|
|
@ -8694,7 +8696,7 @@ static inline u32 CalcAttackStat(struct DamageContext *ctx)
|
|||
}
|
||||
break;
|
||||
case ABILITY_QUARK_DRIVE:
|
||||
if (!(gBattleMons[battlerAtk].status2 & STATUS2_TRANSFORMED))
|
||||
if (!(gBattleMons[battlerAtk].volatiles.transformed))
|
||||
{
|
||||
u32 atkHighestStat = GetHighestStatId(battlerAtk);
|
||||
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gDisableStructs[battlerAtk].boosterEnergyActivated)
|
||||
|
|
@ -8919,7 +8921,7 @@ static inline u32 CalcDefenseStat(struct DamageContext *ctx)
|
|||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
|
||||
break;
|
||||
case HOLD_EFFECT_METAL_POWDER:
|
||||
if (gBattleMons[battlerDef].species == SPECIES_DITTO && usesDefStat && !(gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED))
|
||||
if (gBattleMons[battlerDef].species == SPECIES_DITTO && usesDefStat && !(gBattleMons[battlerDef].volatiles.transformed))
|
||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
|
||||
break;
|
||||
case HOLD_EFFECT_EVIOLITE:
|
||||
|
|
@ -9521,7 +9523,7 @@ static inline void MulByTypeEffectiveness(struct DamageContext *ctx, uq4_12_t *m
|
|||
if (ctx->updateFlags)
|
||||
RecordItemEffectBattle(ctx->battlerDef, HOLD_EFFECT_RING_TARGET);
|
||||
}
|
||||
else if ((ctx->moveType == TYPE_FIGHTING || ctx->moveType == TYPE_NORMAL) && defType == TYPE_GHOST && gBattleMons[ctx->battlerDef].status2 & STATUS2_FORESIGHT && mod == UQ_4_12(0.0))
|
||||
else if ((ctx->moveType == TYPE_FIGHTING || ctx->moveType == TYPE_NORMAL) && defType == TYPE_GHOST && gBattleMons[ctx->battlerDef].volatiles.foresight && mod == UQ_4_12(0.0))
|
||||
{
|
||||
mod = UQ_4_12(1.0);
|
||||
}
|
||||
|
|
@ -9964,7 +9966,7 @@ void ActivateUltraBurst(u32 battler)
|
|||
bool32 IsBattlerMegaEvolved(u32 battler)
|
||||
{
|
||||
// While Transform does copy stats and visuals, it shouldn't be counted as true Mega Evolution.
|
||||
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
if (gBattleMons[battler].volatiles.transformed)
|
||||
return FALSE;
|
||||
return (gSpeciesInfo[gBattleMons[battler].species].isMegaEvolution);
|
||||
}
|
||||
|
|
@ -9972,7 +9974,7 @@ bool32 IsBattlerMegaEvolved(u32 battler)
|
|||
bool32 IsBattlerPrimalReverted(u32 battler)
|
||||
{
|
||||
// While Transform does copy stats and visuals, it shouldn't be counted as true Primal Revesion.
|
||||
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
if (gBattleMons[battler].volatiles.transformed)
|
||||
return FALSE;
|
||||
return (gSpeciesInfo[gBattleMons[battler].species].isPrimalReversion);
|
||||
}
|
||||
|
|
@ -9980,7 +9982,7 @@ bool32 IsBattlerPrimalReverted(u32 battler)
|
|||
bool32 IsBattlerUltraBursted(u32 battler)
|
||||
{
|
||||
// While Transform does copy stats and visuals, it shouldn't be counted as true Ultra Burst.
|
||||
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
if (gBattleMons[battler].volatiles.transformed)
|
||||
return FALSE;
|
||||
return (gSpeciesInfo[gBattleMons[battler].species].isUltraBurst);
|
||||
}
|
||||
|
|
@ -9988,7 +9990,7 @@ bool32 IsBattlerUltraBursted(u32 battler)
|
|||
bool32 IsBattlerInTeraForm(u32 battler)
|
||||
{
|
||||
// While Transform does copy stats and visuals, it shouldn't be counted as a true Tera Form.
|
||||
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
if (gBattleMons[battler].volatiles.transformed)
|
||||
return FALSE;
|
||||
return (gSpeciesInfo[gBattleMons[battler].species].isTeraForm);
|
||||
}
|
||||
|
|
@ -10106,7 +10108,7 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, enum FormChanges method)
|
|||
bool32 CanBattlerFormChange(u32 battler, enum FormChanges method)
|
||||
{
|
||||
// Can't change form if transformed.
|
||||
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED
|
||||
if (gBattleMons[battler].volatiles.transformed
|
||||
&& B_TRANSFORM_FORM_CHANGES >= GEN_5)
|
||||
return FALSE;
|
||||
// Mega Evolved and Ultra Bursted Pokémon should always revert to normal upon fainting or ending the battle.
|
||||
|
|
@ -10856,7 +10858,7 @@ void RecalcBattlerStats(u32 battler, struct Pokemon *mon, bool32 isDynamaxing)
|
|||
|
||||
void RemoveConfusionStatus(u32 battler)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~STATUS2_CONFUSION;
|
||||
gBattleMons[battler].volatiles.confusionTurns = 0;
|
||||
gStatuses4[battler] &= ~STATUS4_INFINITE_CONFUSION;
|
||||
}
|
||||
|
||||
|
|
@ -11415,7 +11417,7 @@ bool32 TrySwitchInEjectPack(enum ItemCaseId caseID)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#define UNPACK_VOLATILE_GETTERS(_enum, _fieldName, _typeBitSize, ...) case _enum: return gBattleMons[battler].volatiles._fieldName;
|
||||
#define UNPACK_VOLATILE_GETTERS(_enum, _fieldName, _typeMaxValue, ...) case _enum: return gBattleMons[battler].volatiles._fieldName;
|
||||
|
||||
// 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
|
||||
|
|
@ -11433,7 +11435,7 @@ u32 GetMonVolatile(u32 battler, enum Volatile _volatile)
|
|||
}
|
||||
}
|
||||
|
||||
#define UNPACK_VOLATILE_SETTERS(_enum, _fieldName, _typeBitSize, ...) case _enum: gBattleMons[battler].volatiles._fieldName = min(GET_VOLATILE_MAXIMUM(_typeBitSize), newValue); break;
|
||||
#define UNPACK_VOLATILE_SETTERS(_enum, _fieldName, _typeMaxValue, ...) case _enum: gBattleMons[battler].volatiles._fieldName = min(GET_VOLATILE_MAXIMUM(_typeMaxValue), newValue); break;
|
||||
|
||||
// Sets 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
|
||||
|
|
@ -11452,6 +11454,30 @@ void SetMonVolatile(u32 battler, enum Volatile _volatile, u32 newValue)
|
|||
}
|
||||
}
|
||||
|
||||
bool32 ItemHealMonVolatile(u32 battler, u16 itemId)
|
||||
{
|
||||
bool32 statusChanged = FALSE;
|
||||
const u8 *effect = GetItemEffect(itemId);
|
||||
if (effect[3] & ITEM3_STATUS_ALL)
|
||||
{
|
||||
statusChanged = (gBattleMons[battler].volatiles.infatuation || gBattleMons[battler].volatiles.confusionTurns > 0);
|
||||
gBattleMons[battler].volatiles.infatuation = 0;
|
||||
gBattleMons[battler].volatiles.confusionTurns = 0;
|
||||
}
|
||||
else if (effect[0] & ITEM0_INFATUATION)
|
||||
{
|
||||
statusChanged = !!gBattleMons[battler].volatiles.infatuation;
|
||||
gBattleMons[battler].volatiles.infatuation = 0;
|
||||
}
|
||||
else if (effect[3] & ITEM3_CONFUSION)
|
||||
{
|
||||
statusChanged = gBattleMons[battler].volatiles.confusionTurns > 0;
|
||||
gBattleMons[battler].volatiles.confusionTurns = 0;
|
||||
}
|
||||
|
||||
return statusChanged;
|
||||
}
|
||||
|
||||
// Hazards are added to a queue and applied based in order (FIFO)
|
||||
void PushHazardTypeToQueue(u32 side, enum Hazards hazardType)
|
||||
{
|
||||
|
|
@ -11634,7 +11660,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
|
|||
if (defAbility == ABILITY_UNAWARE)
|
||||
accStage = DEFAULT_STAT_STAGE;
|
||||
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_FORESIGHT || gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED)
|
||||
if (gBattleMons[battlerDef].volatiles.foresight || gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED)
|
||||
buff = accStage;
|
||||
else
|
||||
buff = accStage + DEFAULT_STAT_STAGE - evasionStage;
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ u32 BattlePalace_TryEscapeStatus(u8 battler)
|
|||
{
|
||||
// Wake up from Uproar
|
||||
gBattleMons[battler].status1 &= ~(STATUS1_SLEEP);
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_NIGHTMARE);
|
||||
gBattleMons[battler].volatiles.nightmare = FALSE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP_UPROAR;
|
||||
BattleScriptCall(BattleScript_MoveUsedWokeUp);
|
||||
effect = 2;
|
||||
|
|
@ -162,7 +162,7 @@ u32 BattlePalace_TryEscapeStatus(u8 battler)
|
|||
else
|
||||
{
|
||||
// Wake up
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_NIGHTMARE);
|
||||
gBattleMons[battler].volatiles.nightmare = FALSE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP;
|
||||
BattleScriptCall(BattleScript_MoveUsedWokeUp);
|
||||
effect = 2;
|
||||
|
|
|
|||
|
|
@ -486,9 +486,9 @@ void SetZEffect(void)
|
|||
break;
|
||||
}
|
||||
case Z_EFFECT_BOOST_CRITS:
|
||||
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY_ANY))
|
||||
if (!(gBattleMons[gBattlerAttacker].volatiles.dragonCheer || gBattleMons[gBattlerAttacker].volatiles.focusEnergy))
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_FOCUS_ENERGY;
|
||||
gBattleMons[gBattlerAttacker].volatiles.focusEnergy = TRUE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_BOOST_CRITS;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH);
|
||||
gBattlescriptCurrInstr = BattleScript_ZEffectPrintString;
|
||||
|
|
|
|||
|
|
@ -3108,7 +3108,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
|||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.zMove = { .effect = Z_EFFECT_ACC_UP_1 },
|
||||
.argument = { .status = STATUS2_FOCUS_ENERGY },
|
||||
.argument = { .status = VOLATILE_FOCUS_ENERGY },
|
||||
.ignoresProtect = TRUE,
|
||||
.mirrorMoveBanned = TRUE,
|
||||
.snatchAffected = TRUE,
|
||||
|
|
|
|||
19
src/item.c
19
src/item.c
|
|
@ -958,17 +958,18 @@ u32 GetItemStatus1Mask(u16 itemId)
|
|||
return 0;
|
||||
}
|
||||
|
||||
u32 GetItemStatus2Mask(u16 itemId)
|
||||
bool32 ItemHasVolatileFlag(u16 itemId, enum Volatile _volatile)
|
||||
{
|
||||
const u8 *effect = GetItemEffect(itemId);
|
||||
if (effect[3] & ITEM3_STATUS_ALL)
|
||||
return STATUS2_INFATUATION | STATUS2_CONFUSION;
|
||||
else if (effect[0] & ITEM0_INFATUATION)
|
||||
return STATUS2_INFATUATION;
|
||||
else if (effect[3] & ITEM3_CONFUSION)
|
||||
return STATUS2_CONFUSION;
|
||||
else
|
||||
return 0;
|
||||
switch (_volatile)
|
||||
{
|
||||
case VOLATILE_CONFUSION:
|
||||
return (effect[3] & ITEM3_STATUS_ALL) || (effect[3] & ITEM3_CONFUSION);
|
||||
case VOLATILE_INFATUATION:
|
||||
return (effect[3] & ITEM3_STATUS_ALL) || (effect[0] & ITEM0_INFATUATION);
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
u32 GetItemSellPrice(u32 itemId)
|
||||
|
|
|
|||
|
|
@ -1191,12 +1191,25 @@ void ItemUseInBattle_PartyMenuChooseMove(u8 taskId)
|
|||
ItemUseInBattle_ShowPartyMenu(taskId);
|
||||
}
|
||||
|
||||
static bool32 SelectedMonHasStatus2(u16 itemId)
|
||||
static bool32 IteamHealsMonVolatile(u32 battler, u16 itemId)
|
||||
{
|
||||
const u8 *effect = GetItemEffect(itemId);
|
||||
if (effect[3] & ITEM3_STATUS_ALL)
|
||||
return (gBattleMons[battler].volatiles.infatuation || gBattleMons[battler].volatiles.confusionTurns > 0);
|
||||
else if (effect[0] & ITEM0_INFATUATION)
|
||||
return gBattleMons[battler].volatiles.infatuation;
|
||||
else if (effect[3] & ITEM3_CONFUSION)
|
||||
return gBattleMons[battler].volatiles.confusionTurns > 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 SelectedMonHasVolatile(u16 itemId)
|
||||
{
|
||||
if (gPartyMenu.slotId == 0)
|
||||
return gBattleMons[0].status2 & GetItemStatus2Mask(itemId);
|
||||
return IteamHealsMonVolatile(0, itemId);
|
||||
else if (gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI) && gPartyMenu.slotId == 1)
|
||||
return gBattleMons[2].status2 & GetItemStatus2Mask(itemId);
|
||||
return IteamHealsMonVolatile(2, itemId);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -1224,7 +1237,7 @@ bool32 CannotUseItemsInBattle(u16 itemId, struct Pokemon *mon)
|
|||
cannotUse = TRUE;
|
||||
break;
|
||||
case EFFECT_ITEM_SET_FOCUS_ENERGY:
|
||||
if (gBattleMons[gBattlerInMenuId].status2 & STATUS2_FOCUS_ENERGY_ANY)
|
||||
if (gBattleMons[gBattlerInMenuId].volatiles.dragonCheer || gBattleMons[gBattlerInMenuId].volatiles.focusEnergy)
|
||||
cannotUse = TRUE;
|
||||
break;
|
||||
case EFFECT_ITEM_SET_MIST:
|
||||
|
|
@ -1272,13 +1285,13 @@ bool32 CannotUseItemsInBattle(u16 itemId, struct Pokemon *mon)
|
|||
break;
|
||||
case EFFECT_ITEM_CURE_STATUS:
|
||||
if (!((GetMonData(mon, MON_DATA_STATUS) & GetItemStatus1Mask(itemId))
|
||||
|| SelectedMonHasStatus2(itemId)))
|
||||
|| SelectedMonHasVolatile(itemId)))
|
||||
cannotUse = TRUE;
|
||||
break;
|
||||
case EFFECT_ITEM_HEAL_AND_CURE_STATUS:
|
||||
if ((hp == 0 || hp == GetMonData(mon, MON_DATA_MAX_HP))
|
||||
&& !((GetMonData(mon, MON_DATA_STATUS) & GetItemStatus1Mask(itemId))
|
||||
|| SelectedMonHasStatus2(itemId)))
|
||||
|| SelectedMonHasVolatile(itemId)))
|
||||
cannotUse = TRUE;
|
||||
break;
|
||||
case EFFECT_ITEM_REVIVE:
|
||||
|
|
|
|||
|
|
@ -3693,7 +3693,7 @@ void PokemonToBattleMon(struct Pokemon *src, struct BattlePokemon *dst)
|
|||
for (i = 0; i < NUM_BATTLE_STATS; i++)
|
||||
dst->statStages[i] = DEFAULT_STAT_STAGE;
|
||||
|
||||
dst->status2 = 0;
|
||||
memset(&dst->volatiles, 0, sizeof(struct Volatiles));
|
||||
}
|
||||
|
||||
void CopyPartyMonToBattleData(u32 battler, u32 partyIndex)
|
||||
|
|
|
|||
|
|
@ -756,7 +756,7 @@ void RecordedBattle_CheckMovesetChanges(u8 mode)
|
|||
gDisableStructs[battler].mimickedMoves |= mimickedMoveSlots[j] << j;
|
||||
}
|
||||
|
||||
if (!(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
|
||||
if (!(gBattleMons[battler].volatiles.transformed))
|
||||
{
|
||||
struct Pokemon *mon = GetBattlerMon(battler);
|
||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ SINGLE_BATTLE_TEST("Shield Dust blocks secondary effects")
|
|||
MESSAGE("The opposing Vivillon was prevented from healing!");
|
||||
}
|
||||
} THEN { // Can't find good way to test trapping
|
||||
EXPECT(!(opponent->status2 & STATUS2_ESCAPE_PREVENTION));
|
||||
EXPECT(!opponent->volatiles.escapePrevention);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,8 +78,8 @@ SINGLE_BATTLE_TEST("Shield Dust does not block primary effects")
|
|||
}
|
||||
} THEN { // Can't find good way to test trapping
|
||||
if (move == MOVE_JAW_LOCK) {
|
||||
EXPECT(opponent->status2 & STATUS2_ESCAPE_PREVENTION);
|
||||
EXPECT(player->status2 & STATUS2_ESCAPE_PREVENTION);
|
||||
EXPECT(opponent->volatiles.escapePrevention);
|
||||
EXPECT(player->volatiles.escapePrevention);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1221,7 +1221,7 @@ DOUBLE_BATTLE_TEST("Dynamax: G-Max Terror traps both opponents")
|
|||
MESSAGE("The opposing Wobbuffet can no longer escape!");
|
||||
MESSAGE("The opposing Wobbuffet can no longer escape!");
|
||||
} THEN { // Can't find good way to test trapping
|
||||
EXPECT(opponentLeft->status2 & STATUS2_ESCAPE_PREVENTION);
|
||||
EXPECT(opponentLeft->volatiles.escapePrevention);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1238,7 +1238,7 @@ SINGLE_BATTLE_TEST("Dynamax: Baton Pass passes G-Max Terror's escape prevention
|
|||
ANIMATION(ANIM_TYPE_MOVE, MOVE_G_MAX_TERROR, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BATON_PASS, opponent);
|
||||
} THEN {
|
||||
EXPECT(opponent->status2 & STATUS2_ESCAPE_PREVENTION);
|
||||
EXPECT(opponent->volatiles.escapePrevention);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ SINGLE_BATTLE_TEST("Berserk Gene causes infinite confusion") // check if bit is
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Berserk Gene causes confusion timer to not tick down", u32 status2)
|
||||
SINGLE_BATTLE_TEST("Berserk Gene causes confusion timer to not tick down", u32 confusionTurns)
|
||||
{
|
||||
u32 turns;
|
||||
PARAMETRIZE { turns = 1; }
|
||||
|
|
@ -231,9 +231,9 @@ SINGLE_BATTLE_TEST("Berserk Gene causes confusion timer to not tick down", u32 s
|
|||
TURN {}
|
||||
}
|
||||
} THEN {
|
||||
results[i].status2 = player->status2;
|
||||
results[i].confusionTurns = player->volatiles.confusionTurns;
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].status2, results[1].status2);
|
||||
EXPECT_EQ(results[0].confusionTurns, results[1].confusionTurns);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ SINGLE_BATTLE_TEST("Covert Cloak blocks secondary effects")
|
|||
MESSAGE("The opposing Wobbuffet was prevented from healing!");
|
||||
}
|
||||
} THEN { // Can't find good way to test trapping
|
||||
EXPECT(!(opponent->status2 & STATUS2_ESCAPE_PREVENTION));
|
||||
EXPECT(!opponent->volatiles.escapePrevention);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -82,8 +82,8 @@ SINGLE_BATTLE_TEST("Covert Cloak does not block primary effects")
|
|||
}
|
||||
} THEN { // Can't find good way to test trapping
|
||||
if (move == MOVE_JAW_LOCK) {
|
||||
EXPECT(opponent->status2 & STATUS2_ESCAPE_PREVENTION);
|
||||
EXPECT(player->status2 & STATUS2_ESCAPE_PREVENTION);
|
||||
EXPECT(opponent->volatiles.escapePrevention);
|
||||
EXPECT(player->volatiles.escapePrevention);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -389,6 +389,6 @@ SINGLE_BATTLE_TEST("Full Heal, Heal Powder and Local Specialties heal a battler
|
|||
} SCENE {
|
||||
MESSAGE("Wobbuffet had its status healed!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->status2, STATUS1_NONE); // because we dont have STATUS2_NONE
|
||||
EXPECT(player->volatiles.confusionTurns == 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ SINGLE_BATTLE_TEST("Attract causes the target to become infatuated with the user
|
|||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ATTRACT, player);
|
||||
MESSAGE("The opposing Nidoking fell in love!");
|
||||
} THEN {
|
||||
EXPECT(opponent->status2 & STATUS2_INFATUATION);
|
||||
EXPECT(opponent->volatiles.infatuation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ SINGLE_BATTLE_TEST("Attract ignores type immunity")
|
|||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ATTRACT, player);
|
||||
MESSAGE("The opposing Misdreavus fell in love!");
|
||||
} THEN {
|
||||
EXPECT(opponent->status2 & STATUS2_INFATUATION);
|
||||
EXPECT(opponent->volatiles.infatuation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ SINGLE_BATTLE_TEST("Attract bypasses Substitute")
|
|||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ATTRACT, player);
|
||||
MESSAGE("The opposing Nidoking fell in love!");
|
||||
} THEN {
|
||||
EXPECT(opponent->status2 & STATUS2_INFATUATION);
|
||||
EXPECT(opponent->volatiles.infatuation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ SINGLE_BATTLE_TEST("Attract fails if the target is already infatuated")
|
|||
MESSAGE("Nidoqueen used Attract!");
|
||||
MESSAGE("But it failed!");
|
||||
} THEN {
|
||||
EXPECT(opponent->status2 & STATUS2_INFATUATION);
|
||||
EXPECT(opponent->volatiles.infatuation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ SINGLE_BATTLE_TEST("Attract fails when used on a Pokémon of the same gender")
|
|||
MESSAGE("Nidoqueen used Attract!");
|
||||
MESSAGE("But it failed!");
|
||||
} THEN {
|
||||
EXPECT(!(opponent->status2 & STATUS2_INFATUATION));
|
||||
EXPECT(!(opponent->volatiles.infatuation));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,6 +100,6 @@ SINGLE_BATTLE_TEST("Attract fails when used on a genderless Pokémon")
|
|||
MESSAGE("Nidoqueen used Attract!");
|
||||
MESSAGE("But it failed!");
|
||||
} THEN {
|
||||
EXPECT(!(opponent->status2 & STATUS2_INFATUATION));
|
||||
EXPECT(!(opponent->volatiles.infatuation));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ TO_DO_BATTLE_TEST("Baton Pass doesn't pass ability changes");
|
|||
//
|
||||
// Move these to the corresponding effect files.
|
||||
//
|
||||
TO_DO_BATTLE_TEST("Baton Pass passes confusion status"); // test/battle/status2/confusion.c
|
||||
TO_DO_BATTLE_TEST("Baton Pass passes confusion status"); // test/battle/volatiles/confusion.c
|
||||
|
||||
TO_DO_BATTLE_TEST("Baton Pass passes Fairy lock's escape prevention effect"); // test/battle/move_effect/fairy_lock.c
|
||||
TO_DO_BATTLE_TEST("Baton Pass passes Focus Energy's effect"); // test/battle/move_effect/focus_energy.c
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ SINGLE_BATTLE_TEST("Attract fails when used by a genderless Pokémon")
|
|||
MESSAGE("Starmie used Attract!");
|
||||
MESSAGE("But it failed!");
|
||||
} THEN {
|
||||
EXPECT(!(opponent->status2 & STATUS2_INFATUATION));
|
||||
EXPECT(!(opponent->volatiles.infatuation));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,6 +107,6 @@ SINGLE_BATTLE_TEST("Attract fails if both the user and the target are genderless
|
|||
MESSAGE("Starmie used Attract!");
|
||||
MESSAGE("But it failed!");
|
||||
} THEN {
|
||||
EXPECT(!(opponent->status2 & STATUS2_INFATUATION));
|
||||
EXPECT(!(opponent->volatiles.infatuation));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,6 @@ SINGLE_BATTLE_TEST("Petal Dance does not lock mons that copy the move with Dance
|
|||
ANIMATION(ANIM_TYPE_MOVE, MOVE_PETAL_DANCE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_PETAL_DANCE, opponent);
|
||||
// How do you actually test locking?
|
||||
EXPECT(!(opponent->status2 & STATUS2_MULTIPLETURNS));
|
||||
EXPECT(!(opponent->volatiles.multipleTurns));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ SINGLE_BATTLE_TEST("Jaw Lock traps both opponents")
|
|||
ANIMATION(ANIM_TYPE_MOVE, MOVE_JAW_LOCK, player);
|
||||
MESSAGE("Neither Pokémon can run away!");
|
||||
} THEN { // Can't find good way to test trapping
|
||||
EXPECT(opponent->status2 & STATUS2_ESCAPE_PREVENTION);
|
||||
EXPECT(player->status2 & STATUS2_ESCAPE_PREVENTION);
|
||||
EXPECT(opponent->volatiles.escapePrevention);
|
||||
EXPECT(player->volatiles.escapePrevention);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user