From 0a0687ae78ea2e71bca8b9f6e44fccc6f1907aae Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 27 Jul 2021 09:49:39 -0600 Subject: [PATCH 1/4] add smart wild AI --- include/battle_main.h | 1 + include/constants/battle_config.h | 4 ++++ src/battle_ai_main.c | 28 ++++++++++++++++++++++++++++ src/battle_controller_opponent.c | 3 ++- src/battle_main.c | 5 +++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/include/battle_main.h b/include/battle_main.h index bf95ca156..aa2c4c605 100644 --- a/include/battle_main.h +++ b/include/battle_main.h @@ -70,6 +70,7 @@ void RunBattleScriptCommands(void); bool8 TryRunFromBattle(u8 battlerId); void SpecialStatusesClear(void); void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk); +bool32 IsWildMonSmart(void); extern struct UnknownPokemonStruct4 gMultiPartnerParty[MULTI_PARTY_SIZE]; diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index bf31c77b3..b6c8b98e9 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -153,6 +153,10 @@ #define B_CRITICAL_CAPTURE TRUE // If set to TRUE, Critical Capture will be enabled. #define B_CATCHING_CHARM_BOOST 20 // % boost in Critical Capture odds if player has the Catching Charm. +// AI Settings +#define B_SMART_WILD_AI_FLAG 0x1DE // If not 0, you can set this flag in a script to enable smart wild pokemon +#define B_VAR_WILD_AI_FLAGS 0x40F7 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15) + // Other #define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. #define B_SLEEP_TURNS GEN_7 // In Gen5+, sleep lasts for 1-3 turns instead of 2-5 turns. diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 81d97fcab..8909afed4 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,29 @@ 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; + + if (avgLevel < 20) + flags |= AI_FLAG_CHECK_BAD_MOVE; + if (avgLevel < 40) + flags |= AI_FLAG_CHECK_VIABILITY; + if (avgLevel < 60) + flags |= AI_FLAG_PREFER_STRONGEST_MOVE; + if (avgLevel < 100) + 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 +165,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 4eeef55c3..fdd650754 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -1558,7 +1558,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 94700bf96..bb376c665 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5130,3 +5130,8 @@ void SetTotemBoost(void) } } } + +bool32 IsWildMonSmart(void) +{ + return (B_SMART_WILD_AI_FLAG != 0 && FlagGet(B_SMART_WILD_AI_FLAG)); +} From 3dcfc0fc12f7f3e0112887c2257dca441eefa715 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 27 Jul 2021 09:53:47 -0600 Subject: [PATCH 2/4] fix default wild ai flag logic --- src/battle_ai_main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 8909afed4..56c50c009 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -132,13 +132,12 @@ static u32 GetWildAiFlags(void) if (IsDoubleBattle()) avgLevel = (GetMonData(&gEnemyParty[0], MON_DATA_LEVEL) + GetMonData(&gEnemyParty[1], MON_DATA_LEVEL)) / 2; - if (avgLevel < 20) - flags |= AI_FLAG_CHECK_BAD_MOVE; - if (avgLevel < 40) + flags |= AI_FLAG_CHECK_BAD_MOVE; + if (avgLevel >= 20) flags |= AI_FLAG_CHECK_VIABILITY; - if (avgLevel < 60) + if (avgLevel >= 60) flags |= AI_FLAG_PREFER_STRONGEST_MOVE; - if (avgLevel < 100) + if (avgLevel >= 80) flags |= AI_FLAG_HP_AWARE; if (B_VAR_WILD_AI_FLAGS != 0 && VarGet(B_VAR_WILD_AI_FLAGS) != 0) From 02fe96cc0815db17bc3660eee31d64ead7211428 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 20 Dec 2021 13:06:23 -0500 Subject: [PATCH 3/4] fix config settings --- include/constants/battle_config.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 4076b3ed0..08f6988f3 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -176,11 +176,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) // Interface settings #define B_ABILITY_POP_UP TRUE // In Gen5+, the Pokémon abilities are displayed in a pop-up, when they activate in battle. @@ -198,10 +200,6 @@ #define B_LAST_USED_BALL TRUE // If TRUE, the "last used ball" feature from Gen 7 will be implemented #define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball. -// AI Settings -#define B_SMART_WILD_AI_FLAG 0x1DE // If not 0, you can set this flag in a script to enable smart wild pokemon -#define B_VAR_WILD_AI_FLAGS 0x40F7 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15) - // Other #define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. #define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8. From 05f91bc24347909d81347470af1baf0577ae5f4b Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Mon, 20 Dec 2021 14:06:32 -0500 Subject: [PATCH 4/4] Update include/constants/battle_config.h Co-authored-by: LOuroboros --- include/constants/battle_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 08f6988f3..bdcf871b8 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -176,7 +176,7 @@ // 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 +#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.