fix (AI scoring): shield dust considerations, IsMoveEffectInMinus self effect edge case, hitsToKO zero-case consideration (#8126)
Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com>
This commit is contained in:
parent
6bcf9823c5
commit
3c72ca1158
@ -155,6 +155,7 @@ bool32 IsAffectedByPowder(u32 battler, u32 ability, enum ItemHoldEffect holdEffe
|
||||
bool32 MovesWithCategoryUnusable(u32 attacker, u32 target, enum DamageCategory category);
|
||||
enum MoveComparisonResult AI_WhichMoveBetter(u32 move1, u32 move2, u32 battlerAtk, u32 battlerDef, s32 noOfHitsToKo);
|
||||
struct SimulatedDamage AI_CalcDamageSaveBattlers(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef);
|
||||
bool32 IsAdditionalEffectBlocked(u32 battlerAtk, u32 abilityAtk, u32 battlerDef, u32 abilityDef);
|
||||
struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef, u32 weather);
|
||||
bool32 AI_IsDamagedByRecoil(u32 battler);
|
||||
u32 GetNoOfHitsToKO(u32 dmg, s32 hp);
|
||||
|
||||
@ -5069,7 +5069,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
if (gBattleMons[battlerDef].speed > gBattleMons[battlerAtk].speed)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case EFFECT_GUARD_SPLIT:
|
||||
case EFFECT_GUARD_SPLIT:
|
||||
{
|
||||
u32 atkDefense = gBattleMons[battlerAtk].defense;
|
||||
u32 defDefense = gBattleMons[battlerDef].defense;
|
||||
@ -5590,6 +5590,9 @@ case EFFECT_GUARD_SPLIT:
|
||||
}
|
||||
else // consider move effects that hinder the target
|
||||
{
|
||||
if (IsAdditionalEffectBlocked(battlerAtk, aiData->abilities[battlerAtk], battlerDef, aiData->abilities[battlerDef]))
|
||||
continue;
|
||||
|
||||
switch (additionalEffect->moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_FLINCH:
|
||||
|
||||
@ -701,6 +701,17 @@ bool32 IsDamageMoveUnusable(struct DamageContext *ctx)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsAdditionalEffectBlocked(u32 battlerAtk, u32 abilityAtk, u32 battlerDef, u32 abilityDef)
|
||||
{
|
||||
if (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_COVERT_CLOAK)
|
||||
return TRUE;
|
||||
|
||||
if (abilityDef == ABILITY_SHIELD_DUST && !IsMoldBreakerTypeAbility(battlerAtk, abilityAtk))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline s32 GetDamageByRollType(s32 dmg, enum DamageRollType rollType)
|
||||
{
|
||||
if (rollType == DMG_ROLL_LOWEST)
|
||||
@ -1073,6 +1084,9 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
||||
}
|
||||
else // consider move effects that hinder the target
|
||||
{
|
||||
if (IsAdditionalEffectBlocked(battlerAtk, abilityAtk, battlerDef, abilityDef))
|
||||
continue;
|
||||
|
||||
switch (additionalEffect->moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_POISON:
|
||||
@ -1107,7 +1121,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 (CanLowerStat(battlerAtk, battlerDef, gAiLogicData, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo != 1)
|
||||
if (CanLowerStat(battlerAtk, battlerDef, gAiLogicData, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo > 1)
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_ATK_MINUS_2:
|
||||
@ -1117,7 +1131,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 (CanLowerStat(battlerAtk, battlerDef, gAiLogicData, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo != 1)
|
||||
if (CanLowerStat(battlerAtk, battlerDef, gAiLogicData, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo > 1)
|
||||
return TRUE;
|
||||
break;
|
||||
default:
|
||||
@ -1174,7 +1188,7 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
|
||||
case MOVE_EFFECT_ATK_DEF_DOWN:
|
||||
case MOVE_EFFECT_DEF_SPDEF_DOWN:
|
||||
if ((additionalEffect->self && abilityAtk != ABILITY_CONTRARY)
|
||||
|| (noOfHitsToKo != 1 && abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(battlerAtk, abilityAtk, move)))
|
||||
|| (noOfHitsToKo > 1 && !additionalEffect->self && abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(battlerAtk, abilityAtk, move)))
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_RECHARGE:
|
||||
@ -1195,7 +1209,7 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
|
||||
case MOVE_EFFECT_ACC_PLUS_2:
|
||||
case MOVE_EFFECT_ALL_STATS_UP:
|
||||
if ((additionalEffect->self && abilityAtk == ABILITY_CONTRARY)
|
||||
|| (noOfHitsToKo != 1 && !(abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(battlerAtk, abilityAtk, move))))
|
||||
|| (noOfHitsToKo > 1 && !additionalEffect->self && !(abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(battlerAtk, abilityAtk, move))))
|
||||
return TRUE;
|
||||
break;
|
||||
default:
|
||||
|
||||
@ -188,3 +188,31 @@ SINGLE_BATTLE_TEST("Shield Dust does not prevent ability stat changes")
|
||||
MESSAGE("Vivillon's Speed fell!");
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI will score secondary effects against shield dust correctly")
|
||||
{
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_OMNISCIENT);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_DUSTOX){ Ability(ABILITY_SHIELD_DUST); Moves(MOVE_GUST); }
|
||||
OPPONENT(SPECIES_SUNFLORA){ Ability(ABILITY_EARLY_BIRD); Moves(MOVE_MYSTICAL_FIRE, MOVE_FIERY_DANCE); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(player, MOVE_GUST);
|
||||
EXPECT_MOVE(opponent, MOVE_FIERY_DANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI will score secondary effects against shield dust correctly when it has Mold Breaker")
|
||||
{
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_OMNISCIENT);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_DUSTOX){ Ability(ABILITY_SHIELD_DUST); Moves(MOVE_GUST); }
|
||||
OPPONENT(SPECIES_SUNFLORA){ Ability(ABILITY_MOLD_BREAKER); Moves(MOVE_MYSTICAL_FIRE, MOVE_FIERY_DANCE); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(player, MOVE_GUST);
|
||||
EXPECT_MOVE(opponent, MOVE_MYSTICAL_FIRE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user