add AI_FLAG_SMART_SWITCHING, some burn checks

This commit is contained in:
Evan 2021-02-14 09:37:04 -07:00
parent 167aaef8f6
commit d65d5cb8fd
4 changed files with 39 additions and 13 deletions

View File

@ -81,6 +81,7 @@ u8 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef);
u16 *GetMovesArray(u32 battler);
bool32 IsConfusionMoveEffect(u16 moveEffect);
bool32 HasMove(u32 battlerId, u32 move);
bool32 HasOnlyMovesWithSplit(u32 battlerId, u32 split, bool32 onlyOffensive);
bool32 HasMoveWithSplit(u32 battler, u32 split);
bool32 HasMoveWithType(u32 battler, u8 type);
bool32 HasMoveWithTypeAndSplit(u32 battler, u8 type, u8 split);

View File

@ -53,6 +53,7 @@
#define AI_FLAG_PREFER_STATUS_MOVES (1 << 12) // AI gets a score bonus for status moves. Should be combined with AI_FLAG_CHECK_BAD_MOVE to prevent using only status moves
#define AI_FLAG_STALL (1 << 13) // AI stalls battle and prefers secondary damage/trapping/etc. TODO not finished
#define AI_FLAG_SCREENER (1 << 14) // AI prefers screening effects like reflect, mist, etc. TODO unfinished
#define AI_FLAG_SMART_SWITCHING (1 << 15) // AI includes a lot more switching checks
// 'other' ai logic flags
#define AI_FLAG_ROAMING (1 << 29)

View File

@ -2864,18 +2864,6 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
// check damage
if (gBattleMoves[move].power != 0 && GetMoveDamageResult(move) == MOVE_POWER_WEAK)
score--;
/*if (CountUsablePartyMons(battlerAtk) != 0
&& GetMoveDamageResult(move) != 0 && !HasMoveWithSplit(battlerAtk, SPLIT_STATUS)
&& GetCurrDamageHpPercent(battlerAtk, battlerDef) < 30)
{
if (GetCurrDamageHpPercent(battlerAtk, battlerDef) > 20)
score--;
else if (GetMoveDamageResult(move) == MOVE_POWER_BEST)
score -= 2;
else
score -= 3;
}*/
// check status move preference
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_PREFER_STATUS_MOVES && IS_MOVE_STATUS(move) && effectiveness != AI_EFFECTIVENESS_x0)
@ -2885,6 +2873,25 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if ((gBattleMons[battlerAtk].status1 & STATUS1_FREEZE) && IsThawingMove(battlerAtk, move))
score += (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) ? 20 : 10;
// check burn
if (gBattleMons[battlerAtk].status1 & STATUS1_BURN)
{
switch (AI_DATA->atkAbility)
{
case ABILITY_GUTS:
break;
case ABILITY_NATURAL_CURE:
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING
&& HasOnlyMovesWithSplit(battlerAtk, SPLIT_PHYSICAL, TRUE))
score = 90; // Force switch if all your attacking moves are physical and you have Natural Cure.
break;
default:
if (IS_MOVE_PHYSICAL(move) && gBattleMoves[move].effect != EFFECT_FACADE)
score -= 2;
break;
}
}
// ability checks
switch (AI_DATA->atkAbility)
{
@ -4534,7 +4541,8 @@ static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|| gBattleResults.battleTurnCounter != 0)
return score;
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING
&& GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1
&& CanTargetFaintAi(battlerDef, battlerAtk)
&& GetMovePriority(battlerAtk, move) == 0)
{

View File

@ -1755,6 +1755,22 @@ u16 *GetMovesArray(u32 battler)
return gBattleResources->battleHistory->usedMoves[battler];
}
bool32 HasOnlyMovesWithSplit(u32 battlerId, u32 split, bool32 onlyOffensive)
{
u32 i;
u16 *moves = GetMovesArray(battlerId);
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (onlyOffensive && IS_MOVE_STATUS(moves[i]))
continue;
if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && GetBattleMoveSplit(moves[i]) != split)
return FALSE;
}
return TRUE;
}
bool32 HasMoveWithSplit(u32 battler, u32 split)
{
u32 i;