Optimized use of GetBattlerAbility

This commit is contained in:
Eduardo Quezada D'Ottone 2022-01-22 20:25:51 -03:00
parent 88d4b188cc
commit b7df21b263
3 changed files with 114 additions and 74 deletions

View file

@ -4468,15 +4468,16 @@ s8 GetChosenMovePriority(u32 battlerId)
s8 GetMovePriority(u32 battlerId, u16 move)
{
s8 priority;
u16 ability = GetBattlerAbility(battlerId);
priority = gBattleMoves[move].priority;
if (GetBattlerAbility(battlerId) == ABILITY_GALE_WINGS
if (ability == ABILITY_GALE_WINGS
&& gBattleMoves[move].type == TYPE_FLYING
&& (B_GALE_WINGS <= GEN_6 || BATTLER_MAX_HP(battlerId)))
{
priority++;
}
else if (GetBattlerAbility(battlerId) == ABILITY_PRANKSTER && IS_MOVE_STATUS(move))
else if (ability == ABILITY_PRANKSTER && IS_MOVE_STATUS(move))
{
gProtectStructs[battlerId].pranksterElevated = 1;
priority++;
@ -4485,7 +4486,7 @@ s8 GetMovePriority(u32 battlerId, u16 move)
{
priority++;
}
else if (GetBattlerAbility(battlerId) == ABILITY_TRIAGE)
else if (ability == ABILITY_TRIAGE)
{
switch (gBattleMoves[move].effect)
{
@ -4515,12 +4516,13 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
u32 speedBattler1 = 0, speedBattler2 = 0;
u32 holdEffectBattler1 = 0, holdEffectBattler2 = 0;
s8 priority1 = 0, priority2 = 0;
u16 ability1 = GetBattlerAbility(battler1), ability2 = GetBattlerAbility(battler2);
// Battler 1
speedBattler1 = GetBattlerTotalSpeedStat(battler1);
holdEffectBattler1 = GetBattlerHoldEffect(battler1, TRUE);
// Quick Draw
if (!ignoreChosenMoves && GetBattlerAbility(battler1) == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && Random() % 100 < 30)
if (!ignoreChosenMoves && ability1 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && Random() % 100 < 30)
gProtectStructs[battler1].quickDraw = TRUE;
// Quick Claw and Custap Berry
if (!gProtectStructs[battler1].quickDraw
@ -4534,7 +4536,7 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
speedBattler2 = GetBattlerTotalSpeedStat(battler2);
holdEffectBattler2 = GetBattlerHoldEffect(battler2, TRUE);
// Quick Draw
if (!ignoreChosenMoves && GetBattlerAbility(battler2) == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && Random() % 100 < 30)
if (!ignoreChosenMoves && ability2 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && Random() % 100 < 30)
gProtectStructs[battler2].quickDraw = TRUE;
// Quick Claw and Custap Berry
if (!gProtectStructs[battler2].quickDraw
@ -4570,9 +4572,9 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
strikesFirst = 1;
else if (holdEffectBattler2 == HOLD_EFFECT_LAGGING_TAIL && holdEffectBattler1 != HOLD_EFFECT_LAGGING_TAIL)
strikesFirst = 0;
else if (GetBattlerAbility(battler1) == ABILITY_STALL && GetBattlerAbility(battler2) != ABILITY_STALL)
else if (ability1 == ABILITY_STALL && ability2 != ABILITY_STALL)
strikesFirst = 1;
else if (GetBattlerAbility(battler2) == ABILITY_STALL && GetBattlerAbility(battler1) != ABILITY_STALL)
else if (ability2 == ABILITY_STALL && ability1 != ABILITY_STALL)
strikesFirst = 0;
else
{

View file

@ -1353,6 +1353,7 @@ static bool32 TryAegiFormChange(void)
static void Cmd_attackcanceler(void)
{
s32 i, moveType;
u16 attackerAbility = GetBattlerAbility(gBattlerAttacker);
GET_MOVE_TYPE(gCurrentMove, moveType);
@ -1395,7 +1396,7 @@ static void Cmd_attackcanceler(void)
return;
// Check Protean activation.
if ((GetBattlerAbility(gBattlerAttacker) == ABILITY_PROTEAN || GetBattlerAbility(gBattlerAttacker) == ABILITY_LIBERO)
if ((attackerAbility == ABILITY_PROTEAN || attackerAbility == ABILITY_LIBERO)
&& (gBattleMons[gBattlerAttacker].type1 != moveType || gBattleMons[gBattlerAttacker].type2 != moveType ||
(gBattleMons[gBattlerAttacker].type3 != moveType && gBattleMons[gBattlerAttacker].type3 != TYPE_MYSTERY))
&& gCurrentMove != MOVE_STRUGGLE)
@ -2616,6 +2617,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
bool32 statusChanged = FALSE;
bool32 mirrorArmorReflected = (GetBattlerAbility(gBattlerTarget) == ABILITY_MIRROR_ARMOR);
u32 flags = 0;
u16 battlerAbility;
switch (gBattleScripting.moveEffect) // Set move effects which happen later on
{
@ -2638,10 +2640,12 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattleScripting.battler = gBattlerAttacker;
}
battlerAbility = GetBattlerAbility(gEffectBattler);
// Just in case this flag is still set
gBattleScripting.moveEffect &= ~MOVE_EFFECT_CERTAIN;
if (GetBattlerAbility(gEffectBattler) == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
if (battlerAbility == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
&& !primary && gBattleScripting.moveEffect <= 9)
INCREMENT_RESET_RETURN
@ -2666,7 +2670,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
{
case STATUS1_SLEEP:
// check active uproar
if (GetBattlerAbility(gEffectBattler) != ABILITY_SOUNDPROOF)
if (battlerAbility != ABILITY_SOUNDPROOF)
{
for (gActiveBattler = 0;
gActiveBattler < gBattlersCount && !(gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR);
@ -2685,7 +2689,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
statusChanged = TRUE;
break;
case STATUS1_POISON:
if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY
if (battlerAbility == ABILITY_IMMUNITY
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{
gLastUsedAbility = ABILITY_IMMUNITY;
@ -2724,11 +2728,11 @@ void SetMoveEffect(bool32 primary, u32 certain)
if (gCurrentMove == MOVE_BURNING_JEALOUSY && !gProtectStructs[gEffectBattler].statRaised)
break;
if ((GetBattlerAbility(gEffectBattler) == ABILITY_WATER_VEIL || GetBattlerAbility(gEffectBattler) == ABILITY_WATER_BUBBLE)
if ((battlerAbility == ABILITY_WATER_VEIL || battlerAbility == ABILITY_WATER_BUBBLE)
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{
gLastUsedAbility = GetBattlerAbility(gEffectBattler);
RecordAbilityBattle(gEffectBattler, GetBattlerAbility(gEffectBattler));
gLastUsedAbility = battlerAbility;
RecordAbilityBattle(gEffectBattler, battlerAbility);
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_BRNPrevention;
@ -2767,7 +2771,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
statusChanged = TRUE;
break;
case STATUS1_PARALYSIS:
if (GetBattlerAbility(gEffectBattler) == ABILITY_LIMBER)
if (battlerAbility == ABILITY_LIMBER)
{
if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)
{
@ -2809,7 +2813,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
statusChanged = TRUE;
break;
case STATUS1_TOXIC_POISON:
if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
if (battlerAbility == ABILITY_IMMUNITY && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{
gLastUsedAbility = ABILITY_IMMUNITY;
RecordAbilityBattle(gEffectBattler, ABILITY_IMMUNITY);
@ -2935,7 +2939,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
}
break;
case MOVE_EFFECT_FLINCH:
if (GetBattlerAbility(gEffectBattler) == ABILITY_INNER_FOCUS)
if (battlerAbility == ABILITY_INNER_FOCUS)
{
gBattlescriptCurrInstr++;
}
@ -3442,7 +3446,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
break;
case MOVE_EFFECT_BUG_BITE:
if (ItemId_GetPocket(gBattleMons[gEffectBattler].item) == POCKET_BERRIES
&& GetBattlerAbility(gEffectBattler) != ABILITY_STICKY_HOLD)
&& battlerAbility != ABILITY_STICKY_HOLD)
{
// target loses their berry
gLastUsedItem = gBattleMons[gEffectBattler].item;
@ -8059,9 +8063,12 @@ static void Cmd_various(void)
MarkBattlerForControllerExec(gActiveBattler);
break;
case VARIOUS_TRY_ACTIVATE_MOXIE: // and chilling neigh + as one ice rider
if ((GetBattlerAbility(gActiveBattler) == ABILITY_MOXIE
|| GetBattlerAbility(gActiveBattler) == ABILITY_CHILLING_NEIGH
|| GetBattlerAbility(gActiveBattler) == ABILITY_AS_ONE_ICE_RIDER)
{
u16 battlerAbility = GetBattlerAbility(gActiveBattler);
if ((battlerAbility == ABILITY_MOXIE
|| battlerAbility == ABILITY_CHILLING_NEIGH
|| battlerAbility == ABILITY_AS_ONE_ICE_RIDER)
&& HasAttackerFaintedTarget()
&& !NoAliveMonsForEitherParty()
&& CompareStat(gBattlerAttacker, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
@ -8070,16 +8077,20 @@ static void Cmd_various(void)
SET_STATCHANGER(STAT_ATK, 1, FALSE);
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK);
BattleScriptPush(gBattlescriptCurrInstr + 3);
gLastUsedAbility = GetBattlerAbility(gActiveBattler);
if (GetBattlerAbility(gActiveBattler) == ABILITY_AS_ONE_ICE_RIDER)
gLastUsedAbility = battlerAbility;
if (battlerAbility == ABILITY_AS_ONE_ICE_RIDER)
gBattleScripting.abilityPopupOverwrite = gLastUsedAbility = ABILITY_CHILLING_NEIGH;
gBattlescriptCurrInstr = BattleScript_RaiseStatOnFaintingTarget;
return;
}
}
break;
case VARIOUS_TRY_ACTIVATE_GRIM_NEIGH: // and as one shadow rider
if ((GetBattlerAbility(gActiveBattler) == ABILITY_GRIM_NEIGH
|| GetBattlerAbility(gActiveBattler) == ABILITY_AS_ONE_SHADOW_RIDER)
{
u16 battlerAbility = GetBattlerAbility(gActiveBattler);
if ((battlerAbility == ABILITY_GRIM_NEIGH
|| battlerAbility == ABILITY_AS_ONE_SHADOW_RIDER)
&& HasAttackerFaintedTarget()
&& !NoAliveMonsForEitherParty()
&& CompareStat(gBattlerAttacker, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN))
@ -8088,12 +8099,13 @@ static void Cmd_various(void)
SET_STATCHANGER(STAT_SPATK, 1, FALSE);
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK);
BattleScriptPush(gBattlescriptCurrInstr + 3);
gLastUsedAbility = GetBattlerAbility(gActiveBattler);
if (GetBattlerAbility(gActiveBattler) == ABILITY_AS_ONE_SHADOW_RIDER)
gLastUsedAbility = battlerAbility;
if (battlerAbility == ABILITY_AS_ONE_SHADOW_RIDER)
gBattleScripting.abilityPopupOverwrite = gLastUsedAbility = ABILITY_GRIM_NEIGH;
gBattlescriptCurrInstr = BattleScript_RaiseStatOnFaintingTarget;
return;
}
}
break;
case VARIOUS_TRY_ACTIVATE_RECEIVER: // Partner gets fainted's ally ability
gBattlerAbility = BATTLE_PARTNER(gActiveBattler);
@ -8644,10 +8656,12 @@ static void Cmd_various(void)
gBattlescriptCurrInstr += 4;
return;
case VARIOUS_PSYCHO_SHIFT:
{
u16 targetAbility = GetBattlerAbility(gBattlerTarget);
i = TRUE;
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS)
{
if (GetBattlerAbility(gBattlerTarget) == ABILITY_LIMBER)
if (targetAbility == ABILITY_LIMBER)
{
gBattlerAbility = gBattlerTarget;
BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
@ -8667,7 +8681,7 @@ static void Cmd_various(void)
}
else if (gBattleMons[gBattlerAttacker].status1 & STATUS1_PSN_ANY)
{
if (GetBattlerAbility(gBattlerTarget) == ABILITY_IMMUNITY)
if (targetAbility == ABILITY_IMMUNITY)
{
gBattlerAbility = gBattlerTarget;
BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
@ -8690,8 +8704,8 @@ static void Cmd_various(void)
}
else if (gBattleMons[gBattlerAttacker].status1 & STATUS1_BURN)
{
if (GetBattlerAbility(gBattlerTarget) == ABILITY_WATER_VEIL
|| GetBattlerAbility(gBattlerTarget) == ABILITY_WATER_BUBBLE)
if (targetAbility == ABILITY_WATER_VEIL
|| targetAbility == ABILITY_WATER_BUBBLE)
{
gBattlerAbility = gBattlerTarget;
BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
@ -8711,7 +8725,7 @@ static void Cmd_various(void)
}
else if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
{
if (GetBattlerAbility(gBattlerTarget) == ABILITY_INSOMNIA || GetBattlerAbility(gBattlerTarget) == ABILITY_VITAL_SPIRIT)
if (targetAbility == ABILITY_INSOMNIA || targetAbility == ABILITY_VITAL_SPIRIT)
{
gBattlerAbility = gBattlerTarget;
// BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
@ -8732,6 +8746,7 @@ static void Cmd_various(void)
MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 7;
}
}
return;
case VARIOUS_CURE_STATUS:
gBattleMons[gActiveBattler].status1 = 0;
@ -10054,11 +10069,14 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
bool32 notProtectAffected = FALSE;
u32 index;
bool32 affectsUser = (flags & MOVE_EFFECT_AFFECTS_USER);
u16 activeBattlerAbility;
if (affectsUser)
gActiveBattler = gBattlerAttacker;
else
gActiveBattler = gBattlerTarget;
activeBattlerAbility = GetBattlerAbility(gActiveBattler);
gSpecialStatuses[gActiveBattler].changedStatsBattlerId = gBattlerAttacker;
@ -10072,7 +10090,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
notProtectAffected++;
flags &= ~STAT_BUFF_NOT_PROTECT_AFFECTED;
if (GetBattlerAbility(gActiveBattler) == ABILITY_CONTRARY)
if (activeBattlerAbility == ABILITY_CONTRARY)
{
statValue ^= STAT_BUFF_NEGATIVE;
gBattleScripting.statChanger ^= STAT_BUFF_NEGATIVE;
@ -10082,7 +10100,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
gBattleScripting.moveEffect = ReverseStatChangeMoveEffect(gBattleScripting.moveEffect);
}
}
else if (GetBattlerAbility(gActiveBattler) == ABILITY_SIMPLE)
else if (activeBattlerAbility == ABILITY_SIMPLE)
{
statValue = (SET_STAT_BUFF_VALUE(GET_STAT_BUFF_VALUE(statValue) * 2)) | ((statValue <= -1) ? STAT_BUFF_NEGATIVE : 0);
}
@ -10117,9 +10135,9 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
gBattlescriptCurrInstr = BattleScript_ButItFailed;
return STAT_CHANGE_DIDNT_WORK;
}
else if ((GetBattlerAbility(gActiveBattler) == ABILITY_CLEAR_BODY
|| GetBattlerAbility(gActiveBattler) == ABILITY_FULL_METAL_BODY
|| GetBattlerAbility(gActiveBattler) == ABILITY_WHITE_SMOKE)
else if ((activeBattlerAbility == ABILITY_CLEAR_BODY
|| activeBattlerAbility == ABILITY_FULL_METAL_BODY
|| activeBattlerAbility == ABILITY_WHITE_SMOKE)
&& !certain && gCurrentMove != MOVE_CURSE)
{
if (flags == STAT_BUFF_ALLOW_PTR)
@ -10134,7 +10152,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
gBattleScripting.battler = gActiveBattler;
gBattlerAbility = gActiveBattler;
gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss;
gLastUsedAbility = GetBattlerAbility(gActiveBattler);
gLastUsedAbility = activeBattlerAbility;
RecordAbilityBattle(gActiveBattler, gLastUsedAbility);
gSpecialStatuses[gActiveBattler].statLowered = TRUE;
}
@ -10162,9 +10180,9 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
return STAT_CHANGE_DIDNT_WORK;
}
else if (!certain
&& ((GetBattlerAbility(gActiveBattler) == ABILITY_KEEN_EYE && statId == STAT_ACC)
|| (GetBattlerAbility(gActiveBattler) == ABILITY_HYPER_CUTTER && statId == STAT_ATK)
|| (GetBattlerAbility(gActiveBattler) == ABILITY_BIG_PECKS && statId == STAT_DEF)))
&& ((activeBattlerAbility == ABILITY_KEEN_EYE && statId == STAT_ACC)
|| (activeBattlerAbility == ABILITY_HYPER_CUTTER && statId == STAT_ATK)
|| (activeBattlerAbility == ABILITY_BIG_PECKS && statId == STAT_DEF)))
{
if (flags == STAT_BUFF_ALLOW_PTR)
{
@ -10172,12 +10190,12 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
gBattleScripting.battler = gActiveBattler;
gBattlerAbility = gActiveBattler;
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss;
gLastUsedAbility = GetBattlerAbility(gActiveBattler);
gLastUsedAbility = activeBattlerAbility;
RecordAbilityBattle(gActiveBattler, gLastUsedAbility);
}
return STAT_CHANGE_DIDNT_WORK;
}
else if (GetBattlerAbility(gActiveBattler) == ABILITY_MIRROR_ARMOR && !affectsUser && gBattlerAttacker != gBattlerTarget && gActiveBattler == gBattlerTarget)
else if (activeBattlerAbility == ABILITY_MIRROR_ARMOR && !affectsUser && gBattlerAttacker != gBattlerTarget && gActiveBattler == gBattlerTarget)
{
if (flags == STAT_BUFF_ALLOW_PTR)
{
@ -10190,7 +10208,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
}
return STAT_CHANGE_DIDNT_WORK;
}
else if (GetBattlerAbility(gActiveBattler) == ABILITY_SHIELD_DUST && flags == 0)
else if (activeBattlerAbility == ABILITY_SHIELD_DUST && flags == 0)
{
return STAT_CHANGE_DIDNT_WORK;
}
@ -10724,6 +10742,7 @@ static void Cmd_tryKO(void)
{
bool32 lands = FALSE;
u32 holdEffect = GetBattlerHoldEffect(gBattlerTarget, TRUE);
u16 targetAbility = GetBattlerAbility(gBattlerTarget);
gPotentialItemEffectBattler = gBattlerTarget;
if (holdEffect == HOLD_EFFECT_FOCUS_BAND
@ -10738,7 +10757,7 @@ static void Cmd_tryKO(void)
RecordItemEffectBattle(gBattlerTarget, holdEffect);
}
if (GetBattlerAbility(gBattlerTarget) == ABILITY_STURDY)
if (targetAbility == ABILITY_STURDY)
{
gMoveResultFlags |= MOVE_RESULT_MISSED;
gLastUsedAbility = ABILITY_STURDY;
@ -10750,7 +10769,7 @@ static void Cmd_tryKO(void)
if ((((gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS)
&& gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker)
|| GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD
|| GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD)
|| targetAbility == ABILITY_NO_GUARD)
&& gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
{
lands = TRUE;

View file

@ -386,11 +386,14 @@ void HandleAction_UseMove(void)
}
else
{
u16 battlerAbility;
gActiveBattler = gBattlerByTurnOrder[var];
battlerAbility = GetBattlerAbility(gActiveBattler);
RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability);
if (GetBattlerAbility(gActiveBattler) == ABILITY_LIGHTNING_ROD)
if (battlerAbility == ABILITY_LIGHTNING_ROD)
gSpecialStatuses[gActiveBattler].lightningRodRedirected = TRUE;
else if (GetBattlerAbility(gActiveBattler) == ABILITY_STORM_DRAIN)
else if (battlerAbility == ABILITY_STORM_DRAIN)
gSpecialStatuses[gActiveBattler].stormDrainRedirected = TRUE;
gBattlerTarget = gActiveBattler;
}
@ -1544,6 +1547,8 @@ bool8 WasUnableToUseMove(u8 battler)
void PrepareStringBattle(u16 stringId, u8 battler)
{
u16 battlerAbility = GetBattlerAbility(battler);
u16 targetAbility = GetBattlerAbility(gBattlerTarget);
// Support for Contrary ability.
// If a move attempted to raise stat - print "won't increase".
// If a move attempted to lower stat - print "won't decrease".
@ -1552,22 +1557,22 @@ void PrepareStringBattle(u16 stringId, u8 battler)
else if (stringId == STRINGID_STATSWONTINCREASE && gBattleScripting.statChanger & STAT_BUFF_NEGATIVE)
stringId = STRINGID_STATSWONTDECREASE;
else if (stringId == STRINGID_STATSWONTDECREASE2 && GetBattlerAbility(battler) == ABILITY_CONTRARY)
else if (stringId == STRINGID_STATSWONTDECREASE2 && battlerAbility == ABILITY_CONTRARY)
stringId = STRINGID_STATSWONTINCREASE2;
else if (stringId == STRINGID_STATSWONTINCREASE2 && GetBattlerAbility(battler) == ABILITY_CONTRARY)
else if (stringId == STRINGID_STATSWONTINCREASE2 && battlerAbility == ABILITY_CONTRARY)
stringId = STRINGID_STATSWONTDECREASE2;
// Check Defiant and Competitive stat raise whenever a stat is lowered.
else if ((stringId == STRINGID_DEFENDERSSTATFELL || stringId == STRINGID_PKMNCUTSATTACKWITH)
&& ((GetBattlerAbility(gBattlerTarget) == ABILITY_DEFIANT && CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|| (GetBattlerAbility(gBattlerTarget) == ABILITY_COMPETITIVE && CompareStat(gBattlerTarget, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)))
&& ((targetAbility == ABILITY_DEFIANT && CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|| (targetAbility == ABILITY_COMPETITIVE && CompareStat(gBattlerTarget, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)))
&& gSpecialStatuses[gBattlerTarget].changedStatsBattlerId != BATTLE_PARTNER(gBattlerTarget)
&& gSpecialStatuses[gBattlerTarget].changedStatsBattlerId != gBattlerTarget)
{
gBattlerAbility = gBattlerTarget;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_DefiantActivates;
if (GetBattlerAbility(gBattlerTarget) == ABILITY_DEFIANT)
if (targetAbility == ABILITY_DEFIANT)
SET_STATCHANGER(STAT_ATK, 2, FALSE);
else
SET_STATCHANGER(STAT_SPATK, 2, FALSE);
@ -2822,16 +2827,19 @@ u8 DoBattlerEndTurnEffects(void)
gBattleStruct->turnEffectsTracker++;
break;
case ENDTURN_OCTOLOCK:
{
u16 battlerAbility = GetBattlerAbility(gActiveBattler);
if (gDisableStructs[gActiveBattler].octolock
&& !(GetBattlerAbility(gActiveBattler) == ABILITY_CLEAR_BODY
|| GetBattlerAbility(gActiveBattler) == ABILITY_FULL_METAL_BODY
|| GetBattlerAbility(gActiveBattler) == ABILITY_WHITE_SMOKE))
&& !(battlerAbility == ABILITY_CLEAR_BODY
|| battlerAbility == ABILITY_FULL_METAL_BODY
|| battlerAbility == ABILITY_WHITE_SMOKE))
{
gBattlerTarget = gActiveBattler;
BattleScriptExecute(BattleScript_OctolockEndTurn);
effect++;
}
gBattleStruct->turnEffectsTracker++;
}
break;
case ENDTURN_UPROAR: // uproar
if (gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR)
@ -2972,10 +2980,11 @@ u8 DoBattlerEndTurnEffects(void)
case ENDTURN_YAWN: // yawn
if (gStatuses3[gActiveBattler] & STATUS3_YAWN)
{
u16 battlerAbility = GetBattlerAbility(gActiveBattler);
gStatuses3[gActiveBattler] -= STATUS3_YAWN_TURN(1);
if (!(gStatuses3[gActiveBattler] & STATUS3_YAWN) && !(gBattleMons[gActiveBattler].status1 & STATUS1_ANY)
&& GetBattlerAbility(gActiveBattler) != ABILITY_VITAL_SPIRIT
&& GetBattlerAbility(gActiveBattler) != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler)
&& battlerAbility != ABILITY_VITAL_SPIRIT
&& battlerAbility != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler)
&& !IsLeafGuardProtected(gActiveBattler))
{
CancelMultiTurnMoves(gActiveBattler);
@ -3937,6 +3946,8 @@ static const u16 sWeatherFlagsInfo[][3] =
bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility)
{
u16 battlerAbility = GetBattlerAbility(battler);
if (viaAbility && B_ABILITY_WEATHER <= GEN_5
&& !(gBattleWeather & sWeatherFlagsInfo[weatherEnumId][1]))
{
@ -3944,9 +3955,9 @@ bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility)
return TRUE;
}
else if (gBattleWeather & B_WEATHER_PRIMAL_ANY
&& GetBattlerAbility(battler) != ABILITY_DESOLATE_LAND
&& GetBattlerAbility(battler) != ABILITY_PRIMORDIAL_SEA
&& GetBattlerAbility(battler) != ABILITY_DELTA_STREAM)
&& battlerAbility != ABILITY_DESOLATE_LAND
&& battlerAbility != ABILITY_PRIMORDIAL_SEA
&& battlerAbility != ABILITY_DELTA_STREAM)
{
return FALSE;
}
@ -4002,10 +4013,11 @@ static bool32 ShouldChangeFormHpBased(u32 battler)
{ABILITY_ZEN_MODE, SPECIES_DARMANITAN_GALARIAN, SPECIES_DARMANITAN_ZEN_MODE_GALARIAN, 2},
};
u32 i;
u16 battlerAbility = GetBattlerAbility(battler);
for (i = 0; i < ARRAY_COUNT(forms); i++)
{
if (GetBattlerAbility(battler) == forms[i][0])
if (battlerAbility == forms[i][0])
{
if (gBattleMons[battler].species == forms[i][2]
&& gBattleMons[battler].hp > gBattleMons[battler].maxHP / forms[i][3])
@ -5593,7 +5605,8 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
case ABILITYEFFECT_FORECAST: // 6
for (battler = 0; battler < gBattlersCount; battler++)
{
if (GetBattlerAbility(battler) == ABILITY_FORECAST || GetBattlerAbility(battler) == ABILITY_FLOWER_GIFT)
u16 battlerAbility = GetBattlerAbility(battler);
if (battlerAbility == ABILITY_FORECAST || battlerAbility == ABILITY_FLOWER_GIFT)
{
effect = TryWeatherFormChange(battler);
if (effect)
@ -6138,13 +6151,14 @@ static u8 RandomStatRaiseBerry(u32 battlerId, u32 itemId, bool32 end2)
}
if (i != NUM_STATS - 1 && HasEnoughHpToEatBerry(battlerId, GetBattlerHoldEffectParam(battlerId), itemId))
{
u16 battlerAbility = GetBattlerAbility(battlerId);
do
{
i = Random() % (NUM_STATS - 1);
} while (!CompareStat(battlerId, STAT_ATK + i, MAX_STAT_STAGE, CMP_LESS_THAN));
PREPARE_STAT_BUFFER(gBattleTextBuff1, i + 1);
stringId = (GetBattlerAbility(battlerId) == ABILITY_CONTRARY) ? STRINGID_STATFELL : STRINGID_STATROSE;
stringId = (battlerAbility == ABILITY_CONTRARY) ? STRINGID_STATFELL : STRINGID_STATROSE;
gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN;
gBattleTextBuff2[1] = B_BUFF_STRING;
gBattleTextBuff2[2] = STRINGID_STATSHARPLY;
@ -6154,7 +6168,7 @@ static u8 RandomStatRaiseBerry(u32 battlerId, u32 itemId, bool32 end2)
gBattleTextBuff2[6] = stringId >> 8;
gBattleTextBuff2[7] = EOS;
gEffectBattler = battlerId;
if (GetBattlerAbility(battlerId) == ABILITY_RIPEN)
if (battlerAbility == ABILITY_RIPEN)
SET_STATCHANGER(i + 1, 4, FALSE);
else
SET_STATCHANGER(i + 1, 2, FALSE);
@ -7313,13 +7327,15 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
}
break;
case ITEMEFFECT_ORBS:
{
u16 battlerAbility = GetBattlerAbility(battlerId);
switch (battlerHoldEffect)
{
case HOLD_EFFECT_TOXIC_ORB:
if (!gBattleMons[battlerId].status1
&& CanPoisonType(battlerId, battlerId)
&& GetBattlerAbility(battlerId) != ABILITY_IMMUNITY
&& GetBattlerAbility(battlerId) != ABILITY_COMATOSE
&& battlerAbility != ABILITY_IMMUNITY
&& battlerAbility != ABILITY_COMATOSE
&& IsBattlerAlive)
{
effect = ITEM_STATUS_CHANGE;
@ -7331,9 +7347,9 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
case HOLD_EFFECT_FLAME_ORB:
if (!gBattleMons[battlerId].status1
&& !IS_BATTLER_OF_TYPE(battlerId, TYPE_FIRE)
&& GetBattlerAbility(battlerId) != ABILITY_WATER_VEIL
&& GetBattlerAbility(battlerId) != ABILITY_WATER_BUBBLE
&& GetBattlerAbility(battlerId) != ABILITY_COMATOSE
&& battlerAbility != ABILITY_WATER_VEIL
&& battlerAbility != ABILITY_WATER_BUBBLE
&& battlerAbility != ABILITY_COMATOSE
&& IsBattlerAlive)
{
effect = ITEM_STATUS_CHANGE;
@ -7343,7 +7359,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
}
break;
case HOLD_EFFECT_STICKY_BARB: // Not an orb per se, but similar effect, and needs to NOT activate with pickpocket
if (GetBattlerAbility(battlerId) != ABILITY_MAGIC_GUARD)
if (battlerAbility != ABILITY_MAGIC_GUARD)
{
gBattleMoveDamage = gBattleMons[battlerId].maxHP / 8;
if (gBattleMoveDamage == 0)
@ -7362,6 +7378,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battlerId].status1);
MarkBattlerForControllerExec(gActiveBattler);
}
}
break;
}
@ -9093,6 +9110,8 @@ static void UpdateMoveResultFlags(u16 modifier)
static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 battlerAtk, u8 battlerDef, bool32 recordAbilities, u16 modifier)
{
u16 defAbility = GetBattlerAbility(battlerDef);
MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, gBattleMons[battlerDef].type1, battlerAtk, recordAbilities);
if (gBattleMons[battlerDef].type2 != gBattleMons[battlerDef].type1)
MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, gBattleMons[battlerDef].type2, battlerAtk, recordAbilities);
@ -9103,7 +9122,7 @@ static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 bat
if (moveType == TYPE_GROUND && !IsBattlerGrounded(battlerDef) && !(gBattleMoves[move].flags & FLAG_DMG_UNGROUNDED_IGNORE_TYPE_IF_FLYING))
{
modifier = UQ_4_12(0.0);
if (recordAbilities && GetBattlerAbility(battlerDef) == ABILITY_LEVITATE)
if (recordAbilities && defAbility == ABILITY_LEVITATE)
{
gLastUsedAbility = ABILITY_LEVITATE;
gMoveResultFlags |= (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE);
@ -9124,8 +9143,8 @@ static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 bat
modifier = UQ_4_12(1.0);
}
if (((GetBattlerAbility(battlerDef) == ABILITY_WONDER_GUARD && modifier <= UQ_4_12(1.0))
|| (GetBattlerAbility(battlerDef) == ABILITY_TELEPATHY && battlerDef == BATTLE_PARTNER(battlerAtk)))
if (((defAbility == ABILITY_WONDER_GUARD && modifier <= UQ_4_12(1.0))
|| (defAbility == ABILITY_TELEPATHY && battlerDef == BATTLE_PARTNER(battlerAtk)))
&& gBattleMoves[move].power)
{
modifier = UQ_4_12(0.0);