diff --git a/asm/macros/battle_ai_script.inc b/asm/macros/battle_ai_script.inc index 2e2b54c57..b91f518fd 100644 --- a/asm/macros/battle_ai_script.inc +++ b/asm/macros/battle_ai_script.inc @@ -559,6 +559,16 @@ .4byte \param2 .endm + .macro get_ally_chosen_move bank + .byte 0x63 + .endm + + .macro if_has_no_attacking_moves bank, param1 + .byte 0x64 + .byte \bank + .4byte \param1 + .endm + @ useful script macros .macro get_curr_move_type get_type AI_TYPE_MOVE diff --git a/data/battle_ai_scripts.s b/data/battle_ai_scripts.s index d0e580459..1c86dbd28 100644 --- a/data/battle_ai_scripts.s +++ b/data/battle_ai_scripts.s @@ -2943,8 +2943,35 @@ BattleAIScript_82DDF7B: BattleAIScript_82DDFB3: end - + +AI_ConsiderAllyChosenMove: + get_ally_chosen_move + if_equal 0, AI_ConsiderAllyChosenMoveRet + get_move_effect_from_result + if_equal EFFECT_HELPING_HAND, AI_PartnerChoseHelpingHand +AI_ConsiderAllyChosenMoveRet: + end + +AI_PartnerChoseHelpingHand: + @ Do not use a status move if you know your move's power will be boosted + get_considered_move_power + if_equal 0, Score_Minus3 + end + +AI_ConsiderAllyKnownMoves: + @ If ally already chose a move, there is nothing to do here. + get_ally_chosen_move + if_not_equal 0, AI_Ret + if_move MOVE_HELPING_HAND, AI_HelpingHandInDoubles + end + +AI_HelpingHandInDoubles: + if_has_no_attacking_moves AI_USER_PARTNER, Score_Minus3 + end + AI_DoubleBattle: + call AI_ConsiderAllyChosenMove + call AI_ConsiderAllyKnownMoves if_target_is_ally AI_TryOnAlly if_move MOVE_SKILL_SWAP, BattleAIScript_82DE04B get_curr_move_type diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c index 53e5e4c23..0817bbca0 100644 --- a/src/battle_ai_script_commands.c +++ b/src/battle_ai_script_commands.c @@ -153,6 +153,8 @@ static void BattleAICmd_is_of_type(void); static void BattleAICmd_if_target_is_ally(void); static void BattleAICmd_if_flash_fired(void); static void BattleAICmd_if_holds_item(void); +static void BattleAICmd_get_ally_chosen_move(void); +static void BattleAICmd_if_has_no_attacking_moves(void); // ewram EWRAM_DATA const u8 *gAIScriptPtr = NULL; @@ -262,6 +264,8 @@ static const BattleAICmdFunc sBattleAICmdTable[] = BattleAICmd_check_ability, // 0x60 BattleAICmd_if_flash_fired, // 0x61 BattleAICmd_if_holds_item, // 0x62 + BattleAICmd_get_ally_chosen_move, // 0x63 + BattleAICmd_if_has_no_attacking_moves, // 0x64 }; static const u16 sDiscouragedPowerfulMoveEffects[] = @@ -379,7 +383,7 @@ void BattleAI_SetupAIData(u8 defaultScoreMoves) else AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE || gTrainers[gTrainerBattleOpponent_A].doubleBattle) AI_THINKING_STRUCT->aiFlags |= AI_SCRIPT_DOUBLE_BATTLE; // Act smart in doubles and don't attack your partner. gBattleStruct->debugAIFlags = AI_THINKING_STRUCT->aiFlags; @@ -2453,3 +2457,43 @@ static bool8 AIStackPop(void) return FALSE; } } + +static void BattleAICmd_get_ally_chosen_move(void) +{ + u8 partnerBattler = BATTLE_PARTNER(sBattler_AI); + if (!IsBattlerAlive(partnerBattler) || !IsBattlerAIControlled(partnerBattler)) + AI_THINKING_STRUCT->funcResult = 0; + else if (partnerBattler > sBattler_AI) // Battler with the lower id chooses the move first. + AI_THINKING_STRUCT->funcResult = 0; + else + AI_THINKING_STRUCT->funcResult = gBattleMons[partnerBattler].moves[gBattleStruct->chosenMovePositions[partnerBattler]]; + + gAIScriptPtr++; +} + +static void BattleAICmd_if_has_no_attacking_moves(void) +{ + s32 i; + u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); + if (IsBattlerAIControlled(battlerId)) + { + for (i = 0; i < 4; i++) + { + if (gBattleMons[battlerId].moves[i] != 0 && gBattleMoves[gBattleMons[battlerId].moves[i]].power != 0) + break; + } + } + else + { + for (i = 0; i < 4; i++) + { + if (BATTLE_HISTORY->usedMoves[battlerId].moves[i] != 0 && gBattleMoves[BATTLE_HISTORY->usedMoves[battlerId].moves[i]].power != 0) + break; + } + } + + if (i == 4) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} diff --git a/src/data/trainers.h b/src/data/trainers.h index 19e210acc..9e1662995 100644 --- a/src/data/trainers.h +++ b/src/data/trainers.h @@ -4249,7 +4249,7 @@ const struct Trainer gTrainers[] = { .trainerPic = TRAINER_PIC_WINSTRATE_F, .trainerName = _("ISABEL"), .items = {ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, - .doubleBattle = FALSE, + .doubleBattle = 1, .aiFlags = 0x1, .partySize = 2, .party = {.ItemDefaultMoves = gTrainerParty_Isabel2 }