Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Duplicate ai code from battle_ai_util.c #4883

Merged
merged 2 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions include/battle_ai_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,8 @@ bool32 HasMagicCoatAffectedMove(u32 battler);
bool32 HasSnatchAffectedMove(u32 battler);

// status checks
bool32 AI_CanBeBurned(u32 battler, u32 ability);
bool32 AI_CanGetFrostbite(u32 battler, u32 ability);
bool32 AI_CanBeConfused(u32 battlerAtk, u32 battlerDef, u32 move, u32 ability);
bool32 AI_CanSleep(u32 battler, u32 ability);
bool32 IsBattlerIncapacitated(u32 battler, u32 ability);
bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
bool32 ShouldPoisonSelf(u32 battler, u32 ability);
Expand Down
8 changes: 4 additions & 4 deletions include/battle_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,10 @@ bool32 MoveHasAdditionalEffectSelf(u32 move, u32 moveEffect);
bool32 MoveHasAdditionalEffectSelfArg(u32 move, u32 moveEffect, u32 argument);
bool32 MoveHasChargeTurnAdditionalEffect(u32 move);

bool32 CanSleep(u32 battler);
bool32 CanBePoisoned(u32 battlerAttacker, u32 battlerTarget);
bool32 CanBeBurned(u32 battler);
bool32 CanBeParalyzed(u32 battler);
bool32 CanBeSlept(u32 battler, u32 ability);
bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 CanBeBurned(u32 battler, u32 ability);
bool32 CanBeParalyzed(u32 battler, u32 ability);
bool32 CanBeFrozen(u32 battler);
bool32 CanGetFrostbite(u32 battler);
bool32 CanBeConfused(u32 battler);
Expand Down
6 changes: 3 additions & 3 deletions src/battle_ai_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1866,7 +1866,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-10);
break;
case EFFECT_REST:
if (!AI_CanSleep(battlerAtk, aiData->abilities[battlerAtk]))
if (!CanBeSlept(battlerAtk, aiData->abilities[battlerAtk]))
ADJUST_SCORE(-10);
//fallthrough
case EFFECT_RESTORE_HP:
Expand Down Expand Up @@ -3456,7 +3456,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
}
break;
case EFFECT_REST:
if (!(AI_CanSleep(battlerAtk, aiData->abilities[battlerAtk])))
if (!(CanBeSlept(battlerAtk, aiData->abilities[battlerAtk])))
{
break;
}
Expand Down Expand Up @@ -3936,7 +3936,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
ADJUST_SCORE(DECENT_EFFECT);
break;
case HOLD_EFFECT_FLAME_ORB:
if (!ShouldBurnSelf(battlerAtk, aiData->abilities[battlerAtk]) && AI_CanBeBurned(battlerAtk, aiData->abilities[battlerDef]))
if (!ShouldBurnSelf(battlerAtk, aiData->abilities[battlerAtk]) && CanBeBurned(battlerAtk, aiData->abilities[battlerDef]))
ADJUST_SCORE(DECENT_EFFECT);
break;
case HOLD_EFFECT_BLACK_SLUDGE:
Expand Down
4 changes: 1 addition & 3 deletions src/battle_ai_switch_items.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ static bool32 ShouldSwitchIfGameStatePrompt(u32 battler, bool32 emitResult)
{
//Yawn
if (gStatuses3[battler] & STATUS3_YAWN
&& AI_CanSleep(battler, monAbility)
&& CanBeSlept(battler, monAbility)
&& gBattleMons[battler].hp > gBattleMons[battler].maxHP / 3)
{
switchMon = TRUE;
Expand Down Expand Up @@ -1291,8 +1291,6 @@ static u32 GetSwitchinHazardsDamage(u32 battler, struct BattlePokemon *battleMon
hazardDamage += spikesDamage;
}

// Toxic Spikes
// TODO: CanBePoisoned compatibility to avoid duplicate code
if ((hazardFlags & SIDE_STATUS_TOXIC_SPIKES) && (defType1 != TYPE_POISON && defType2 != TYPE_POISON
&& defType1 != TYPE_STEEL && defType2 != TYPE_STEEL
&& ability != ABILITY_IMMUNITY && ability != ABILITY_POISON_HEAL && ability != ABILITY_COMATOSE
Expand Down
66 changes: 6 additions & 60 deletions src/battle_ai_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -2624,48 +2624,18 @@ bool32 IsBattlerIncapacitated(u32 battler, u32 ability)
return FALSE;
}

bool32 AI_CanSleep(u32 battler, u32 ability)
{
if (ability == ABILITY_INSOMNIA
|| ability == ABILITY_VITAL_SPIRIT
|| ability == ABILITY_COMATOSE
|| gBattleMons[battler].status1 & STATUS1_ANY
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|| (gFieldStatuses & (STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN))
|| IsAbilityStatusProtected(battler))
return FALSE;
return TRUE;
}

bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove)
{
if (!AI_CanSleep(battlerDef, defAbility)
if (!CanBeSlept(battlerDef, defAbility)
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) // shouldn't try to sleep mon that partner is trying to make sleep
return FALSE;
return TRUE;
}

static bool32 AI_CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 move)
{
u32 ability = AI_DATA->abilities[battlerDef];

if (!(CanPoisonType(battlerAtk, battlerDef))
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|| gBattleMons[battlerDef].status1 & STATUS1_ANY
|| ability == ABILITY_IMMUNITY
|| ability == ABILITY_COMATOSE
|| AI_IsAbilityOnSide(battlerDef, ABILITY_PASTEL_VEIL)
|| gBattleMons[battlerDef].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battlerDef)
|| AI_IsTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN))
return FALSE;
return TRUE;
}

bool32 ShouldPoisonSelf(u32 battler, u32 ability)
{
if (AI_CanBePoisoned(battler, battler, 0) && (
if (CanBePoisoned(battler, battler, GetBattlerAbility(battler)) && (
ability == ABILITY_MARVEL_SCALE
|| ability == ABILITY_POISON_HEAL
|| ability == ABILITY_QUICK_FEET
Expand All @@ -2680,7 +2650,7 @@ bool32 ShouldPoisonSelf(u32 battler, u32 ability)

bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove)
{
if (!AI_CanBePoisoned(battlerAtk, battlerDef, move)
if (!CanBePoisoned(battlerAtk, battlerDef, GetBattlerAbility(battlerDef))
|| AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex] == AI_EFFECTIVENESS_x0
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove))
Expand All @@ -2693,20 +2663,9 @@ bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u3
return TRUE;
}

static bool32 AI_CanBeParalyzed(u32 battler, u32 ability)
{
if (ability == ABILITY_LIMBER
|| ability == ABILITY_COMATOSE
|| IS_BATTLER_OF_TYPE(battler, TYPE_ELECTRIC)
|| gBattleMons[battler].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battler))
return FALSE;
return TRUE;
}

bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove)
{
if (!AI_CanBeParalyzed(battlerDef, defAbility)
if (!CanBeParalyzed(battlerDef, defAbility)
|| AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex] == AI_EFFECTIVENESS_x0
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
Expand Down Expand Up @@ -2740,19 +2699,6 @@ bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battler
return TRUE;
}

bool32 AI_CanBeBurned(u32 battler, u32 ability)
{
if (ability == ABILITY_WATER_VEIL
|| ability == ABILITY_WATER_BUBBLE
|| ability == ABILITY_COMATOSE
|| IS_BATTLER_OF_TYPE(battler, TYPE_FIRE)
|| gBattleMons[battler].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battler)
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD)
return FALSE;
return TRUE;
}

bool32 AI_CanGetFrostbite(u32 battler, u32 ability)
{
if (ability == ABILITY_MAGMA_ARMOR
Expand All @@ -2767,7 +2713,7 @@ bool32 AI_CanGetFrostbite(u32 battler, u32 ability)

bool32 ShouldBurnSelf(u32 battler, u32 ability)
{
if (AI_CanBeBurned(battler, ability) && (
if (CanBeBurned(battler, ability) && (
ability == ABILITY_QUICK_FEET
|| ability == ABILITY_HEATPROOF
|| ability == ABILITY_MAGIC_GUARD
Expand All @@ -2781,7 +2727,7 @@ bool32 ShouldBurnSelf(u32 battler, u32 ability)

bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove)
{
if (!AI_CanBeBurned(battlerDef, defAbility)
if (!CanBeBurned(battlerDef, defAbility)
|| AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex] == AI_EFFECTIVENESS_x0
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| PartnerMoveEffectIsStatusSameTarget(battlerAtkPartner, battlerDef, partnerMove))
Expand Down
8 changes: 4 additions & 4 deletions src/battle_dynamax.c
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ void BS_SetMaxMoveEffect(void)
{
static const u8 sSnoozeEffects[] = {TRUE, FALSE};
if (!(gStatuses3[gBattlerTarget] & STATUS3_YAWN)
&& CanSleep(gBattlerTarget)
&& CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget))
&& RandomElement(RNG_G_MAX_SNOOZE, sSnoozeEffects)) // 50% chance of success
{
gStatuses3[gBattlerTarget] |= STATUS3_YAWN_TURN(2);
Expand Down Expand Up @@ -897,23 +897,23 @@ void BS_TrySetStatus1(void)
switch (status1)
{
case STATUS1_POISON:
if (CanBePoisoned(gBattlerAttacker, gBattlerTarget))
if (CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget)))
{
gBattleMons[gBattlerTarget].status1 |= STATUS1_POISON;
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
effect++;
}
break;
case STATUS1_PARALYSIS:
if (CanBeParalyzed(gBattlerTarget))
if (CanBeParalyzed(gBattlerTarget, GetBattlerAbility(gBattlerTarget)))
{
gBattleMons[gBattlerTarget].status1 |= STATUS1_PARALYSIS;
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
effect++;
}
break;
case STATUS1_SLEEP:
if (CanSleep(gBattlerTarget))
if (CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget)))
{
if (B_SLEEP_TURNS >= GEN_5)
gBattleMons[gBattlerTarget].status1 |= STATUS1_SLEEP_TURN((Random() % 3) + 2);
Expand Down
23 changes: 12 additions & 11 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -2907,7 +2907,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)

if (i != gBattlersCount)
break;
if (!CanSleep(gEffectBattler))
if (!CanBeSlept(gEffectBattler, GetBattlerAbility(gEffectBattler)))
break;

cancelMultiTurnMovesResult = CancelMultiTurnMoves(gEffectBattler);
Expand Down Expand Up @@ -2946,7 +2946,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUS_HAD_NO_EFFECT;
RESET_RETURN
}
if (!CanBePoisoned(gBattleScripting.battler, gEffectBattler))
if (!CanBePoisoned(gBattleScripting.battler, gEffectBattler, GetBattlerAbility(gEffectBattler)))
break;

statusChanged = TRUE;
Expand Down Expand Up @@ -2990,7 +2990,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
break;
}

if (!CanBeBurned(gEffectBattler))
if (!CanBeBurned(gEffectBattler, GetBattlerAbility(gEffectBattler)))
break;

statusChanged = TRUE;
Expand Down Expand Up @@ -3055,7 +3055,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
}
if (!CanParalyzeType(gBattleScripting.battler, gEffectBattler))
break;
if (!CanBeParalyzed(gEffectBattler))
if (!CanBeParalyzed(gEffectBattler, GetBattlerAbility(gEffectBattler)))
break;

statusChanged = TRUE;
Expand Down Expand Up @@ -3093,7 +3093,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
}
if (gBattleMons[gEffectBattler].status1)
break;
if (CanBePoisoned(gBattleScripting.battler, gEffectBattler))
if (CanBePoisoned(gBattleScripting.battler, gEffectBattler, GetBattlerAbility(gEffectBattler)))
{
// It's redundant, because at this point we know the status1 value is 0.
gBattleMons[gEffectBattler].status1 &= ~STATUS1_TOXIC_POISON;
Expand Down Expand Up @@ -5514,7 +5514,7 @@ static void Cmd_moveend(void)
}
// Not strictly a protect effect, but works the same way
else if (gProtectStructs[gBattlerTarget].beakBlastCharge
&& CanBeBurned(gBattlerAttacker)
&& CanBeBurned(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
{
gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE;
Expand Down Expand Up @@ -9940,16 +9940,17 @@ static void Cmd_various(void)
case VARIOUS_PSYCHO_SHIFT:
{
VARIOUS_ARGS(const u8 *failInstr);
u32 targetAbility = GetBattlerAbility(gBattlerTarget);
// Psycho shift works
if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget))
if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, targetAbility))
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_TOXIC_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget))
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_TOXIC_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, targetAbility))
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_BURN) && CanBeBurned(gBattlerTarget))
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_BURN) && CanBeBurned(gBattlerTarget, targetAbility))
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && CanBeParalyzed(gBattlerTarget))
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && CanBeParalyzed(gBattlerTarget, targetAbility))
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) && CanSleep(gBattlerTarget))
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) && CanBeSlept(gBattlerTarget, targetAbility))
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE) && CanBeFrozen(gBattlerTarget))
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
Expand Down
Loading
Loading