diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index 415c4fb93882..d15fa0140922 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -182,7 +182,6 @@ bool32 HasBattlerSideMoveWithEffect(u32 battler, u32 effect); bool32 HasBattlerSideMoveWithAIEffect(u32 battler, u32 effect); bool32 HasBattlerSideUsedMoveWithEffect(u32 battler, u32 effect); bool32 HasNonVolatileMoveEffect(u32 battlerId, u32 effect); -bool32 IsPowerBasedOnStatus(u32 battlerId, enum BattleMoveEffects effect, u32 argument); bool32 HasMoveWithAdditionalEffect(u32 battlerId, u32 moveEffect); bool32 HasBattlerSideMoveWithAdditionalEffect(u32 battler, u32 moveEffect); bool32 HasMoveWithCriticalHitChance(u32 battlerId); @@ -286,12 +285,12 @@ bool32 SideHasMoveCategory(u32 battlerId, enum DamageCategory category); u32 IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, enum StatChange statId); u32 IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, enum StatChange statId); u32 IncreaseStatDownScore(u32 battlerAtk, u32 battlerDef, u32 stat); -void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score); -void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score); -void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score); -void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score); +s32 IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move); +s32 IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move); +s32 IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move); +s32 IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move); +s32 IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move); void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score); -void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score); s32 AI_CalcPartyMonDamage(u32 move, u32 battlerAtk, u32 battlerDef, struct BattlePokemon switchinCandidate, uq4_12_t *effectiveness, enum DamageCalcContext calcContext); u32 AI_WhoStrikesFirstPartyMon(u32 battlerAtk, u32 battlerDef, struct BattlePokemon switchinCandidate, u32 aiMoveConsidered, u32 playerMoveConsidered, enum ConsiderPriority ConsiderPriority); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index ec13d78a9441..2e421cef59ec 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -4075,23 +4075,23 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, stru { case MOVE_EFFECT_POISON: case MOVE_EFFECT_TOXIC: - IncreasePoisonScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreasePoisonScore(battlerAtk, battlerDef, move)); break; case MOVE_EFFECT_SLEEP: - IncreaseSleepScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreaseSleepScore(battlerAtk, battlerDef, move)); break; case MOVE_EFFECT_PARALYSIS: - IncreaseParalyzeScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreaseParalyzeScore(battlerAtk, battlerDef, move)); break; case MOVE_EFFECT_BURN: - IncreaseBurnScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreaseBurnScore(battlerAtk, battlerDef, move)); break; } // move effect checks switch (moveEffect) { case EFFECT_YAWN: - IncreaseSleepScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreaseSleepScore(battlerAtk, battlerDef, move)); break; case EFFECT_ABSORB: if (aiData->holdEffects[battlerAtk] == HOLD_EFFECT_BIG_ROOT && effectiveness >= UQ_4_12(1.0)) @@ -5066,15 +5066,15 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, stru break; case EFFECT_PSYCHO_SHIFT: if (gBattleMons[battlerAtk].status1 & STATUS1_PSN_ANY) - IncreasePoisonScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreasePoisonScore(battlerAtk, battlerDef, move)); else if (gBattleMons[battlerAtk].status1 & STATUS1_BURN) - IncreaseBurnScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreaseBurnScore(battlerAtk, battlerDef, move)); else if (gBattleMons[battlerAtk].status1 & STATUS1_PARALYSIS) - IncreaseParalyzeScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreaseParalyzeScore(battlerAtk, battlerDef, move)); else if (gBattleMons[battlerAtk].status1 & STATUS1_SLEEP) - IncreaseSleepScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreaseSleepScore(battlerAtk, battlerDef, move)); else if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE) - IncreaseFrostbiteScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreaseFrostbiteScore(battlerAtk, battlerDef, move)); break; case EFFECT_GRUDGE: break; @@ -5312,7 +5312,7 @@ case EFFECT_GUARD_SPLIT: // improve accuracy of Hypnosis if (HasSleepMoveWithLowAccuracy(battlerAtk, battlerDef) || HasSleepMoveWithLowAccuracy(BATTLE_PARTNER(battlerAtk), battlerDef)) - IncreaseSleepScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreaseSleepScore(battlerAtk, battlerDef, move)); if (HasMoveWithLowAccuracy(battlerAtk, battlerDef, 90, TRUE) || HasMoveWithLowAccuracy(BATTLE_PARTNER(battlerAtk), battlerDef, 90, TRUE)) ADJUST_SCORE(WEAK_EFFECT); @@ -5332,17 +5332,17 @@ case EFFECT_GUARD_SPLIT: switch (gFlingTable[aiData->items[battlerAtk]].effect) { case MOVE_EFFECT_BURN: - IncreaseBurnScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreaseBurnScore(battlerAtk, battlerDef, move)); break; case MOVE_EFFECT_FLINCH: score += ShouldTryToFlinch(battlerAtk, battlerDef, aiData->abilities[battlerAtk], aiData->abilities[battlerDef], move); break; case MOVE_EFFECT_PARALYSIS: - IncreaseParalyzeScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreaseParalyzeScore(battlerAtk, battlerDef, move)); break; case MOVE_EFFECT_POISON: case MOVE_EFFECT_TOXIC: - IncreasePoisonScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreasePoisonScore(battlerAtk, battlerDef, move)); break; case MOVE_EFFECT_FREEZE: if (AI_CanFreeze(battlerAtk, battlerDef)) @@ -5468,7 +5468,7 @@ case EFFECT_GUARD_SPLIT: ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_TOXIC_THREAD: - IncreasePoisonScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreasePoisonScore(battlerAtk, battlerDef, move)); ADJUST_SCORE(IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_SPEED)); break; case EFFECT_COUNTER: @@ -5784,7 +5784,7 @@ static s32 AI_CalcAdditionalEffectScore(u32 battlerAtk, u32 battlerDef, u32 move break; } case MOVE_EFFECT_POISON: - IncreasePoisonScore(battlerAtk, battlerDef, move, &score); + ADJUST_SCORE(IncreasePoisonScore(battlerAtk, battlerDef, move)); break; case MOVE_EFFECT_CLEAR_SMOG: { diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index d8d8e3a5c28a..67a21e087771 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -2464,22 +2464,6 @@ bool32 HasNonVolatileMoveEffect(u32 battlerId, u32 effect) return FALSE; } -bool32 IsPowerBasedOnStatus(u32 battlerId, enum BattleMoveEffects effect, u32 argument) -{ - s32 i; - u16 *moves = GetMovesArray(battlerId); - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE - && GetMoveEffect(moves[i]) == effect - && (GetMoveEffectArg_Status(moves[i]) & argument)) - return TRUE; - } - - return FALSE; -} - bool32 HasMoveWithAdditionalEffect(u32 battlerId, u32 moveEffect) { s32 i; @@ -4793,93 +4777,153 @@ u32 IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, enum StatChange return IncreaseStatUpScoreInternal(battlerAtk, battlerDef, statChange, FALSE); } -void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) +static bool32 HasMoveWithPowerBasedOnStatus(u32 battler, enum BattleMoveEffects effect, u32 argument) { - if (((gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) - || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PSN || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) - return; + s32 i; + u16 *moves = GetMovesArray(battler); - if (AI_CanPoison(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], move, gAiLogicData->partnerMove) && gAiLogicData->hpPercents[battlerDef] > 20) + for (i = 0; i < MAX_MON_MOVES; i++) { - if (!HasDamagingMove(battlerDef)) - ADJUST_SCORE_PTR(DECENT_EFFECT); - - if (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_STALL && HasMoveWithEffect(battlerAtk, EFFECT_PROTECT)) - ADJUST_SCORE_PTR(WEAK_EFFECT); // stall tactic - - if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PSN_ANY) - || HasMoveWithEffect(battlerAtk, EFFECT_VENOM_DRENCH) - || gAiLogicData->abilities[battlerAtk] == ABILITY_MERCILESS) - ADJUST_SCORE_PTR(DECENT_EFFECT); - else - ADJUST_SCORE_PTR(WEAK_EFFECT); + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE + && GetMoveEffect(moves[i]) == effect + && (GetMoveEffectArg_Status(moves[i]) & argument)) + return TRUE; } + + return FALSE; } -void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) +static s32 IncreaseNonvolatileScoreInternal(u32 battlerAtk, u32 battlerDef, u32 move, u32 status) { - if (((gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) - || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_BRN || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) - return; + s32 score = NO_INCREASE; - if (AI_CanBurn(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, gAiLogicData->partnerMove)) + if ((gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + return score; + + if (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) + return score; + + if (status & STATUS1_PSN_ANY) { - if (HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_PHYSICAL) - || (!(gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_OMNISCIENT) // Not Omniscient but expects physical attacker - && GetSpeciesBaseAttack(gBattleMons[battlerDef].species) >= GetSpeciesBaseSpAttack(gBattleMons[battlerDef].species) + 10)) + if (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PSN) + return score; + + if (AI_CanPoison(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], move, gAiLogicData->partnerMove) && gAiLogicData->hpPercents[battlerDef] > 20) { - if (GetMoveCategory(GetBestDmgMoveFromBattler(battlerDef, battlerAtk, AI_DEFENDING)) == DAMAGE_CATEGORY_PHYSICAL) - ADJUST_SCORE_PTR(DECENT_EFFECT); + if (!HasDamagingMove(battlerDef)) + score += DECENT_EFFECT; + + if (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_STALL && HasMoveWithEffect(battlerAtk, EFFECT_PROTECT)) + score += WEAK_EFFECT; // stall tactic + + if (HasMoveWithEffect(battlerAtk, EFFECT_VENOM_DRENCH) + || gAiLogicData->abilities[battlerAtk] == ABILITY_MERCILESS) + score += DECENT_EFFECT; else - ADJUST_SCORE_PTR(WEAK_EFFECT); + score += WEAK_EFFECT; } - - if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN) - || IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN)) - ADJUST_SCORE_PTR(WEAK_EFFECT); } -} + else if (status & STATUS1_BURN) + { + if (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_BRN) + return score; -void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) -{ - if (((gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) - || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PAR || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) - return; + if (AI_CanBurn(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, gAiLogicData->partnerMove)) + { + if (HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_PHYSICAL) + || (!(gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_OMNISCIENT) // Not Omniscient but expects physical attacker + && GetSpeciesBaseAttack(gBattleMons[battlerDef].species) >= GetSpeciesBaseSpAttack(gBattleMons[battlerDef].species) + 10)) + { + if (GetMoveCategory(GetBestDmgMoveFromBattler(battlerDef, battlerAtk, AI_DEFENDING)) == DAMAGE_CATEGORY_PHYSICAL) + score += DECENT_EFFECT; + else + score += WEAK_EFFECT; + } + } + } + else if (status & STATUS1_PARALYSIS) + { + if (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PAR) + return score; - if (AI_CanParalyze(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], move, gAiLogicData->partnerMove)) + if (AI_CanParalyze(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], move, gAiLogicData->partnerMove)) + { + u32 atkSpeed = gAiLogicData->speedStats[battlerAtk]; + u32 defSpeed = gAiLogicData->speedStats[battlerDef]; + + if ((defSpeed >= atkSpeed && defSpeed / 2 < atkSpeed) // You'll go first after paralyzing foe + || HasMoveWithMoveEffectExcept(battlerAtk, MOVE_EFFECT_FLINCH, EFFECT_FIRST_TURN_ONLY) // filter out Fake Out + || gBattleMons[battlerDef].volatiles.infatuation + || gBattleMons[battlerDef].volatiles.confusionTurns > 0) + score += GOOD_EFFECT; + else + score += DECENT_EFFECT; + } + } + else if (status & STATUS1_SLEEP) { - u32 atkSpeed = gAiLogicData->speedStats[battlerAtk]; - u32 defSpeed = gAiLogicData->speedStats[battlerDef]; + if ((GetMoveEffect(GetBestDmgMoveFromBattler(battlerAtk, battlerDef, AI_ATTACKING)) != EFFECT_FOCUS_PUNCH) + || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_SLP) + return score; - if ((defSpeed >= atkSpeed && defSpeed / 2 < atkSpeed) // You'll go first after paralyzing foe - || IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PARALYSIS) - || (HasMoveWithMoveEffectExcept(battlerAtk, MOVE_EFFECT_FLINCH, EFFECT_FIRST_TURN_ONLY)) // filter out Fake Out - || gBattleMons[battlerDef].volatiles.infatuation - || gBattleMons[battlerDef].volatiles.confusionTurns > 0) - ADJUST_SCORE_PTR(GOOD_EFFECT); + if (AI_CanPutToSleep(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], move, gAiLogicData->partnerMove)) + score += DECENT_EFFECT; else - ADJUST_SCORE_PTR(DECENT_EFFECT); + return score; + + if ((HasMoveWithEffect(battlerAtk, EFFECT_DREAM_EATER) || HasMoveWithEffect(battlerAtk, EFFECT_NIGHTMARE)) + && !(HasMoveWithEffect(battlerDef, EFFECT_SNORE) || HasMoveWithEffect(battlerDef, EFFECT_SLEEP_TALK))) + score += WEAK_EFFECT; } + else if (status & STATUS1_FROSTBITE) + { + if (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_FRZ) + return score; + + if (AI_CanGiveFrostbite(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, gAiLogicData->partnerMove)) + { + if (HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_SPECIAL) + || (!(gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_OMNISCIENT) // Not Omniscient but expects special attacker + && GetSpeciesBaseSpAttack(gBattleMons[battlerDef].species) >= GetSpeciesBaseAttack(gBattleMons[battlerDef].species) + 10)) + { + if (GetMoveCategory(GetBestDmgMoveFromBattler(battlerDef, battlerAtk, AI_DEFENDING)) == DAMAGE_CATEGORY_SPECIAL) + score += DECENT_EFFECT; + else + score += WEAK_EFFECT; + } + } + } + + if (HasMoveWithPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, status) + || HasMoveWithPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, status)) + score += WEAK_EFFECT; + + return score; } -void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) +s32 IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move) { - if (((gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0) && GetMoveEffect(GetBestDmgMoveFromBattler(battlerAtk, battlerDef, AI_ATTACKING)) != EFFECT_FOCUS_PUNCH) - || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_SLP || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) - return; + return IncreaseNonvolatileScoreInternal(battlerAtk, battlerDef, move, STATUS1_PSN_ANY); +} - if (AI_CanPutToSleep(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], move, gAiLogicData->partnerMove)) - ADJUST_SCORE_PTR(DECENT_EFFECT); - else - return; +s32 IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move) +{ + return IncreaseNonvolatileScoreInternal(battlerAtk, battlerDef, move, STATUS1_BURN); +} - if ((HasMoveWithEffect(battlerAtk, EFFECT_DREAM_EATER) || HasMoveWithEffect(battlerAtk, EFFECT_NIGHTMARE)) - && !(HasMoveWithEffect(battlerDef, EFFECT_SNORE) || HasMoveWithEffect(battlerDef, EFFECT_SLEEP_TALK))) - ADJUST_SCORE_PTR(WEAK_EFFECT); +s32 IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move) +{ + return IncreaseNonvolatileScoreInternal(battlerAtk, battlerDef, move, STATUS1_PARALYSIS); +} - if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP) - || IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP)) - ADJUST_SCORE_PTR(WEAK_EFFECT); +s32 IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move) +{ + return IncreaseNonvolatileScoreInternal(battlerAtk, battlerDef, move, STATUS1_SLEEP); +} + +s32 IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move) +{ + return IncreaseNonvolatileScoreInternal(battlerAtk, battlerDef, move, STATUS1_FROSTBITE); } void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) @@ -4901,29 +4945,6 @@ void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score } } -void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) -{ - if ((gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) - return; - - if (AI_CanGiveFrostbite(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, gAiLogicData->partnerMove)) - { - if (HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_SPECIAL) - || (!(gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_OMNISCIENT) // Not Omniscient but expects special attacker - && GetSpeciesBaseSpAttack(gBattleMons[battlerDef].species) >= GetSpeciesBaseAttack(gBattleMons[battlerDef].species) + 10)) - { - if (GetMoveCategory(GetBestDmgMoveFromBattler(battlerDef, battlerAtk, AI_DEFENDING)) == DAMAGE_CATEGORY_SPECIAL) - ADJUST_SCORE_PTR(DECENT_EFFECT); - else - ADJUST_SCORE_PTR(WEAK_EFFECT); - } - - if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE) - || IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE)) - ADJUST_SCORE_PTR(WEAK_EFFECT); - } -} - bool32 AI_MoveMakesContact(enum Ability ability, enum ItemHoldEffect holdEffect, u32 move) { if (MoveMakesContact(move)