diff --git a/include/battle_main.h b/include/battle_main.h index ed35566d8f..02ede6e0ec 100644 --- a/include/battle_main.h +++ b/include/battle_main.h @@ -68,6 +68,7 @@ void RunBattleScriptCommands(void); bool8 TryRunFromBattle(u8 battlerId); void SpecialStatusesClear(void); void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk); +bool32 IsWildMonSmart(void); extern struct MultiPartnerMenuPokemon gMultiPartnerParty[MULTI_PARTY_SIZE]; diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 9563e6b50e..a408e4c696 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -198,11 +198,13 @@ // Eg: Replace with FLAG_UNUSED_0x264 so you can use that flag to toggle the feature. #define B_FLAG_INVERSE_BATTLE 0 // If this flag is set, the battle's type effectiveness are inversed. For example, fire is super effective against water. #define B_FLAG_FORCE_DOUBLE_WILD 0 // If this flag is set, all land and surfing wild battles will be double battles. +#define B_SMART_WILD_AI_FLAG 0 // If not 0, you can set this flag in a script to enable smart wild pokemon // Var Settings // To use the following features in scripting, replace the 0s with the var ID you're assigning it to. // Eg: Replace with VAR_UNUSED_0x40F7 so you can use VAR_TERRAIN for that feature. #define VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active +#define B_VAR_WILD_AI_FLAGS 0 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15) // Terrain settings #define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades. diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index e6159f7251..21227cc857 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -7,6 +7,7 @@ #include "battle_factory.h" #include "battle_setup.h" #include "data.h" +#include "event_data.h" #include "item.h" #include "pokemon.h" #include "random.h" @@ -123,6 +124,28 @@ void BattleAI_SetupItems(void) } } +static u32 GetWildAiFlags(void) +{ + u8 avgLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL); + u32 flags; + + if (IsDoubleBattle()) + avgLevel = (GetMonData(&gEnemyParty[0], MON_DATA_LEVEL) + GetMonData(&gEnemyParty[1], MON_DATA_LEVEL)) / 2; + + flags |= AI_FLAG_CHECK_BAD_MOVE; + if (avgLevel >= 20) + flags |= AI_FLAG_CHECK_VIABILITY; + if (avgLevel >= 60) + flags |= AI_FLAG_PREFER_STRONGEST_MOVE; + if (avgLevel >= 80) + flags |= AI_FLAG_HP_AWARE; + + if (B_VAR_WILD_AI_FLAGS != 0 && VarGet(B_VAR_WILD_AI_FLAGS) != 0) + flags |= VarGet(B_VAR_WILD_AI_FLAGS); + + return flags; +} + void BattleAI_SetupFlags(void) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) @@ -141,6 +164,10 @@ void BattleAI_SetupFlags(void) AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags | gTrainers[gTrainerBattleOpponent_B].aiFlags; else AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags; + + // check smart wild AI + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER)) && IsWildMonSmart()) + AI_THINKING_STRUCT->aiFlags |= GetWildAiFlags(); if (gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS) || gTrainers[gTrainerBattleOpponent_A].doubleBattle) AI_THINKING_STRUCT->aiFlags |= AI_FLAG_DOUBLE_BATTLE; // Act smart in doubles and don't attack your partner. diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index 1107787960..0c4b08620c 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -1563,7 +1563,8 @@ static void OpponentHandleChooseMove(void) u8 chosenMoveId; struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]); - if (gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER)) + if (gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER) + || IsWildMonSmart()) { BattleAI_SetupAIData(0xF); chosenMoveId = BattleAI_ChooseMoveOrAction(); diff --git a/src/battle_main.c b/src/battle_main.c index 298762ebc9..ca6fda8574 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5370,3 +5370,8 @@ void SetTotemBoost(void) } } } + +bool32 IsWildMonSmart(void) +{ + return (B_SMART_WILD_AI_FLAG != 0 && FlagGet(B_SMART_WILD_AI_FLAG)); +}