Merge pull request #1358 from ghoulslash/misty_terrain

Electric and Misty Terrain Effects
This commit is contained in:
ultima-soul 2021-09-16 19:09:39 -07:00 committed by GitHub
commit 58356fdcd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 230 additions and 93 deletions

View File

@ -1791,6 +1791,12 @@
.4byte \ptr .4byte \ptr
.endm .endm
.macro jumpifterrainaffected battler:req, terrainFlags:req, ptr:req
various \battler, VARIOUS_JUMP_IF_TERRAIN_AFFECTED
.4byte \terrainFlags
.4byte \ptr
.endm
@ helpful macros @ helpful macros
.macro setstatchanger stat:req, stages:req, down:req .macro setstatchanger stat:req, stages:req, down:req
setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7 setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7

View File

@ -2123,6 +2123,8 @@ BattleScript_EffectSleep::
jumpifleafguard BattleScript_LeafGuardProtects jumpifleafguard BattleScript_LeafGuardProtects
jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifterrainaffected BS_TARGET, STATUS_FIELD_ELECTRIC_TERRAIN, BattleScript_ElectricTerrainPrevents
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected jumpifsafeguard BattleScript_SafeguardProtected
attackanimation attackanimation
@ -2130,6 +2132,26 @@ BattleScript_EffectSleep::
setmoveeffect MOVE_EFFECT_SLEEP setmoveeffect MOVE_EFFECT_SLEEP
seteffectprimary seteffectprimary
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_TerrainPreventsEnd2::
pause B_WAIT_TIME_SHORT
printfromtable gTerrainPreventsStringIds
waitmessage B_WAIT_TIME_LONG
end2
BattleScript_ElectricTerrainPrevents::
pause B_WAIT_TIME_SHORT
printstring STRINGID_ELECTRICTERRAINPREVENTS
waitmessage B_WAIT_TIME_LONG
orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_MistyTerrainPrevents::
pause B_WAIT_TIME_SHORT
printstring STRINGID_MISTYTERRAINPREVENTS
waitmessage B_WAIT_TIME_LONG
orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_FlowerVeilProtectsRet:: BattleScript_FlowerVeilProtectsRet::
pause B_WAIT_TIME_SHORT pause B_WAIT_TIME_SHORT
@ -2645,6 +2667,7 @@ BattleScript_EffectToxic::
jumpifsubstituteblocks BattleScript_ButItFailed jumpifsubstituteblocks BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_POISON | STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned jumpifstatus BS_TARGET, STATUS1_POISON | STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
trypoisontype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected trypoisontype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected jumpifsafeguard BattleScript_SafeguardProtected
@ -2869,6 +2892,7 @@ BattleScript_EffectConfuse:
jumpifability BS_TARGET, ABILITY_OWN_TEMPO, BattleScript_OwnTempoPrevents jumpifability BS_TARGET, ABILITY_OWN_TEMPO, BattleScript_OwnTempoPrevents
jumpifsubstituteblocks BattleScript_ButItFailed jumpifsubstituteblocks BattleScript_ButItFailed
jumpifstatus2 BS_TARGET, STATUS2_CONFUSION, BattleScript_AlreadyConfused jumpifstatus2 BS_TARGET, STATUS2_CONFUSION, BattleScript_AlreadyConfused
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected jumpifsafeguard BattleScript_SafeguardProtected
attackanimation attackanimation
@ -2987,6 +3011,7 @@ BattleScript_EffectPoison::
jumpifstatus BS_TARGET, STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned jumpifstatus BS_TARGET, STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned
trypoisontype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected trypoisontype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected jumpifsafeguard BattleScript_SafeguardProtected
attackanimation attackanimation
@ -3012,6 +3037,7 @@ BattleScript_EffectParalyze:
jumpifstatus BS_TARGET, STATUS1_PARALYSIS, BattleScript_AlreadyParalyzed jumpifstatus BS_TARGET, STATUS1_PARALYSIS, BattleScript_AlreadyParalyzed
tryparalyzetype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected tryparalyzetype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected jumpifsafeguard BattleScript_SafeguardProtected
bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
@ -4316,6 +4342,7 @@ BattleScript_EffectWillOWisp::
jumpifleafguard BattleScript_LeafGuardProtects jumpifleafguard BattleScript_LeafGuardProtects
jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected jumpifsafeguard BattleScript_SafeguardProtected
attackanimation attackanimation

View File

@ -119,10 +119,10 @@ bool32 IsUngroundingEffect(u16 effect);
bool32 IsSemiInvulnerable(u8 battlerDef, u16 move); bool32 IsSemiInvulnerable(u8 battlerDef, u16 move);
// status checks // status checks
bool32 CanBeBurned(u8 battler, u16 ability); bool32 AI_CanBeBurned(u8 battler, u16 ability);
bool32 CanBePoisoned(u8 battler, u16 ability); bool32 AI_CanBePoisoned(u8 battler, u16 ability);
bool32 CanBeConfused(u8 battler, u16 ability); bool32 AI_CanBeConfused(u8 battler, u16 ability);
bool32 CanSleep(u8 battler, u16 ability); bool32 AI_CanSleep(u8 battler, u16 ability);
bool32 IsBattlerIncapacitated(u8 battler, u16 ability); bool32 IsBattlerIncapacitated(u8 battler, u16 ability);
bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove); bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
bool32 ShouldPoisonSelf(u8 battler, u16 ability); bool32 ShouldPoisonSelf(u8 battler, u16 ability);

View File

@ -381,5 +381,8 @@ extern const u8 BattleScript_EjectPackActivate_End2[];
extern const u8 BattleScript_EjectPackActivates[]; extern const u8 BattleScript_EjectPackActivates[];
extern const u8 BattleScript_MentalHerbCureRet[]; extern const u8 BattleScript_MentalHerbCureRet[];
extern const u8 BattleScript_MentalHerbCureEnd2[]; extern const u8 BattleScript_MentalHerbCureEnd2[];
extern const u8 BattleScript_TerrainPreventsEnd2[];
extern const u8 BattleScript_MistyTerrainPrevents[];
extern const u8 BattleScript_ElectricTerrainPrevents[];
#endif // GUARD_BATTLE_SCRIPTS_H #endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -161,4 +161,12 @@ bool32 IsGastroAcidBannedAbility(u16 ability);
bool32 IsEntrainmentBannedAbilityAttacker(u16 ability); bool32 IsEntrainmentBannedAbilityAttacker(u16 ability);
bool32 IsEntrainmentTargetOrSimpleBeamBannedAbility(u16 ability); bool32 IsEntrainmentTargetOrSimpleBeamBannedAbility(u16 ability);
bool32 CanSleep(u8 battlerId);
bool32 CanBePoisoned(u8 battlerId);
bool32 CanBeBurned(u8 battlerId);
bool32 CanBeParalyzed(u8 battlerId);
bool32 CanBeFrozen(u8 battlerId);
bool32 CanBeConfused(u8 battlerId);
bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag);
#endif // GUARD_BATTLE_UTIL_H #endif // GUARD_BATTLE_UTIL_H

View File

@ -178,6 +178,7 @@
#define VARIOUS_TERRAIN_SEED 106 #define VARIOUS_TERRAIN_SEED 106
#define VARIOUS_MAKE_INVISIBLE 107 #define VARIOUS_MAKE_INVISIBLE 107
#define VARIOUS_ROOM_SERVICE 108 #define VARIOUS_ROOM_SERVICE 108
#define VARIOUS_JUMP_IF_TERRAIN_AFFECTED 109
// Cmd_manipulatedamage // Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0 #define DMG_CHANGE_SIGN 0

View File

@ -823,4 +823,9 @@
#define B_MSG_MENTALHERBCURE_HEALBLOCK 4 #define B_MSG_MENTALHERBCURE_HEALBLOCK 4
#define B_MSG_MENTALHERBCURE_DISABLE 5 #define B_MSG_MENTALHERBCURE_DISABLE 5
// gTerrainPreventsStringIds
#define B_MSG_TERRAINPREVENTS_MISTY 0
#define B_MSG_TERRAINPREVENTS_ELECTRIC 1
#define B_MSG_TERRAINPREVENTS_PSYCHIC 2
#endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H #endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H

View File

@ -1570,7 +1570,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score -= 10; score -= 10;
break; break;
case EFFECT_REST: case EFFECT_REST:
if (!CanSleep(battlerAtk, AI_DATA->atkAbility)) if (!AI_CanSleep(battlerAtk, AI_DATA->atkAbility))
score -= 10; score -= 10;
//fallthrough //fallthrough
case EFFECT_RESTORE_HP: case EFFECT_RESTORE_HP:
@ -2686,7 +2686,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_SWAGGER: case EFFECT_SWAGGER:
if (gBattleMons[battlerAtkPartner].statStages[STAT_ATK] < MAX_STAT_STAGE if (gBattleMons[battlerAtkPartner].statStages[STAT_ATK] < MAX_STAT_STAGE
&& HasMoveWithSplit(battlerAtkPartner, SPLIT_PHYSICAL) && HasMoveWithSplit(battlerAtkPartner, SPLIT_PHYSICAL)
&& (!CanBeConfused(battlerAtkPartner, TRUE) && (!AI_CanBeConfused(battlerAtkPartner, TRUE)
|| atkPartnerHoldEffect == HOLD_EFFECT_CURE_CONFUSION || atkPartnerHoldEffect == HOLD_EFFECT_CURE_CONFUSION
|| atkPartnerHoldEffect == HOLD_EFFECT_CURE_STATUS)) || atkPartnerHoldEffect == HOLD_EFFECT_CURE_STATUS))
{ {
@ -2696,7 +2696,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_FLATTER: case EFFECT_FLATTER:
if (gBattleMons[battlerAtkPartner].statStages[STAT_SPATK] < MAX_STAT_STAGE if (gBattleMons[battlerAtkPartner].statStages[STAT_SPATK] < MAX_STAT_STAGE
&& HasMoveWithSplit(battlerAtkPartner, SPLIT_SPECIAL) && HasMoveWithSplit(battlerAtkPartner, SPLIT_SPECIAL)
&& (!CanBeConfused(battlerAtkPartner, TRUE) && (!AI_CanBeConfused(battlerAtkPartner, TRUE)
|| atkPartnerHoldEffect == HOLD_EFFECT_CURE_CONFUSION || atkPartnerHoldEffect == HOLD_EFFECT_CURE_CONFUSION
|| atkPartnerHoldEffect == HOLD_EFFECT_CURE_STATUS)) || atkPartnerHoldEffect == HOLD_EFFECT_CURE_STATUS))
{ {
@ -3248,7 +3248,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
} }
break; break;
case EFFECT_REST: case EFFECT_REST:
if (!(CanSleep(battlerAtk, AI_DATA->atkAbility))) if (!(AI_CanSleep(battlerAtk, AI_DATA->atkAbility)))
{ {
break; break;
} }
@ -3937,11 +3937,11 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score += 2; score += 2;
break; break;
case HOLD_EFFECT_TOXIC_ORB: case HOLD_EFFECT_TOXIC_ORB:
if (!ShouldPoisonSelf(battlerAtk, AI_DATA->atkAbility) && CanBePoisoned(battlerDef, AI_DATA->defAbility)) if (!ShouldPoisonSelf(battlerAtk, AI_DATA->atkAbility) && AI_CanBePoisoned(battlerDef, AI_DATA->defAbility))
score += 2; score += 2;
break; break;
case HOLD_EFFECT_FLAME_ORB: case HOLD_EFFECT_FLAME_ORB:
if (!ShouldBurnSelf(battlerAtk, AI_DATA->atkAbility) && CanBeBurned(battlerAtk, AI_DATA->defAbility)) if (!ShouldBurnSelf(battlerAtk, AI_DATA->atkAbility) && AI_CanBeBurned(battlerAtk, AI_DATA->defAbility))
score += 2; score += 2;
break; break;
case HOLD_EFFECT_BLACK_SLUDGE: case HOLD_EFFECT_BLACK_SLUDGE:

View File

@ -2589,7 +2589,7 @@ bool32 IsBattlerIncapacitated(u8 battler, u16 ability)
return FALSE; return FALSE;
} }
bool32 CanSleep(u8 battler, u16 ability) bool32 AI_CanSleep(u8 battler, u16 ability)
{ {
if (ability == ABILITY_INSOMNIA if (ability == ABILITY_INSOMNIA
|| ability == ABILITY_VITAL_SPIRIT || ability == ABILITY_VITAL_SPIRIT
@ -2603,7 +2603,7 @@ bool32 CanSleep(u8 battler, u16 ability)
bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove) bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
{ {
if (!CanSleep(battlerDef, defAbility) if (!AI_CanSleep(battlerDef, defAbility)
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) // shouldn't try to sleep mon that partner is trying to make sleep || PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) // shouldn't try to sleep mon that partner is trying to make sleep
@ -2611,7 +2611,7 @@ bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move,
return TRUE; return TRUE;
} }
bool32 CanBePoisoned(u8 battler, u16 ability) bool32 AI_CanBePoisoned(u8 battler, u16 ability)
{ {
if (ability == ABILITY_IMMUNITY if (ability == ABILITY_IMMUNITY
|| ability == ABILITY_PASTEL_VEIL || ability == ABILITY_PASTEL_VEIL
@ -2624,7 +2624,7 @@ bool32 CanBePoisoned(u8 battler, u16 ability)
bool32 ShouldPoisonSelf(u8 battler, u16 ability) bool32 ShouldPoisonSelf(u8 battler, u16 ability)
{ {
if (CanBePoisoned(battler, ability) && ( if (AI_CanBePoisoned(battler, ability) && (
ability == ABILITY_MARVEL_SCALE ability == ABILITY_MARVEL_SCALE
|| ability == ABILITY_POISON_HEAL || ability == ABILITY_POISON_HEAL
|| ability == ABILITY_QUICK_FEET || ability == ABILITY_QUICK_FEET
@ -2639,7 +2639,7 @@ bool32 ShouldPoisonSelf(u8 battler, u16 ability)
bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove) bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
{ {
if (!CanBePoisoned(battlerDef, defAbility) if (!AI_CanBePoisoned(battlerDef, defAbility)
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) || PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove))
@ -2673,7 +2673,7 @@ bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u1
return TRUE; return TRUE;
} }
bool32 CanBeConfused(u8 battler, u16 ability) bool32 AI_CanBeConfused(u8 battler, u16 ability)
{ {
if ((gBattleMons[battler].status2 & STATUS2_CONFUSION) if ((gBattleMons[battler].status2 & STATUS2_CONFUSION)
|| (ability == ABILITY_OWN_TEMPO) || (ability == ABILITY_OWN_TEMPO)
@ -2684,7 +2684,7 @@ bool32 CanBeConfused(u8 battler, u16 ability)
bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove) bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove)
{ {
if (!CanBeConfused(battlerDef, defAbility) if (!AI_CanBeConfused(battlerDef, defAbility)
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD || gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
@ -2696,7 +2696,7 @@ bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtk
return TRUE; return TRUE;
} }
bool32 CanBeBurned(u8 battler, u16 ability) bool32 AI_CanBeBurned(u8 battler, u16 ability)
{ {
if (ability == ABILITY_WATER_VEIL if (ability == ABILITY_WATER_VEIL
|| ability == ABILITY_WATER_BUBBLE || ability == ABILITY_WATER_BUBBLE
@ -2710,7 +2710,7 @@ bool32 CanBeBurned(u8 battler, u16 ability)
bool32 ShouldBurnSelf(u8 battler, u16 ability) bool32 ShouldBurnSelf(u8 battler, u16 ability)
{ {
if (CanBeBurned(battler, ability) && ( if (AI_CanBeBurned(battler, ability) && (
ability == ABILITY_QUICK_FEET ability == ABILITY_QUICK_FEET
|| ability == ABILITY_HEATPROOF || ability == ABILITY_HEATPROOF
|| ability == ABILITY_MAGIC_GUARD || ability == ABILITY_MAGIC_GUARD
@ -2724,7 +2724,7 @@ bool32 ShouldBurnSelf(u8 battler, u16 ability)
bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove) bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove)
{ {
if (!CanBeBurned(battlerDef, defAbility) if (!AI_CanBeBurned(battlerDef, defAbility)
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| PartnerMoveEffectIsStatusSameTarget(battlerAtkPartner, battlerDef, partnerMove)) || PartnerMoveEffectIsStatusSameTarget(battlerAtkPartner, battlerDef, partnerMove))

View File

@ -1292,7 +1292,9 @@ const u16 gTerrainStringIds[] =
const u16 gTerrainPreventsStringIds[] = const u16 gTerrainPreventsStringIds[] =
{ {
STRINGID_MISTYTERRAINPREVENTS, STRINGID_ELECTRICTERRAINPREVENTS, STRINGID_PSYCHICTERRAINPREVENTS [B_MSG_TERRAINPREVENTS_MISTY] = STRINGID_MISTYTERRAINPREVENTS,
[B_MSG_TERRAINPREVENTS_ELECTRIC] = STRINGID_ELECTRICTERRAINPREVENTS,
[B_MSG_TERRAINPREVENTS_PSYCHIC] = STRINGID_PSYCHICTERRAINPREVENTS
}; };
const u16 gMagicCoatBounceStringIds[] = const u16 gMagicCoatBounceStringIds[] =

View File

@ -2502,8 +2502,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
{ {
s32 i, byTwo, affectsUser = 0; s32 i, byTwo, affectsUser = 0;
bool32 statusChanged = FALSE; bool32 statusChanged = FALSE;
bool32 noSunCanFreeze = TRUE;
switch (gBattleScripting.moveEffect) // Set move effects which happen later on switch (gBattleScripting.moveEffect) // Set move effects which happen later on
{ {
case MOVE_EFFECT_KNOCK_OFF: case MOVE_EFFECT_KNOCK_OFF:
@ -2562,15 +2561,9 @@ void SetMoveEffect(bool32 primary, u32 certain)
else else
gActiveBattler = gBattlersCount; gActiveBattler = gBattlersCount;
if (gBattleMons[gEffectBattler].status1)
break;
if (gActiveBattler != gBattlersCount) if (gActiveBattler != gBattlersCount)
break; break;
if (GetBattlerAbility(gEffectBattler) == ABILITY_VITAL_SPIRIT if (!CanSleep(gEffectBattler))
|| GetBattlerAbility(gEffectBattler) == ABILITY_INSOMNIA
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
|| IsAbilityOnSide(gEffectBattler, ABILITY_SWEET_VEIL)
|| IsAbilityStatusProtected(gEffectBattler))
break; break;
CancelMultiTurnMoves(gEffectBattler); CancelMultiTurnMoves(gEffectBattler);
@ -2609,11 +2602,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
} }
if (!CanPoisonType(gBattleScripting.battler, gEffectBattler)) if (!CanPoisonType(gBattleScripting.battler, gEffectBattler))
break; break;
if (gBattleMons[gEffectBattler].status1) if (!CanBePoisoned(gEffectBattler))
break;
if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
|| IsAbilityStatusProtected(gEffectBattler))
break; break;
statusChanged = TRUE; statusChanged = TRUE;
@ -2648,30 +2637,14 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUS_HAD_NO_EFFECT; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUS_HAD_NO_EFFECT;
RESET_RETURN RESET_RETURN
} }
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_FIRE))
break; if (!CanBeBurned(gEffectBattler))
if (GetBattlerAbility(gEffectBattler) == ABILITY_WATER_VEIL
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
|| GetBattlerAbility(gEffectBattler) == ABILITY_WATER_BUBBLE
|| IsAbilityStatusProtected(gEffectBattler))
break;
if (gBattleMons[gEffectBattler].status1)
break; break;
statusChanged = TRUE; statusChanged = TRUE;
break; break;
case STATUS1_FREEZE: case STATUS1_FREEZE:
if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY) if (!CanBeFrozen(gEffectBattler))
noSunCanFreeze = FALSE;
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_ICE))
break;
if (gBattleMons[gEffectBattler].status1)
break;
if (noSunCanFreeze == 0)
break;
if (GetBattlerAbility(gEffectBattler) == ABILITY_MAGMA_ARMOR
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
|| IsAbilityStatusProtected(gEffectBattler))
break; break;
CancelMultiTurnMoves(gEffectBattler); CancelMultiTurnMoves(gEffectBattler);
@ -2714,11 +2687,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
} }
if (!CanParalyzeType(gBattleScripting.battler, gEffectBattler)) if (!CanParalyzeType(gBattleScripting.battler, gEffectBattler))
break; break;
if (GetBattlerAbility(gEffectBattler) == ABILITY_LIMBER if (!CanBeParalyzed(gEffectBattler))
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
|| IsAbilityStatusProtected(gEffectBattler))
break;
if (gBattleMons[gEffectBattler].status1)
break; break;
statusChanged = TRUE; statusChanged = TRUE;
@ -2757,9 +2726,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
break; break;
if (CanPoisonType(gBattleScripting.battler, gEffectBattler)) if (CanPoisonType(gBattleScripting.battler, gEffectBattler))
{ {
if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY if (!CanBePoisoned(gEffectBattler))
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
|| IsAbilityStatusProtected(gEffectBattler))
break; break;
// It's redundant, because at this point we know the status1 value is 0. // It's redundant, because at this point we know the status1 value is 0.
@ -2831,8 +2798,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
switch (gBattleScripting.moveEffect) switch (gBattleScripting.moveEffect)
{ {
case MOVE_EFFECT_CONFUSION: case MOVE_EFFECT_CONFUSION:
if (GetBattlerAbility(gEffectBattler) == ABILITY_OWN_TEMPO if (!CanBeConfused(gEffectBattler))
|| gBattleMons[gEffectBattler].status2 & STATUS2_CONFUSION)
{ {
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
} }
@ -6037,7 +6003,8 @@ static void Cmd_switchineffects(void)
if (!(gBattleMons[gActiveBattler].status1 & STATUS1_ANY) if (!(gBattleMons[gActiveBattler].status1 & STATUS1_ANY)
&& !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL) && !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL)
&& GetBattlerAbility(gActiveBattler) != ABILITY_IMMUNITY && GetBattlerAbility(gActiveBattler) != ABILITY_IMMUNITY
&& !(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SAFEGUARD)) && !(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SAFEGUARD)
&& !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN))
{ {
if (gSideTimers[GetBattlerSide(gActiveBattler)].toxicSpikesAmount >= 2) if (gSideTimers[GetBattlerSide(gActiveBattler)].toxicSpikesAmount >= 2)
gBattleMons[gActiveBattler].status1 |= STATUS1_TOXIC_POISON; gBattleMons[gActiveBattler].status1 |= STATUS1_TOXIC_POISON;
@ -8599,6 +8566,15 @@ static void Cmd_various(void)
BtlController_EmitSpriteInvisibility(0, TRUE); BtlController_EmitSpriteInvisibility(0, TRUE);
MarkBattlerForControllerExec(gActiveBattler); MarkBattlerForControllerExec(gActiveBattler);
break; break;
case VARIOUS_JUMP_IF_TERRAIN_AFFECTED:
{
u32 flags = T1_READ_32(gBattlescriptCurrInstr + 3);
if (IsBattlerTerrainAffected(gActiveBattler, flags))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 7);
else
gBattlescriptCurrInstr += 11;
}
return;
} }
gBattlescriptCurrInstr += 3; gBattlescriptCurrInstr += 3;
@ -8925,6 +8901,14 @@ static void Cmd_trysetrest(void)
{ {
gBattlescriptCurrInstr = failJump; gBattlescriptCurrInstr = failJump;
} }
else if (IsBattlerTerrainAffected(gBattlerTarget, STATUS_FIELD_ELECTRIC_TERRAIN))
{
gBattlescriptCurrInstr = BattleScript_ElectricTerrainPrevents;
}
else if (IsBattlerTerrainAffected(gBattlerTarget, STATUS_FIELD_MISTY_TERRAIN))
{
gBattlescriptCurrInstr = BattleScript_MistyTerrainPrevents;
}
else else
{ {
if (gBattleMons[gBattlerTarget].status1 & ((u8)(~STATUS1_SLEEP))) if (gBattleMons[gBattlerTarget].status1 & ((u8)(~STATUS1_SLEEP)))
@ -11602,6 +11586,18 @@ static void Cmd_setyawn(void)
{ {
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
} }
else if (IsBattlerTerrainAffected(gBattlerTarget, STATUS_FIELD_ELECTRIC_TERRAIN))
{
// When Yawn is used while Electric Terrain is set and drowsiness is set from Yawn being used against target in the previous turn:
// "But it failed" will display first.
gBattlescriptCurrInstr = BattleScript_ElectricTerrainPrevents;
}
else if (IsBattlerTerrainAffected(gBattlerTarget, STATUS_FIELD_MISTY_TERRAIN))
{
// When Yawn is used while Misty Terrain is set and drowsiness is set from Yawn being used against target in the previous turn:
// "But it failed" will display first.
gBattlescriptCurrInstr = BattleScript_MistyTerrainPrevents;
}
else else
{ {
gStatuses3[gBattlerTarget] |= STATUS3_YAWN_TURN(2); gStatuses3[gBattlerTarget] |= STATUS3_YAWN_TURN(2);

View File

@ -2726,11 +2726,24 @@ u8 DoBattlerEndTurnEffects(void)
&& !IsLeafGuardProtected(gActiveBattler)) && !IsLeafGuardProtected(gActiveBattler))
{ {
CancelMultiTurnMoves(gActiveBattler); CancelMultiTurnMoves(gActiveBattler);
gBattleMons[gActiveBattler].status1 |= (Random() & 3) + 2;
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
gEffectBattler = gActiveBattler; gEffectBattler = gActiveBattler;
BattleScriptExecute(BattleScript_YawnMakesAsleep); if (IsBattlerTerrainAffected(gActiveBattler, STATUS_FIELD_ELECTRIC_TERRAIN))
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAINPREVENTS_ELECTRIC;
BattleScriptExecute(BattleScript_TerrainPreventsEnd2);
}
else if (IsBattlerTerrainAffected(gActiveBattler, STATUS_FIELD_MISTY_TERRAIN))
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAINPREVENTS_MISTY;
BattleScriptExecute(BattleScript_TerrainPreventsEnd2);
}
else
{
gBattleMons[gActiveBattler].status1 |= (Random() & 3) + 2;
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
BattleScriptExecute(BattleScript_YawnMakesAsleep);
}
effect++; effect++;
} }
} }
@ -4800,10 +4813,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
&& gBattleMons[gBattlerAttacker].hp != 0 && gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg && !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED && TARGET_TURN_DAMAGED
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_INSOMNIA && CanSleep(gBattlerAttacker)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_VITAL_SPIRIT
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY)
&& !IsAbilityStatusProtected(gBattlerAttacker)
&& IsMoveMakingContact(move, gBattlerAttacker) && IsMoveMakingContact(move, gBattlerAttacker)
&& (Random() % 3) == 0) && (Random() % 3) == 0)
{ {
@ -4822,11 +4832,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
&& gBattleMons[gBattlerAttacker].hp != 0 && gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg && !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED && TARGET_TURN_DAMAGED
&& !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_POISON) && CanBePoisoned(gBattlerAttacker)
&& !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_STEEL)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_IMMUNITY
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY)
&& !IsAbilityStatusProtected(gBattlerAttacker)
&& IsMoveMakingContact(move, gBattlerAttacker) && IsMoveMakingContact(move, gBattlerAttacker)
&& (Random() % 3) == 0) && (Random() % 3) == 0)
{ {
@ -4844,10 +4850,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
&& gBattleMons[gBattlerAttacker].hp != 0 && gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg && !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED && TARGET_TURN_DAMAGED
&& CanParalyzeType(gBattlerTarget, gBattlerAttacker) && CanBeParalyzed(gBattlerAttacker)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_LIMBER
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY)
&& !IsAbilityStatusProtected(gBattlerAttacker)
&& IsMoveMakingContact(move, gBattlerAttacker) && IsMoveMakingContact(move, gBattlerAttacker)
&& (Random() % 3) == 0) && (Random() % 3) == 0)
{ {
@ -4864,11 +4867,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg && !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
&& TARGET_TURN_DAMAGED && TARGET_TURN_DAMAGED
&& !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE) && CanBeBurned(gBattlerAttacker)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_WATER_VEIL
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_WATER_BUBBLE
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY)
&& !IsAbilityStatusProtected(gBattlerAttacker)
&& (Random() % 3) == 0) && (Random() % 3) == 0)
{ {
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_BURN; gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_BURN;
@ -4976,11 +4975,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& gBattleMons[gBattlerTarget].hp != 0 && gBattleMons[gBattlerTarget].hp != 0
&& !gProtectStructs[gBattlerTarget].confusionSelfDmg && !gProtectStructs[gBattlerTarget].confusionSelfDmg
&& !IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_POISON) && CanBePoisoned(gBattlerTarget)
&& !IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_STEEL)
&& GetBattlerAbility(gBattlerTarget) != ABILITY_IMMUNITY
&& !(gBattleMons[gBattlerTarget].status1 & STATUS1_ANY)
&& !IsAbilityStatusProtected(gBattlerTarget)
&& IsMoveMakingContact(move, gBattlerAttacker) && IsMoveMakingContact(move, gBattlerAttacker)
&& (Random() % 3) == 0) && (Random() % 3) == 0)
{ {
@ -5383,6 +5378,100 @@ enum
ITEM_STATS_CHANGE, // 5 ITEM_STATS_CHANGE, // 5
}; };
bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag)
{
if (!(gFieldStatuses & terrainFlag))
return FALSE;
else if (gStatuses3[battlerId] & STATUS3_SEMI_INVULNERABLE)
return FALSE;
return IsBattlerGrounded(battlerId);
}
bool32 CanSleep(u8 battlerId)
{
u16 ability = GetBattlerAbility(battlerId);
if (ability == ABILITY_INSOMNIA
|| ability == ABILITY_VITAL_SPIRIT
|| ability == ABILITY_COMATOSE
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_SAFEGUARD
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| IsAbilityOnSide(battlerId, ABILITY_SWEET_VEIL)
|| IsAbilityStatusProtected(battlerId)
|| IsBattlerTerrainAffected(battlerId, STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_MISTY_TERRAIN))
return FALSE;
return TRUE;
}
bool32 CanBePoisoned(u8 battlerId)
{
u16 ability = GetBattlerAbility(battlerId);
if (IS_BATTLER_OF_TYPE(battlerId, TYPE_POISON)
|| IS_BATTLER_OF_TYPE(battlerId, TYPE_STEEL)
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_SAFEGUARD
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| ability == ABILITY_IMMUNITY
|| ability == ABILITY_COMATOSE
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battlerId)
|| IsBattlerTerrainAffected(battlerId, STATUS_FIELD_MISTY_TERRAIN))
return FALSE;
return TRUE;
}
bool32 CanBeBurned(u8 battlerId)
{
u16 ability = GetBattlerAbility(battlerId);
if (IS_BATTLER_OF_TYPE(battlerId, TYPE_FIRE)
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_SAFEGUARD
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| ability == ABILITY_WATER_VEIL
|| ability == ABILITY_WATER_BUBBLE
|| ability == ABILITY_COMATOSE
|| IsAbilityStatusProtected(battlerId)
|| IsBattlerTerrainAffected(battlerId, STATUS_FIELD_MISTY_TERRAIN))
return FALSE;
return TRUE;
}
bool32 CanBeParalyzed(u8 battlerId)
{
u16 ability = GetBattlerAbility(battlerId);
if ((B_PARALYZE_ELECTRIC >= GEN_6 && IS_BATTLER_OF_TYPE(battlerId, TYPE_ELECTRIC))
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_SAFEGUARD
|| ability == ABILITY_LIMBER
|| ability == ABILITY_COMATOSE
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battlerId)
|| IsBattlerTerrainAffected(battlerId, STATUS_FIELD_MISTY_TERRAIN))
return FALSE;
return TRUE;
}
bool32 CanBeFrozen(u8 battlerId)
{
u16 ability = GetBattlerAbility(battlerId);
if (IS_BATTLER_OF_TYPE(battlerId, TYPE_ICE)
|| (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY)
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_SAFEGUARD
|| ability == ABILITY_MAGMA_ARMOR
|| ability == ABILITY_COMATOSE
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battlerId)
|| IsBattlerTerrainAffected(battlerId, STATUS_FIELD_MISTY_TERRAIN))
return FALSE;
return TRUE;
}
bool32 CanBeConfused(u8 battlerId)
{
if (GetBattlerAbility(gEffectBattler) == ABILITY_OWN_TEMPO
|| gBattleMons[gEffectBattler].status2 & STATUS2_CONFUSION
|| IsBattlerTerrainAffected(battlerId, STATUS_FIELD_MISTY_TERRAIN))
return FALSE;
return TRUE;
}
// second argument is 1/X of current hp compared to max hp // second argument is 1/X of current hp compared to max hp
bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId) bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId)
{ {
@ -6901,7 +6990,7 @@ u8 IsMonDisobedient(void)
obedienceLevel = gBattleMons[gBattlerAttacker].level - obedienceLevel; obedienceLevel = gBattleMons[gBattlerAttacker].level - obedienceLevel;
calc = (Random() & 255); calc = (Random() & 255);
if (calc < obedienceLevel && !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY) && gBattleMons[gBattlerAttacker].ability != ABILITY_VITAL_SPIRIT && gBattleMons[gBattlerAttacker].ability != ABILITY_INSOMNIA) if (calc < obedienceLevel && CanSleep(gBattlerAttacker))
{ {
// try putting asleep // try putting asleep
int i; int i;