From 48fc44df3184a43258009b5bf5d8389983a97ba3 Mon Sep 17 00:00:00 2001 From: Pawkkie <61265402+Pawkkie@users.noreply.github.com> Date: Fri, 21 Feb 2025 12:11:47 -0500 Subject: [PATCH] Fix AI hold effect considerations (#6310) --- include/battle_ai_util.h | 1 + src/battle_ai_main.c | 9 +++------ src/battle_ai_switch_items.c | 6 +++--- src/battle_ai_util.c | 25 ++++++++++++++----------- src/battle_util.c | 2 +- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index c74cad2e78..eb8ca35cf8 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -213,5 +213,6 @@ bool32 AI_ShouldSetUpHazards(u32 battlerAtk, u32 battlerDef, struct AiLogicData void IncreaseTidyUpScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score); bool32 AI_ShouldSpicyExtract(u32 battlerAtk, u32 battlerAtkPartner, u32 move, struct AiLogicData *aiData); void IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score); +bool32 IsBattlerItemEnabled(u32 battler); #endif //GUARD_BATTLE_AI_UTIL_H diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index bcdd1b9ae3..584d60d4dd 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -2216,9 +2216,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } break; case EFFECT_NATURAL_GIFT: - if (aiData->abilities[battlerAtk] == ABILITY_KLUTZ - || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM - || GetPocketByItemId(gBattleMons[battlerAtk].item) != POCKET_BERRIES) + if (!IsBattlerItemEnabled(battlerAtk) || GetPocketByItemId(gBattleMons[battlerAtk].item) != POCKET_BERRIES) ADJUST_SCORE(-10); break; case EFFECT_GRASSY_TERRAIN: @@ -2325,8 +2323,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } break; case EFFECT_EMBARGO: - if (aiData->abilities[battlerDef] == ABILITY_KLUTZ - || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM + if (!IsBattlerItemEnabled(battlerAtk) || gDisableStructs[battlerDef].embargoTimer != 0 || PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove)) ADJUST_SCORE(-10); @@ -2577,7 +2574,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } // move effect checks // Choice items - if (HOLD_EFFECT_CHOICE(aiData->holdEffects[battlerAtk]) && gBattleMons[battlerAtk].ability != ABILITY_KLUTZ) + if (HOLD_EFFECT_CHOICE(aiData->holdEffects[battlerAtk]) && IsBattlerItemEnabled(battlerAtk)) { // Don't use user-target moves ie. Swords Dance, with exceptions if ((moveTarget & MOVE_TARGET_USER) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 23d96dedfe..e5ff01fab6 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -854,7 +854,7 @@ static bool32 ShouldSwitchIfBadChoiceLock(u32 battler) { u32 holdEffect = GetBattlerHoldEffect(battler, FALSE); - if (HOLD_EFFECT_CHOICE(holdEffect) && gBattleMons[battler].ability != ABILITY_KLUTZ) + if (HOLD_EFFECT_CHOICE(holdEffect) && IsBattlerItemEnabled(battler)) { if (gMovesInfo[gLastUsedMove].category == DAMAGE_CATEGORY_STATUS) return SetSwitchinAndSwitch(battler, PARTY_SIZE); @@ -1249,10 +1249,10 @@ bool32 IsMonGrounded(u16 heldItemEffect, u32 ability, u8 type1, u8 type2) { // List that makes mon not grounded if (type1 == TYPE_FLYING || type2 == TYPE_FLYING || ability == ABILITY_LEVITATE - || (heldItemEffect == HOLD_EFFECT_AIR_BALLOON && ability != ABILITY_KLUTZ)) + || (heldItemEffect == HOLD_EFFECT_AIR_BALLOON && !(ability == ABILITY_KLUTZ || (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM)))) { // List that overrides being off the ground - if ((heldItemEffect == HOLD_EFFECT_IRON_BALL && ability != ABILITY_KLUTZ) || (gFieldStatuses & STATUS_FIELD_GRAVITY) || (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM)) + if ((heldItemEffect == HOLD_EFFECT_IRON_BALL && !(ability == ABILITY_KLUTZ || (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM))) || (gFieldStatuses & STATUS_FIELD_GRAVITY) || (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM)) return TRUE; else return FALSE; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index dadf39c61e..622426f2bd 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -412,22 +412,12 @@ static inline s32 DmgRoll(s32 dmg) bool32 IsDamageMoveUnusable(u32 battlerAtk, u32 battlerDef, u32 move, u32 moveType) { struct AiLogicData *aiData = AI_DATA; - u32 battlerDefAbility; u32 partnerBattlerDefAbility; if (DoesBattlerIgnoreAbilityChecks(aiData->abilities[battlerAtk], move)) - { - battlerDefAbility = ABILITY_NONE; partnerBattlerDefAbility = ABILITY_NONE; - } else - { - battlerDefAbility = aiData->abilities[battlerDef]; partnerBattlerDefAbility = aiData->abilities[BATTLE_PARTNER(battlerDef)]; - } - - if (battlerDef == BATTLE_PARTNER(battlerAtk)) - battlerDefAbility = aiData->abilities[battlerDef]; if (gBattleStruct->commandingDondozo & (1u << battlerDef)) return TRUE; @@ -469,7 +459,7 @@ bool32 IsDamageMoveUnusable(u32 battlerAtk, u32 battlerDef, u32 move, u32 moveTy return TRUE; break; case EFFECT_POLTERGEIST: - if (AI_DATA->items[battlerDef] == ITEM_NONE || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM || battlerDefAbility == ABILITY_KLUTZ) + if (AI_DATA->items[battlerDef] == ITEM_NONE || !IsBattlerItemEnabled(battlerDef)) return TRUE; break; case EFFECT_FIRST_TURN_ONLY: @@ -4141,3 +4131,16 @@ void IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 * if (AI_DATA->hpPercents[battlerAtk] > 70) ADJUST_SCORE_PTR(WEAK_EFFECT); } + +bool32 IsBattlerItemEnabled(u32 battler) +{ + if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_NEGATE_UNAWARE) + return TRUE; + if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM) + return FALSE; + if (gStatuses3[battler] & STATUS3_EMBARGO) + return FALSE; + if (gBattleMons[battler].ability == ABILITY_KLUTZ && !(gStatuses3[battler] & STATUS3_GASTRO_ACID)) + return FALSE; + return TRUE; +} diff --git a/src/battle_util.c b/src/battle_util.c index 09679f656a..5c32262b43 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8606,7 +8606,7 @@ u32 GetBattlerHoldEffectInternal(u32 battler, bool32 checkNegating, bool32 check return HOLD_EFFECT_NONE; if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM) return HOLD_EFFECT_NONE; - if (checkAbility && GetBattlerAbility(battler) == ABILITY_KLUTZ) + if (checkAbility && GetBattlerAbility(battler) == ABILITY_KLUTZ && !(gStatuses3[battler] & STATUS3_GASTRO_ACID)) return HOLD_EFFECT_NONE; }