electric and misty terrain preventions

This commit is contained in:
Evan 2021-01-16 11:40:02 -07:00
parent bd8950e8a0
commit 9e29d303ec
4 changed files with 111 additions and 64 deletions

View file

@ -2134,6 +2134,8 @@ BattleScript_EffectSleep::
jumpifleafguard BattleScript_LeafGuardProtects
jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_ELECTRIC_TERRAIN, BattleScript_ElectricTerrainPrevents
jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected
attackanimation
@ -2141,6 +2143,20 @@ BattleScript_EffectSleep::
setmoveeffect MOVE_EFFECT_SLEEP
seteffectprimary
goto BattleScript_MoveEnd
BattleScript_ElectricTerrainPrevents:
pause 0x20
printstring STRINGID_ELECTRICTERRAINPREVENTS
waitmessage 0x40
orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_MistyTerrainPrevents:
pause 0x20
printstring STRINGID_MISTYTERRAINPREVENTS
waitmessage 0x40
orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_FlowerVeilProtectsRet::
pause 0x20
@ -2654,6 +2670,7 @@ BattleScript_EffectToxic::
jumpifsubstituteblocks BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_POISON | STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
trypoisontype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected
@ -2704,6 +2721,7 @@ BattleScript_EffectRest::
attackcanceler
attackstring
ppreduce
jumpifword CMP_COMMON_BITS, gFieldStatuses, (STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_MISTY_TERRAIN), BattleScript_ButItFailed
jumpifstatus BS_ATTACKER, STATUS1_SLEEP, BattleScript_RestIsAlreadyAsleep
jumpifability BS_ATTACKER, ABILITY_COMATOSE, BattleScript_RestIsAlreadyAsleep
jumpifcantmakeasleep BattleScript_RestCantSleep
@ -2994,6 +3012,7 @@ BattleScript_EffectPoison::
jumpifstatus BS_TARGET, STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned
trypoisontype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected
attackanimation
@ -3019,6 +3038,7 @@ BattleScript_EffectParalyze:
jumpifstatus BS_TARGET, STATUS1_PARALYSIS, BattleScript_AlreadyParalyzed
tryparalyzetype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected
bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
@ -4317,6 +4337,7 @@ BattleScript_EffectWillOWisp::
jumpifleafguard BattleScript_LeafGuardProtects
jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected
attackanimation

View file

@ -130,5 +130,10 @@ void ClearIllusionMon(u32 battlerId);
bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId);
bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battlerId);
u8 GetBattleMoveSplit(u32 moveId);
bool32 CanSleep(u8 battlerId);
bool32 CanBePoisoned(u8 battlerId);
bool32 CanBeBurned(u8 battlerId);
bool32 CanBeParalyzed(u8 battlerId);
bool32 CanBeFrozen(u8 battlerId);
#endif // GUARD_BATTLE_UTIL_H

View file

@ -2386,8 +2386,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
{
s32 i, byTwo, affectsUser = 0;
bool32 statusChanged = FALSE;
bool32 noSunCanFreeze = TRUE;
switch (gBattleScripting.moveEffect) // Set move effects which happen later on
{
case MOVE_EFFECT_KNOCK_OFF:
@ -2448,15 +2447,9 @@ void SetMoveEffect(bool32 primary, u32 certain)
else
gActiveBattler = gBattlersCount;
if (gBattleMons[gEffectBattler].status1)
break;
if (gActiveBattler != gBattlersCount)
break;
if (GetBattlerAbility(gEffectBattler) == ABILITY_VITAL_SPIRIT
|| GetBattlerAbility(gEffectBattler) == ABILITY_INSOMNIA
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
|| IsAbilityOnSide(gEffectBattler, ABILITY_SWEET_VEIL)
|| IsAbilityStatusProtected(gEffectBattler))
if (!CanSleep(gEffectBattler))
break;
CancelMultiTurnMoves(gEffectBattler);
@ -2495,11 +2488,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
}
if (!CanPoisonType(gBattleScripting.battler, gEffectBattler))
break;
if (gBattleMons[gEffectBattler].status1)
break;
if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
|| IsAbilityStatusProtected(gEffectBattler))
if (!CanBePoisoned(gEffectBattler))
break;
statusChanged = TRUE;
@ -2534,29 +2523,14 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
RESET_RETURN
}
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_FIRE))
break;
if (GetBattlerAbility(gEffectBattler) == ABILITY_WATER_VEIL
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
|| IsAbilityStatusProtected(gEffectBattler))
break;
if (gBattleMons[gEffectBattler].status1)
if (!CanBeBurned(gEffectBattler))
break;
statusChanged = TRUE;
break;
case STATUS1_FREEZE:
if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY)
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))
if (!CanBeFrozen(gEffectBattler))
break;
CancelMultiTurnMoves(gEffectBattler);
@ -2599,11 +2573,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
}
if (!CanParalyzeType(gBattleScripting.battler, gEffectBattler))
break;
if (GetBattlerAbility(gEffectBattler) == ABILITY_LIMBER
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
|| IsAbilityStatusProtected(gEffectBattler))
break;
if (gBattleMons[gEffectBattler].status1)
if (!CanBeParalyzed(gEffectBattler))
break;
statusChanged = TRUE;
@ -2642,9 +2612,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
break;
if (CanPoisonType(gBattleScripting.battler, gEffectBattler))
{
if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
|| IsAbilityStatusProtected(gEffectBattler))
if (!CanBePoisoned(gEffectBattler))
break;
// It's redundant, because at this point we know the status1 value is 0.

View file

@ -2500,7 +2500,8 @@ u8 DoBattlerEndTurnEffects(void)
if (!(gStatuses3[gActiveBattler] & STATUS3_YAWN) && !(gBattleMons[gActiveBattler].status1 & STATUS1_ANY)
&& gBattleMons[gActiveBattler].ability != ABILITY_VITAL_SPIRIT
&& gBattleMons[gActiveBattler].ability != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler)
&& !IsLeafGuardProtected(gActiveBattler))
&& !IsLeafGuardProtected(gActiveBattler)
&& !(gFieldStatuses & (STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_MISTY_TERRAIN)))
{
CancelMultiTurnMoves(gActiveBattler);
gBattleMons[gActiveBattler].status1 |= (Random() & 3) + 2;
@ -4523,10 +4524,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
&& gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_INSOMNIA
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_VITAL_SPIRIT
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY)
&& !IsAbilityStatusProtected(gBattlerAttacker)
&& CanSleep(gBattlerAttacker)
&& IsMoveMakingContact(move, gBattlerAttacker)
&& (Random() % 3) == 0)
{
@ -4545,11 +4543,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
&& gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_POISON)
&& !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_STEEL)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_IMMUNITY
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY)
&& !IsAbilityStatusProtected(gBattlerAttacker)
&& CanBePoisoned(gBattlerAttacker)
&& IsMoveMakingContact(move, gBattlerAttacker)
&& (Random() % 3) == 0)
{
@ -4567,10 +4561,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
&& gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& CanParalyzeType(gBattlerTarget, gBattlerAttacker)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_LIMBER
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY)
&& !IsAbilityStatusProtected(gBattlerAttacker)
&& CanBeParalyzed(gBattlerAttacker)
&& IsMoveMakingContact(move, gBattlerAttacker)
&& (Random() % 3) == 0)
{
@ -4587,10 +4578,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
&& TARGET_TURN_DAMAGED
&& !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_WATER_VEIL
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY)
&& !IsAbilityStatusProtected(gBattlerAttacker)
&& CanBeBurned(gBattlerAttacker)
&& (Random() % 3) == 0)
{
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_BURN;
@ -4698,11 +4686,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& gBattleMons[gBattlerTarget].hp != 0
&& !gProtectStructs[gBattlerTarget].confusionSelfDmg
&& !IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_POISON)
&& !IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_STEEL)
&& GetBattlerAbility(gBattlerTarget) != ABILITY_IMMUNITY
&& !(gBattleMons[gBattlerTarget].status1 & STATUS1_ANY)
&& !IsAbilityStatusProtected(gBattlerTarget)
&& CanBePoisoned(gBattlerTarget)
&& IsMoveMakingContact(move, gBattlerAttacker)
&& (Random() % 3) == 0)
{
@ -5075,6 +5059,75 @@ enum
ITEM_STATS_CHANGE, // 5
};
bool32 CanSleep(u8 battlerId)
{
u16 ability = GetBattlerAbility(battlerId);
if (ability == ABILITY_INSOMNIA
|| ability == ABILITY_VITAL_SPIRIT
|| ability == ABILITY_COMATOSE
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| IsAbilityOnSide(battlerId, ABILITY_SWEET_VEIL)
|| IsAbilityStatusProtected(battlerId)
|| gFieldStatuses & (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)
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| ability == ABILITY_IMMUNITY
|| ability == ABILITY_COMATOSE
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battlerId)
|| gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)
return FALSE;
return TRUE;
}
bool32 CanBeBurned(u8 battlerId)
{
u16 ability = GetBattlerAbility(battlerId);
if (IS_BATTLER_OF_TYPE(battlerId, TYPE_FIRE)
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| ability == ABILITY_WATER_VEIL
|| ability == ABILITY_COMATOSE
|| IsAbilityStatusProtected(battlerId)
|| gFieldStatuses & 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))
|| ability == ABILITY_LIMBER
|| ability == ABILITY_COMATOSE
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battlerId)
|| gFieldStatuses & 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)
|| ability == ABILITY_MAGMA_ARMOR
|| ability == ABILITY_COMATOSE
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battlerId)
|| gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)
return FALSE;
return TRUE;
}
// second argument is 1/X of current hp compared to max hp
static bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId)
{
@ -6207,7 +6260,7 @@ u8 IsMonDisobedient(void)
obedienceLevel = gBattleMons[gBattlerAttacker].level - obedienceLevel;
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
int i;