Merge pull request #1582 from ghoulslash/smart_wild_ai

Smart Wild AI Option
This commit is contained in:
Eduardo Quezada D'Ottone 2021-12-23 20:18:18 -03:00 committed by GitHub
commit 67697d2de3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 1 deletions

View File

@ -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];

View File

@ -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.

View File

@ -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.

View File

@ -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();

View File

@ -5370,3 +5370,8 @@ void SetTotemBoost(void)
}
}
}
bool32 IsWildMonSmart(void)
{
return (B_SMART_WILD_AI_FLAG != 0 && FlagGet(B_SMART_WILD_AI_FLAG));
}