Fix AI hazard move handling, minor AI tweaks (#6311)
This commit is contained in:
parent
fe7ed22f5b
commit
bf263efa4b
@ -127,7 +127,7 @@ bool32 IsAromaVeilProtectedEffect(u32 moveEffect);
|
||||
bool32 IsNonVolatileStatusMoveEffect(u32 moveEffect);
|
||||
bool32 IsMoveRedirectionPrevented(u32 battlerAtk, u32 move, u32 atkAbility);
|
||||
bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 IsHazardMoveEffect(u32 moveEffect);
|
||||
bool32 IsHazardMove(u32 move);
|
||||
bool32 IsTwoTurnNotSemiInvulnerableMove(u32 battlerAtk, u32 move);
|
||||
void ProtectChecks(u32 battlerAtk, u32 battlerDef, u32 move, u32 predictedMove, s32 *score);
|
||||
bool32 ShouldSetSandstorm(u32 battler, u32 ability, u32 holdEffect);
|
||||
@ -154,6 +154,7 @@ bool32 HasSubstituteIgnoringMove(u32 battler);
|
||||
bool32 HasHighCritRatioMove(u32 battler);
|
||||
bool32 HasMagicCoatAffectedMove(u32 battler);
|
||||
bool32 HasSnatchAffectedMove(u32 battler);
|
||||
bool32 IsHazardClearingMove(u32 move);
|
||||
|
||||
// status checks
|
||||
bool32 AI_CanGetFrostbite(u32 battler, u32 ability);
|
||||
@ -217,5 +218,6 @@ void IncreaseTidyUpScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
bool32 AI_ShouldSpicyExtract(u32 battlerAtk, u32 battlerAtkPartner, u32 move, struct AiLogicData *aiData);
|
||||
void IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
bool32 IsBattlerPredictedToSwitch(u32 battler);
|
||||
bool32 HasLowAccuracyMove(u32 battlerAtk, u32 battlerDef);
|
||||
|
||||
#endif //GUARD_BATTLE_AI_UTIL_H
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
#define SHOULD_SWITCH_REGENERATOR_STATS_RAISED_PERCENTAGE 20
|
||||
|
||||
// AI held item-based move scoring
|
||||
#define BLUNDER_POLICY_ACCURACY_THRESHOLD 75 // Moves with accuracy equal below this value are prioritized when holding Blunder Policy
|
||||
#define LOW_ACCURACY_THRESHOLD 75 // Moves with accuracy equal OR below this value are considered low accuracy
|
||||
|
||||
// AI prediction chances
|
||||
#define PREDICT_SWITCH_CHANCE 50
|
||||
|
||||
@ -2112,7 +2112,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
|
||||
if (isDoubleBattle)
|
||||
{
|
||||
if (IsHazardMoveEffect(GetMoveEffect(aiData->partnerMove)) // partner is going to set up hazards
|
||||
if (IsHazardMove(aiData->partnerMove) // partner is going to set up hazards
|
||||
&& AI_IsFaster(BATTLE_PARTNER(battlerAtk), battlerAtk, aiData->partnerMove)) // partner is going to set up before the potential Defog
|
||||
{
|
||||
ADJUST_SCORE(-10);
|
||||
@ -3308,7 +3308,7 @@ static u32 AI_CalcHoldEffectMoveScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
{
|
||||
u32 moveAcc = aiData->moveAccuracy[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex];
|
||||
|
||||
if (moveAcc <= BLUNDER_POLICY_ACCURACY_THRESHOLD)
|
||||
if (moveAcc <= LOW_ACCURACY_THRESHOLD)
|
||||
{
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
}
|
||||
@ -4015,7 +4015,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
{
|
||||
if (isDoubleBattle)
|
||||
{
|
||||
if (IsHazardMoveEffect(GetMoveEffect(aiData->partnerMove)) // Partner is going to set up hazards
|
||||
if (IsHazardMove(aiData->partnerMove) // Partner is going to set up hazards
|
||||
&& AI_IsSlower(battlerAtk, BATTLE_PARTNER(battlerAtk), move)) // Partner going first
|
||||
break; // Don't use Defog if partner is going to set up hazards
|
||||
}
|
||||
|
||||
@ -908,14 +908,8 @@ static bool32 CanMonSurviveHazardSwitchin(u32 battler)
|
||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||
{
|
||||
aiMove = GetMonData(&party[i], MON_DATA_MOVE1 + j, NULL);
|
||||
u32 aiEffect = GetMoveEffect(aiMove);
|
||||
if (aiEffect == EFFECT_RAPID_SPIN
|
||||
|| (B_DEFOG_EFFECT_CLEARING >= GEN_6 && aiEffect == EFFECT_DEFOG)
|
||||
|| aiEffect == EFFECT_TIDY_UP)
|
||||
{
|
||||
// Have a mon that can clear the hazards, so switching out is okay
|
||||
if (IsHazardClearingMove(aiMove)) // Have a mon that can clear the hazards, so switching out is okay
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Faints to hazards and party can't clear them, don't switch out
|
||||
|
||||
@ -1471,8 +1471,10 @@ bool32 IsConfusionMoveEffect(u32 moveEffect)
|
||||
}
|
||||
}
|
||||
|
||||
bool32 IsHazardMoveEffect(u32 moveEffect)
|
||||
bool32 IsHazardMove(u32 move)
|
||||
{
|
||||
// Hazard setting moves like Stealth Rock, Spikes, etc.
|
||||
u32 i, moveEffect = gMovesInfo[move].effect;
|
||||
switch (moveEffect)
|
||||
{
|
||||
case EFFECT_SPIKES:
|
||||
@ -1480,9 +1482,48 @@ bool32 IsHazardMoveEffect(u32 moveEffect)
|
||||
case EFFECT_STICKY_WEB:
|
||||
case EFFECT_STEALTH_ROCK:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u32 additionalEffectCount = GetMoveAdditionalEffectCount(move);
|
||||
for (i = 0; i < additionalEffectCount; i++)
|
||||
{
|
||||
const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
|
||||
switch (additionalEffect->moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_STEELSURGE:
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsHazardClearingMove(u32 move)
|
||||
{
|
||||
// Hazard clearing effects like Rapid Spin, Tidy Up, etc.
|
||||
u32 i, moveEffect = gMovesInfo[move].effect;
|
||||
switch (moveEffect)
|
||||
{
|
||||
case EFFECT_RAPID_SPIN:
|
||||
case EFFECT_TIDY_UP:
|
||||
return TRUE;
|
||||
case EFFECT_DEFOG:
|
||||
if (B_DEFOG_EFFECT_CLEARING >= GEN_6)
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
u32 additionalEffectCount = GetMoveAdditionalEffectCount(move);
|
||||
for (i = 0; i < additionalEffectCount; i++)
|
||||
{
|
||||
const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
|
||||
switch (additionalEffect->moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_DEFOG:
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsMoveRedirectionPrevented(u32 battlerAtk, u32 move, u32 atkAbility)
|
||||
@ -2957,7 +2998,7 @@ bool32 IsBattlerIncapacitated(u32 battler, u32 ability)
|
||||
if ((gBattleMons[battler].status1 & STATUS1_FREEZE) && !HasThawingMove(battler))
|
||||
return TRUE; // if battler has thawing move we assume they will definitely use it, and thus being frozen should be neglected
|
||||
|
||||
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
|
||||
if (gBattleMons[battler].status1 & STATUS1_SLEEP && !HasMoveEffect(battler, EFFECT_SLEEP_TALK))
|
||||
return TRUE;
|
||||
|
||||
if (gBattleMons[battler].status2 & STATUS2_RECHARGE || (ability == ABILITY_TRUANT && gDisableStructs[battler].truantCounter != 0))
|
||||
@ -3713,6 +3754,20 @@ static const u16 sRecycleEncouragedItems[] =
|
||||
ITEM_CUSTAP_BERRY,
|
||||
ITEM_MENTAL_HERB,
|
||||
ITEM_FOCUS_SASH,
|
||||
ITEM_SALAC_BERRY,
|
||||
ITEM_LIECHI_BERRY,
|
||||
ITEM_AGUAV_BERRY,
|
||||
ITEM_FIGY_BERRY,
|
||||
ITEM_IAPAPA_BERRY,
|
||||
ITEM_MAGO_BERRY,
|
||||
ITEM_WIKI_BERRY,
|
||||
ITEM_MENTAL_HERB,
|
||||
ITEM_POWER_HERB,
|
||||
ITEM_BERRY_JUICE,
|
||||
ITEM_WEAKNESS_POLICY,
|
||||
ITEM_BLUNDER_POLICY,
|
||||
ITEM_KEE_BERRY,
|
||||
ITEM_MARANGA_BERRY,
|
||||
// TODO expand this
|
||||
};
|
||||
|
||||
@ -4091,6 +4146,7 @@ bool32 AI_ShouldCopyStatChanges(u32 battlerAtk, u32 battlerDef)
|
||||
case STAT_SPATK:
|
||||
return (HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_SPECIAL));
|
||||
case STAT_ACC:
|
||||
return (HasLowAccuracyMove(battlerAtk, battlerDef));
|
||||
case STAT_EVASION:
|
||||
case STAT_SPEED:
|
||||
return TRUE;
|
||||
@ -4110,7 +4166,10 @@ bool32 AI_ShouldSetUpHazards(u32 battlerAtk, u32 battlerDef, struct AiLogicData
|
||||
if (aiData->abilities[battlerDef] == ABILITY_MAGIC_BOUNCE
|
||||
|| CountUsablePartyMons(battlerDef) == 0
|
||||
|| HasMoveEffect(battlerDef, EFFECT_RAPID_SPIN)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_DEFOG))
|
||||
|| HasMoveEffect(battlerDef, EFFECT_TIDY_UP)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_DEFOG)
|
||||
|| HasMoveWithAdditionalEffect(battlerDef, MOVE_EFFECT_DEFOG)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_MAGIC_COAT))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
@ -4211,3 +4270,14 @@ void IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *
|
||||
if (AI_DATA->hpPercents[battlerAtk] > 70)
|
||||
ADJUST_SCORE_PTR(WEAK_EFFECT);
|
||||
}
|
||||
|
||||
bool32 HasLowAccuracyMove(u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (AI_DATA->moveAccuracy[battlerAtk][battlerDef][i] <= LOW_ACCURACY_THRESHOLD)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user