Unify GetBattlerAbility/TerrainAffected to remove duplicate ai function

This commit is contained in:
AlexOn1ine 2024-10-10 09:55:25 +02:00
parent 806321f3c8
commit d0a97970ba
5 changed files with 13 additions and 47 deletions

View file

@ -52,8 +52,6 @@ bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move);
u32 AI_GetWeather(struct AiLogicData *aiData);
bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u32 numHits);
bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u32 index, u32 numHits);
bool32 AI_IsTerrainAffected(u32 battlerId, u32 flags);
bool32 AI_IsBattlerGrounded(u32 battlerId);
bool32 HasDamagingMove(u32 battlerId);
bool32 HasDamagingMoveOfType(u32 battlerId, u32 type);
u32 GetBattlerSecondaryDamage(u32 battlerId);

View file

@ -477,6 +477,7 @@ void SetAiLogicDataForTurn(struct AiLogicData *aiData)
// get/assume all battler data and simulate AI damage
battlersCount = gBattlersCount;
AI_DATA->aiCalcInProgress = TRUE;
for (battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++)
{
if (!IsBattlerAlive(battlerAtk))
@ -492,6 +493,7 @@ void SetAiLogicDataForTurn(struct AiLogicData *aiData)
SetBattlerAiMovesData(aiData, battlerAtk, battlersCount);
}
AI_DATA->aiCalcInProgress = FALSE;
}
static bool32 AI_SwitchMonIfSuitable(u32 battler, bool32 doubleBattle)
@ -1017,19 +1019,19 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
RETURN_SCORE_MINUS(10);
// terrain & effect checks
if (AI_IsTerrainAffected(battlerDef, STATUS_FIELD_ELECTRIC_TERRAIN))
if (IsBattlerTerrainAffected(battlerDef, STATUS_FIELD_ELECTRIC_TERRAIN))
{
if (moveEffect == EFFECT_SLEEP || moveEffect == EFFECT_YAWN)
RETURN_SCORE_MINUS(20);
}
if (AI_IsTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN))
if (IsBattlerTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN))
{
if (IsNonVolatileStatusMoveEffect(moveEffect) || IsConfusionMoveEffect(moveEffect))
RETURN_SCORE_MINUS(20);
}
if (AI_IsTerrainAffected(battlerAtk, STATUS_FIELD_PSYCHIC_TERRAIN) && atkPriority > 0)
if (IsBattlerTerrainAffected(battlerAtk, STATUS_FIELD_PSYCHIC_TERRAIN) && atkPriority > 0)
{
RETURN_SCORE_MINUS(20);
}
@ -1250,10 +1252,10 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
if (isDoubleBattle)
{
if (!(IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GRASS)
&& AI_IsBattlerGrounded(battlerAtk)
&& IsBattlerGrounded(battlerAtk)
&& (BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_ATK) || BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_SPATK)))
&& !(IS_BATTLER_OF_TYPE(BATTLE_PARTNER(battlerAtk), TYPE_GRASS)
&& AI_IsBattlerGrounded(BATTLE_PARTNER(battlerAtk))
&& IsBattlerGrounded(BATTLE_PARTNER(battlerAtk))
&& aiData->abilities[BATTLE_PARTNER(battlerAtk)] != ABILITY_CONTRARY
&& (BattlerStatCanRise(BATTLE_PARTNER(battlerAtk), aiData->abilities[BATTLE_PARTNER(battlerAtk)], STAT_ATK)
|| BattlerStatCanRise(BATTLE_PARTNER(battlerAtk), aiData->abilities[BATTLE_PARTNER(battlerAtk)], STAT_SPATK))))
@ -1262,7 +1264,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
}
}
else if (!(IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GRASS)
&& AI_IsBattlerGrounded(battlerAtk)
&& IsBattlerGrounded(battlerAtk)
&& (BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_ATK) || BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_SPATK))))
{
ADJUST_SCORE(-10);
@ -3947,7 +3949,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
ADJUST_SCORE(DECENT_EFFECT);
break;
case EFFECT_SAFEGUARD:
if (!AI_IsTerrainAffected(battlerAtk, STATUS_FIELD_MISTY_TERRAIN) || !IsBattlerGrounded(battlerAtk))
if (!IsBattlerTerrainAffected(battlerAtk, STATUS_FIELD_MISTY_TERRAIN) || !IsBattlerGrounded(battlerAtk))
ADJUST_SCORE(DECENT_EFFECT); // TODO: check if opp has status move?
//if (CountUsablePartyMons(battlerDef) != 0)
//ADJUST_SCORE(8);

View file

@ -1344,42 +1344,6 @@ u32 AI_DecideHoldEffectForTurn(u32 battlerId)
return holdEffect;
}
bool32 AI_IsTerrainAffected(u32 battlerId, u32 flags)
{
if (gStatuses3[battlerId] & STATUS3_SEMI_INVULNERABLE)
return FALSE;
else if (!(gFieldStatuses & flags))
return FALSE;
return AI_IsBattlerGrounded(battlerId);
}
// different from IsBattlerGrounded in that we don't always know battler's hold effect or ability
bool32 AI_IsBattlerGrounded(u32 battlerId)
{
u32 holdEffect = AI_DATA->holdEffects[battlerId];
if (holdEffect == HOLD_EFFECT_IRON_BALL)
return TRUE;
else if (gFieldStatuses & STATUS_FIELD_GRAVITY)
return TRUE;
else if (gStatuses3[battlerId] & STATUS3_ROOTED)
return TRUE;
else if (gStatuses3[battlerId] & STATUS3_SMACKED_DOWN)
return TRUE;
else if (gStatuses3[battlerId] & STATUS3_TELEKINESIS)
return FALSE;
else if (gStatuses3[battlerId] & STATUS3_MAGNET_RISE)
return FALSE;
else if (holdEffect == HOLD_EFFECT_AIR_BALLOON)
return FALSE;
else if (AI_DATA->abilities[battlerId] == ABILITY_LEVITATE)
return FALSE;
else if (IS_BATTLER_OF_TYPE(battlerId, TYPE_FLYING))
return FALSE;
else
return TRUE;
}
bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move)
{
if (AI_THINKING_STRUCT->aiFlags[sBattler_AI] & AI_FLAG_NEGATE_UNAWARE)

View file

@ -4196,6 +4196,7 @@ static void HandleTurnActionSelectionState(void)
if ((gBattleTypeFlags & BATTLE_TYPE_HAS_AI || IsWildMonSmart())
&& (BattlerHasAi(battler) && !(gBattleTypeFlags & BATTLE_TYPE_PALACE)))
{
AI_DATA->aiCalcInProgress = TRUE;
if (ShouldSwitch(battler, FALSE))
AI_DATA->shouldSwitch |= (1u << battler);
if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_RISKY) // Risky AI switches aggressively even mid battle
@ -4204,6 +4205,7 @@ static void HandleTurnActionSelectionState(void)
AI_DATA->mostSuitableMonId[battler] = GetMostSuitableMonToSwitchInto(battler, FALSE);
gBattleStruct->aiMoveOrAction[battler] = ComputeBattleAiScores(battler);
AI_DATA->aiCalcInProgress = FALSE;
}
// fallthrough
case STATE_BEFORE_ACTION_CHOSEN: // Choose an action.

View file

@ -6394,7 +6394,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_PROTOSYNTHESIS:
if (!gDisableStructs[battler].weatherAbilityDone
if (!gDisableStructs[battler].weatherAbilityDone
&& (gBattleWeather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
&& !(gBattleStruct->boosterEnergyActivates & (1u << battler)))
@ -8683,7 +8683,7 @@ static bool32 IsBattlerGrounded2(u32 battler, bool32 considerInverse)
return FALSE;
if (holdEffect == HOLD_EFFECT_AIR_BALLOON)
return FALSE;
if (GetBattlerAbility(battler) == ABILITY_LEVITATE)
if ((AI_DATA->aiCalcInProgress ? AI_DATA->abilities[battler] : GetBattlerAbility(battler)) == ABILITY_LEVITATE)
return FALSE;
if (IS_BATTLER_OF_TYPE(battler, TYPE_FLYING) && (!considerInverse || !FlagGet(B_FLAG_INVERSE_BATTLE)))
return FALSE;