Skip to content

Commit

Permalink
Remove Duplicate ai code from battle_ai_util.c (rh-hideout#4883)
Browse files Browse the repository at this point in the history
* Remove Duplicate ai code from battle_ai_util.c

* Add GetBattlerAbility in toxic self check
  • Loading branch information
AlexOn1ine authored Jul 3, 2024
1 parent d81662d commit 594633a
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 147 deletions.
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

0 comments on commit 594633a

Please sign in to comment.