From 746d9ea6c52c523ebd52d765fd63b112e9933912 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Wed, 27 Apr 2022 22:23:20 +1200 Subject: [PATCH] Add AI_GetBattlerMoveTargetType() Add AI version of the function that handles move target selection, as it needs to have ability and item info that it may not have access to. --- include/battle_ai_util.h | 1 + src/battle_ai_main.c | 18 +++++++++--------- src/battle_ai_util.c | 12 +++++++++++- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index 5ccf68c58..0b2afebae 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -60,6 +60,7 @@ bool32 IsAbilityOfRating(u16 ability, s8 rating); s8 GetAbilityRating(u16 ability); bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability); bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move); +u32 AI_GetBattlerMoveTargetType(u8 battlerId, u16 move); // stat stage checks bool32 AnyStatIsRaised(u8 battlerId); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 16e830efe..192b75d74 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -550,7 +550,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) u8 atkPriority = GetMovePriority(battlerAtk, move); u16 moveEffect = gBattleMoves[move].effect; s32 moveType; - u16 moveTarget = GetBattlerMoveTargetType(battlerAtk, move); + u16 moveTarget = AI_GetBattlerMoveTargetType(battlerAtk, move); u16 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect, move); u8 effectiveness = AI_GetMoveEffectiveness(move, battlerAtk, battlerDef); bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk); @@ -2371,7 +2371,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) } else { - if (GetBattlerMoveTargetType(battlerDef, instructedMove) & (MOVE_TARGET_SELECTED + if (AI_GetBattlerMoveTargetType(battlerDef, instructedMove) & (MOVE_TARGET_SELECTED | MOVE_TARGET_DEPENDS | MOVE_TARGET_RANDOM | MOVE_TARGET_BOTH @@ -2568,7 +2568,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) // move data u8 moveType = gBattleMoves[move].type; u16 effect = gBattleMoves[move].effect; - u16 moveTarget = GetBattlerMoveTargetType(battlerAtk, move); + u16 moveTarget = AI_GetBattlerMoveTargetType(battlerAtk, move); // ally data u8 battlerAtkPartner = AI_DATA->battlerAtkPartner; u16 atkPartnerAbility = AI_DATA->atkPartnerAbility; @@ -2875,7 +2875,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (instructedMove != MOVE_NONE && !IS_MOVE_STATUS(instructedMove) - && (GetBattlerMoveTargetType(battlerAtkPartner, instructedMove) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) // Use instruct on multi-target moves + && (AI_GetBattlerMoveTargetType(battlerAtkPartner, instructedMove) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) // Use instruct on multi-target moves { RETURN_SCORE_PLUS(1); } @@ -3698,24 +3698,24 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); break; case MOVE_WIDE_GUARD: - if (predictedMove != MOVE_NONE && GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_BOTH)) + if (predictedMove != MOVE_NONE && AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_BOTH)) { ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); } - else if (isDoubleBattle && GetBattlerMoveTargetType(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove) & MOVE_TARGET_FOES_AND_ALLY) + else if (isDoubleBattle && AI_GetBattlerMoveTargetType(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove) & MOVE_TARGET_FOES_AND_ALLY) { if (AI_DATA->atkAbility != ABILITY_TELEPATHY) ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); } break; case MOVE_CRAFTY_SHIELD: - if (predictedMove != MOVE_NONE && IS_MOVE_STATUS(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER)) + if (predictedMove != MOVE_NONE && IS_MOVE_STATUS(predictedMove) && !(AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER)) ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); break; case MOVE_MAT_BLOCK: if (gDisableStructs[battlerAtk].isFirstTurn && predictedMove != MOVE_NONE - && !IS_MOVE_STATUS(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER)) + && !IS_MOVE_STATUS(predictedMove) && !(AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER)) ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); break; case MOVE_KINGS_SHIELD: @@ -4160,7 +4160,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) score += 10; break; case EFFECT_MAGIC_COAT: - if (IS_MOVE_STATUS(predictedMove) && GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_SELECTED | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH)) + if (IS_MOVE_STATUS(predictedMove) && AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_SELECTED | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH)) score += 3; break; case EFFECT_RECYCLE: diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 4b344ecba..de4271bba 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1251,6 +1251,16 @@ bool32 AI_WeatherHasEffect(void) return TRUE; } +u32 AI_GetBattlerMoveTargetType(u8 battlerId, u16 move) +{ + u32 target; + + if (gBattleMoves[move].effect == EFFECT_EXPANDING_FORCE && AI_IsTerrainAffected(battlerId, STATUS_FIELD_PSYCHIC_TERRAIN)) + return MOVE_TARGET_BOTH; + else + return gBattleMoves[move].target; +} + bool32 IsAromaVeilProtectedMove(u16 move) { u32 i; @@ -1919,7 +1929,7 @@ bool32 HasMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef, u8 accCheck, bool32 if (ignoreStatus && IS_MOVE_STATUS(moves[i])) continue; else if ((!IS_MOVE_STATUS(moves[i]) && gBattleMoves[moves[i]].accuracy == 0) - || GetBattlerMoveTargetType(battlerAtk, moves[i]) & (MOVE_TARGET_USER | MOVE_TARGET_OPPONENTS_FIELD)) + || AI_GetBattlerMoveTargetType(battlerAtk, moves[i]) & (MOVE_TARGET_USER | MOVE_TARGET_OPPONENTS_FIELD)) continue; if (AI_GetMoveAccuracy(battlerAtk, battlerDef, atkAbility, defAbility, atkHoldEffect, defHoldEffect, moves[i]) <= accCheck) return TRUE;