fix (scoring): AI_IsMoveEffectInPlus - AI should not see secondary effect of Sheer Force boosted moves as beneficial (#8579)

Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com>
This commit is contained in:
ghostyboyy97 2025-12-19 12:40:46 -05:00 committed by GitHub
parent 9451af1c64
commit a901d227cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 25 additions and 12 deletions

View File

@ -343,7 +343,7 @@ bool32 IsPartnerMonFromSameTrainer(u32 battler);
enum DamageCategory GetCategoryBasedOnStats(u32 battler);
void SetShellSideArmCategory(void);
bool32 MoveIsAffectedBySheerForce(u32 move);
bool32 TestIfSheerForceAffected(u32 battler, u16 move);
bool32 IsSheerForceAffected(u16 move, enum Ability ability);
void TryRestoreHeldItems(void);
bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item);
void TrySaveExchangedItem(u32 battler, u16 stolenItem);

View File

@ -5697,17 +5697,14 @@ static s32 AI_CalcAdditionalEffectScore(u32 battlerAtk, u32 battlerDef, u32 move
u32 i;
u32 additionalEffectCount = GetMoveAdditionalEffectCount(move);
if (IsSheerForceAffected(move, aiData->abilities[battlerAtk]))
return score;
// check move additional effects that are likely to happen
for (i = 0; i < additionalEffectCount; i++)
{
const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
if (aiData->abilities[battlerAtk] == ABILITY_SHEER_FORCE)
{
if ((additionalEffect->chance > 0) != additionalEffect->sheerForceOverride)
continue;
}
// Only consider effects with a guaranteed chance to happen
if (!MoveEffectIsGuaranteed(battlerAtk, aiData->abilities[battlerAtk], additionalEffect))
continue;

View File

@ -1030,6 +1030,9 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
enum Ability abilityDef = gAiLogicData->abilities[battlerDef];
enum Ability abilityAtk = gAiLogicData->abilities[battlerAtk];
if (IsSheerForceAffected(move, abilityAtk))
return FALSE;
switch (GetMoveEffect(move))
{
case EFFECT_HIT_ESCAPE:

View File

@ -3049,7 +3049,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, enum MoveEffect moveEffect, c
if (!primary && !affectsUser && IsMoveEffectBlockedByTarget(battlerAbility))
moveEffect = MOVE_EFFECT_NONE;
else if (!primary
&& TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
&& IsSheerForceAffected(gCurrentMove, GetBattlerAbility(battler))
&& !(GetMoveEffect(gCurrentMove) == EFFECT_ORDER_UP && gBattleStruct->battlerState[gBattlerAttacker].commanderSpecies != SPECIES_NONE))
moveEffect = MOVE_EFFECT_NONE;
else if (!IsBattlerAlive(gEffectBattler) && !activateAfterFaint)
@ -6400,7 +6400,7 @@ static void Cmd_moveend(void)
&& gBattlerTarget != gBattlerAttacker
&& !IsBattlerAlly(gBattlerTarget, gBattlerAttacker)
&& gProtectStructs[gBattlerTarget].physicalBattlerId == gBattlerAttacker
&& !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
&& !IsSheerForceAffected(gCurrentMove, GetBattlerAbility(gBattlerAttacker)))
{
gProtectStructs[gBattlerTarget].shellTrap = TRUE;
// Change move order in double battles, so the hit mon with shell trap moves immediately after being hit.
@ -6660,7 +6660,7 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
case MOVEEND_SHEER_FORCE:
if (TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
if (IsSheerForceAffected(gCurrentMove, GetBattlerAbility(gBattlerAttacker)))
gBattleScripting.moveendState = MOVEEND_EJECT_PACK;
else
gBattleScripting.moveendState++;

View File

@ -9892,9 +9892,9 @@ bool32 IsBattlerAffectedByHazards(u32 battler, bool32 toxicSpikes)
return ret;
}
bool32 TestIfSheerForceAffected(u32 battler, u16 move)
bool32 IsSheerForceAffected(u16 move, enum Ability ability)
{
return GetBattlerAbility(battler) == ABILITY_SHEER_FORCE && MoveIsAffectedBySheerForce(move);
return ability == ABILITY_SHEER_FORCE && MoveIsAffectedBySheerForce(move);
}
// This function is the body of "jumpifstat", but can be used dynamically in a function

View File

@ -133,3 +133,16 @@ AI_SINGLE_BATTLE_TEST("HasMoveThatChangesKOThreshold - AI should not see self-ta
TURN { MOVE(player, MOVE_HAMMER_ARM); EXPECT_MOVE(opponent, move == MOVE_EARTHQUAKE ? MOVE_NASTY_PLOT : MOVE_AURA_SPHERE); }
}
}
AI_SINGLE_BATTLE_TEST("AI_IsMoveEffectInPlus - AI should not see secondary effect of Sheer Force boosted moves as beneficial")
{
GIVEN {
ASSUME(GetMovePower(MOVE_PSYCHIC) == 90);
ASSUME(MoveHasAdditionalEffect(MOVE_PSYCHIC, MOVE_EFFECT_SP_DEF_MINUS_1) == TRUE);
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);
PLAYER(SPECIES_STEELIX) { Level(100); Nature(NATURE_SASSY); Item(ITEM_STEELIXITE); Ability(ABILITY_STURDY); Speed(58); Moves(MOVE_GYRO_BALL); }
OPPONENT(SPECIES_BRAVIARY_HISUI) { Level(100); Nature(NATURE_TIMID); Ability(ABILITY_SHEER_FORCE); Speed(251); Moves(MOVE_PSYCHIC, MOVE_NIGHT_SHADE); }
} WHEN {
TURN { MOVE(player, MOVE_GYRO_BALL); SCORE_EQ_VAL(opponent, MOVE_PSYCHIC, 101); SCORE_EQ_VAL(opponent, MOVE_NIGHT_SHADE, 101); }
}
}