Remove redundancy for ShouldLowerStat functions (#6577)
This commit is contained in:
parent
260813fc3f
commit
cb4ef705f7
@ -120,18 +120,11 @@ void DecideTerastal(u32 battler);
|
||||
|
||||
// stat stage checks
|
||||
bool32 AnyStatIsRaised(u32 battlerId);
|
||||
bool32 ShouldLowerStat(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 stat);
|
||||
bool32 CanLowerStat(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 stat);
|
||||
bool32 BattlerStatCanRise(u32 battler, u32 battlerAbility, u32 stat);
|
||||
bool32 AreBattlersStatsMaxed(u32 battler);
|
||||
u32 CountPositiveStatStages(u32 battlerId);
|
||||
u32 CountNegativeStatStages(u32 battlerId);
|
||||
bool32 ShouldLowerAttack(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerDefense(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerSpeed(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerSpAtk(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerSpDef(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerEvasion(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
|
||||
// move checks
|
||||
bool32 IsAffectedByPowder(u32 battler, u32 ability, enum ItemHoldEffect holdEffect);
|
||||
@ -152,6 +145,7 @@ bool32 HasOnlyMovesWithCategory(u32 battlerId, u32 category, bool32 onlyOffensiv
|
||||
bool32 HasMoveWithCategory(u32 battler, u32 category);
|
||||
bool32 HasMoveWithType(u32 battler, u32 type);
|
||||
bool32 HasMoveWithEffect(u32 battlerId, enum BattleMoveEffects moveEffect);
|
||||
bool32 HasBattlerSideMoveWithEffect(u32 battler, u32 effect);
|
||||
bool32 HasNonVolatileMoveEffect(u32 battlerId, u32 effect);
|
||||
bool32 IsPowerBasedOnStatus(u32 battlerId, enum BattleMoveEffects effect, u32 argument);
|
||||
bool32 HasMoveWithAdditionalEffect(u32 battlerId, u32 moveEffect);
|
||||
@ -245,6 +239,7 @@ bool32 SideHasMoveCategory(u32 battlerId, u32 category);
|
||||
// score increases
|
||||
u32 IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, enum StatChange statId);
|
||||
u32 IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, enum StatChange statId);
|
||||
u32 IncreaseStatDownScore(u32 battlerAtk, u32 battlerDef, u32 stat);
|
||||
void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
|
||||
@ -1543,40 +1543,40 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
// stat lowering effects
|
||||
case EFFECT_ATTACK_DOWN:
|
||||
case EFFECT_ATTACK_DOWN_2:
|
||||
if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK)) //|| !HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_PHYSICAL))
|
||||
if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_DEFENSE_DOWN:
|
||||
case EFFECT_DEFENSE_DOWN_2:
|
||||
if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_DEF))
|
||||
if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_DEF))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_SPEED_DOWN:
|
||||
case EFFECT_SPEED_DOWN_2:
|
||||
if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPEED))
|
||||
if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPEED))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_SPECIAL_ATTACK_DOWN:
|
||||
case EFFECT_SPECIAL_ATTACK_DOWN_2:
|
||||
if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPATK)) //|| !HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_SPECIAL))
|
||||
if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPATK))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_SPECIAL_DEFENSE_DOWN:
|
||||
case EFFECT_SPECIAL_DEFENSE_DOWN_2:
|
||||
if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPDEF))
|
||||
if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPDEF))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_ACCURACY_DOWN:
|
||||
case EFFECT_ACCURACY_DOWN_2:
|
||||
if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ACC))
|
||||
if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ACC))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_EVASION_DOWN:
|
||||
case EFFECT_EVASION_DOWN_2:
|
||||
case EFFECT_TICKLE:
|
||||
if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK))
|
||||
if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK))
|
||||
ADJUST_SCORE(-10);
|
||||
else if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_DEF))
|
||||
else if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_DEF))
|
||||
ADJUST_SCORE(-8);
|
||||
break;
|
||||
case EFFECT_VENOM_DRENCH:
|
||||
@ -1586,18 +1586,18 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPEED))
|
||||
if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPEED))
|
||||
ADJUST_SCORE(-10);
|
||||
else if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPATK))
|
||||
else if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPATK))
|
||||
ADJUST_SCORE(-8);
|
||||
else if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK))
|
||||
else if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK))
|
||||
ADJUST_SCORE(-6);
|
||||
}
|
||||
break;
|
||||
case EFFECT_NOBLE_ROAR:
|
||||
if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPATK))
|
||||
if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPATK))
|
||||
ADJUST_SCORE(-10);
|
||||
else if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK))
|
||||
else if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK))
|
||||
ADJUST_SCORE(-8);
|
||||
break;
|
||||
case EFFECT_CAPTIVATE:
|
||||
@ -1658,7 +1658,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_TOXIC_THREAD:
|
||||
if (!ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPEED))
|
||||
if (!CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_SPEED))
|
||||
ADJUST_SCORE(-1); // may still want to just poison
|
||||
//fallthrough
|
||||
case EFFECT_LIGHT_SCREEN:
|
||||
@ -2066,7 +2066,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case EFFECT_STRENGTH_SAP:
|
||||
if (aiData->abilities[battlerDef] == ABILITY_CONTRARY)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (!ShouldLowerStat(battlerAtk, battlerDef, aiData->abilities[battlerDef], STAT_ATK))
|
||||
else if (!CanLowerStat(battlerAtk, battlerDef, aiData->abilities[battlerDef], STAT_ATK))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_COPYCAT:
|
||||
@ -3940,89 +3940,31 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
break;
|
||||
case EFFECT_ATTACK_DOWN:
|
||||
case EFFECT_ATTACK_DOWN_2:
|
||||
if (!ShouldLowerAttack(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
ADJUST_SCORE(-2);
|
||||
if (gBattleMons[battlerDef].statStages[STAT_ATK] < DEFAULT_STAT_STAGE)
|
||||
ADJUST_SCORE(-1);
|
||||
else if (aiData->hpPercents[battlerAtk] <= 90)
|
||||
ADJUST_SCORE(-1);
|
||||
if (gBattleMons[battlerDef].statStages[STAT_ATK] > 3 && !AI_RandLessThan(50))
|
||||
ADJUST_SCORE(-2);
|
||||
else if (aiData->hpPercents[battlerDef] < 70)
|
||||
ADJUST_SCORE(-2);
|
||||
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, STAT_ATK));
|
||||
break;
|
||||
case EFFECT_DEFENSE_DOWN:
|
||||
case EFFECT_DEFENSE_DOWN_2:
|
||||
if (!ShouldLowerDefense(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
ADJUST_SCORE(-2);
|
||||
if ((aiData->hpPercents[battlerAtk] < 70 && !AI_RandLessThan(50)) || (gBattleMons[battlerDef].statStages[STAT_DEF] <= 3 && !AI_RandLessThan(50)))
|
||||
ADJUST_SCORE(-2);
|
||||
if (aiData->hpPercents[battlerDef] <= 70)
|
||||
ADJUST_SCORE(-2);
|
||||
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, STAT_DEF));
|
||||
break;
|
||||
case EFFECT_SPEED_DOWN:
|
||||
case EFFECT_SPEED_DOWN_2:
|
||||
if (AI_IsFaster(battlerAtk, battlerDef, move))
|
||||
ADJUST_SCORE(-3);
|
||||
else if (!AI_RandLessThan(70))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, STAT_SPEED));
|
||||
break;
|
||||
case EFFECT_SPECIAL_ATTACK_DOWN:
|
||||
case EFFECT_SPECIAL_ATTACK_DOWN_2:
|
||||
if (!ShouldLowerSpAtk(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
ADJUST_SCORE(-2);
|
||||
if (gBattleMons[battlerDef].statStages[STAT_SPATK] < DEFAULT_STAT_STAGE)
|
||||
ADJUST_SCORE(-1);
|
||||
else if (aiData->hpPercents[battlerAtk] <= 90)
|
||||
ADJUST_SCORE(-1);
|
||||
if (gBattleMons[battlerDef].statStages[STAT_SPATK] > 3 && !AI_RandLessThan(50))
|
||||
ADJUST_SCORE(-2);
|
||||
else if (aiData->hpPercents[battlerDef] < 70)
|
||||
ADJUST_SCORE(-2);
|
||||
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, STAT_SPATK));
|
||||
break;
|
||||
case EFFECT_SPECIAL_DEFENSE_DOWN:
|
||||
case EFFECT_SPECIAL_DEFENSE_DOWN_2:
|
||||
if (!ShouldLowerSpDef(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
ADJUST_SCORE(-2);
|
||||
if ((aiData->hpPercents[battlerAtk] < 70 && !AI_RandLessThan(50))
|
||||
|| (gBattleMons[battlerDef].statStages[STAT_SPDEF] <= 3 && !AI_RandLessThan(50)))
|
||||
ADJUST_SCORE(-2);
|
||||
if (aiData->hpPercents[battlerDef] <= 70)
|
||||
ADJUST_SCORE(-2);
|
||||
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, STAT_SPDEF));
|
||||
break;
|
||||
case EFFECT_ACCURACY_DOWN:
|
||||
case EFFECT_ACCURACY_DOWN_2:
|
||||
if (ShouldLowerAccuracy(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
ADJUST_SCORE(-2);
|
||||
if ((aiData->hpPercents[battlerAtk] < 70 || aiData->hpPercents[battlerDef] < 70) && AI_RandLessThan(100))
|
||||
ADJUST_SCORE(-1);
|
||||
if (gBattleMons[battlerDef].statStages[STAT_ACC] <= 4 && !AI_RandLessThan(80))
|
||||
ADJUST_SCORE(-2);
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY && !AI_RandLessThan(70))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
if (gStatuses3[battlerDef] & STATUS3_LEECHSEED && !AI_RandLessThan(70))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
if (gStatuses3[battlerDef] & STATUS3_ROOTED && AI_RandLessThan(128))
|
||||
ADJUST_SCORE(WEAK_EFFECT);
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_CURSED && !AI_RandLessThan(70))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
if (aiData->hpPercents[battlerAtk] > 70 || gBattleMons[battlerDef].statStages[STAT_ACC] < DEFAULT_STAT_STAGE)
|
||||
break;
|
||||
else if (aiData->hpPercents[battlerAtk] < 40 || aiData->hpPercents[battlerDef] < 40 || !AI_RandLessThan(70))
|
||||
ADJUST_SCORE(-2);
|
||||
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, STAT_ACC));
|
||||
break;
|
||||
case EFFECT_EVASION_DOWN:
|
||||
case EFFECT_EVASION_DOWN_2:
|
||||
if (!ShouldLowerEvasion(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
ADJUST_SCORE(-2);
|
||||
if ((aiData->hpPercents[battlerAtk] < 70 || gBattleMons[battlerDef].statStages[STAT_EVASION] <= 3) && !AI_RandLessThan(50))
|
||||
ADJUST_SCORE(-2);
|
||||
if (aiData->hpPercents[battlerDef] <= 70)
|
||||
ADJUST_SCORE(-2);
|
||||
if (gBattleMons[battlerAtk].statStages[STAT_ACC] < DEFAULT_STAT_STAGE)
|
||||
ADJUST_SCORE(WEAK_EFFECT);
|
||||
if (gBattleMons[battlerDef].statStages[STAT_EVASION] < 7 || aiData->abilities[battlerAtk] == ABILITY_NO_GUARD)
|
||||
ADJUST_SCORE(-2);
|
||||
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, STAT_EVASION));
|
||||
break;
|
||||
case EFFECT_SPICY_EXTRACT:
|
||||
// TODO: Make IncreaseStatDownScore function, just like IncreaseStatUpScore
|
||||
@ -4543,8 +4485,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
&& AI_IsSlower(battlerAtk, BATTLE_PARTNER(battlerAtk), move)) // Partner going first
|
||||
break; // Don't use Defog if partner is going to set up hazards
|
||||
}
|
||||
if (ShouldLowerEvasion(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, STAT_EVASION));
|
||||
}
|
||||
break;
|
||||
case EFFECT_TORMENT:
|
||||
@ -4789,11 +4730,8 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
ADJUST_SCORE(WEAK_EFFECT);
|
||||
break;
|
||||
case EFFECT_TICKLE:
|
||||
if (gBattleMons[battlerDef].statStages[STAT_DEF] > 4 && HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_PHYSICAL)
|
||||
&& aiData->abilities[battlerDef] != ABILITY_CONTRARY && ShouldLowerDefense(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
else if (ShouldLowerAttack(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, STAT_ATK));
|
||||
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, STAT_DEF));
|
||||
break;
|
||||
case EFFECT_COSMIC_POWER:
|
||||
ADJUST_SCORE(IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_DEF));
|
||||
@ -5231,8 +5169,8 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
break;
|
||||
case MOVE_EFFECT_SPD_MINUS_1:
|
||||
case MOVE_EFFECT_SPD_MINUS_2:
|
||||
if (!ShouldLowerSpeed(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
|
||||
break;
|
||||
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, STAT_SPEED));
|
||||
break;
|
||||
case MOVE_EFFECT_ATK_MINUS_1:
|
||||
case MOVE_EFFECT_DEF_MINUS_1:
|
||||
case MOVE_EFFECT_SP_ATK_MINUS_1:
|
||||
|
||||
@ -992,7 +992,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_1:
|
||||
case MOVE_EFFECT_ACC_MINUS_1:
|
||||
case MOVE_EFFECT_EVS_MINUS_1:
|
||||
if (ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo != 1)
|
||||
if (CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo != 1)
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_ATK_MINUS_2:
|
||||
@ -1002,7 +1002,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_2:
|
||||
case MOVE_EFFECT_ACC_MINUS_2:
|
||||
case MOVE_EFFECT_EVS_MINUS_2:
|
||||
if (ShouldLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo != 1)
|
||||
if (CanLowerStat(battlerAtk, battlerDef, abilityDef, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo != 1)
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
@ -1928,7 +1928,7 @@ s32 ProtectChecks(u32 battlerAtk, u32 battlerDef, u32 move, u32 predictedMove)
|
||||
}
|
||||
|
||||
// stat stages
|
||||
bool32 ShouldLowerStat(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 stat)
|
||||
bool32 CanLowerStat(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 stat)
|
||||
{
|
||||
if (gBattleMons[battlerDef].statStages[stat] == MIN_STAT_STAGE)
|
||||
return FALSE;
|
||||
@ -1965,7 +1965,6 @@ bool32 ShouldLowerStat(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 stat)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// This should be a viability check
|
||||
if (stat == STAT_SPEED)
|
||||
{
|
||||
// If AI is faster and doesn't have any mons left, lowering speed doesn't give any
|
||||
@ -1977,6 +1976,73 @@ bool32 ShouldLowerStat(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 stat)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u32 IncreaseStatDownScore(u32 battlerAtk, u32 battlerDef, u32 stat)
|
||||
{
|
||||
u32 tempScore = NO_INCREASE;
|
||||
|
||||
// Don't increase score if target is already -3 stat stage
|
||||
if (stat != STAT_SPEED && gBattleMons[battlerDef].statStages[stat] <= DEFAULT_STAT_STAGE - 3)
|
||||
return NO_INCREASE;
|
||||
|
||||
// Don't decrease stat if target will die to residual damage
|
||||
if (GetBattlerSecondaryDamage(battlerDef) >= gBattleMons[battlerDef].hp)
|
||||
return NO_INCREASE;
|
||||
|
||||
// Don't decrese stat if opposing battler has Encore
|
||||
if (HasBattlerSideMoveWithEffect(battlerDef, EFFECT_ENCORE))
|
||||
return NO_INCREASE;
|
||||
|
||||
// TODO: Avoid decreasing stat if
|
||||
// player can kill ai in 2 hits with decreased attack / sp atk stages
|
||||
// ai can kill target in 2 hits without decreasing defense / sp def stages
|
||||
|
||||
switch (stat)
|
||||
{
|
||||
case STAT_ATK:
|
||||
if (HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_PHYSICAL))
|
||||
tempScore += DECENT_EFFECT;
|
||||
break;
|
||||
case STAT_DEF:
|
||||
if (HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_PHYSICAL))
|
||||
tempScore += DECENT_EFFECT;
|
||||
break;
|
||||
case STAT_SPEED:
|
||||
if (AI_IsSlower(battlerAtk, battlerDef, gAiThinkingStruct->moveConsidered))
|
||||
tempScore += DECENT_EFFECT;
|
||||
break;
|
||||
case STAT_SPATK:
|
||||
if (HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_SPECIAL))
|
||||
tempScore += DECENT_EFFECT;
|
||||
break;
|
||||
case STAT_SPDEF:
|
||||
if (HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_SPECIAL))
|
||||
tempScore += DECENT_EFFECT;
|
||||
break;
|
||||
case STAT_ACC:
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)
|
||||
tempScore += WEAK_EFFECT;
|
||||
if (gStatuses3[battlerDef] & STATUS3_LEECHSEED)
|
||||
tempScore += WEAK_EFFECT;
|
||||
if (gStatuses3[battlerDef] & STATUS3_ROOTED)
|
||||
tempScore += WEAK_EFFECT;
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_CURSED)
|
||||
tempScore += WEAK_EFFECT;
|
||||
break;
|
||||
case STAT_EVASION:
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)
|
||||
tempScore += WEAK_EFFECT;
|
||||
if (gStatuses3[battlerDef] & STATUS3_LEECHSEED)
|
||||
tempScore += WEAK_EFFECT;
|
||||
if (gStatuses3[battlerDef] & STATUS3_ROOTED)
|
||||
tempScore += WEAK_EFFECT;
|
||||
if (gBattleMons[battlerDef].status2 & STATUS2_CURSED)
|
||||
tempScore += WEAK_EFFECT;
|
||||
break;
|
||||
}
|
||||
|
||||
return (tempScore > BEST_EFFECT) ? BEST_EFFECT : tempScore; // don't inflate score so only max +4
|
||||
}
|
||||
|
||||
bool32 BattlerStatCanRise(u32 battler, u32 battlerAbility, u32 stat)
|
||||
{
|
||||
if ((gBattleMons[battler].statStages[stat] < MAX_STAT_STAGE && battlerAbility != ABILITY_CONTRARY)
|
||||
@ -2032,128 +2098,6 @@ u32 CountNegativeStatStages(u32 battlerId)
|
||||
return count;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerAttack(u32 battlerAtk, u32 battlerDef, u32 defAbility)
|
||||
{
|
||||
if (AI_IsFaster(battlerAtk, battlerDef, gAiThinkingStruct->moveConsidered)
|
||||
&& (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT)
|
||||
&& CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (gBattleMons[battlerDef].statStages[STAT_ATK] > 4
|
||||
&& HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_PHYSICAL)
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_HYPER_CUTTER
|
||||
&& gAiLogicData->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerDefense(u32 battlerAtk, u32 battlerDef, u32 defAbility)
|
||||
{
|
||||
if (AI_IsFaster(battlerAtk, battlerDef, gAiThinkingStruct->moveConsidered)
|
||||
&& (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT)
|
||||
&& CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (gBattleMons[battlerDef].statStages[STAT_DEF] > 4
|
||||
&& HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_PHYSICAL)
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_BIG_PECKS
|
||||
&& gAiLogicData->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerSpeed(u32 battlerAtk, u32 battlerDef, u32 defAbility)
|
||||
{
|
||||
if (defAbility == ABILITY_CONTRARY
|
||||
|| defAbility == ABILITY_CLEAR_BODY
|
||||
|| defAbility == ABILITY_FULL_METAL_BODY
|
||||
|| defAbility == ABILITY_WHITE_SMOKE
|
||||
|| gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_CLEAR_AMULET)
|
||||
return FALSE;
|
||||
|
||||
return (AI_IsSlower(battlerAtk, battlerDef, gAiThinkingStruct->moveConsidered));
|
||||
}
|
||||
|
||||
bool32 ShouldLowerSpAtk(u32 battlerAtk, u32 battlerDef, u32 defAbility)
|
||||
{
|
||||
if (AI_IsFaster(battlerAtk, battlerDef, gAiThinkingStruct->moveConsidered)
|
||||
&& (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT)
|
||||
&& CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (gBattleMons[battlerDef].statStages[STAT_SPATK] > 4
|
||||
&& HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_SPECIAL)
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE
|
||||
&& gAiLogicData->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerSpDef(u32 battlerAtk, u32 battlerDef, u32 defAbility)
|
||||
{
|
||||
if (AI_IsFaster(battlerAtk, battlerDef, gAiThinkingStruct->moveConsidered)
|
||||
&& (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT)
|
||||
&& CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (gBattleMons[battlerDef].statStages[STAT_SPDEF] > 4
|
||||
&& HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_SPECIAL)
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE
|
||||
&& gAiLogicData->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u32 defAbility)
|
||||
{
|
||||
if (AI_IsFaster(battlerAtk, battlerDef, gAiThinkingStruct->moveConsidered)
|
||||
&& (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT)
|
||||
&& CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_KEEN_EYE
|
||||
&& defAbility != ABILITY_MINDS_EYE
|
||||
&& (B_ILLUMINATE_EFFECT >= GEN_9 && defAbility != ABILITY_ILLUMINATE)
|
||||
&& gAiLogicData->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerEvasion(u32 battlerAtk, u32 battlerDef, u32 defAbility)
|
||||
{
|
||||
if (AI_IsFaster(battlerAtk, battlerDef, gAiThinkingStruct->moveConsidered)
|
||||
&& (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT)
|
||||
&& CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (gBattleMons[battlerDef].statStages[STAT_EVASION] > DEFAULT_STAT_STAGE
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE
|
||||
&& gAiLogicData->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u32 moveIndex, enum DamageCalcContext calcContext)
|
||||
{
|
||||
s32 dmg;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user