From bfdfad9c11bae36d0a7e17c664109028937228e4 Mon Sep 17 00:00:00 2001 From: surskitty Date: Mon, 6 Oct 2025 15:47:51 -0400 Subject: [PATCH 1/3] Homogenizing the increase nonvolatile score checks. --- include/battle_ai_util.h | 12 +-- src/battle_ai_main.c | 32 +++---- src/battle_ai_util.c | 199 ++++++++++++++++++++++----------------- 3 files changed, 132 insertions(+), 111 deletions(-) diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index 415c4fb93882..de6f0f70a297 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -182,7 +182,7 @@ 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 HasMoveWithEffectArg(u32 battler, enum BattleMoveEffects effect, u32 argument); bool32 HasMoveWithAdditionalEffect(u32 battlerId, u32 moveEffect); bool32 HasBattlerSideMoveWithAdditionalEffect(u32 battler, u32 moveEffect); bool32 HasMoveWithCriticalHitChance(u32 battlerId); @@ -286,12 +286,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..14f1fb7f4493 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -2464,10 +2464,10 @@ bool32 HasNonVolatileMoveEffect(u32 battlerId, u32 effect) return FALSE; } -bool32 IsPowerBasedOnStatus(u32 battlerId, enum BattleMoveEffects effect, u32 argument) +bool32 HasMoveWithEffectArg(u32 battler, enum BattleMoveEffects effect, u32 argument) { s32 i; - u16 *moves = GetMovesArray(battlerId); + u16 *moves = GetMovesArray(battler); for (i = 0; i < MAX_MON_MOVES; i++) { @@ -4793,93 +4793,137 @@ u32 IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, enum StatChange return IncreaseStatUpScoreInternal(battlerAtk, battlerDef, statChange, FALSE); } -void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) +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_PSN || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) - return; + s32 score = NO_INCREASE; + + 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 (AI_CanPoison(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], move, gAiLogicData->partnerMove) && gAiLogicData->hpPercents[battlerDef] > 20) + if (status & STATUS1_PSN_ANY) { - if (!HasDamagingMove(battlerDef)) - ADJUST_SCORE_PTR(DECENT_EFFECT); + if (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PSN) + return score; - if (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_STALL && HasMoveWithEffect(battlerAtk, EFFECT_PROTECT)) - ADJUST_SCORE_PTR(WEAK_EFFECT); // stall tactic + if (AI_CanPoison(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], move, gAiLogicData->partnerMove) && gAiLogicData->hpPercents[battlerDef] > 20) + { + if (!HasDamagingMove(battlerDef)) + score += DECENT_EFFECT; - 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 (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_STALL && HasMoveWithEffect(battlerAtk, EFFECT_PROTECT)) + score += WEAK_EFFECT; // stall tactic -void IncreaseBurnScore(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_BRN || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) - return; + if (HasMoveWithEffect(battlerAtk, EFFECT_VENOM_DRENCH) + || gAiLogicData->abilities[battlerAtk] == ABILITY_MERCILESS) + score += DECENT_EFFECT; + else + score += WEAK_EFFECT; + } + } + else if (status & STATUS1_BURN) + { + if (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_BRN) + return score; - if (AI_CanBurn(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, gAiLogicData->partnerMove)) + 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 (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_PAR) + return score; + + if (AI_CanParalyze(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], move, gAiLogicData->partnerMove)) { - if (GetMoveCategory(GetBestDmgMoveFromBattler(battlerDef, battlerAtk, AI_DEFENDING)) == DAMAGE_CATEGORY_PHYSICAL) - ADJUST_SCORE_PTR(DECENT_EFFECT); + 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 - ADJUST_SCORE_PTR(WEAK_EFFECT); + score += DECENT_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_SLEEP) + { + if ((GetMoveEffect(GetBestDmgMoveFromBattler(battlerAtk, battlerDef, AI_ATTACKING)) != EFFECT_FOCUS_PUNCH) + || gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_SLP) + 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_CanPutToSleep(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], move, gAiLogicData->partnerMove)) + score += DECENT_EFFECT; + else + return score; - if (AI_CanParalyze(battlerAtk, battlerDef, gAiLogicData->abilities[battlerDef], move, gAiLogicData->partnerMove)) + 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) { - u32 atkSpeed = gAiLogicData->speedStats[battlerAtk]; - u32 defSpeed = gAiLogicData->speedStats[battlerDef]; + if (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CURE_FRZ) + 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); - else - ADJUST_SCORE_PTR(DECENT_EFFECT); + 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 (HasMoveWithEffectArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, status) + || HasMoveWithEffectArg(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) From 05aa85db2b94ffedef75e757ba94323e9dfccd24 Mon Sep 17 00:00:00 2001 From: surskitty Date: Mon, 6 Oct 2025 16:01:38 -0400 Subject: [PATCH 2/3] Making relevant functions static. --- include/battle_ai_util.h | 1 - src/battle_ai_util.c | 38 +++++++++++++++++++------------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index de6f0f70a297..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 HasMoveWithEffectArg(u32 battler, enum BattleMoveEffects effect, u32 argument); bool32 HasMoveWithAdditionalEffect(u32 battlerId, u32 moveEffect); bool32 HasBattlerSideMoveWithAdditionalEffect(u32 battler, u32 moveEffect); bool32 HasMoveWithCriticalHitChance(u32 battlerId); diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 14f1fb7f4493..f854ee882574 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 HasMoveWithEffectArg(u32 battler, enum BattleMoveEffects effect, u32 argument) -{ - s32 i; - u16 *moves = GetMovesArray(battler); - - 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,7 +4777,23 @@ u32 IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, enum StatChange return IncreaseStatUpScoreInternal(battlerAtk, battlerDef, statChange, FALSE); } -s32 IncreaseNonvolatileScoreInternal(u32 battlerAtk, u32 battlerDef, u32 move, u32 status) +static bool32 HasMoveDoubleDamageOnStatus(u32 battler, enum BattleMoveEffects effect, u32 argument) +{ + s32 i; + u16 *moves = GetMovesArray(battler); + + 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; +} + +static s32 IncreaseNonvolatileScoreInternal(u32 battlerAtk, u32 battlerDef, u32 move, u32 status) { s32 score = NO_INCREASE; @@ -4894,8 +4894,8 @@ s32 IncreaseNonvolatileScoreInternal(u32 battlerAtk, u32 battlerDef, u32 move, u } } - if (HasMoveWithEffectArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, status) - || HasMoveWithEffectArg(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, status)) + if (HasMoveDoubleDamageOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, status) + || HasMoveDoubleDamageOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, status)) score += WEAK_EFFECT; return score; From db39fdd045cd47a8c62660b22d95297a13b17122 Mon Sep 17 00:00:00 2001 From: surskitty Date: Mon, 6 Oct 2025 16:02:59 -0400 Subject: [PATCH 3/3] Cleaning up HasMoveWithPowerBasedOnStatus. --- src/battle_ai_util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index f854ee882574..67a21e087771 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -4777,7 +4777,7 @@ u32 IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, enum StatChange return IncreaseStatUpScoreInternal(battlerAtk, battlerDef, statChange, FALSE); } -static bool32 HasMoveDoubleDamageOnStatus(u32 battler, enum BattleMoveEffects effect, u32 argument) +static bool32 HasMoveWithPowerBasedOnStatus(u32 battler, enum BattleMoveEffects effect, u32 argument) { s32 i; u16 *moves = GetMovesArray(battler); @@ -4894,8 +4894,8 @@ static s32 IncreaseNonvolatileScoreInternal(u32 battlerAtk, u32 battlerDef, u32 } } - if (HasMoveDoubleDamageOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, status) - || HasMoveDoubleDamageOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, status)) + 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;