From d0a97970baae433f24e3e62a4a3b3e942157ea76 Mon Sep 17 00:00:00 2001 From: AlexOn1ine Date: Thu, 10 Oct 2024 09:55:25 +0200 Subject: [PATCH 1/2] Unify GetBattlerAbility/TerrainAffected to remove duplicate ai function --- include/battle_ai_util.h | 2 -- src/battle_ai_main.c | 16 +++++++++------- src/battle_ai_util.c | 36 ------------------------------------ src/battle_main.c | 2 ++ src/battle_util.c | 4 ++-- 5 files changed, 13 insertions(+), 47 deletions(-) diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index 69cf92ed0d..c87a35e750 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -52,8 +52,6 @@ bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move); u32 AI_GetWeather(struct AiLogicData *aiData); bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u32 numHits); bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u32 index, u32 numHits); -bool32 AI_IsTerrainAffected(u32 battlerId, u32 flags); -bool32 AI_IsBattlerGrounded(u32 battlerId); bool32 HasDamagingMove(u32 battlerId); bool32 HasDamagingMoveOfType(u32 battlerId, u32 type); u32 GetBattlerSecondaryDamage(u32 battlerId); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index a08ca0f71f..1b2f24e635 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -477,6 +477,7 @@ void SetAiLogicDataForTurn(struct AiLogicData *aiData) // get/assume all battler data and simulate AI damage battlersCount = gBattlersCount; + AI_DATA->aiCalcInProgress = TRUE; for (battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++) { if (!IsBattlerAlive(battlerAtk)) @@ -492,6 +493,7 @@ void SetAiLogicDataForTurn(struct AiLogicData *aiData) SetBattlerAiMovesData(aiData, battlerAtk, battlersCount); } + AI_DATA->aiCalcInProgress = FALSE; } static bool32 AI_SwitchMonIfSuitable(u32 battler, bool32 doubleBattle) @@ -1017,19 +1019,19 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) RETURN_SCORE_MINUS(10); // terrain & effect checks - if (AI_IsTerrainAffected(battlerDef, STATUS_FIELD_ELECTRIC_TERRAIN)) + if (IsBattlerTerrainAffected(battlerDef, STATUS_FIELD_ELECTRIC_TERRAIN)) { if (moveEffect == EFFECT_SLEEP || moveEffect == EFFECT_YAWN) RETURN_SCORE_MINUS(20); } - if (AI_IsTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN)) + if (IsBattlerTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN)) { if (IsNonVolatileStatusMoveEffect(moveEffect) || IsConfusionMoveEffect(moveEffect)) RETURN_SCORE_MINUS(20); } - if (AI_IsTerrainAffected(battlerAtk, STATUS_FIELD_PSYCHIC_TERRAIN) && atkPriority > 0) + if (IsBattlerTerrainAffected(battlerAtk, STATUS_FIELD_PSYCHIC_TERRAIN) && atkPriority > 0) { RETURN_SCORE_MINUS(20); } @@ -1250,10 +1252,10 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (isDoubleBattle) { if (!(IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GRASS) - && AI_IsBattlerGrounded(battlerAtk) + && IsBattlerGrounded(battlerAtk) && (BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_ATK) || BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_SPATK))) && !(IS_BATTLER_OF_TYPE(BATTLE_PARTNER(battlerAtk), TYPE_GRASS) - && AI_IsBattlerGrounded(BATTLE_PARTNER(battlerAtk)) + && IsBattlerGrounded(BATTLE_PARTNER(battlerAtk)) && aiData->abilities[BATTLE_PARTNER(battlerAtk)] != ABILITY_CONTRARY && (BattlerStatCanRise(BATTLE_PARTNER(battlerAtk), aiData->abilities[BATTLE_PARTNER(battlerAtk)], STAT_ATK) || BattlerStatCanRise(BATTLE_PARTNER(battlerAtk), aiData->abilities[BATTLE_PARTNER(battlerAtk)], STAT_SPATK)))) @@ -1262,7 +1264,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } } else if (!(IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GRASS) - && AI_IsBattlerGrounded(battlerAtk) + && IsBattlerGrounded(battlerAtk) && (BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_ATK) || BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_SPATK)))) { ADJUST_SCORE(-10); @@ -3947,7 +3949,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_SAFEGUARD: - if (!AI_IsTerrainAffected(battlerAtk, STATUS_FIELD_MISTY_TERRAIN) || !IsBattlerGrounded(battlerAtk)) + if (!IsBattlerTerrainAffected(battlerAtk, STATUS_FIELD_MISTY_TERRAIN) || !IsBattlerGrounded(battlerAtk)) ADJUST_SCORE(DECENT_EFFECT); // TODO: check if opp has status move? //if (CountUsablePartyMons(battlerDef) != 0) //ADJUST_SCORE(8); diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index bf84f98b4d..1288ed1201 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1344,42 +1344,6 @@ u32 AI_DecideHoldEffectForTurn(u32 battlerId) return holdEffect; } -bool32 AI_IsTerrainAffected(u32 battlerId, u32 flags) -{ - if (gStatuses3[battlerId] & STATUS3_SEMI_INVULNERABLE) - return FALSE; - else if (!(gFieldStatuses & flags)) - return FALSE; - return AI_IsBattlerGrounded(battlerId); -} - -// different from IsBattlerGrounded in that we don't always know battler's hold effect or ability -bool32 AI_IsBattlerGrounded(u32 battlerId) -{ - u32 holdEffect = AI_DATA->holdEffects[battlerId]; - - if (holdEffect == HOLD_EFFECT_IRON_BALL) - return TRUE; - else if (gFieldStatuses & STATUS_FIELD_GRAVITY) - return TRUE; - else if (gStatuses3[battlerId] & STATUS3_ROOTED) - return TRUE; - else if (gStatuses3[battlerId] & STATUS3_SMACKED_DOWN) - return TRUE; - else if (gStatuses3[battlerId] & STATUS3_TELEKINESIS) - return FALSE; - else if (gStatuses3[battlerId] & STATUS3_MAGNET_RISE) - return FALSE; - else if (holdEffect == HOLD_EFFECT_AIR_BALLOON) - return FALSE; - else if (AI_DATA->abilities[battlerId] == ABILITY_LEVITATE) - return FALSE; - else if (IS_BATTLER_OF_TYPE(battlerId, TYPE_FLYING)) - return FALSE; - else - return TRUE; -} - bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move) { if (AI_THINKING_STRUCT->aiFlags[sBattler_AI] & AI_FLAG_NEGATE_UNAWARE) diff --git a/src/battle_main.c b/src/battle_main.c index 6e8a0d0e8f..b2b6e14447 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4196,6 +4196,7 @@ static void HandleTurnActionSelectionState(void) if ((gBattleTypeFlags & BATTLE_TYPE_HAS_AI || IsWildMonSmart()) && (BattlerHasAi(battler) && !(gBattleTypeFlags & BATTLE_TYPE_PALACE))) { + AI_DATA->aiCalcInProgress = TRUE; if (ShouldSwitch(battler, FALSE)) AI_DATA->shouldSwitch |= (1u << battler); if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_RISKY) // Risky AI switches aggressively even mid battle @@ -4204,6 +4205,7 @@ static void HandleTurnActionSelectionState(void) AI_DATA->mostSuitableMonId[battler] = GetMostSuitableMonToSwitchInto(battler, FALSE); gBattleStruct->aiMoveOrAction[battler] = ComputeBattleAiScores(battler); + AI_DATA->aiCalcInProgress = FALSE; } // fallthrough case STATE_BEFORE_ACTION_CHOSEN: // Choose an action. diff --git a/src/battle_util.c b/src/battle_util.c index 01b41aaf7a..d98ce5cbb8 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6394,7 +6394,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 } break; case ABILITY_PROTOSYNTHESIS: - if (!gDisableStructs[battler].weatherAbilityDone + if (!gDisableStructs[battler].weatherAbilityDone && (gBattleWeather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED) && !(gBattleStruct->boosterEnergyActivates & (1u << battler))) @@ -8683,7 +8683,7 @@ static bool32 IsBattlerGrounded2(u32 battler, bool32 considerInverse) return FALSE; if (holdEffect == HOLD_EFFECT_AIR_BALLOON) return FALSE; - if (GetBattlerAbility(battler) == ABILITY_LEVITATE) + if ((AI_DATA->aiCalcInProgress ? AI_DATA->abilities[battler] : GetBattlerAbility(battler)) == ABILITY_LEVITATE) return FALSE; if (IS_BATTLER_OF_TYPE(battler, TYPE_FLYING) && (!considerInverse || !FlagGet(B_FLAG_INVERSE_BATTLE))) return FALSE; From ab50009526e258994bd30fd891b7c0643d3b8e95 Mon Sep 17 00:00:00 2001 From: AlexOn1ine Date: Thu, 10 Oct 2024 10:04:44 +0200 Subject: [PATCH 2/2] rename IsBattlerGround2 --- src/battle_util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index d98ce5cbb8..83ed114c07 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8665,7 +8665,7 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move) } // Only called directly when calculating damage type effectiveness -static bool32 IsBattlerGrounded2(u32 battler, bool32 considerInverse) +static bool32 IsBattlerGroundedInverseCheck(u32 battler, bool32 considerInverse) { u32 holdEffect = GetBattlerHoldEffect(battler, TRUE); @@ -8692,7 +8692,7 @@ static bool32 IsBattlerGrounded2(u32 battler, bool32 considerInverse) bool32 IsBattlerGrounded(u32 battler) { - return IsBattlerGrounded2(battler, FALSE); + return IsBattlerGroundedInverseCheck(battler, FALSE); } bool32 IsBattlerAlive(u32 battler) @@ -10484,7 +10484,7 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(u32 move, u32 mov if (B_GLARE_GHOST < GEN_4 && move == MOVE_GLARE && IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST)) modifier = UQ_4_12(0.0); } - else if (moveType == TYPE_GROUND && !IsBattlerGrounded2(battlerDef, TRUE) && !(gMovesInfo[move].ignoreTypeIfFlyingAndUngrounded)) + else if (moveType == TYPE_GROUND && !IsBattlerGroundedInverseCheck(battlerDef, TRUE) && !(gMovesInfo[move].ignoreTypeIfFlyingAndUngrounded)) { modifier = UQ_4_12(0.0); if (recordAbilities && defAbility == ABILITY_LEVITATE)