mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 03:34:15 +01:00
Fix how AI categorizes Weak moves and give priority to always hits moves when needed (#3109)
* ai weak move fix and always hits move prioritarizing
This commit is contained in:
parent
58ede15263
commit
3c5c68ac58
@ -85,6 +85,7 @@ bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility);
|
||||
bool32 IsAffectedByPowder(u8 battler, u16 ability, u16 holdEffect);
|
||||
bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split);
|
||||
s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *effectiveness, bool32 considerZPower);
|
||||
u32 GetNoOfHitsToKO(u32 dmg, s32 hp);
|
||||
u8 GetMoveDamageResult(u16 move);
|
||||
u32 GetCurrDamageHpPercent(u8 battlerAtk, u8 battlerDef);
|
||||
u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef);
|
||||
|
@ -3102,6 +3102,19 @@ static bool32 IsPinchBerryItemEffect(u16 holdEffect)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static u32 GetAIMostDamagingMoveId(u8 battlerAtk, u8 battlerDef)
|
||||
{
|
||||
u32 i, id = 0;
|
||||
u32 mostDmg = 0;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (AI_DATA->simulatedDmg[battlerAtk][battlerDef][i] > mostDmg)
|
||||
id = i, mostDmg = AI_DATA->simulatedDmg[battlerAtk][battlerDef][i];
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
// AI_FLAG_CHECK_VIABILITY - a weird mix of increasing and decreasing scores
|
||||
static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
@ -3122,6 +3135,14 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
// check always hits
|
||||
if (!IS_MOVE_STATUS(move) && gBattleMoves[move].accuracy == 0)
|
||||
{
|
||||
// If 2 moves can KO the target in the same number of turns, but one of them always hits and there is a risk the other move could miss, prioritize the always hits move.
|
||||
if (gBattleMons[battlerDef].statStages[STAT_EVASION] > 6 || gBattleMons[battlerAtk].statStages[STAT_ACC] < 6)
|
||||
{
|
||||
u32 mostDmgMoveId = GetAIMostDamagingMoveId(battlerAtk, battlerDef);
|
||||
u32 *dmgs = AI_DATA->simulatedDmg[battlerAtk][battlerDef];
|
||||
if (GetNoOfHitsToKO(dmgs[mostDmgMoveId], gBattleMons[battlerDef].hp) == GetNoOfHitsToKO(dmgs[AI_THINKING_STRUCT->movesetIndex], gBattleMons[battlerDef].hp))
|
||||
score++;
|
||||
}
|
||||
if (gBattleMons[battlerDef].statStages[STAT_EVASION] >= 10 || gBattleMons[battlerAtk].statStages[STAT_ACC] <= 2)
|
||||
score++;
|
||||
if (AI_RandLessThan(100) && (gBattleMons[battlerDef].statStages[STAT_EVASION] >= 8 || gBattleMons[battlerAtk].statStages[STAT_ACC] <= 4))
|
||||
|
@ -953,6 +953,11 @@ static u32 WhichMoveBetter(u32 move1, u32 move2)
|
||||
return 2;
|
||||
}
|
||||
|
||||
u32 GetNoOfHitsToKO(u32 dmg, s32 hp)
|
||||
{
|
||||
return hp / (dmg + 1) + 1;
|
||||
}
|
||||
|
||||
u8 GetMoveDamageResult(u16 move)
|
||||
{
|
||||
s32 i, checkedMove, bestId, currId, hp;
|
||||
@ -1018,9 +1023,8 @@ u8 GetMoveDamageResult(u16 move)
|
||||
currId = AI_THINKING_STRUCT->movesetIndex;
|
||||
if (currId == bestId)
|
||||
AI_THINKING_STRUCT->funcResult = MOVE_POWER_BEST;
|
||||
// Compare percentage difference.
|
||||
else if ((moveDmgs[currId] >= hp || moveDmgs[bestId] < hp) // If current move can faint as well, or if neither can
|
||||
&& (moveDmgs[bestId] * 100 / hp) - (moveDmgs[currId] * 100 / hp) <= 30
|
||||
&& GetNoOfHitsToKO(moveDmgs[currId], hp) - GetNoOfHitsToKO(moveDmgs[bestId], hp) <= 2 // Consider a move weak if it needs to be used at least 2 times more to faint the target, compared to the best move.
|
||||
&& WhichMoveBetter(gBattleMons[sBattler_AI].moves[bestId], gBattleMons[sBattler_AI].moves[currId]) != 0)
|
||||
AI_THINKING_STRUCT->funcResult = MOVE_POWER_GOOD;
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user