Centralizes non volatile status effect checks (#6533)
Co-authored-by: PhallenTree <168426989+PhallenTree@users.noreply.github.com>
This commit is contained in:
parent
2412666b01
commit
4ff2f3de42
@ -799,7 +799,8 @@
|
||||
2:
|
||||
.endm
|
||||
|
||||
.macro unused_0x8d
|
||||
.macro trynonvolatilestatus
|
||||
.byte 0x8d
|
||||
.endm
|
||||
|
||||
.macro initmultihitstring
|
||||
@ -1335,9 +1336,8 @@
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro unused ptr:req
|
||||
.macro setnonvolatilestatus
|
||||
.byte 0xfd
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro tryworryseed failInstr:req
|
||||
@ -2169,18 +2169,6 @@
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro trypoisontype attacker:req, target:req, failInstr:req
|
||||
various \attacker, VARIOUS_POISON_TYPE_IMMUNITY
|
||||
.byte \target
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro tryparalyzetype attacker:req, target:req, failInstr:req
|
||||
various \attacker, VARIOUS_PARALYZE_TYPE_IMMUNITY
|
||||
.byte \target
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro trysetfairylock failInstr:req
|
||||
various BS_ATTACKER, VARIOUS_TRY_FAIRY_LOCK
|
||||
.4byte \failInstr
|
||||
|
||||
@ -2863,34 +2863,9 @@ BattleScript_MoveMissed::
|
||||
|
||||
BattleScript_EffectDarkVoid::
|
||||
.if B_DARK_VOID_FAIL >= GEN_7
|
||||
jumpifspecies BS_ATTACKER, SPECIES_DARKRAI, BattleScript_EffectSleep
|
||||
jumpifspecies BS_ATTACKER, SPECIES_DARKRAI, BattleScript_EffectNonVolatileStatus
|
||||
goto BattleScript_PokemonCantUseTheMove
|
||||
.endif
|
||||
BattleScript_EffectSleep::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
jumpifsubstituteblocks BattleScript_ButItFailed
|
||||
jumpifstatus BS_TARGET, STATUS1_SLEEP, BattleScript_AlreadyAsleep
|
||||
jumpifuproarwakes BattleScript_CantMakeAsleep
|
||||
jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_InsomniaProtects
|
||||
jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_InsomniaProtects
|
||||
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifflowerveil BattleScript_FlowerVeilProtects
|
||||
jumpifability BS_TARGET_SIDE, ABILITY_SWEET_VEIL, BattleScript_SweetVeilProtects
|
||||
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
|
||||
jumpifsleepclause BattleScript_SleepClauseBlocked
|
||||
jumpifterrainaffected BS_TARGET, STATUS_FIELD_ELECTRIC_TERRAIN, BattleScript_ElectricTerrainPrevents
|
||||
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
|
||||
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
|
||||
jumpifsafeguard BattleScript_SafeguardProtected
|
||||
attackanimation
|
||||
waitanimation
|
||||
seteffectprimary MOVE_EFFECT_SLEEP
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_TerrainPreventsEnd2::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
@ -2919,7 +2894,7 @@ BattleScript_FlowerVeilProtectsRet::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_FlowerVeilProtects:
|
||||
BattleScript_FlowerVeilProtects::
|
||||
call BattleScript_FlowerVeilProtectsRet
|
||||
setmoveresultflags MOVE_RESULT_FAILED
|
||||
goto BattleScript_MoveEnd
|
||||
@ -2948,15 +2923,11 @@ BattleScript_AromaVeilProtects:
|
||||
setmoveresultflags MOVE_RESULT_FAILED
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_PastelVeilProtectsRet::
|
||||
BattleScript_PastelVeilProtects:
|
||||
pause B_WAIT_TIME_SHORT
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_PASTELVEILPROTECTED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_PastelVeilProtects:
|
||||
call BattleScript_PastelVeilProtectsRet
|
||||
setmoveresultflags MOVE_RESULT_FAILED
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
@ -2967,7 +2938,7 @@ BattleScript_AbilityProtectsDoesntAffectRet::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_AbilityProtectsDoesntAffect:
|
||||
BattleScript_AbilityProtectsDoesntAffect::
|
||||
call BattleScript_AbilityProtectsDoesntAffectRet
|
||||
setmoveresultflags MOVE_RESULT_FAILED
|
||||
goto BattleScript_MoveEnd
|
||||
@ -3315,31 +3286,6 @@ BattleScript_RestoreHp:
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectToxic::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected
|
||||
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifability BS_TARGET_SIDE, ABILITY_PASTEL_VEIL, BattleScript_PastelVeilProtects
|
||||
jumpifflowerveil BattleScript_FlowerVeilProtects
|
||||
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifsubstituteblocks BattleScript_ButItFailed
|
||||
jumpifstatus BS_TARGET, STATUS1_POISON | STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned
|
||||
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
|
||||
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
|
||||
trypoisontype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
|
||||
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
|
||||
jumpifsafeguard BattleScript_SafeguardProtected
|
||||
attackanimation
|
||||
waitanimation
|
||||
seteffectprimary MOVE_EFFECT_TOXIC
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_AlreadyPoisoned::
|
||||
setalreadystatusedmoveattempt BS_ATTACKER
|
||||
pause B_WAIT_TIME_LONG
|
||||
@ -3348,10 +3294,10 @@ BattleScript_AlreadyPoisoned::
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_ImmunityProtected::
|
||||
copybyte gEffectBattler, gBattlerTarget
|
||||
call BattleScript_AbilityPopUp
|
||||
setbyte cMULTISTRING_CHOOSER, B_MSG_ABILITY_PREVENTS_MOVE_STATUS
|
||||
call BattleScript_PSNPrevention
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printfromtable gStatusPreventionStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectAuroraVeil::
|
||||
@ -3571,78 +3517,18 @@ BattleScript_EffectAuroraVeilSuccess::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectPoison::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected
|
||||
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifability BS_TARGET_SIDE, ABILITY_PASTEL_VEIL, BattleScript_PastelVeilProtects
|
||||
jumpifflowerveil BattleScript_FlowerVeilProtects
|
||||
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifsubstituteblocks BattleScript_ButItFailed
|
||||
jumpifstatus BS_TARGET, STATUS1_POISON, BattleScript_AlreadyPoisoned
|
||||
jumpifstatus BS_TARGET, STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned
|
||||
trypoisontype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
|
||||
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
|
||||
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
|
||||
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
|
||||
jumpifsafeguard BattleScript_SafeguardProtected
|
||||
attackanimation
|
||||
waitanimation
|
||||
seteffectprimary MOVE_EFFECT_POISON
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectParalyze::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
jumpifability BS_TARGET, ABILITY_LIMBER, BattleScript_LimberProtected
|
||||
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifflowerveil BattleScript_FlowerVeilProtects
|
||||
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifsubstituteblocks BattleScript_ButItFailed
|
||||
typecalc
|
||||
jumpifmovehadnoeffect BattleScript_ButItFailed
|
||||
jumpifstatus BS_TARGET, STATUS1_PARALYSIS, BattleScript_AlreadyParalyzed
|
||||
jumpifelectricabilityaffected BS_TARGET, ABILITY_VOLT_ABSORB, BattleScript_VoltAbsorbHeal
|
||||
clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
|
||||
tryparalyzetype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
|
||||
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
|
||||
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
|
||||
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
|
||||
jumpifsafeguard BattleScript_SafeguardProtected
|
||||
attackanimation
|
||||
waitanimation
|
||||
seteffectprimary MOVE_EFFECT_PARALYSIS
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_VoltAbsorbHeal:
|
||||
copybyte gBattlerAbility, gBattlerTarget
|
||||
tryhealquarterhealth BS_TARGET BattleScript_MonMadeMoveUseless @ Check if max hp
|
||||
goto BattleScript_MoveHPDrain
|
||||
|
||||
BattleScript_AlreadyParalyzed:
|
||||
BattleScript_AlreadyParalyzed::
|
||||
setalreadystatusedmoveattempt BS_ATTACKER
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printstring STRINGID_PKMNISALREADYPARALYZED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_LimberProtected::
|
||||
copybyte gEffectBattler, gBattlerTarget
|
||||
setbyte cMULTISTRING_CHOOSER, B_MSG_ABILITY_PREVENTS_MOVE_STATUS
|
||||
call BattleScript_PRLZPrevention
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_PowerHerbActivation:
|
||||
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT
|
||||
printstring STRINGID_POWERHERB
|
||||
@ -4786,35 +4672,17 @@ BattleScript_FlatterTryConfuse::
|
||||
seteffectprimary MOVE_EFFECT_CONFUSION
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectWillOWisp::
|
||||
BattleScript_EffectNonVolatileStatus::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
jumpifsubstituteblocks BattleScript_ButItFailed
|
||||
jumpifstatus BS_TARGET, STATUS1_BURN, BattleScript_AlreadyBurned
|
||||
jumpiftype BS_TARGET, TYPE_FIRE, BattleScript_NotAffected
|
||||
jumpifability BS_TARGET, ABILITY_WATER_VEIL, BattleScript_WaterVeilPrevents
|
||||
jumpifability BS_TARGET, ABILITY_WATER_BUBBLE, BattleScript_WaterVeilPrevents
|
||||
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifability BS_TARGET, ABILITY_THERMAL_EXCHANGE, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifflowerveil BattleScript_FlowerVeilProtects
|
||||
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
|
||||
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
|
||||
trynonvolatilestatus
|
||||
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
|
||||
jumpifsafeguard BattleScript_SafeguardProtected
|
||||
attackanimation
|
||||
waitanimation
|
||||
seteffectprimary MOVE_EFFECT_BURN
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_WaterVeilPrevents::
|
||||
call BattleScript_AbilityPopUp
|
||||
copybyte gEffectBattler, gBattlerTarget
|
||||
setbyte cMULTISTRING_CHOOSER, B_MSG_ABILITY_PREVENTS_MOVE_STATUS
|
||||
call BattleScript_BRNPrevention
|
||||
setnonvolatilestatus
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_AlreadyBurned::
|
||||
@ -5068,18 +4936,8 @@ BattleScript_EffectYawn::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_PrintBattlerAbilityMadeIneffective
|
||||
jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_PrintBattlerAbilityMadeIneffective
|
||||
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_PrintBattlerAbilityMadeIneffective
|
||||
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifflowerveil BattleScript_FlowerVeilProtects
|
||||
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
|
||||
jumpifsleepclause BattleScript_SleepClauseBlocked
|
||||
jumpifsubstituteblocks BattleScript_ButItFailed
|
||||
jumpifsafeguard BattleScript_SafeguardProtected
|
||||
trynonvolatilestatus
|
||||
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
|
||||
jumpifuproarwakes BattleScript_ButItFailed
|
||||
setyawn BattleScript_ButItFailed
|
||||
attackanimation
|
||||
waitanimation
|
||||
@ -5087,8 +4945,7 @@ BattleScript_EffectYawnSuccess::
|
||||
printstring STRINGID_PKMNWASMADEDROWSY
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
BattleScript_PrintBattlerAbilityMadeIneffective::
|
||||
copybyte sBATTLER, gBattlerAbility
|
||||
|
||||
BattleScript_PrintAbilityMadeIneffective::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
call BattleScript_AbilityPopUp
|
||||
@ -7456,9 +7313,9 @@ BattleScript_AbilityRaisesDefenderStat::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_AbilityPopUpTarget:
|
||||
BattleScript_AbilityPopUpTarget::
|
||||
copybyte gBattlerAbility, gBattlerTarget
|
||||
BattleScript_AbilityPopUp:
|
||||
BattleScript_AbilityPopUp::
|
||||
.if B_ABILITY_POP_UP == TRUE
|
||||
showabilitypopup BS_ABILITY_BATTLER
|
||||
pause 40
|
||||
@ -8198,24 +8055,6 @@ BattleScript_ItemNoStatLoss::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_BRNPrevention::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printfromtable gBRNPreventionStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_PRLZPrevention::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printfromtable gPRLZPreventionStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_PSNPrevention::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printfromtable gPSNPreventionStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_ObliviousPreventsAttraction::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
call BattleScript_AbilityPopUp
|
||||
|
||||
@ -175,7 +175,6 @@ bool32 IsHazardClearingMove(u32 move);
|
||||
bool32 IsSubstituteEffect(enum BattleMoveEffects effect);
|
||||
|
||||
// status checks
|
||||
bool32 AI_CanGetFrostbite(u32 battler, u32 ability);
|
||||
bool32 AI_CanBeConfused(u32 battlerAtk, u32 battlerDef, u32 move, u32 ability);
|
||||
bool32 IsBattlerIncapacitated(u32 battler, u32 ability);
|
||||
bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
|
||||
@ -183,9 +182,9 @@ bool32 ShouldPoison(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
|
||||
bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
|
||||
bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
||||
bool32 ShouldBurn(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 ShouldFreezeOrFrostbite(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 ShouldParalyze(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 ShouldBurn(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
|
||||
bool32 ShouldFreezeOrFrostbite(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
|
||||
bool32 ShouldParalyze(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
|
||||
bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
||||
bool32 AI_CanGiveFrostbite(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
||||
bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
|
||||
@ -39,8 +39,6 @@ void HandleBattleWindow(u8 xStart, u8 yStart, u8 xEnd, u8 yEnd, u8 flags);
|
||||
bool8 UproarWakeUpCheck(u8 battlerId);
|
||||
bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 DoesDisguiseBlockMove(u32 battler, u32 move);
|
||||
bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget);
|
||||
bool32 CanParalyzeType(u8 battlerAttacker, u8 battlerTarget);
|
||||
bool32 CanUseLastResort(u8 battlerId);
|
||||
u32 IsFlowerVeilProtected(u32 battler);
|
||||
u32 IsLeafGuardProtected(u32 battler, u32 ability);
|
||||
@ -60,6 +58,7 @@ bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler);
|
||||
void SaveBattlerTarget(u32 battler);
|
||||
void SaveBattlerAttacker(u32 battler);
|
||||
bool32 CanBurnHitThaw(u16 move);
|
||||
void SetNonVolatileStatusCondition(u32 target, enum MoveEffects effect);
|
||||
|
||||
extern void (* const gBattleScriptingCommandsTable[])(void);
|
||||
extern const struct StatFractions gAccuracyStageRatios[];
|
||||
|
||||
@ -186,9 +186,6 @@ extern const u8 BattleScript_FlashFireBoost[];
|
||||
extern const u8 BattleScript_AbilityNoStatLoss[];
|
||||
extern const u8 BattleScript_ItemNoStatLoss[];
|
||||
extern const u8 BattleScript_ItemNoStatLossSpicyExtract[];
|
||||
extern const u8 BattleScript_BRNPrevention[];
|
||||
extern const u8 BattleScript_PRLZPrevention[];
|
||||
extern const u8 BattleScript_PSNPrevention[];
|
||||
extern const u8 BattleScript_ObliviousPreventsAttraction[];
|
||||
extern const u8 BattleScript_FlinchPrevention[];
|
||||
extern const u8 BattleScript_OwnTempoPrevents[];
|
||||
@ -519,6 +516,18 @@ extern const u8 BattleScript_TeraShellDistortingTypeMatchups[];
|
||||
extern const u8 BattleScript_TeraFormChange[];
|
||||
extern const u8 BattleScript_SleepClausePreventsEnd[];
|
||||
|
||||
extern const u8 BattleScript_AbilityProtectsDoesntAffect[];
|
||||
extern const u8 BattleScript_ImmunityProtected[];
|
||||
extern const u8 BattleScript_SafeguardProtected[];
|
||||
extern const u8 BattleScript_FlowerVeilProtects[];
|
||||
extern const u8 BattleScript_SleepClauseBlocked[];
|
||||
extern const u8 BattleScript_AlreadyAsleep[];
|
||||
extern const u8 BattleScript_CantMakeAsleep[];
|
||||
extern const u8 BattleScript_AlreadyPoisoned[];
|
||||
extern const u8 BattleScript_AlreadyParalyzed[];
|
||||
extern const u8 BattleScript_AlreadyBurned[];
|
||||
extern const u8 BattleScript_PrintAbilityMadeIneffective[];
|
||||
|
||||
// zmoves
|
||||
extern const u8 BattleScript_ZMoveActivateDamaging[];
|
||||
extern const u8 BattleScript_ZMoveActivateStatus[];
|
||||
@ -565,7 +574,6 @@ extern const u8 BattleScript_DynamaxEnds_Ret[];
|
||||
extern const u8 BattleScript_MoveBlockedByDynamax[];
|
||||
|
||||
// Battle move scripts
|
||||
extern const u8 BattleScript_EffectSleep[];
|
||||
extern const u8 BattleScript_EffectAbsorb[];
|
||||
extern const u8 BattleScript_EffectAbsorbLiquidOoze[];
|
||||
extern const u8 BattleScript_EffectExplosion[];
|
||||
@ -592,7 +600,6 @@ extern const u8 BattleScript_EffectRoar[];
|
||||
extern const u8 BattleScript_EffectHit[];
|
||||
extern const u8 BattleScript_EffectConversion[];
|
||||
extern const u8 BattleScript_EffectRestoreHp[];
|
||||
extern const u8 BattleScript_EffectToxic[];
|
||||
extern const u8 BattleScript_EffectLightScreen[];
|
||||
extern const u8 BattleScript_EffectRest[];
|
||||
extern const u8 BattleScript_EffectOHKO[];
|
||||
@ -617,8 +624,6 @@ extern const u8 BattleScript_EffectSpecialDefenseDown2[];
|
||||
extern const u8 BattleScript_EffectAccuracyDown2[];
|
||||
extern const u8 BattleScript_EffectEvasionDown2[];
|
||||
extern const u8 BattleScript_EffectReflect[];
|
||||
extern const u8 BattleScript_EffectPoison[];
|
||||
extern const u8 BattleScript_EffectParalyze[];
|
||||
extern const u8 BattleScript_EffectTwoTurnsAttack[];
|
||||
extern const u8 BattleScript_EffectSubstitute[];
|
||||
extern const u8 BattleScript_EffectRage[];
|
||||
@ -688,7 +693,7 @@ extern const u8 BattleScript_EffectWorrySeed[];
|
||||
extern const u8 BattleScript_EffectHail[];
|
||||
extern const u8 BattleScript_EffectTorment[];
|
||||
extern const u8 BattleScript_EffectFlatter[];
|
||||
extern const u8 BattleScript_EffectWillOWisp[];
|
||||
extern const u8 BattleScript_EffectNonVolatileStatus[];
|
||||
extern const u8 BattleScript_EffectMemento[];
|
||||
extern const u8 BattleScript_EffectFocusPunch[];
|
||||
extern const u8 BattleScript_EffectFollowMe[];
|
||||
@ -858,5 +863,7 @@ extern const u8 BattleScript_EffectFickleBeam[];
|
||||
extern const u8 BattleScript_FickleBeamDoubled[];
|
||||
extern const u8 BattleScript_QuestionForfeitBattle[];
|
||||
extern const u8 BattleScript_ForfeitBattleGaveMoney[];
|
||||
extern const u8 BattleScript_EffectNonVolatileStatus[];
|
||||
extern const u8 BattleScript_AbilityPopUp[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||
|
||||
@ -23,6 +23,12 @@
|
||||
#define MOVE_LIMITATION_PLACEHOLDER (1 << 15)
|
||||
#define MOVE_LIMITATIONS_ALL 0xFFFF
|
||||
|
||||
enum NonVolatileStatus
|
||||
{
|
||||
STATUS_CHECK_TRIGGER,
|
||||
STATUS_RUN_SCRIPT,
|
||||
};
|
||||
|
||||
enum AbilityEffectOptions
|
||||
{
|
||||
ABILITY_CHECK_TRIGGER,
|
||||
@ -331,12 +337,13 @@ bool32 MoveHasChargeTurnAdditionalEffect(u32 move);
|
||||
bool32 CanTargetPartner(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 TargetFullyImmuneToCurrMove(u32 battlerAtk, u32 battlerDef);
|
||||
|
||||
bool32 CanBeSlept(u32 battler, u32 ability, enum SleepClauseBlock isBlockedBySleepClause);
|
||||
bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 CanBeBurned(u32 battler, u32 ability);
|
||||
bool32 CanBeParalyzed(u32 battler, u32 ability);
|
||||
bool32 CanBeFrozen(u32 battler);
|
||||
bool32 CanGetFrostbite(u32 battler);
|
||||
bool32 CanBeSlept(u32 battlerAtk, u32 battlerDef, u32 abilityDef, enum SleepClauseBlock isBlockedBySleepClause);
|
||||
bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef);
|
||||
bool32 CanBeBurned(u32 battlerAtk, u32 battlerDef, u32 ability);
|
||||
bool32 CanBeParalyzed(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
|
||||
bool32 CanBeFrozen(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
|
||||
bool32 CanGetFrostbite(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
|
||||
bool32 CanSetNonVolatileStatus(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef, enum MoveEffects secondaryMoveEffect, enum NonVolatileStatus option);
|
||||
bool32 CanBeConfused(u32 battler);
|
||||
bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag);
|
||||
u32 GetBattlerAffectionHearts(u32 battler);
|
||||
|
||||
@ -206,7 +206,7 @@
|
||||
#define HITMARKER_NO_PPDEDUCT (1 << 11)
|
||||
#define HITMARKER_UNUSED_2 (1 << 12)
|
||||
#define HITMARKER_STATUS_ABILITY_EFFECT (1 << 13)
|
||||
#define HITMARKER_SYNCHRONISE_EFFECT (1 << 14)
|
||||
#define HITMARKER_SYNCHRONIZE_EFFECT (1 << 14)
|
||||
#define HITMARKER_RUN (1 << 15)
|
||||
#define HITMARKER_IGNORE_DISGUISE (1 << 16)
|
||||
#define HITMARKER_DISABLE_ANIMATION (1 << 17) // disable animations during battle scripts, e.g. for Bug Bite
|
||||
|
||||
@ -170,11 +170,9 @@ enum CmdVarious
|
||||
VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED,
|
||||
VARIOUS_TRY_FAIRY_LOCK,
|
||||
VARIOUS_JUMP_IF_NO_ALLY,
|
||||
VARIOUS_POISON_TYPE_IMMUNITY,
|
||||
VARIOUS_JUMP_IF_HOLD_EFFECT,
|
||||
VARIOUS_INFATUATE_WITH_BATTLER,
|
||||
VARIOUS_SET_LAST_USED_ITEM,
|
||||
VARIOUS_PARALYZE_TYPE_IMMUNITY,
|
||||
VARIOUS_JUMP_IF_ABSENT,
|
||||
VARIOUS_DESTROY_ABILITY_POPUP,
|
||||
VARIOUS_TOTEM_BOOST,
|
||||
|
||||
@ -1046,12 +1046,15 @@ enum GotStatusedStringID
|
||||
B_MSG_STATUSED_BY_ABILITY,
|
||||
};
|
||||
|
||||
// gBRNPreventionStringIds / gPRLZPreventionStringIds / gPSNPreventionStringIds
|
||||
// gStatusPreventionStringIds
|
||||
enum StatusPreventionStringID
|
||||
{
|
||||
B_MSG_ABILITY_PREVENTS_MOVE_STATUS,
|
||||
B_MSG_ABILITY_PREVENTS_MOVE_BURN,
|
||||
B_MSG_ABILITY_PREVENTS_MOVE_PARALYSIS,
|
||||
B_MSG_ABILITY_PREVENTS_MOVE_POISON,
|
||||
B_MSG_ABILITY_PREVENTS_ABILITY_STATUS,
|
||||
B_MSG_STATUS_HAD_NO_EFFECT,
|
||||
B_MSG_ABILITY_PASTEL_VEIL,
|
||||
};
|
||||
|
||||
// gGotDefrostedStringIds
|
||||
|
||||
@ -145,6 +145,7 @@ struct MoveInfo
|
||||
u32 fixedDamage;
|
||||
u32 absorbPercentage;
|
||||
u32 recoilPercentage;
|
||||
u32 nonVolatileStatus;
|
||||
} argument;
|
||||
|
||||
// primary/secondary effects
|
||||
@ -516,6 +517,11 @@ static inline u32 GetMoveRecoil(u32 moveId)
|
||||
return gMovesInfo[SanitizeMoveId(moveId)].argument.recoilPercentage;
|
||||
}
|
||||
|
||||
static inline u32 GetMoveNonVolatileStatus(u32 moveId)
|
||||
{
|
||||
return gMovesInfo[SanitizeMoveId(moveId)].argument.nonVolatileStatus;
|
||||
}
|
||||
|
||||
static inline const struct AdditionalEffect *GetMoveAdditionalEffectById(u32 moveId, u32 effect)
|
||||
{
|
||||
return &gMovesInfo[SanitizeMoveId(moveId)].additionalEffects[effect];
|
||||
|
||||
@ -1518,7 +1518,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case EFFECT_PARALYZE:
|
||||
if (!AI_CanParalyze(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
if (!ShouldParalyze(battlerAtk, battlerDef))
|
||||
if (!ShouldParalyze(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
ADJUST_SCORE(-5);
|
||||
break;
|
||||
case EFFECT_SUBSTITUTE:
|
||||
@ -1812,7 +1812,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case EFFECT_WILL_O_WISP:
|
||||
if (!AI_CanBurn(battlerAtk, battlerDef, aiData->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
if (!ShouldBurn(battlerAtk, battlerDef))
|
||||
if (!ShouldBurn(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
ADJUST_SCORE(-5);
|
||||
break;
|
||||
case EFFECT_MEMENTO:
|
||||
@ -1926,7 +1926,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_REST:
|
||||
if (!CanBeSlept(battlerAtk, aiData->abilities[battlerAtk], NOT_BLOCKED_BY_SLEEP_CLAUSE))
|
||||
if (!CanBeSlept(battlerAtk, battlerAtk, aiData->abilities[battlerAtk], NOT_BLOCKED_BY_SLEEP_CLAUSE))
|
||||
ADJUST_SCORE(-10);
|
||||
//fallthrough
|
||||
case EFFECT_RESTORE_HP:
|
||||
@ -2434,25 +2434,14 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
switch (effect)
|
||||
{
|
||||
case MOVE_EFFECT_BURN:
|
||||
if (!AI_CanBurn(battlerAtk, battlerDef, BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case MOVE_EFFECT_PARALYSIS:
|
||||
if (!AI_CanParalyze(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case MOVE_EFFECT_POISON:
|
||||
if (!AI_CanPoison(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case MOVE_EFFECT_TOXIC:
|
||||
if (!AI_CanPoison(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case MOVE_EFFECT_FREEZE:
|
||||
if (!CanBeFrozen(battlerDef, TRUE)
|
||||
|| MoveBlockedBySubstitute(move, battlerAtk, battlerDef))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
@ -3629,7 +3618,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
}
|
||||
break;
|
||||
case EFFECT_REST:
|
||||
if (!(CanBeSlept(battlerAtk, aiData->abilities[battlerAtk], NOT_BLOCKED_BY_SLEEP_CLAUSE)))
|
||||
if (!(CanBeSlept(battlerAtk, battlerAtk, aiData->abilities[battlerAtk], NOT_BLOCKED_BY_SLEEP_CLAUSE)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -4096,7 +4085,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case HOLD_EFFECT_FLAME_ORB:
|
||||
if (!ShouldBurn(battlerAtk, battlerAtk) && CanBeBurned(battlerAtk, aiData->abilities[battlerDef]))
|
||||
if (!ShouldBurn(battlerAtk, battlerAtk, aiData->abilities[battlerAtk]))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case HOLD_EFFECT_BLACK_SLUDGE:
|
||||
@ -4146,7 +4135,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case HOLD_EFFECT_FLAME_ORB:
|
||||
if (ShouldBurn(battlerAtk, battlerAtk))
|
||||
if (ShouldBurn(battlerAtk, battlerAtk, aiData->abilities[battlerAtk]))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case HOLD_EFFECT_BLACK_SLUDGE:
|
||||
@ -4802,7 +4791,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case HOLD_EFFECT_FLAME_ORB:
|
||||
if (ShouldBurn(battlerAtk, battlerAtk))
|
||||
if (ShouldBurn(battlerAtk, battlerAtk, aiData->abilities[battlerAtk]))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case HOLD_EFFECT_BLACK_SLUDGE:
|
||||
|
||||
@ -646,7 +646,7 @@ static bool32 ShouldSwitchIfBadlyStatused(u32 battler)
|
||||
{
|
||||
//Yawn
|
||||
if (gStatuses3[battler] & STATUS3_YAWN
|
||||
&& CanBeSlept(battler, monAbility, BLOCKED_BY_SLEEP_CLAUSE)
|
||||
&& CanBeSlept(battler, battler, monAbility, BLOCKED_BY_SLEEP_CLAUSE) // TODO: ask for help from pawwkie
|
||||
&& gBattleMons[battler].hp > gBattleMons[battler].maxHP / 3
|
||||
&& RandomPercentage(RNG_AI_SWITCH_YAWN, GetSwitchChance(SHOULD_SWITCH_YAWN)))
|
||||
{
|
||||
|
||||
@ -917,7 +917,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_FREEZE_OR_FROSTBITE:
|
||||
if (AI_CanGetFrostbite(battlerDef, abilityDef))
|
||||
if (CanBeFrozen(battlerAtk, battlerDef, abilityDef))
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_PARALYSIS:
|
||||
@ -3109,7 +3109,7 @@ bool32 IsBattlerIncapacitated(u32 battler, u32 ability)
|
||||
|
||||
bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove)
|
||||
{
|
||||
if (!CanBeSlept(battlerDef, defAbility, BLOCKED_BY_SLEEP_CLAUSE)
|
||||
if (!CanBeSlept(battlerAtk, battlerDef, defAbility, BLOCKED_BY_SLEEP_CLAUSE)
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) // shouldn't try to sleep mon that partner is trying to make sleep
|
||||
return FALSE;
|
||||
@ -3130,12 +3130,12 @@ static inline bool32 DoesBattlerBenefitFromAllVolatileStatus(u32 battler, u32 ab
|
||||
|
||||
bool32 ShouldPoison(u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
u32 defAbility = AI_DATA->abilities[battlerDef];
|
||||
u32 abilityDef = AI_DATA->abilities[battlerDef];
|
||||
// Battler can be poisoned and has move/ability that synergizes with being poisoned
|
||||
if (CanBePoisoned(battlerAtk, battlerDef, defAbility) && (
|
||||
DoesBattlerBenefitFromAllVolatileStatus(battlerDef, defAbility)
|
||||
|| defAbility == ABILITY_POISON_HEAL
|
||||
|| (defAbility == ABILITY_TOXIC_BOOST && HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_PHYSICAL))))
|
||||
if (CanBePoisoned(battlerAtk, battlerDef, AI_DATA->abilities[battlerAtk], abilityDef) && (
|
||||
DoesBattlerBenefitFromAllVolatileStatus(battlerDef, abilityDef)
|
||||
|| abilityDef == ABILITY_POISON_HEAL
|
||||
|| (abilityDef == ABILITY_TOXIC_BOOST && HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_PHYSICAL))))
|
||||
{
|
||||
if (battlerAtk == battlerDef) // Targeting self
|
||||
return TRUE;
|
||||
@ -3148,14 +3148,13 @@ bool32 ShouldPoison(u32 battlerAtk, u32 battlerDef)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 ShouldBurn(u32 battlerAtk, u32 battlerDef)
|
||||
bool32 ShouldBurn(u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
||||
{
|
||||
u32 defAbility = AI_DATA->abilities[battlerDef];
|
||||
// Battler can be burned and has move/ability that synergizes with being burned
|
||||
if (CanBeBurned(battlerDef, defAbility) && (
|
||||
DoesBattlerBenefitFromAllVolatileStatus(battlerDef, defAbility)
|
||||
|| defAbility == ABILITY_HEATPROOF
|
||||
|| (defAbility == ABILITY_FLARE_BOOST && HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_SPECIAL))))
|
||||
if (CanBeBurned(battlerAtk, battlerDef, abilityDef) && (
|
||||
DoesBattlerBenefitFromAllVolatileStatus(battlerDef, abilityDef)
|
||||
|| abilityDef == ABILITY_HEATPROOF
|
||||
|| (abilityDef == ABILITY_FLARE_BOOST && HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_SPECIAL))))
|
||||
{
|
||||
if (battlerAtk == battlerDef) // Targeting self
|
||||
return TRUE;
|
||||
@ -3169,11 +3168,11 @@ bool32 ShouldBurn(u32 battlerAtk, u32 battlerDef)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 ShouldFreezeOrFrostbite(u32 battlerAtk, u32 battlerDef)
|
||||
bool32 ShouldFreezeOrFrostbite(u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
||||
{
|
||||
if (!B_USE_FROSTBITE)
|
||||
{
|
||||
if (CanBeFrozen(battlerDef))
|
||||
if (CanBeFrozen(battlerAtk, battlerDef, abilityDef))
|
||||
{
|
||||
if (battlerAtk == battlerDef) // Targeting self
|
||||
return FALSE;
|
||||
@ -3184,17 +3183,16 @@ bool32 ShouldFreezeOrFrostbite(u32 battlerAtk, u32 battlerDef)
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 defAbility = AI_DATA->abilities[battlerDef];
|
||||
// Battler can be frostbitten and has move/ability that synergizes with being frostbitten
|
||||
if (CanBeFrozen(battlerDef) &&
|
||||
DoesBattlerBenefitFromAllVolatileStatus(battlerDef, defAbility))
|
||||
if (CanBeFrozen(battlerAtk, battlerDef, abilityDef) &&
|
||||
DoesBattlerBenefitFromAllVolatileStatus(battlerDef, abilityDef))
|
||||
{
|
||||
if (battlerAtk == battlerDef) // Targeting self
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (battlerAtk == battlerDef)
|
||||
return FALSE;
|
||||
else
|
||||
@ -3202,12 +3200,11 @@ bool32 ShouldFreezeOrFrostbite(u32 battlerAtk, u32 battlerDef)
|
||||
}
|
||||
}
|
||||
|
||||
bool32 ShouldParalyze(u32 battlerAtk, u32 battlerDef)
|
||||
bool32 ShouldParalyze(u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
||||
{
|
||||
u32 defAbility = AI_DATA->abilities[battlerDef];
|
||||
// Battler can be paralyzed and has move/ability that synergizes with being paralyzed
|
||||
if (CanBeParalyzed(battlerDef, defAbility) && (
|
||||
DoesBattlerBenefitFromAllVolatileStatus(battlerDef, defAbility)))
|
||||
if (CanBeParalyzed(battlerAtk, battlerDef, abilityDef) && (
|
||||
DoesBattlerBenefitFromAllVolatileStatus(battlerDef, abilityDef)))
|
||||
{
|
||||
if (battlerAtk == battlerDef) // Targeting self
|
||||
return TRUE;
|
||||
@ -3222,24 +3219,19 @@ bool32 ShouldParalyze(u32 battlerAtk, u32 battlerDef)
|
||||
|
||||
bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove)
|
||||
{
|
||||
if (!CanBePoisoned(battlerAtk, battlerDef, GetBattlerAbility(battlerDef))
|
||||
if (!CanBePoisoned(battlerAtk, battlerDef, AI_DATA->abilities[battlerAtk], defAbility)
|
||||
|| AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex] == UQ_4_12(0.0)
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove))
|
||||
return FALSE;
|
||||
else if (defAbility != ABILITY_CORROSION && IS_BATTLER_ANY_TYPE(battlerDef, TYPE_POISON, TYPE_STEEL))
|
||||
return FALSE;
|
||||
else if (IsValidDoubleBattle(battlerAtk) && AI_DATA->abilities[BATTLE_PARTNER(battlerDef)] == ABILITY_PASTEL_VEIL)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove)
|
||||
{
|
||||
if (!CanBeParalyzed(battlerDef, defAbility)
|
||||
if (!CanBeParalyzed(battlerAtk, battlerDef, defAbility)
|
||||
|| AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex] == UQ_4_12(0.0)
|
||||
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove))
|
||||
return FALSE;
|
||||
@ -3271,21 +3263,9 @@ bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battler
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 AI_CanGetFrostbite(u32 battler, u32 ability)
|
||||
{
|
||||
if (ability == ABILITY_MAGMA_ARMOR
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| IS_BATTLER_OF_TYPE(battler, TYPE_ICE)
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| IsAbilityStatusProtected(battler, ability)
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove)
|
||||
{
|
||||
if (!CanBeBurned(battlerDef, defAbility)
|
||||
if (!CanBeBurned(battlerAtk, battlerDef, defAbility)
|
||||
|| AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex] == UQ_4_12(0.0)
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|| PartnerMoveEffectIsStatusSameTarget(battlerAtkPartner, battlerDef, partnerMove))
|
||||
@ -3297,7 +3277,7 @@ bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtk
|
||||
|
||||
bool32 AI_CanGiveFrostbite(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove)
|
||||
{
|
||||
if (!AI_CanGetFrostbite(battlerDef, defAbility)
|
||||
if (!CanBeFrozen(battlerAtk, battlerDef, defAbility)
|
||||
|| AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex] == UQ_4_12(0.0)
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|| PartnerMoveEffectIsStatusSameTarget(battlerAtkPartner, battlerDef, partnerMove))
|
||||
|
||||
@ -362,9 +362,9 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
|
||||
[STRINGID_PKMNPREVENTSUSAGE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevents {B_ATK_NAME_WITH_PREFIX2} from using {B_CURRENT_MOVE}!"), //I don't see this in SV text
|
||||
[STRINGID_PKMNRESTOREDHPUSING] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} restored HP using its {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNCHANGEDTYPEWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} made it the {B_BUFF1} type!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNPREVENTSPARALYSISWITH] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevents paralysis!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNPREVENTSPARALYSISWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_LAST_ABILITY} prevents paralysis!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNPREVENTSROMANCEWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevents romance!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNPREVENTSPOISONINGWITH] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevents poisoning!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNPREVENTSPOISONINGWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_LAST_ABILITY} prevents poisoning!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNPREVENTSCONFUSIONWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevents confusion!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNRAISEDFIREPOWERWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} raised the power of Fire-type moves!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNANCHORSITSELFWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} anchors itself with {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
|
||||
@ -468,7 +468,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
|
||||
[STRINGID_ITEMALLOWSONLYYMOVE] = COMPOUND_STRING("{B_LAST_ITEM} only allows the use of {B_CURRENT_MOVE}!\p"),
|
||||
[STRINGID_PKMNHUNGONWITHX] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} hung on using its {B_LAST_ITEM}!"),
|
||||
[STRINGID_EMPTYSTRING3] = gText_EmptyString3,
|
||||
[STRINGID_PKMNSXPREVENTSBURNS] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_EFF_ABILITY} prevents burns!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNSXPREVENTSBURNS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_LAST_ABILITY} prevents burns!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNSXBLOCKSY] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} blocks {B_CURRENT_MOVE}!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNSXRESTOREDHPALITTLE2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} restored its HP a little!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNSXWHIPPEDUPSANDSTORM] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} whipped up a sandstorm!"), //not in gen 5+, ability popup
|
||||
@ -525,7 +525,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
|
||||
[STRINGID_PKMNOBTAINEDX2] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} obtained {B_BUFF2}."),
|
||||
[STRINGID_PKMNOBTAINEDXYOBTAINEDZ] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} obtained {B_BUFF1}.\p{B_DEF_NAME_WITH_PREFIX} obtained {B_BUFF2}."),
|
||||
[STRINGID_BUTNOEFFECT] = COMPOUND_STRING("But it had no effect!"),
|
||||
[STRINGID_PKMNSXHADNOEFFECTONY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} had no effect on {B_EFF_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNSXHADNOEFFECTONY] = COMPOUND_STRING("Target protected by {B_LAST_ABILITY}!"), //not in gen 5+, ability popup
|
||||
[STRINGID_TWOENEMIESDEFEATED] = sText_TwoInGameTrainersDefeated,
|
||||
[STRINGID_TRAINER2LOSETEXT] = COMPOUND_STRING("{B_TRAINER2_LOSE_TEXT}"),
|
||||
[STRINGID_PKMNINCAPABLEOFPOWER] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} appears incapable of using its power!"),
|
||||
@ -1333,25 +1333,14 @@ const u16 gBerryEffectStringIds[] =
|
||||
[B_MSG_NORMALIZED_STATUS] = STRINGID_PKMNSITEMNORMALIZEDSTATUS
|
||||
};
|
||||
|
||||
const u16 gBRNPreventionStringIds[] =
|
||||
const u16 gStatusPreventionStringIds[] =
|
||||
{
|
||||
[B_MSG_ABILITY_PREVENTS_MOVE_STATUS] = STRINGID_PKMNSXPREVENTSBURNS,
|
||||
[B_MSG_ABILITY_PREVENTS_MOVE_BURN] = STRINGID_PKMNSXPREVENTSBURNS,
|
||||
[B_MSG_ABILITY_PREVENTS_MOVE_PARALYSIS] = STRINGID_PKMNPREVENTSPARALYSISWITH,
|
||||
[B_MSG_ABILITY_PREVENTS_MOVE_POISON] = STRINGID_PKMNPREVENTSPOISONINGWITH,
|
||||
[B_MSG_ABILITY_PREVENTS_ABILITY_STATUS] = STRINGID_PKMNSXPREVENTSYSZ,
|
||||
[B_MSG_STATUS_HAD_NO_EFFECT] = STRINGID_PKMNSXHADNOEFFECTONY
|
||||
};
|
||||
|
||||
const u16 gPRLZPreventionStringIds[] =
|
||||
{
|
||||
[B_MSG_ABILITY_PREVENTS_MOVE_STATUS] = STRINGID_PKMNPREVENTSPARALYSISWITH,
|
||||
[B_MSG_ABILITY_PREVENTS_ABILITY_STATUS] = STRINGID_PKMNSXPREVENTSYSZ,
|
||||
[B_MSG_STATUS_HAD_NO_EFFECT] = STRINGID_PKMNSXHADNOEFFECTONY
|
||||
};
|
||||
|
||||
const u16 gPSNPreventionStringIds[] =
|
||||
{
|
||||
[B_MSG_ABILITY_PREVENTS_MOVE_STATUS] = STRINGID_PKMNPREVENTSPOISONINGWITH,
|
||||
[B_MSG_ABILITY_PREVENTS_ABILITY_STATUS] = STRINGID_PKMNSXPREVENTSYSZ,
|
||||
[B_MSG_STATUS_HAD_NO_EFFECT] = STRINGID_PKMNSXHADNOEFFECTONY
|
||||
[B_MSG_STATUS_HAD_NO_EFFECT] = STRINGID_PKMNSXHADNOEFFECTONY,
|
||||
[B_MSG_ABILITY_PASTEL_VEIL] = STRINGID_PASTELVEILPROTECTED
|
||||
};
|
||||
|
||||
const u16 gItemSwapStringIds[] =
|
||||
|
||||
@ -487,7 +487,7 @@ static void Cmd_statbuffchange(void);
|
||||
static void Cmd_normalisebuffs(void);
|
||||
static void Cmd_setbide(void);
|
||||
static void Cmd_twoturnmoveschargestringandanimation(void);
|
||||
static void Cmd_unused_0x8d(void);
|
||||
static void Cmd_trynonvolatilestatus(void);
|
||||
static void Cmd_initmultihitstring(void);
|
||||
static void Cmd_forcerandomswitch(void);
|
||||
static void Cmd_tryconversiontypechange(void);
|
||||
@ -599,7 +599,7 @@ static void Cmd_settelekinesis(void);
|
||||
static void Cmd_swapstatstages(void);
|
||||
static void Cmd_averagestats(void);
|
||||
static void Cmd_jumpifcaptivateaffected(void);
|
||||
static void Cmd_unused(void);
|
||||
static void Cmd_setnonvolatilestatus(void);
|
||||
static void Cmd_tryworryseed(void);
|
||||
static void Cmd_callnative(void);
|
||||
|
||||
@ -746,7 +746,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
|
||||
Cmd_normalisebuffs, //0x8A
|
||||
Cmd_setbide, //0x8B
|
||||
Cmd_twoturnmoveschargestringandanimation, //0x8C
|
||||
Cmd_unused_0x8d, //0x8D
|
||||
Cmd_trynonvolatilestatus, //0x8D
|
||||
Cmd_initmultihitstring, //0x8E
|
||||
Cmd_forcerandomswitch, //0x8F
|
||||
Cmd_tryconversiontypechange, //0x90
|
||||
@ -858,7 +858,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
|
||||
Cmd_swapstatstages, //0xFA
|
||||
Cmd_averagestats, //0xFB
|
||||
Cmd_jumpifcaptivateaffected, //0xFC
|
||||
Cmd_unused, //0xFD
|
||||
Cmd_setnonvolatilestatus, //0xFD
|
||||
Cmd_tryworryseed, //0xFE
|
||||
Cmd_callnative, //0xFF
|
||||
};
|
||||
@ -3190,6 +3190,64 @@ static inline bool32 TrySetLightScreen(u32 battler)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SetNonVolatileStatusCondition(u32 effectBattler, enum MoveEffects effect)
|
||||
{
|
||||
if (effect == MOVE_EFFECT_SLEEP
|
||||
|| effect == MOVE_EFFECT_FREEZE)
|
||||
{
|
||||
const u8 *cancelMultiTurnMovesResult = NULL;
|
||||
cancelMultiTurnMovesResult = CancelMultiTurnMoves(effectBattler, SKY_DROP_STATUS_FREEZE_SLEEP);
|
||||
if (cancelMultiTurnMovesResult)
|
||||
gBattlescriptCurrInstr = cancelMultiTurnMovesResult;
|
||||
}
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
|
||||
if (sStatusFlagsForMoveEffects[effect] == STATUS1_SLEEP)
|
||||
{
|
||||
if (B_SLEEP_TURNS >= GEN_5)
|
||||
gBattleMons[effectBattler].status1 |= STATUS1_SLEEP_TURN(1 + RandomUniform(RNG_SLEEP_TURNS, 1, 3));
|
||||
else
|
||||
gBattleMons[effectBattler].status1 |= STATUS1_SLEEP_TURN(1 + RandomUniform(RNG_SLEEP_TURNS, 2, 5));
|
||||
|
||||
TryActivateSleepClause(effectBattler, gBattlerPartyIndexes[effectBattler]);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[effectBattler].status1 |= sStatusFlagsForMoveEffects[effect];
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[effect];
|
||||
|
||||
BtlController_EmitSetMonData(effectBattler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[effectBattler].status1), &gBattleMons[effectBattler].status1);
|
||||
MarkBattlerForControllerExec(effectBattler);
|
||||
|
||||
if (gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUSED_BY_ABILITY;
|
||||
gHitMarker &= ~HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUSED;
|
||||
}
|
||||
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_NONE;
|
||||
|
||||
// for synchronize
|
||||
if (effect == MOVE_EFFECT_POISON
|
||||
|| effect == MOVE_EFFECT_TOXIC
|
||||
|| effect == MOVE_EFFECT_PARALYSIS
|
||||
|| effect == MOVE_EFFECT_BURN)
|
||||
{
|
||||
gBattleStruct->synchronizeMoveEffect = effect;
|
||||
gHitMarker |= HITMARKER_SYNCHRONIZE_EFFECT;
|
||||
}
|
||||
|
||||
if (effect == MOVE_EFFECT_POISON || effect == MOVE_EFFECT_TOXIC)
|
||||
gBattleStruct->poisonPuppeteerConfusion = TRUE;
|
||||
}
|
||||
|
||||
#define INCREMENT_RESET_RETURN \
|
||||
{ \
|
||||
gBattlescriptCurrInstr++; \
|
||||
@ -3197,12 +3255,6 @@ static inline bool32 TrySetLightScreen(u32 battler)
|
||||
return; \
|
||||
}
|
||||
|
||||
#define RESET_RETURN \
|
||||
{ \
|
||||
gBattleScripting.moveEffect = 0; \
|
||||
return; \
|
||||
}
|
||||
|
||||
void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
{
|
||||
s32 i, affectsUser = 0;
|
||||
@ -3210,7 +3262,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
bool32 mirrorArmorReflected = (GetBattlerAbility(gBattlerTarget) == ABILITY_MIRROR_ARMOR);
|
||||
u32 flags = 0;
|
||||
u32 battlerAbility;
|
||||
bool8 activateAfterFaint = FALSE;
|
||||
bool32 activateAfterFaint = FALSE;
|
||||
|
||||
// NULL move effect
|
||||
if (gBattleScripting.moveEffect == 0)
|
||||
@ -3284,287 +3336,24 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
|
||||
if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT) // status change
|
||||
{
|
||||
const u8 *cancelMultiTurnMovesResult = NULL;
|
||||
switch (sStatusFlagsForMoveEffects[gBattleScripting.moveEffect])
|
||||
if (!(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)) // Calcs already done
|
||||
{
|
||||
case STATUS1_SLEEP:
|
||||
// check active uproar
|
||||
if (battlerAbility != ABILITY_SOUNDPROOF || B_UPROAR_IGNORE_SOUNDPROOF >= GEN_5)
|
||||
{
|
||||
for (i = 0; i < gBattlersCount && !(gBattleMons[i].status2 & STATUS2_UPROAR); i++)
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = gBattlersCount;
|
||||
}
|
||||
|
||||
if (i != gBattlersCount)
|
||||
break;
|
||||
if (!CanBeSlept(gEffectBattler, GetBattlerAbility(gEffectBattler), BLOCKED_BY_SLEEP_CLAUSE) && !gBattleStruct->battlerState[gEffectBattler].sleepClauseEffectExempt)
|
||||
break;
|
||||
|
||||
cancelMultiTurnMovesResult = CancelMultiTurnMoves(gEffectBattler, SKY_DROP_STATUS_FREEZE_SLEEP);
|
||||
if (cancelMultiTurnMovesResult)
|
||||
gBattlescriptCurrInstr = cancelMultiTurnMovesResult;
|
||||
statusChanged = TRUE;
|
||||
break;
|
||||
case STATUS1_POISON:
|
||||
if ((battlerAbility == ABILITY_IMMUNITY || battlerAbility == ABILITY_PASTEL_VEIL)
|
||||
&& (primary == TRUE || certain == TRUE))
|
||||
{
|
||||
gLastUsedAbility = battlerAbility;
|
||||
RecordAbilityBattle(gEffectBattler, battlerAbility);
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_PSNPrevention;
|
||||
|
||||
if (gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PREVENTS_ABILITY_STATUS;
|
||||
gHitMarker &= ~HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PREVENTS_MOVE_STATUS;
|
||||
}
|
||||
RESET_RETURN
|
||||
}
|
||||
if (!CanPoisonType(gBattleScripting.battler, gEffectBattler)
|
||||
&& (gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
&& (primary == TRUE || certain == TRUE))
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_PSNPrevention;
|
||||
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUS_HAD_NO_EFFECT;
|
||||
RESET_RETURN
|
||||
}
|
||||
if (!CanBePoisoned(gBattleScripting.battler, gEffectBattler, GetBattlerAbility(gEffectBattler)))
|
||||
break;
|
||||
|
||||
statusChanged = TRUE;
|
||||
break;
|
||||
case STATUS1_BURN:
|
||||
if ((battlerAbility == ABILITY_WATER_VEIL || battlerAbility == ABILITY_WATER_BUBBLE)
|
||||
&& (primary == TRUE || certain == TRUE))
|
||||
{
|
||||
gLastUsedAbility = battlerAbility;
|
||||
RecordAbilityBattle(gEffectBattler, battlerAbility);
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_BRNPrevention;
|
||||
if (gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PREVENTS_ABILITY_STATUS;
|
||||
gHitMarker &= ~HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PREVENTS_MOVE_STATUS;
|
||||
}
|
||||
RESET_RETURN
|
||||
}
|
||||
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_FIRE)
|
||||
&& (gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
&& (primary == TRUE || certain == TRUE))
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_BRNPrevention;
|
||||
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUS_HAD_NO_EFFECT;
|
||||
RESET_RETURN
|
||||
}
|
||||
|
||||
if (B_STATUS_TYPE_IMMUNITY == GEN_1)
|
||||
{
|
||||
u32 moveType = GetBattleMoveType(gCurrentMove);
|
||||
if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CanBeBurned(gEffectBattler, GetBattlerAbility(gEffectBattler)))
|
||||
break;
|
||||
|
||||
statusChanged = TRUE;
|
||||
break;
|
||||
case STATUS1_FREEZE:
|
||||
if (B_STATUS_TYPE_IMMUNITY == GEN_1)
|
||||
{
|
||||
u32 moveType = GetBattleMoveType(gCurrentMove);
|
||||
if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType))
|
||||
break;
|
||||
}
|
||||
if (!CanBeFrozen(gEffectBattler))
|
||||
break;
|
||||
|
||||
cancelMultiTurnMovesResult = CancelMultiTurnMoves(gEffectBattler, SKY_DROP_STATUS_FREEZE_SLEEP);
|
||||
if (cancelMultiTurnMovesResult)
|
||||
gBattlescriptCurrInstr = cancelMultiTurnMovesResult;
|
||||
statusChanged = TRUE;
|
||||
break;
|
||||
case STATUS1_PARALYSIS:
|
||||
if (battlerAbility == ABILITY_LIMBER)
|
||||
{
|
||||
if (primary == TRUE || certain == TRUE)
|
||||
{
|
||||
gLastUsedAbility = ABILITY_LIMBER;
|
||||
RecordAbilityBattle(gEffectBattler, ABILITY_LIMBER);
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_PRLZPrevention;
|
||||
|
||||
if (gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PREVENTS_ABILITY_STATUS;
|
||||
gHitMarker &= ~HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PREVENTS_MOVE_STATUS;
|
||||
}
|
||||
RESET_RETURN
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (B_STATUS_TYPE_IMMUNITY == GEN_1)
|
||||
{
|
||||
u32 moveType = GetBattleMoveType(gCurrentMove);
|
||||
if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType))
|
||||
break;
|
||||
}
|
||||
if (!CanParalyzeType(gBattleScripting.battler, gEffectBattler)
|
||||
&& (gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
&& (primary == TRUE || certain == TRUE))
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_PRLZPrevention;
|
||||
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
||||
RESET_RETURN
|
||||
}
|
||||
if (!CanParalyzeType(gBattleScripting.battler, gEffectBattler))
|
||||
break;
|
||||
if (!CanBeParalyzed(gEffectBattler, GetBattlerAbility(gEffectBattler)))
|
||||
break;
|
||||
|
||||
statusChanged = TRUE;
|
||||
break;
|
||||
case STATUS1_TOXIC_POISON:
|
||||
if ((battlerAbility == ABILITY_IMMUNITY || battlerAbility == ABILITY_PASTEL_VEIL)
|
||||
&& (primary == TRUE || certain == TRUE))
|
||||
{
|
||||
gLastUsedAbility = battlerAbility;
|
||||
RecordAbilityBattle(gEffectBattler, battlerAbility);
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_PSNPrevention;
|
||||
|
||||
if (gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PREVENTS_ABILITY_STATUS;
|
||||
gHitMarker &= ~HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PREVENTS_MOVE_STATUS;
|
||||
}
|
||||
RESET_RETURN
|
||||
}
|
||||
if (!CanPoisonType(gBattleScripting.battler, gEffectBattler)
|
||||
&& (gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
&& (primary == TRUE || certain == TRUE))
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_PSNPrevention;
|
||||
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUS_HAD_NO_EFFECT;
|
||||
RESET_RETURN
|
||||
}
|
||||
if (gBattleMons[gEffectBattler].status1)
|
||||
break;
|
||||
if (CanBePoisoned(gBattleScripting.battler, gEffectBattler, GetBattlerAbility(gEffectBattler)))
|
||||
{
|
||||
// It's redundant, because at this point we know the status1 value is 0.
|
||||
gBattleMons[gEffectBattler].status1 &= ~STATUS1_TOXIC_POISON;
|
||||
gBattleMons[gEffectBattler].status1 &= ~STATUS1_POISON;
|
||||
statusChanged = TRUE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_DOESNT_AFFECT_FOE;
|
||||
}
|
||||
break;
|
||||
case STATUS1_FROSTBITE:
|
||||
if (B_STATUS_TYPE_IMMUNITY == GEN_1)
|
||||
{
|
||||
u32 moveType = GetBattleMoveType(gCurrentMove);
|
||||
if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType))
|
||||
break;
|
||||
}
|
||||
if (!CanGetFrostbite(gEffectBattler))
|
||||
break;
|
||||
|
||||
statusChanged = TRUE;
|
||||
break;
|
||||
statusChanged = CanSetNonVolatileStatus(gBattlerAttacker,
|
||||
gEffectBattler,
|
||||
GetBattlerAbility(gBattlerAttacker),
|
||||
battlerAbility,
|
||||
gBattleScripting.moveEffect,
|
||||
STATUS_CHECK_TRIGGER);
|
||||
}
|
||||
if (statusChanged == TRUE)
|
||||
|
||||
if (statusChanged || gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
|
||||
if (sStatusFlagsForMoveEffects[gBattleScripting.moveEffect] == STATUS1_SLEEP)
|
||||
{
|
||||
if (B_SLEEP_TURNS >= GEN_5)
|
||||
gBattleMons[gEffectBattler].status1 |= STATUS1_SLEEP_TURN(1 + RandomUniform(RNG_SLEEP_TURNS, 1, 3));
|
||||
else
|
||||
gBattleMons[gEffectBattler].status1 |= STATUS1_SLEEP_TURN(1 + RandomUniform(RNG_SLEEP_TURNS, 2, 5));
|
||||
|
||||
TryActivateSleepClause(gEffectBattler, gBattlerPartyIndexes[gEffectBattler]);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gEffectBattler].status1 |= sStatusFlagsForMoveEffects[gBattleScripting.moveEffect];
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect];
|
||||
|
||||
BtlController_EmitSetMonData(gEffectBattler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gEffectBattler].status1), &gBattleMons[gEffectBattler].status1);
|
||||
MarkBattlerForControllerExec(gEffectBattler);
|
||||
|
||||
if (gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUSED_BY_ABILITY;
|
||||
gHitMarker &= ~HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUSED;
|
||||
}
|
||||
|
||||
// for synchronize
|
||||
if (gBattleScripting.moveEffect == MOVE_EFFECT_POISON
|
||||
|| gBattleScripting.moveEffect == MOVE_EFFECT_TOXIC
|
||||
|| gBattleScripting.moveEffect == MOVE_EFFECT_PARALYSIS
|
||||
|| gBattleScripting.moveEffect == MOVE_EFFECT_BURN)
|
||||
{
|
||||
gBattleStruct->synchronizeMoveEffect = gBattleScripting.moveEffect;
|
||||
gHitMarker |= HITMARKER_SYNCHRONISE_EFFECT;
|
||||
}
|
||||
|
||||
if (gBattleScripting.moveEffect == MOVE_EFFECT_POISON || gBattleScripting.moveEffect == MOVE_EFFECT_TOXIC)
|
||||
gBattleStruct->poisonPuppeteerConfusion = TRUE;
|
||||
|
||||
return;
|
||||
SetNonVolatileStatusCondition(gEffectBattler, gBattleScripting.moveEffect);
|
||||
}
|
||||
else if (statusChanged == FALSE)
|
||||
else
|
||||
{
|
||||
gBattleScripting.moveEffect = 0;
|
||||
gBattlescriptCurrInstr++;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -4574,7 +4363,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
case MOVE_EFFECT_YAWN_FOE:
|
||||
{
|
||||
if (!(gStatuses3[gBattlerTarget] & STATUS3_YAWN)
|
||||
&& CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget), BLOCKED_BY_SLEEP_CLAUSE)
|
||||
&& CanBeSlept(gBattlerTarget, gBattlerTarget, GetBattlerAbility(gBattlerTarget), BLOCKED_BY_SLEEP_CLAUSE)
|
||||
&& RandomPercentage(RNG_G_MAX_SNOOZE, 50))
|
||||
{
|
||||
gStatuses3[gBattlerTarget] |= STATUS3_YAWN_TURN(2);
|
||||
@ -5560,7 +5349,7 @@ static void MoveValuesCleanUp(void)
|
||||
gBattleCommunication[MISS_TYPE] = 0;
|
||||
if (!gMultiHitCounter)
|
||||
gHitMarker &= ~HITMARKER_DESTINYBOND;
|
||||
gHitMarker &= ~HITMARKER_SYNCHRONISE_EFFECT;
|
||||
gHitMarker &= ~HITMARKER_SYNCHRONIZE_EFFECT;
|
||||
}
|
||||
|
||||
static void Cmd_movevaluescleanup(void)
|
||||
@ -6606,7 +6395,7 @@ static void Cmd_moveend(void)
|
||||
|
||||
// Not strictly a protect effect, but works the same way
|
||||
if (gProtectStructs[gBattlerTarget].beakBlastCharge
|
||||
&& CanBeBurned(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
|
||||
&& CanBeBurned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker))
|
||||
&& !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT))
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE;
|
||||
@ -8455,8 +8244,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
|
||||
}
|
||||
else if (IsBattlerAffectedByHazards(battler, TRUE))
|
||||
{
|
||||
i = GetBattlerAbility(battler);
|
||||
if (CanBePoisoned(gBattlerAttacker, battler, i))
|
||||
if (CanBePoisoned(gBattlerAttacker, battler, GetBattlerAbility(gBattlerAttacker), GetBattlerAbility(battler)))
|
||||
{
|
||||
if (gSideTimers[GetBattlerSide(battler)].toxicSpikesAmount >= 2)
|
||||
gBattleMons[battler].status1 |= STATUS1_TOXIC_POISON;
|
||||
@ -9808,17 +9596,6 @@ static bool32 HasAttackerFaintedTarget(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget)
|
||||
{
|
||||
return GetBattlerAbility(battlerAttacker) == ABILITY_CORROSION
|
||||
|| !IS_BATTLER_ANY_TYPE(battlerTarget, TYPE_POISON, TYPE_STEEL);
|
||||
}
|
||||
|
||||
bool32 CanParalyzeType(u8 battlerAttacker, u8 battlerTarget)
|
||||
{
|
||||
return !(B_PARALYZE_ELECTRIC >= GEN_6 && IS_BATTLER_OF_TYPE(battlerTarget, TYPE_ELECTRIC));
|
||||
}
|
||||
|
||||
bool32 CanUseLastResort(u8 battler)
|
||||
{
|
||||
u32 i;
|
||||
@ -10396,24 +10173,6 @@ static void Cmd_various(void)
|
||||
gBattleStruct->friskedAbility = FALSE;
|
||||
break;
|
||||
}
|
||||
case VARIOUS_POISON_TYPE_IMMUNITY:
|
||||
{
|
||||
VARIOUS_ARGS(u8 target, const u8 *failInstr);
|
||||
if (!CanPoisonType(battler, GetBattlerForBattleScript(cmd->target)))
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
return;
|
||||
}
|
||||
case VARIOUS_PARALYZE_TYPE_IMMUNITY:
|
||||
{
|
||||
VARIOUS_ARGS(u8 target, const u8 *failInstr);
|
||||
if (!CanParalyzeType(battler, GetBattlerForBattleScript(cmd->target)))
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
return;
|
||||
}
|
||||
case VARIOUS_TRACE_ABILITY:
|
||||
{
|
||||
VARIOUS_ARGS();
|
||||
@ -11182,17 +10941,17 @@ static void Cmd_various(void)
|
||||
VARIOUS_ARGS(const u8 *failInstr, const u8 *sleepClauseFailInstr);
|
||||
u32 targetAbility = GetBattlerAbility(gBattlerTarget);
|
||||
// Psycho shift works
|
||||
if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, targetAbility))
|
||||
if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), targetAbility))
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_TOXIC_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, targetAbility))
|
||||
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_TOXIC_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), targetAbility))
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||||
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_BURN) && CanBeBurned(gBattlerTarget, targetAbility))
|
||||
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_BURN) && CanBeBurned(gBattlerAttacker, gBattlerTarget, targetAbility))
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
||||
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && CanBeParalyzed(gBattlerTarget, targetAbility))
|
||||
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && CanBeParalyzed(gBattlerAttacker, gBattlerTarget, targetAbility))
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
|
||||
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) && CanBeSlept(gBattlerTarget, targetAbility, BLOCKED_BY_SLEEP_CLAUSE))
|
||||
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) && CanBeSlept(gBattlerAttacker, gBattlerTarget, targetAbility, BLOCKED_BY_SLEEP_CLAUSE))
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
|
||||
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE) && CanGetFrostbite(gBattlerTarget))
|
||||
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE) && CanBeFrozen(gBattlerAttacker, gBattlerTarget, targetAbility))
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
|
||||
else if (IsSleepClauseActiveForSide(GetBattlerSide(battler)))
|
||||
{
|
||||
@ -12818,8 +12577,27 @@ static void Cmd_twoturnmoveschargestringandanimation(void)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
static void Cmd_unused_0x8d(void)
|
||||
static void Cmd_trynonvolatilestatus(void)
|
||||
{
|
||||
CMD_ARGS();
|
||||
bool32 canInflictStatus = TRUE;
|
||||
|
||||
if (!CanSetNonVolatileStatus(gBattlerAttacker,
|
||||
gBattlerTarget,
|
||||
GetBattlerAbility(gBattlerAttacker),
|
||||
GetBattlerAbility(gBattlerTarget),
|
||||
GetMoveNonVolatileStatus(gCurrentMove),
|
||||
STATUS_RUN_SCRIPT))
|
||||
canInflictStatus = FALSE;
|
||||
|
||||
if (canInflictStatus && DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))
|
||||
{
|
||||
canInflictStatus = FALSE;
|
||||
gBattlescriptCurrInstr = BattleScript_ButItFailed;
|
||||
}
|
||||
|
||||
if (canInflictStatus)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
static void Cmd_initmultihitstring(void)
|
||||
@ -16747,8 +16525,11 @@ static void Cmd_jumpifcaptivateaffected(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void Cmd_unused(void)
|
||||
static void Cmd_setnonvolatilestatus(void)
|
||||
{
|
||||
CMD_ARGS();
|
||||
gEffectBattler = gBattlerTarget;
|
||||
SetNonVolatileStatusCondition(gBattlerTarget, GetMoveNonVolatileStatus(gCurrentMove));
|
||||
}
|
||||
|
||||
static void Cmd_tryworryseed(void)
|
||||
@ -18622,7 +18403,7 @@ void BS_SwapStats(void)
|
||||
|
||||
static void TrySetParalysis(const u8 *nextInstr, const u8 *failInstr)
|
||||
{
|
||||
if (CanBeParalyzed(gBattlerTarget, GetBattlerAbility(gBattlerTarget)))
|
||||
if (CanBeParalyzed(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget)))
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status1 |= STATUS1_PARALYSIS;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
|
||||
@ -18639,7 +18420,7 @@ static void TrySetParalysis(const u8 *nextInstr, const u8 *failInstr)
|
||||
|
||||
static void TrySetPoison(const u8 *nextInstr, const u8 *failInstr)
|
||||
{
|
||||
if (CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget)))
|
||||
if (CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerAbility(gBattlerTarget)))
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status1 |= STATUS1_POISON;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
@ -18656,7 +18437,7 @@ static void TrySetPoison(const u8 *nextInstr, const u8 *failInstr)
|
||||
|
||||
static void TrySetSleep(const u8 *nextInstr, const u8 *failInstr)
|
||||
{
|
||||
if (CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget), BLOCKED_BY_SLEEP_CLAUSE))
|
||||
if (CanBeSlept(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget), BLOCKED_BY_SLEEP_CLAUSE))
|
||||
{
|
||||
if (B_SLEEP_TURNS >= GEN_5)
|
||||
gBattleMons[gBattlerTarget].status1 |= STATUS1_SLEEP_TURN((Random() % 3) + 2);
|
||||
|
||||
@ -66,6 +66,8 @@ static void SetRandomMultiHitCounter();
|
||||
static u32 GetBattlerItemHoldEffectParam(u32 battler, u32 item);
|
||||
static bool32 CanBeInfinitelyConfused(u32 battler);
|
||||
static bool32 IsAnyTargetAffected(u32 battlerAtk);
|
||||
static bool32 IsNonVolatileStatusBlocked(u32 battlerDef, u32 abilityDef, u32 abilityAffected, const u8 *battleScript, enum NonVolatileStatus option);
|
||||
static bool32 CanSleepDueToSleepClause(u32 battlerAtk, u32 battlerDef, enum NonVolatileStatus option);
|
||||
|
||||
ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12(u32 percent);
|
||||
ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12_Floored(u32 percent);
|
||||
@ -831,8 +833,7 @@ void HandleAction_NothingIsFainted(void)
|
||||
gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
|
||||
gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
|
||||
| HITMARKER_NO_PPDEDUCT | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_PASSIVE_DAMAGE
|
||||
| HITMARKER_OBEYS | HITMARKER_SYNCHRONISE_EFFECT
|
||||
| HITMARKER_CHARGING);
|
||||
| HITMARKER_OBEYS | HITMARKER_SYNCHRONIZE_EFFECT | HITMARKER_CHARGING);
|
||||
}
|
||||
|
||||
void HandleAction_ActionFinished(void)
|
||||
@ -845,7 +846,7 @@ void HandleAction_ActionFinished(void)
|
||||
SpecialStatusesClear();
|
||||
gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
|
||||
| HITMARKER_NO_PPDEDUCT | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_PASSIVE_DAMAGE
|
||||
| HITMARKER_OBEYS | HITMARKER_SYNCHRONISE_EFFECT
|
||||
| HITMARKER_OBEYS | HITMARKER_SYNCHRONIZE_EFFECT
|
||||
| HITMARKER_CHARGING | HITMARKER_IGNORE_DISGUISE);
|
||||
|
||||
// check if Stellar type boost should be used up
|
||||
@ -4635,7 +4636,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||
&& CanBeSlept(gBattlerAttacker, ability, NOT_BLOCKED_BY_SLEEP_CLAUSE)
|
||||
&& CanBeSlept(gBattlerAttacker, gBattlerTarget, ability, NOT_BLOCKED_BY_SLEEP_CLAUSE)
|
||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
|
||||
&& IsMoveMakingContact(move, gBattlerAttacker))
|
||||
{
|
||||
@ -4659,7 +4660,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||
&& CanBePoisoned(gBattlerTarget, gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
|
||||
&& CanBePoisoned(gBattlerTarget, gBattlerAttacker, gLastUsedAbility, GetBattlerAbility(gBattlerAttacker))
|
||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
|
||||
&& IsMoveMakingContact(move, gBattlerAttacker))
|
||||
{
|
||||
@ -4680,7 +4681,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||
&& CanBeParalyzed(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
|
||||
&& CanBeParalyzed(gBattlerTarget, gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
|
||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
|
||||
&& IsMoveMakingContact(move, gBattlerAttacker))
|
||||
{
|
||||
@ -4700,7 +4701,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
|
||||
&& (IsMoveMakingContact(move, gBattlerAttacker))
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||
&& CanBeBurned(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
|
||||
&& CanBeBurned(gBattlerTarget, gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
|
||||
&& (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_FLAME_BODY, 30) : RandomChance(RNG_FLAME_BODY, 1, 3)))
|
||||
{
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_BURN;
|
||||
@ -4917,7 +4918,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerTarget)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget))
|
||||
&& CanBePoisoned(gBattlerAttacker, gBattlerTarget, gLastUsedAbility, GetBattlerAbility(gBattlerTarget))
|
||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
|
||||
&& IsMoveMakingContact(move, gBattlerAttacker)
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget) // Need to actually hit the target
|
||||
@ -4935,7 +4936,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerTarget)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget))
|
||||
&& CanBePoisoned(gBattlerAttacker, gBattlerTarget, gLastUsedAbility, GetBattlerAbility(gBattlerTarget))
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget) // Need to actually hit the target
|
||||
&& RandomWeighted(RNG_TOXIC_CHAIN, 7, 3))
|
||||
{
|
||||
@ -5137,45 +5138,71 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
gBattleStruct->bypassMoldBreakerChecks = FALSE;
|
||||
break;
|
||||
case ABILITYEFFECT_SYNCHRONIZE:
|
||||
if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT))
|
||||
if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONIZE_EFFECT))
|
||||
{
|
||||
gHitMarker &= ~HITMARKER_SYNCHRONISE_EFFECT;
|
||||
gHitMarker &= ~HITMARKER_SYNCHRONIZE_EFFECT;
|
||||
|
||||
if (!(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY))
|
||||
bool32 statusChanged = CanSetNonVolatileStatus(gBattlerTarget,
|
||||
gBattlerAttacker,
|
||||
gLastUsedAbility,
|
||||
GetBattlerAbility(gBattlerAttacker),
|
||||
gBattleStruct->synchronizeMoveEffect,
|
||||
STATUS_CHECK_TRIGGER);
|
||||
|
||||
BattleScriptPushCursor();
|
||||
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
|
||||
RecordAbilityBattle(gBattlerTarget, ABILITY_SYNCHRONIZE);
|
||||
|
||||
if (statusChanged)
|
||||
{
|
||||
gBattleStruct->synchronizeMoveEffect &= ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN);
|
||||
if (B_SYNCHRONIZE_TOXIC < GEN_5 && gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC)
|
||||
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_POISON;
|
||||
|
||||
gBattleScripting.moveEffect = gBattleStruct->synchronizeMoveEffect + MOVE_EFFECT_AFFECTS_USER;
|
||||
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
|
||||
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, ABILITY_SYNCHRONIZE);
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_SynchronizeActivates;
|
||||
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
effect++;
|
||||
}
|
||||
else // Synchronize ability pop up still shows up even if status fails
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_AbilityPopUp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_ATK_SYNCHRONIZE:
|
||||
if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT))
|
||||
if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONIZE_EFFECT))
|
||||
{
|
||||
gHitMarker &= ~HITMARKER_SYNCHRONISE_EFFECT;
|
||||
gHitMarker &= ~HITMARKER_SYNCHRONIZE_EFFECT;
|
||||
|
||||
if (!(gBattleMons[gBattlerTarget].status1 & STATUS1_ANY))
|
||||
bool32 statusChanged = CanSetNonVolatileStatus(gBattlerAttacker,
|
||||
gBattlerTarget,
|
||||
gLastUsedAbility,
|
||||
GetBattlerAbility(gBattlerAttacker),
|
||||
gBattleStruct->synchronizeMoveEffect,
|
||||
STATUS_CHECK_TRIGGER);
|
||||
|
||||
BattleScriptPushCursor();
|
||||
gBattleScripting.battler = gBattlerAbility = gBattlerAttacker;
|
||||
RecordAbilityBattle(gBattlerAttacker, ABILITY_SYNCHRONIZE);
|
||||
|
||||
if (statusChanged)
|
||||
{
|
||||
gBattleStruct->synchronizeMoveEffect &= ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN);
|
||||
if (gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC)
|
||||
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_POISON;
|
||||
|
||||
gBattleScripting.moveEffect = gBattleStruct->synchronizeMoveEffect;
|
||||
gBattleScripting.battler = gBattlerAbility = gBattlerAttacker;
|
||||
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, ABILITY_SYNCHRONIZE);
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_SynchronizeActivates;
|
||||
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
effect++;
|
||||
}
|
||||
else // Synchronize ability pop up still shows up even if status fails
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_AbilityPopUp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -5509,98 +5536,295 @@ bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag)
|
||||
return IsBattlerGrounded(battler);
|
||||
}
|
||||
|
||||
bool32 CanBeSlept(u32 battler, u32 ability, enum SleepClauseBlock isBlockedBySleepClause)
|
||||
bool32 CanBeSlept(u32 battlerAtk, u32 battlerDef, u32 abilityDef, enum SleepClauseBlock isBlockedBySleepClause)
|
||||
{
|
||||
if(IsSleepClauseActiveForSide(GetBattlerSide(battler)) && isBlockedBySleepClause)
|
||||
if (IsSleepClauseActiveForSide(GetBattlerSide(battlerDef)) && isBlockedBySleepClause)
|
||||
return FALSE;
|
||||
|
||||
if (ability == ABILITY_INSOMNIA
|
||||
|| ability == ABILITY_VITAL_SPIRIT
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| ability == ABILITY_PURIFYING_SALT
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| IsAbilityOnSide(battler, ABILITY_SWEET_VEIL)
|
||||
|| IsAbilityStatusProtected(battler, ability)
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_MISTY_TERRAIN))
|
||||
if (CanSetNonVolatileStatus(battlerAtk,
|
||||
battlerDef,
|
||||
ABILITY_NONE, // attacker ability does not matter
|
||||
abilityDef,
|
||||
MOVE_EFFECT_SLEEP, // also covers yawn
|
||||
STATUS_CHECK_TRIGGER))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef)
|
||||
{
|
||||
if (CanSetNonVolatileStatus(battlerAtk,
|
||||
battlerDef,
|
||||
abilityAtk,
|
||||
abilityDef,
|
||||
MOVE_EFFECT_TOXIC, // also covers poison
|
||||
STATUS_CHECK_TRIGGER))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// TODO: check order of battlerAtk and battlerDef
|
||||
bool32 CanBeBurned(u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
||||
{
|
||||
if (CanSetNonVolatileStatus(battlerAtk,
|
||||
battlerDef,
|
||||
ABILITY_NONE, // attacker ability does not matter
|
||||
abilityDef,
|
||||
MOVE_EFFECT_BURN,
|
||||
STATUS_CHECK_TRIGGER))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanBeParalyzed(u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
||||
{
|
||||
if (CanSetNonVolatileStatus(battlerAtk,
|
||||
battlerDef,
|
||||
ABILITY_NONE, // attacker ability does not matter
|
||||
abilityDef,
|
||||
MOVE_EFFECT_PARALYSIS,
|
||||
STATUS_CHECK_TRIGGER))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanBeFrozen(u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
||||
{
|
||||
if (CanSetNonVolatileStatus(battlerAtk,
|
||||
battlerDef,
|
||||
ABILITY_NONE, // attacker ability does not matter
|
||||
abilityDef,
|
||||
MOVE_EFFECT_FREEZE,
|
||||
STATUS_CHECK_TRIGGER))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Unused, technically also redundant
|
||||
bool32 CanGetFrostbite(u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
||||
{
|
||||
if (CanSetNonVolatileStatus(battlerAtk,
|
||||
battlerDef,
|
||||
ABILITY_NONE, // attacker ability does not matter
|
||||
abilityDef,
|
||||
MOVE_EFFECT_FREEZE_OR_FROSTBITE, // also covers frostbite
|
||||
STATUS_CHECK_TRIGGER))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanSetNonVolatileStatus(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef, enum MoveEffects effect, enum NonVolatileStatus option)
|
||||
{
|
||||
const u8 *battleScript = NULL;
|
||||
u32 sideBattler = ABILITY_NONE;
|
||||
bool32 abilityAffected = FALSE;
|
||||
|
||||
// Move specific checks
|
||||
switch (effect)
|
||||
{
|
||||
case MOVE_EFFECT_POISON:
|
||||
case MOVE_EFFECT_TOXIC:
|
||||
if (gBattleMons[battlerDef].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON))
|
||||
{
|
||||
battleScript = BattleScript_AlreadyPoisoned;
|
||||
}
|
||||
else if (abilityAtk != ABILITY_CORROSION && IS_BATTLER_ANY_TYPE(battlerDef, TYPE_POISON, TYPE_STEEL))
|
||||
{
|
||||
battleScript = BattleScript_NotAffected;
|
||||
}
|
||||
else if ((sideBattler = IsAbilityOnSide(battlerDef, ABILITY_PASTEL_VEIL)))
|
||||
{
|
||||
abilityAffected = TRUE;
|
||||
battlerDef = sideBattler - 1;
|
||||
abilityDef = ABILITY_PASTEL_VEIL;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PASTEL_VEIL;
|
||||
battleScript = BattleScript_ImmunityProtected;
|
||||
}
|
||||
else if (abilityDef == ABILITY_IMMUNITY)
|
||||
{
|
||||
abilityAffected = TRUE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PREVENTS_MOVE_POISON;
|
||||
battleScript = BattleScript_ImmunityProtected;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_PARALYSIS:
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_PARALYSIS)
|
||||
{
|
||||
battleScript = BattleScript_AlreadyParalyzed;
|
||||
}
|
||||
else if (B_PARALYZE_ELECTRIC >= GEN_6 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_ELECTRIC))
|
||||
{
|
||||
battleScript = BattleScript_NotAffected;
|
||||
}
|
||||
else if (option == STATUS_RUN_SCRIPT // Check only important during battle execution for moves
|
||||
&& CalcTypeEffectivenessMultiplier(gCurrentMove, GetBattleMoveType(gCurrentMove), battlerAtk, battlerDef, abilityDef, TRUE)
|
||||
&& gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT)
|
||||
{
|
||||
battleScript = BattleScript_ButItFailed;
|
||||
}
|
||||
else if (abilityDef == ABILITY_LIMBER)
|
||||
{
|
||||
abilityAffected = TRUE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PREVENTS_MOVE_PARALYSIS;
|
||||
battleScript = BattleScript_ImmunityProtected;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_BURN:
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_BURN)
|
||||
{
|
||||
battleScript = BattleScript_AlreadyBurned;
|
||||
}
|
||||
else if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_FIRE))
|
||||
{
|
||||
battleScript = BattleScript_NotAffected;
|
||||
}
|
||||
else if (abilityDef == ABILITY_WATER_VEIL || abilityDef == ABILITY_WATER_BUBBLE)
|
||||
{
|
||||
abilityAffected = TRUE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABILITY_PREVENTS_MOVE_BURN;
|
||||
battleScript = BattleScript_ImmunityProtected;
|
||||
}
|
||||
else if (abilityDef == ABILITY_THERMAL_EXCHANGE)
|
||||
{
|
||||
abilityAffected = TRUE;
|
||||
battleScript = BattleScript_AbilityProtectsDoesntAffect;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_SLEEP:
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_SLEEP)
|
||||
{
|
||||
battleScript = BattleScript_AlreadyAsleep;
|
||||
}
|
||||
else if (UproarWakeUpCheck(battlerDef))
|
||||
{
|
||||
battleScript = BattleScript_CantMakeAsleep;
|
||||
}
|
||||
else if (CanSleepDueToSleepClause(battlerAtk, battlerDef, option))
|
||||
{
|
||||
battleScript = BattleScript_SleepClauseBlocked;
|
||||
}
|
||||
else if (IsBattlerTerrainAffected(battlerDef, STATUS_FIELD_ELECTRIC_TERRAIN))
|
||||
{
|
||||
battleScript = BattleScript_ElectricTerrainPrevents;
|
||||
}
|
||||
else if ((sideBattler = IsAbilityOnSide(battlerDef, ABILITY_SWEET_VEIL)))
|
||||
{
|
||||
abilityAffected = TRUE;
|
||||
battlerDef = sideBattler - 1;
|
||||
abilityDef = ABILITY_SWEET_VEIL;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUS_HAD_NO_EFFECT;
|
||||
battleScript = BattleScript_ImmunityProtected;
|
||||
}
|
||||
else if (abilityDef == ABILITY_VITAL_SPIRIT || abilityDef == ABILITY_INSOMNIA)
|
||||
{
|
||||
abilityAffected = TRUE;
|
||||
battleScript = BattleScript_PrintAbilityMadeIneffective;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_FREEZE:
|
||||
case MOVE_EFFECT_FROSTBITE:
|
||||
if (gBattleMons[battlerDef].status1 & (STATUS1_FREEZE | STATUS1_FROSTBITE))
|
||||
{
|
||||
battleScript = BattleScript_AlreadyBurned;
|
||||
}
|
||||
else if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_ICE) || IsBattlerWeatherAffected(battlerDef, B_WEATHER_SUN))
|
||||
{
|
||||
battleScript = BattleScript_NotAffected;
|
||||
}
|
||||
else if (abilityDef == ABILITY_MAGMA_ARMOR)
|
||||
{
|
||||
abilityAffected = TRUE;
|
||||
battleScript = BattleScript_NotAffected;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsNonVolatileStatusBlocked(battlerDef, abilityDef, abilityAffected, battleScript, option))
|
||||
return FALSE;
|
||||
|
||||
// Checks that apply to all non volatile statuses
|
||||
if (abilityDef == ABILITY_COMATOSE
|
||||
|| abilityDef == ABILITY_SHIELDS_DOWN
|
||||
|| abilityDef == ABILITY_PURIFYING_SALT)
|
||||
{
|
||||
abilityAffected = TRUE;
|
||||
battleScript = BattleScript_AbilityProtectsDoesntAffect;
|
||||
}
|
||||
else if (IsBattlerTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN))
|
||||
{
|
||||
battleScript = BattleScript_MistyTerrainPrevents;
|
||||
}
|
||||
else if (IsLeafGuardProtected(battlerDef, abilityDef))
|
||||
{
|
||||
abilityAffected = TRUE;
|
||||
battleScript = BattleScript_AbilityProtectsDoesntAffect;
|
||||
}
|
||||
else if ((sideBattler = IsFlowerVeilProtected(battlerDef)))
|
||||
{
|
||||
abilityAffected = TRUE;
|
||||
battlerDef = sideBattler - 1;
|
||||
abilityDef = ABILITY_FLOWER_VEIL;
|
||||
battleScript = BattleScript_FlowerVeilProtects;
|
||||
}
|
||||
else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD)
|
||||
{
|
||||
battleScript = BattleScript_SafeguardProtected;
|
||||
}
|
||||
else if (gBattleMons[battlerDef].status1 & STATUS1_ANY)
|
||||
{
|
||||
battleScript = BattleScript_ButItFailed;
|
||||
}
|
||||
|
||||
if (IsNonVolatileStatusBlocked(battlerDef, abilityDef, abilityAffected, battleScript, option))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 defAbility)
|
||||
static bool32 IsNonVolatileStatusBlocked(u32 battlerDef, u32 abilityDef, u32 abilityAffected, const u8 *battleScript, enum NonVolatileStatus option)
|
||||
{
|
||||
if (!(CanPoisonType(battlerAtk, battlerDef))
|
||||
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
||||
|| gBattleMons[battlerDef].status1 & STATUS1_ANY
|
||||
|| defAbility == ABILITY_IMMUNITY
|
||||
|| defAbility == ABILITY_COMATOSE
|
||||
|| defAbility == ABILITY_PURIFYING_SALT
|
||||
|| IsAbilityOnSide(battlerDef, ABILITY_PASTEL_VEIL)
|
||||
|| IsAbilityStatusProtected(battlerDef, defAbility)
|
||||
|| IsBattlerTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
if (battleScript != NULL)
|
||||
{
|
||||
if (option == STATUS_RUN_SCRIPT)
|
||||
{
|
||||
if (battleScript != BattleScript_NotAffected)
|
||||
gBattleStruct->moveResultFlags[battlerDef] |= MOVE_RESULT_FAILED;
|
||||
|
||||
if (abilityAffected)
|
||||
{
|
||||
gLastUsedAbility = abilityDef;
|
||||
gBattlerAbility = battlerDef;
|
||||
RecordAbilityBattle(battlerDef, abilityDef);
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = battleScript;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanBeBurned(u32 battler, u32 ability)
|
||||
static bool32 CanSleepDueToSleepClause(u32 battlerAtk, u32 battlerDef, enum NonVolatileStatus option)
|
||||
{
|
||||
if (IS_BATTLER_OF_TYPE(battler, TYPE_FIRE)
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| ability == ABILITY_WATER_VEIL
|
||||
|| ability == ABILITY_WATER_BUBBLE
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| ability == ABILITY_THERMAL_EXCHANGE
|
||||
|| ability == ABILITY_PURIFYING_SALT
|
||||
|| IsAbilityStatusProtected(battler, ability)
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_MISTY_TERRAIN))
|
||||
// Can freely sleep own partner
|
||||
if (IsDoubleBattle() && IsSleepClauseEnabled() && IsBattlerAlly(battlerAtk, battlerDef))
|
||||
{
|
||||
if (option == STATUS_RUN_SCRIPT)
|
||||
gBattleStruct->battlerState[battlerDef].sleepClauseEffectExempt = TRUE;
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
bool32 CanBeParalyzed(u32 battler, u32 ability)
|
||||
{
|
||||
if ((B_PARALYZE_ELECTRIC >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_ELECTRIC))
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|
||||
|| ability == ABILITY_LIMBER
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| ability == ABILITY_PURIFYING_SALT
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| IsAbilityStatusProtected(battler, ability)
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
if (option == STATUS_RUN_SCRIPT)
|
||||
gBattleStruct->battlerState[battlerDef].sleepClauseEffectExempt = FALSE;
|
||||
// Can't sleep if clause is active otherwise
|
||||
if (IsSleepClauseActiveForSide(GetBattlerSide(battlerDef)))
|
||||
return TRUE;
|
||||
|
||||
bool32 CanBeFrozen(u32 battler)
|
||||
{
|
||||
u16 ability = GetBattlerAbility(battler);
|
||||
if (IS_BATTLER_OF_TYPE(battler, TYPE_ICE)
|
||||
|| IsBattlerWeatherAffected(battler, B_WEATHER_SUN)
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|
||||
|| ability == ABILITY_MAGMA_ARMOR
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| ability == ABILITY_PURIFYING_SALT
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| IsAbilityStatusProtected(battler, ability)
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 CanGetFrostbite(u32 battler)
|
||||
{
|
||||
u16 ability = GetBattlerAbility(battler);
|
||||
if (IS_BATTLER_OF_TYPE(battler, TYPE_ICE)
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|
||||
|| ability == ABILITY_MAGMA_ARMOR
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| ability == ABILITY_PURIFYING_SALT
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| IsAbilityStatusProtected(battler, ability)
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanBeConfused(u32 battler)
|
||||
@ -7132,7 +7356,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler, bool32 moveTurn)
|
||||
switch (battlerHoldEffect)
|
||||
{
|
||||
case HOLD_EFFECT_TOXIC_ORB:
|
||||
if (CanBePoisoned(battler, battler, GetBattlerAbility(battler)))
|
||||
if (CanBePoisoned(battler, battler, battlerAbility, battlerAbility)) // Can corrosion trigger toxic orb on itself?
|
||||
{
|
||||
effect = ITEM_STATUS_CHANGE;
|
||||
gBattleMons[battler].status1 = STATUS1_TOXIC_POISON;
|
||||
@ -7141,7 +7365,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler, bool32 moveTurn)
|
||||
}
|
||||
break;
|
||||
case HOLD_EFFECT_FLAME_ORB:
|
||||
if (CanBeBurned(battler, battlerAbility))
|
||||
if (CanBeBurned(battler, battler, battlerAbility))
|
||||
{
|
||||
effect = ITEM_STATUS_CHANGE;
|
||||
gBattleMons[battler].status1 = STATUS1_BURN;
|
||||
@ -7409,7 +7633,7 @@ u8 GetAttackerObedienceForAction()
|
||||
obedienceLevel = levelReferenced - obedienceLevel;
|
||||
|
||||
calc = ((rnd >> 16) & 255);
|
||||
if (calc < obedienceLevel && CanBeSlept(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), NOT_BLOCKED_BY_SLEEP_CLAUSE))
|
||||
if (calc < obedienceLevel && CanBeSlept(gBattlerAttacker, gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), NOT_BLOCKED_BY_SLEEP_CLAUSE))
|
||||
{
|
||||
// try putting asleep
|
||||
int i;
|
||||
|
||||
@ -18,7 +18,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
|
||||
[EFFECT_SLEEP] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectSleep,
|
||||
.battleScript = BattleScript_EffectNonVolatileStatus,
|
||||
.battleTvScore = 1,
|
||||
},
|
||||
|
||||
@ -185,7 +185,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
|
||||
[EFFECT_TOXIC] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectToxic,
|
||||
.battleScript = BattleScript_EffectNonVolatileStatus,
|
||||
.battleTvScore = 5,
|
||||
.encourageEncore = TRUE,
|
||||
},
|
||||
@ -368,14 +368,14 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
|
||||
[EFFECT_POISON] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectPoison,
|
||||
.battleScript = BattleScript_EffectNonVolatileStatus,
|
||||
.battleTvScore = 4,
|
||||
.encourageEncore = TRUE,
|
||||
},
|
||||
|
||||
[EFFECT_PARALYZE] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectParalyze,
|
||||
.battleScript = BattleScript_EffectNonVolatileStatus,
|
||||
.battleTvScore = 4,
|
||||
.encourageEncore = TRUE,
|
||||
},
|
||||
@ -895,7 +895,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
|
||||
[EFFECT_WILL_O_WISP] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectWillOWisp,
|
||||
.battleScript = BattleScript_EffectNonVolatileStatus,
|
||||
.battleTvScore = 5,
|
||||
.encourageEncore = TRUE,
|
||||
},
|
||||
|
||||
@ -1305,6 +1305,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_SLEEP },
|
||||
.zMove = { .effect = Z_EFFECT_SPD_UP_1 },
|
||||
.ignoresSubstitute = B_UPDATED_MOVE_FLAGS >= GEN_6,
|
||||
.magicCoatAffected = TRUE,
|
||||
@ -2066,6 +2067,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_POISON },
|
||||
.zMove = { .effect = Z_EFFECT_DEF_UP_1 },
|
||||
.magicCoatAffected = TRUE,
|
||||
.powderMove = TRUE,
|
||||
@ -2093,6 +2095,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.zMove = { .effect = Z_EFFECT_SPDEF_UP_1 },
|
||||
.magicCoatAffected = TRUE,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_PARALYSIS },
|
||||
.powderMove = TRUE,
|
||||
.contestEffect = CONTEST_EFFECT_BADLY_STARTLE_MONS_WITH_GOOD_APPEALS,
|
||||
.contestCategory = CONTEST_CATEGORY_SMART,
|
||||
@ -2116,6 +2119,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_SLEEP },
|
||||
.zMove = { .effect = Z_EFFECT_SPD_UP_1 },
|
||||
.magicCoatAffected = TRUE,
|
||||
.powderMove = TRUE,
|
||||
@ -2300,6 +2304,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_PARALYSIS },
|
||||
.zMove = { .effect = Z_EFFECT_SPDEF_UP_1 },
|
||||
.magicCoatAffected = TRUE,
|
||||
.contestEffect = CONTEST_EFFECT_BADLY_STARTLE_MONS_WITH_GOOD_APPEALS,
|
||||
@ -2449,6 +2454,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_TOXIC },
|
||||
.zMove = { .effect = Z_EFFECT_DEF_UP_1 },
|
||||
.magicCoatAffected = TRUE,
|
||||
.contestEffect = CONTEST_EFFECT_WORSEN_CONDITION_OF_PREV_MONS,
|
||||
@ -2524,6 +2530,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_SLEEP },
|
||||
.zMove = { .effect = Z_EFFECT_SPD_UP_1 },
|
||||
.magicCoatAffected = TRUE,
|
||||
.contestEffect = CONTEST_EFFECT_BADLY_STARTLE_PREV_MONS,
|
||||
@ -3619,6 +3626,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_PARALYSIS },
|
||||
.zMove = { .effect = Z_EFFECT_SPDEF_UP_1 },
|
||||
.magicCoatAffected = TRUE,
|
||||
.contestEffect = CONTEST_EFFECT_BADLY_STARTLE_PREV_MONS,
|
||||
@ -3673,6 +3681,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = B_UPDATED_MOVE_DATA >= GEN_5 ? MOVE_TARGET_BOTH : MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_POISON },
|
||||
.zMove = { .effect = Z_EFFECT_DEF_UP_1 },
|
||||
.magicCoatAffected = TRUE,
|
||||
.contestEffect = CONTEST_EFFECT_WORSEN_CONDITION_OF_PREV_MONS,
|
||||
@ -3743,6 +3752,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_SLEEP },
|
||||
.zMove = { .effect = Z_EFFECT_SPD_UP_1 },
|
||||
.magicCoatAffected = TRUE,
|
||||
.contestEffect = CONTEST_EFFECT_BADLY_STARTLE_PREV_MONS,
|
||||
@ -3883,6 +3893,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_SLEEP },
|
||||
.zMove = { .effect = Z_EFFECT_RESET_STATS },
|
||||
.magicCoatAffected = TRUE,
|
||||
.powderMove = TRUE,
|
||||
@ -6850,6 +6861,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_BURN },
|
||||
.zMove = { .effect = Z_EFFECT_ATK_UP_1 },
|
||||
.magicCoatAffected = TRUE,
|
||||
.contestEffect = CONTEST_EFFECT_BADLY_STARTLE_FRONT_MON,
|
||||
@ -7374,6 +7386,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_SLEEP },
|
||||
.zMove = { .effect = Z_EFFECT_SPD_UP_1 },
|
||||
.magicCoatAffected = TRUE,
|
||||
.contestEffect = CONTEST_EFFECT_MAKE_FOLLOWING_MONS_NERVOUS,
|
||||
@ -8385,6 +8398,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_SLEEP },
|
||||
.zMove = { .effect = Z_EFFECT_SPD_UP_1 },
|
||||
.ignoresSubstitute = B_UPDATED_MOVE_FLAGS >= GEN_6,
|
||||
.magicCoatAffected = TRUE,
|
||||
@ -11921,6 +11935,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
||||
.target = MOVE_TARGET_BOTH,
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_STATUS,
|
||||
.argument = { .nonVolatileStatus = MOVE_EFFECT_SLEEP },
|
||||
.zMove = { .effect = Z_EFFECT_RESET_STATS },
|
||||
.magicCoatAffected = TRUE,
|
||||
.sketchBanned = (B_SKETCH_BANS >= GEN_9),
|
||||
|
||||
64
test/battle/ability/flower_veil.c
Normal file
64
test/battle/ability/flower_veil.c
Normal file
@ -0,0 +1,64 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_TOXIC) == MOVE_EFFECT_TOXIC);
|
||||
ASSUME(GetMoveEffect(MOVE_POISON_GAS) == EFFECT_POISON);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_POISON_GAS) == MOVE_EFFECT_POISON);
|
||||
ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_WILL_O_WISP) == MOVE_EFFECT_BURN);
|
||||
ASSUME(GetMoveEffect(MOVE_THUNDER_WAVE) == EFFECT_PARALYZE);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_THUNDER_WAVE) == MOVE_EFFECT_PARALYSIS);
|
||||
ASSUME(GetMoveEffect(MOVE_HYPNOSIS) == EFFECT_SLEEP);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_HYPNOSIS) == MOVE_EFFECT_SLEEP);
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Flower Veil prevents Toxic bad poison on partner - right target")
|
||||
{
|
||||
u32 move;
|
||||
|
||||
PARAMETRIZE { move = MOVE_TOXIC; }
|
||||
PARAMETRIZE { move = MOVE_POISON_GAS; }
|
||||
PARAMETRIZE { move = MOVE_WILL_O_WISP; }
|
||||
PARAMETRIZE { move = MOVE_THUNDER_WAVE; }
|
||||
PARAMETRIZE { move = MOVE_HYPNOSIS; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_COMFEY) { Ability(ABILITY_FLOWER_VEIL); }
|
||||
OPPONENT(SPECIES_CHIKORITA);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, move, playerLeft);
|
||||
ABILITY_POPUP(opponentLeft, ABILITY_FLOWER_VEIL);
|
||||
MESSAGE("The opposing Chikorita surrounded itself with a veil of petals!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Flower Veil prevents Toxic bad poison on partner - left target")
|
||||
{
|
||||
u32 move;
|
||||
|
||||
PARAMETRIZE { move = MOVE_TOXIC; }
|
||||
PARAMETRIZE { move = MOVE_POISON_GAS; }
|
||||
PARAMETRIZE { move = MOVE_WILL_O_WISP; }
|
||||
PARAMETRIZE { move = MOVE_THUNDER_WAVE; }
|
||||
PARAMETRIZE { move = MOVE_HYPNOSIS; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_CHIKORITA);
|
||||
OPPONENT(SPECIES_COMFEY) { Ability(ABILITY_FLOWER_VEIL); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, move, target: opponentLeft); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, move, playerLeft);
|
||||
ABILITY_POPUP(opponentRight, ABILITY_FLOWER_VEIL);
|
||||
MESSAGE("The opposing Chikorita surrounded itself with a veil of petals!");
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@
|
||||
SINGLE_BATTLE_TEST("Limber prevents paralysis")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_THUNDER_SHOCK, MOVE_EFFECT_PARALYSIS) == TRUE);
|
||||
PLAYER(SPECIES_PERSIAN) { Ability(ABILITY_LIMBER); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
@ -16,3 +17,22 @@ SINGLE_BATTLE_TEST("Limber prevents paralysis")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SINGLE_BATTLE_TEST("Limber prevents paralysis from Thunder Wave")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_THUNDER_WAVE) == EFFECT_PARALYZE);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_THUNDER_WAVE) == MOVE_EFFECT_PARALYSIS);
|
||||
PLAYER(SPECIES_PERSIAN) { Ability(ABILITY_LIMBER); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_THUNDER_WAVE); }
|
||||
} SCENE {
|
||||
MESSAGE("Persian's Limber prevents paralysis!");
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, player);
|
||||
STATUS_ICON(player, paralysis: TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_TOXIC) == MOVE_EFFECT_TOXIC);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Pastel Veil prevents Poison Sting poison")
|
||||
{
|
||||
GIVEN {
|
||||
@ -34,7 +40,6 @@ DOUBLE_BATTLE_TEST("Pastel Veil prevents Poison Sting poison on partner")
|
||||
SINGLE_BATTLE_TEST("Pastel Veil immediately cures Mold Breaker poison")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
|
||||
PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }
|
||||
OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); }
|
||||
} WHEN {
|
||||
@ -52,7 +57,6 @@ SINGLE_BATTLE_TEST("Pastel Veil immediately cures Mold Breaker poison")
|
||||
DOUBLE_BATTLE_TEST("Pastel Veil does not cure Mold Breaker poison on partner")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
|
||||
PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); }
|
||||
@ -69,7 +73,6 @@ DOUBLE_BATTLE_TEST("Pastel Veil does not cure Mold Breaker poison on partner")
|
||||
SINGLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); }
|
||||
} WHEN {
|
||||
@ -82,10 +85,9 @@ SINGLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison")
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison on partner")
|
||||
DOUBLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison on partner - right target")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); }
|
||||
@ -100,6 +102,23 @@ DOUBLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison on partner")
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison on partner - left target")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_TOXIC, target: opponentLeft); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Toxic!");
|
||||
ABILITY_POPUP(opponentRight, ABILITY_PASTEL_VEIL);
|
||||
MESSAGE("The opposing Wynaut is protected by a pastel veil!");
|
||||
NOT STATUS_ICON(opponentLeft, badPoison: TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Pastel Veil prevents Toxic Spikes poison")
|
||||
{
|
||||
GIVEN {
|
||||
|
||||
@ -49,3 +49,22 @@ SINGLE_BATTLE_TEST("Poison Point triggers 30% of the time")
|
||||
STATUS_ICON(player, poison: TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Poison Point will not poison Poison-Type targets with corrosion")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveMakesContact(MOVE_TACKLE));
|
||||
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
|
||||
OPPONENT(SPECIES_NIDORAN_M) { Ability(ABILITY_POISON_POINT); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ABILITY_POPUP(opponent, ABILITY_POISON_POINT);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player);
|
||||
MESSAGE("Salandit was poisoned by the opposing Nidoran♂'s Poison Point!");
|
||||
STATUS_ICON(player, poison: TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,3 +117,17 @@ SINGLE_BATTLE_TEST("Purifying Salt doesn't prevent pokemon from being poisoned b
|
||||
HP_BAR(player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Purifying Salt protects from secondary effect burn")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_EMBER, MOVE_EFFECT_BURN));
|
||||
PLAYER(SPECIES_GARGANACL) { Ability(ABILITY_PURIFYING_SALT); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_EMBER); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, opponent);
|
||||
NOT STATUS_ICON(player, STATUS1_BURN);
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,3 +47,18 @@ SINGLE_BATTLE_TEST("Static triggers 30% of the time")
|
||||
STATUS_ICON(player, paralysis: TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Static triggers even if attacker is under substitute")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveMakesContact(MOVE_TACKLE));
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_PIKACHU) { Ability(ABILITY_STATIC); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SUBSTITUTE); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_STATIC);
|
||||
STATUS_ICON(player, paralysis: TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
40
test/battle/ability/sweet_veil.c
Normal file
40
test/battle/ability/sweet_veil.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(GetMoveEffect(MOVE_HYPNOSIS) == EFFECT_SLEEP);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_HYPNOSIS) == MOVE_EFFECT_SLEEP);
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Sweet Veil prevents Sleep on partner - right target")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_BOUNSWEET) { Ability(ABILITY_SWEET_VEIL); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Hypnosis!");
|
||||
ABILITY_POPUP(opponentLeft, ABILITY_SWEET_VEIL);
|
||||
NOT STATUS_ICON(opponentRight, sleep: TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Sweet Veil prevents Sleep on partner - left target")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_BOUNSWEET) { Ability(ABILITY_SWEET_VEIL); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentLeft); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Hypnosis!");
|
||||
ABILITY_POPUP(opponentRight, ABILITY_SWEET_VEIL);
|
||||
NOT STATUS_ICON(opponentLeft, sleep: TRUE);
|
||||
}
|
||||
}
|
||||
68
test/battle/ability/synchronize.c
Normal file
68
test/battle/ability/synchronize.c
Normal file
@ -0,0 +1,68 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Synchronize will mirror back non volatile status back at opposing mon")
|
||||
{
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_TOXIC) == MOVE_EFFECT_TOXIC);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_ABRA) { Ability(ABILITY_SYNCHRONIZE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TOXIC); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC, player);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
|
||||
STATUS_ICON(opponent, badPoison: TRUE);
|
||||
ABILITY_POPUP(opponent, ABILITY_SYNCHRONIZE);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player);
|
||||
STATUS_ICON(player, badPoison: TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Synchronize will still show up the ability pop up even if it fails")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveMakesContact(MOVE_TACKLE));
|
||||
PLAYER(SPECIES_PIKACHU) { Ability(ABILITY_STATIC); }
|
||||
OPPONENT(SPECIES_ABRA) { Ability(ABILITY_SYNCHRONIZE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); MOVE(player, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
ABILITY_POPUP(player, ABILITY_STATIC);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, opponent);
|
||||
STATUS_ICON(opponent, paralysis: TRUE);
|
||||
ABILITY_POPUP(opponent, ABILITY_SYNCHRONIZE);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, player);
|
||||
STATUS_ICON(player, paralysis: TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SINGLE_BATTLE_TEST("Synchronize will mirror back static activation")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveMakesContact(MOVE_TACKLE));
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_PIKACHU) { Ability(ABILITY_STATIC); }
|
||||
OPPONENT(SPECIES_ABRA) { Ability(ABILITY_SYNCHRONIZE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SKILL_SWAP); }
|
||||
TURN { SWITCH(opponent, 1); }
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SKILL_SWAP, player);
|
||||
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
ABILITY_POPUP(player, ABILITY_STATIC);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, opponent);
|
||||
STATUS_ICON(opponent, paralysis: TRUE);
|
||||
ABILITY_POPUP(opponent, ABILITY_SYNCHRONIZE);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, player);
|
||||
STATUS_ICON(player, paralysis: TRUE);
|
||||
}
|
||||
}
|
||||
21
test/battle/ability/water_bubble.c
Normal file
21
test/battle/ability/water_bubble.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Water Bubble prevents burn from Will-o-Wisp")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_WILL_O_WISP) == MOVE_EFFECT_BURN);
|
||||
PLAYER(SPECIES_DEWPIDER) { Ability(ABILITY_WATER_BUBBLE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_WILL_O_WISP); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ABILITY_WATER_BUBBLE);
|
||||
MESSAGE("Dewpider's Water Bubble prevents burns!");
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, player);
|
||||
STATUS_ICON(player, burn: TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_TOXIC) == MOVE_EFFECT_TOXIC);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Toxic inflicts bad poison")
|
||||
@ -21,6 +22,27 @@ SINGLE_BATTLE_TEST("Toxic inflicts bad poison")
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Toxic can't bad poison a poison or steel type")
|
||||
{
|
||||
u32 species;
|
||||
|
||||
PARAMETRIZE { species = SPECIES_BELDUM; }
|
||||
PARAMETRIZE { species = SPECIES_BULBASAUR; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(species);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TOXIC); }
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC, player);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
|
||||
STATUS_ICON(opponent, badPoison: TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Toxic cannot miss if used by a Poison-type")
|
||||
{
|
||||
u32 species;
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_WILL_O_WISP) == MOVE_EFFECT_BURN);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Burn deals 1/16th (Gen7+) or 1/8th damage per turn")
|
||||
{
|
||||
u32 j;
|
||||
@ -35,6 +41,37 @@ SINGLE_BATTLE_TEST("Burn reduces Attack by 50%", s16 damage)
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Will-O-Wisp burns target")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_WILL_O_WISP); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WILL_O_WISP, player);
|
||||
MESSAGE("The opposing Wobbuffet was burned!");
|
||||
STATUS_ICON(opponent, burn: TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SINGLE_BATTLE_TEST("Will-O-Wisp can't burn a fire type")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_CHARMANDER);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_WILL_O_WISP); }
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WILL_O_WISP, player);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponent);
|
||||
STATUS_ICON(opponent, burn: TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI avoids Will-o-Wisp when it can not burn target")
|
||||
{
|
||||
u32 species, ability;
|
||||
|
||||
@ -16,3 +16,26 @@ SINGLE_BATTLE_TEST("Poison deals 1/8th damage per turn")
|
||||
HP_BAR(player, damage: maxHP / 8);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Poison can't bad poison a poison or steel type")
|
||||
{
|
||||
u32 species;
|
||||
|
||||
PARAMETRIZE { species = SPECIES_BELDUM; }
|
||||
PARAMETRIZE { species = SPECIES_BULBASAUR; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_POISON_GAS) == EFFECT_POISON);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_POISON_GAS) == MOVE_EFFECT_POISON);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(species);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_POISON_GAS); }
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_POISON_GAS, player);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
|
||||
STATUS_ICON(opponent, poison: TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,20 @@ SINGLE_BATTLE_TEST("Sleep prevents the battler from using a move")
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sleep: Spore doesn't affect grass types (Gen 6+)")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(IsPowderMove(MOVE_SPORE));
|
||||
ASSUME(B_POWDER_GRASS >= GEN_6);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_CHIKORITA);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SPORE); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI avoids hypnosis when it can not put target to sleep")
|
||||
{
|
||||
u32 species, ability;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user