Moving additional effects out of AI_CalcMoveEffectScore and into AI_CalcMoveAdditionalEffectScore (#7727)
This commit is contained in:
parent
fab4dc1163
commit
abc0e10558
@ -3990,9 +3990,8 @@ static void AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef)
|
||||
}
|
||||
}
|
||||
|
||||
static u32 AI_CalcHoldEffectMoveScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
static s32 AI_CalcHoldEffectMoveScore(u32 battlerAtk, u32 battlerDef, u32 move, struct AiLogicData *aiData)
|
||||
{
|
||||
struct AiLogicData *aiData = gAiLogicData;
|
||||
enum ItemHoldEffect holdEffect = aiData->holdEffects[battlerAtk];
|
||||
|
||||
s32 score = 0;
|
||||
@ -4020,17 +4019,16 @@ static u32 AI_CalcHoldEffectMoveScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
return score;
|
||||
}
|
||||
|
||||
static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, struct AiLogicData *aiData)
|
||||
{
|
||||
// move data
|
||||
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
|
||||
struct AiLogicData *aiData = gAiLogicData;
|
||||
u32 movesetIndex = gAiThinkingStruct->movesetIndex;
|
||||
uq4_12_t effectiveness = aiData->effectiveness[battlerAtk][battlerDef][movesetIndex];
|
||||
|
||||
s32 score = 0;
|
||||
u32 predictedMove = GetIncomingMove(battlerAtk, battlerDef, gAiLogicData);
|
||||
u32 predictedMoveSpeedCheck = GetIncomingMoveSpeedCheck(battlerAtk, battlerDef, gAiLogicData);
|
||||
u32 predictedMove = GetIncomingMove(battlerAtk, battlerDef, aiData);
|
||||
u32 predictedMoveSpeedCheck = GetIncomingMoveSpeedCheck(battlerAtk, battlerDef, aiData);
|
||||
u32 predictedType = GetMoveType(predictedMove);
|
||||
u32 predictedMoveSlot = GetMoveSlot(GetMovesArray(battlerDef), predictedMove);
|
||||
bool32 isBattle1v1 = IsBattle1v1();
|
||||
@ -4052,7 +4050,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
ADJUST_SCORE(10);
|
||||
|
||||
// check burn / frostbite
|
||||
if (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_SMART_SWITCHING && gAiLogicData->abilities[battlerAtk] == ABILITY_NATURAL_CURE)
|
||||
if (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_SMART_SWITCHING && aiData->abilities[battlerAtk] == ABILITY_NATURAL_CURE)
|
||||
{
|
||||
if ((gBattleMons[battlerAtk].status1 & STATUS1_BURN && HasOnlyMovesWithCategory(battlerAtk, DAMAGE_CATEGORY_PHYSICAL, TRUE))
|
||||
|| (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE && HasOnlyMovesWithCategory(battlerAtk, DAMAGE_CATEGORY_SPECIAL, TRUE)))
|
||||
@ -4478,7 +4476,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
}
|
||||
break;
|
||||
case EFFECT_BATON_PASS:
|
||||
if ((gAiLogicData->shouldSwitch & (1u << battlerAtk)) && (gBattleMons[battlerAtk].volatiles.substitute
|
||||
if ((aiData->shouldSwitch & (1u << battlerAtk)) && (gBattleMons[battlerAtk].volatiles.substitute
|
||||
|| gBattleMons[battlerAtk].volatiles.powerTrick
|
||||
|| gBattleMons[battlerAtk].volatiles.magnetRise
|
||||
|| gBattleMons[battlerAtk].volatiles.aquaRing
|
||||
@ -5482,9 +5480,9 @@ case EFFECT_GUARD_SPLIT:
|
||||
if (GetFirstFaintedPartyIndex(battlerAtk) != PARTY_SIZE)
|
||||
{
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
if (gAiLogicData->shouldSwitch & (1u << battlerAtk)) // Bad matchup
|
||||
if (aiData->shouldSwitch & (1u << battlerAtk)) // Bad matchup
|
||||
ADJUST_SCORE(WEAK_EFFECT);
|
||||
if (gAiLogicData->mostSuitableMonId[battlerAtk] != PARTY_SIZE) // Good mon to send in after
|
||||
if (aiData->mostSuitableMonId[battlerAtk] != PARTY_SIZE) // Good mon to send in after
|
||||
ADJUST_SCORE(WEAK_EFFECT);
|
||||
}
|
||||
break;
|
||||
@ -5590,11 +5588,30 @@ case EFFECT_GUARD_SPLIT:
|
||||
break;
|
||||
} // move effect checks
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
static s32 AI_CalcAdditionalEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, struct AiLogicData *aiData)
|
||||
{
|
||||
// move data
|
||||
s32 score = 0;
|
||||
|
||||
u32 predictedMove = GetIncomingMove(battlerAtk, battlerDef, aiData);
|
||||
bool32 hasPartner = HasPartner(battlerAtk);
|
||||
u32 i;
|
||||
u32 additionalEffectCount = GetMoveAdditionalEffectCount(move);
|
||||
|
||||
// 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;
|
||||
@ -5753,8 +5770,12 @@ case EFFECT_GUARD_SPLIT:
|
||||
IncreasePoisonScore(battlerAtk, battlerDef, move, &score);
|
||||
break;
|
||||
case MOVE_EFFECT_CLEAR_SMOG:
|
||||
{
|
||||
bool32 moveTargetsBothOpponents = HasTwoOpponents(battlerAtk) && (gMovesInfo[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_ALL_BATTLERS));
|
||||
|
||||
score += AI_TryToClearStats(battlerAtk, battlerDef, moveTargetsBothOpponents);
|
||||
break;
|
||||
}
|
||||
case MOVE_EFFECT_BUG_BITE: // And pluck
|
||||
if (gBattleMons[battlerDef].volatiles.substitute || aiData->abilities[battlerDef] == ABILITY_STICKY_HOLD)
|
||||
break;
|
||||
@ -5783,6 +5804,8 @@ case EFFECT_GUARD_SPLIT:
|
||||
case MOVE_EFFECT_THROAT_CHOP:
|
||||
if (IsSoundMove(GetBestDmgMoveFromBattler(battlerDef, battlerAtk, AI_DEFENDING)))
|
||||
{
|
||||
u32 predictedMoveSpeedCheck = GetIncomingMoveSpeedCheck(battlerAtk, battlerDef, aiData);
|
||||
|
||||
if (AI_IsFaster(battlerAtk, battlerDef, move, predictedMoveSpeedCheck, CONSIDER_PRIORITY))
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
else
|
||||
@ -5874,13 +5897,14 @@ case EFFECT_GUARD_SPLIT:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
// AI_FLAG_CHECK_VIABILITY - Chooses best possible move to hit player
|
||||
static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
{
|
||||
struct AiLogicData *aiData = gAiLogicData;
|
||||
|
||||
// Targeting partner, check benefits of doing that instead
|
||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||
return score;
|
||||
@ -5897,8 +5921,9 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score
|
||||
}
|
||||
}
|
||||
|
||||
ADJUST_SCORE(AI_CalcMoveEffectScore(battlerAtk, battlerDef, move));
|
||||
ADJUST_SCORE(AI_CalcHoldEffectMoveScore(battlerAtk, battlerDef, move));
|
||||
ADJUST_SCORE(AI_CalcMoveEffectScore(battlerAtk, battlerDef, move, aiData));
|
||||
ADJUST_SCORE(AI_CalcAdditionalEffectScore(battlerAtk, battlerDef, move, aiData));
|
||||
ADJUST_SCORE(AI_CalcHoldEffectMoveScore(battlerAtk, battlerDef, move, aiData));
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
@ -1358,3 +1358,19 @@ DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI sees Sheer Force skips additional effects")
|
||||
{
|
||||
u16 ability, expectedMove;
|
||||
|
||||
PARAMETRIZE { ability = ABILITY_NONE; expectedMove = MOVE_POWER_UP_PUNCH; }
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; expectedMove = MOVE_KARATE_CHOP; }
|
||||
|
||||
GIVEN {
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Ability(ability); Moves(MOVE_POWER_UP_PUNCH, MOVE_KARATE_CHOP); }
|
||||
} WHEN {
|
||||
TURN { EXPECT_MOVE(opponent, expectedMove); }
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user