diff --git a/asm/macros/battle_ai_script.inc b/asm/macros/battle_ai_script.inc index 0cb6681e5..1abc94b19 100644 --- a/asm/macros/battle_ai_script.inc +++ b/asm/macros/battle_ai_script.inc @@ -608,6 +608,13 @@ .4byte \ptr .endm + .macro if_physical_moves_unusable attacker:req, target:req, ptr:req + .byte 0x6B + .byte \attacker + .byte \target + .4byte \ptr + .endm + @ useful script macros .macro if_has_physical_move battler:req, ptr:req if_has_move_with_split \battler, SPLIT_PHYSICAL, \ptr diff --git a/data/battle_ai_scripts.s b/data/battle_ai_scripts.s index e9130845b..b103cd78f 100644 --- a/data/battle_ai_scripts.s +++ b/data/battle_ai_scripts.s @@ -1140,6 +1140,7 @@ AI_CV_MirrorMove_EncouragedMovesToMirror: @ 82DCB6C .2byte -1 AI_CV_AttackUp: @ 82DCBBC + if_physical_moves_unusable AI_USER, AI_TARGET, Score_Minus8 if_stat_level_less_than AI_USER, STAT_ATK, 9, AI_CV_AttackUp2 if_random_less_than 100, AI_CV_AttackUp3 score -1 diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c index 4ec4da170..d73857ee8 100644 --- a/src/battle_ai_script_commands.c +++ b/src/battle_ai_script_commands.c @@ -160,6 +160,7 @@ static void BattleAICmd_if_share_type(void); static void BattleAICmd_if_cant_use_last_resort(void); static void BattleAICmd_if_has_move_with_split(void); static void BattleAICmd_if_has_no_move_with_split(void); +static void BattleAICmd_if_physical_moves_unusable(void); // ewram EWRAM_DATA const u8 *gAIScriptPtr = NULL; @@ -277,6 +278,7 @@ static const BattleAICmdFunc sBattleAICmdTable[] = BattleAICmd_if_cant_use_last_resort, // 0x68 BattleAICmd_if_has_move_with_split, // 0x69 BattleAICmd_if_has_no_move_with_split, // 0x6A + BattleAICmd_if_physical_moves_unusable, // 0x6B }; static const u16 sDiscouragedPowerfulMoveEffects[] = @@ -2581,3 +2583,42 @@ static void BattleAICmd_if_has_no_move_with_split(void) else gAIScriptPtr += 7; } + +// This function checks if all physical/special moves are either unusable or unreasonable to use. +// Consider a pokemon boosting their attack against a ghost pokemon having only normal-type physical attacks. +static bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split) +{ + s32 i, moveType; + u16 *moves; + u32 usable = 0; + u32 unusable = CheckMoveLimitations(attacker, 0, 0xFF); + + if (IsBattlerAIControlled(attacker)) + moves = gBattleMons[attacker].moves; + else + moves = gBattleResources->battleHistory->usedMoves[attacker].moves; + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE + && moves[i] != 0xFFFF + && gBattleMoves[moves[i]].split == split + && !(unusable & gBitTable[i])) + { + SetTypeBeforeUsingMove(moves[i], attacker); + GET_MOVE_TYPE(moves[i], moveType); + if (CalcTypeEffectivenessMultiplier(moves[i], moveType, attacker, target, FALSE) != 0) + usable |= gBitTable[i]; + } + } + + return (usable == 0); +} + +static void BattleAICmd_if_physical_moves_unusable(void) +{ + if (MovesWithSplitUnusable(BattleAI_GetWantedBattler(gAIScriptPtr[1]), BattleAI_GetWantedBattler(gAIScriptPtr[2]), SPLIT_PHYSICAL)) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +}