Let AI take Frostbite into account

This commit is contained in:
Bassoonian 2023-04-23 20:53:51 +02:00
parent 6b2a873071
commit 0b8d148c26
3 changed files with 74 additions and 5 deletions

View File

@ -130,6 +130,7 @@ bool32 IsSemiInvulnerable(u8 battlerDef, u16 move);
// status checks
bool32 AI_CanBeBurned(u8 battler, u16 ability);
bool32 AI_CanGetFrostbite(u8 battler, u16 ability);
bool32 AI_CanBeConfused(u8 battler, u16 ability);
bool32 AI_CanSleep(u8 battler, u16 ability);
bool32 IsBattlerIncapacitated(u8 battler, u16 ability);
@ -140,6 +141,7 @@ bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u1
bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 ShouldBurnSelf(u8 battler, u16 ability);
bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 AI_CanGiveFrostbite(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender);
bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof);
u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move);
@ -175,5 +177,6 @@ void IncreaseBurnScore(u8 battlerAtk, u8 battlerdef, u16 move, s16 *score);
void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
void IncreaseFrostbiteScore(u8 battlerAtk, u8 battlerdef, u16 move, s16 *score);
#endif //GUARD_BATTLE_AI_UTIL_H

View File

@ -1725,7 +1725,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score -= 10;
break;
case EFFECT_REFRESH:
if (!(gBattleMons[battlerDef].status1 & (STATUS1_PSN_ANY | STATUS1_BURN | STATUS1_PARALYSIS)))
if (!(gBattleMons[battlerDef].status1 & (STATUS1_PSN_ANY | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_FROSTBITE)))
score -= 10;
break;
case EFFECT_PSYCHO_SHIFT:
@ -1734,6 +1734,9 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
else if (gBattleMons[battlerAtk].status1 & STATUS1_BURN && !AI_CanBurn(battlerAtk, battlerDef,
AI_DATA->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove))
score -= 10;
else if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE && !AI_CanGiveFrostbite(battlerAtk, battlerDef,
AI_DATA->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove))
score -= 10;
else if (gBattleMons[battlerAtk].status1 & STATUS1_PARALYSIS && !AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_DATA->partnerMove))
score -= 10;
else if (gBattleMons[battlerAtk].status1 & STATUS1_SLEEP && !AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_DATA->partnerMove))
@ -3143,7 +3146,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score++;
// check thawing moves
if ((gBattleMons[battlerAtk].status1 & STATUS1_FREEZE) && TestMoveFlags(move, FLAG_THAW_USER))
if ((gBattleMons[battlerAtk].status1 & (STATUS1_FREEZE | STATUS1_FROSTBITE)) && TestMoveFlags(move, FLAG_THAW_USER))
score += (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) ? 20 : 10;
// check burn
@ -3165,6 +3168,25 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
}
}
// check frostbite
if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE)
{
switch (AI_DATA->abilities[battlerAtk])
{
case ABILITY_GUTS:
break;
case ABILITY_NATURAL_CURE:
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING
&& HasOnlyMovesWithSplit(battlerAtk, SPLIT_SPECIAL, TRUE))
score = 90; // Force switch if all your attacking moves are special and you have Natural Cure.
break;
default:
if (IS_MOVE_SPECIAL(move) && gBattleMoves[move].effect != EFFECT_FACADE)
score -= 2;
break;
}
}
// attacker ability checks
switch (AI_DATA->abilities[battlerAtk])
{
@ -3602,7 +3624,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_SUBSTITUTE:
if (gStatuses3[battlerDef] & STATUS3_PERISH_SONG)
score += 3;
if (gBattleMons[battlerDef].status1 & (STATUS1_BURN | STATUS1_PSN_ANY))
if (gBattleMons[battlerDef].status1 & (STATUS1_BURN | STATUS1_PSN_ANY | STATUS1_FROSTBITE))
score++;
if (HasMoveEffect(battlerDef, EFFECT_SLEEP)
|| HasMoveEffect(battlerDef, EFFECT_TOXIC)
@ -4391,6 +4413,8 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
IncreaseParalyzeScore(battlerAtk, battlerDef, move, &score);
else if (gBattleMons[battlerAtk].status1 & STATUS1_SLEEP)
IncreaseSleepScore(battlerAtk, battlerDef, move, &score);
else if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE)
IncreaseFrostbiteScore(battlerAtk, battlerDef, move, &score);
break;
case EFFECT_GRUDGE:
break;
@ -4781,7 +4805,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score += 2;
break;
case EFFECT_FACADE:
if (gBattleMons[battlerAtk].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON))
if (gBattleMons[battlerAtk].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE))
score++;
break;
case EFFECT_FOCUS_PUNCH:

View File

@ -1678,7 +1678,7 @@ void ProtectChecks(u8 battlerAtk, u8 battlerDef, u16 move, u16 predictedMove, s1
(*score) -= min(uses, 3);
}
if (gBattleMons[battlerAtk].status1 & (STATUS1_PSN_ANY | STATUS1_BURN)
if (gBattleMons[battlerAtk].status1 & (STATUS1_PSN_ANY | STATUS1_BURN | STATUS1_FROSTBITE)
|| gBattleMons[battlerAtk].status2 & (STATUS2_CURSED | STATUS2_INFATUATION)
|| gStatuses3[battlerAtk] & (STATUS3_PERISH_SONG | STATUS3_LEECHSEED | STATUS3_YAWN))
{
@ -2892,6 +2892,17 @@ bool32 AI_CanBeBurned(u8 battler, u16 ability)
return TRUE;
}
bool32 AI_CanGetFrostbite(u8 battler, u16 ability)
{
if (ability == ABILITY_MAGMA_ARMOR
|| IS_BATTLER_OF_TYPE(battler, TYPE_ICE)
|| gBattleMons[battler].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battler)
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD)
return FALSE;
return TRUE;
}
bool32 ShouldBurnSelf(u8 battler, u16 ability)
{
if (AI_CanBeBurned(battler, ability) && (
@ -2918,6 +2929,18 @@ bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPar
return TRUE;
}
bool32 AI_CanGiveFrostbite(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove)
{
if (!AI_CanGetFrostbite(battlerDef, defAbility)
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| PartnerMoveEffectIsStatusSameTarget(battlerAtkPartner, battlerDef, partnerMove))
{
return FALSE;
}
return TRUE;
}
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender)
{
if ((gBattleMons[battlerDef].status2 & STATUS2_INFATUATION)
@ -3717,6 +3740,25 @@ void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
}
}
void IncreaseFrostbiteScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
{
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
return;
if (AI_CanGiveFrostbite(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove))
{
(*score)++; // frostbite is good
if (HasMoveWithSplit(battlerDef, SPLIT_SPECIAL))
{
if (CanTargetFaintAi(battlerDef, battlerAtk))
*score += 2; // frostbiting the target to stay alive is cool
}
if (HasMoveEffect(battlerAtk, EFFECT_HEX) || HasMoveEffect(BATTLE_PARTNER(battlerAtk), EFFECT_HEX))
(*score)++;
}
}
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move)
{
if (TestMoveFlags(move, FLAG_MAKES_CONTACT)