2020-12-11 06:10:21 +01:00
|
|
|
#ifndef GUARD_BATTLE_AI_UTIL_H
|
|
|
|
#define GUARD_BATTLE_AI_UTIL_H
|
|
|
|
|
2021-09-28 03:03:27 +02:00
|
|
|
// for AI_WhoStrikesFirst
|
|
|
|
#define AI_IS_FASTER 0
|
|
|
|
#define AI_IS_SLOWER 1
|
2020-12-11 16:05:00 +01:00
|
|
|
|
2022-09-03 05:57:43 +02:00
|
|
|
#define FOE(battler) ((BATTLE_OPPOSITE(battler)) & BIT_SIDE)
|
2020-12-13 23:02:21 +01:00
|
|
|
|
2023-09-13 13:23:19 +02:00
|
|
|
#define AI_STRIKES_FIRST(battlerAi, battlerDef, move)((AI_WhoStrikesFirst(battlerAi, battlerDef, move) == AI_IS_FASTER))
|
|
|
|
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 AI_RandLessThan(u32 val);
|
2023-08-09 15:57:22 +02:00
|
|
|
bool32 IsAiVsAiBattle(void);
|
2023-03-28 16:38:48 +02:00
|
|
|
bool32 BattlerHasAi(u32 battlerId);
|
2023-04-10 17:36:17 +02:00
|
|
|
bool32 IsAiBattlerAware(u32 battlerId);
|
2023-09-13 17:28:26 +02:00
|
|
|
void ClearBattlerMoveHistory(u32 battlerId);
|
2020-12-11 16:05:00 +01:00
|
|
|
void RecordLastUsedMoveBy(u32 battlerId, u32 move);
|
2023-09-13 17:28:26 +02:00
|
|
|
void RecordKnownMove(u32 battlerId, u32 move);
|
|
|
|
void RecordAbilityBattle(u32 battlerId, u32 abilityId);
|
|
|
|
void ClearBattlerAbilityHistory(u32 battlerId);
|
|
|
|
void RecordItemEffectBattle(u32 battlerId, u32 itemEffect);
|
|
|
|
void ClearBattlerItemEffectHistory(u32 battlerId);
|
2023-09-12 23:20:09 +02:00
|
|
|
void SaveBattlerData(u32 battlerId);
|
|
|
|
void SetBattlerData(u32 battlerId);
|
|
|
|
void RestoreBattlerData(u32 battlerId);
|
2023-09-13 17:28:26 +02:00
|
|
|
u16 GetAIChosenMove(u32 battlerId);
|
2020-12-11 16:05:00 +01:00
|
|
|
|
2020-12-20 22:47:20 +01:00
|
|
|
u32 GetTotalBaseStat(u32 species);
|
|
|
|
bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler);
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 AtMaxHp(u32 battler);
|
|
|
|
u32 GetHealthPercentage(u32 battler);
|
|
|
|
bool32 IsBattlerTrapped(u32 battler, bool32 switching);
|
2023-09-13 13:23:19 +02:00
|
|
|
u32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler2, u32 moveConsidered);
|
2023-09-12 23:20:09 +02:00
|
|
|
bool32 CanTargetFaintAi(u32 battlerDef, u32 battlerAtk);
|
2023-09-14 11:05:00 +02:00
|
|
|
bool32 CanTargetMoveFaintAi(u32 move, u32 battlerDef, u32 battlerAtk, u32 nHits);
|
2023-09-12 23:20:09 +02:00
|
|
|
bool32 CanTargetFaintAiWithMod(u32 battlerDef, u32 battlerAtk, s32 hpMod, s32 dmgMod);
|
2020-12-13 23:02:21 +01:00
|
|
|
s32 AI_GetAbility(u32 battlerId);
|
2023-09-14 11:05:00 +02:00
|
|
|
u32 AI_GetHoldEffect(u32 battlerId);
|
2023-09-13 17:28:26 +02:00
|
|
|
u32 AI_GetMoveAccuracy(u32 battlerAtk, u32 battlerDef, u32 move);
|
|
|
|
bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move);
|
|
|
|
u32 AI_GetWeather(struct AiLogicData *aiData);
|
|
|
|
bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u32 numHits);
|
|
|
|
bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u32 index, u32 numHits);
|
|
|
|
bool32 AI_IsTerrainAffected(u32 battlerId, u32 flags);
|
|
|
|
bool32 AI_IsBattlerGrounded(u32 battlerId);
|
|
|
|
bool32 HasDamagingMove(u32 battlerId);
|
|
|
|
bool32 HasDamagingMoveOfType(u32 battlerId, u32 type);
|
|
|
|
u32 GetBattlerSecondaryDamage(u32 battlerId);
|
|
|
|
bool32 BattlerWillFaintFromWeather(u32 battler, u32 ability);
|
|
|
|
bool32 BattlerWillFaintFromSecondaryDamage(u32 battler, u32 ability);
|
|
|
|
bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbility, u32 move);
|
|
|
|
bool32 ShouldUseRecoilMove(u32 battlerAtk, u32 battlerDef, u32 recoilDmg, u32 moveIndex);
|
2023-09-13 14:04:25 +02:00
|
|
|
u32 GetBattlerSideSpeedAverage(u32 battler);
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, u32 move, s32 damage);
|
|
|
|
bool32 ShouldRecover(u32 battlerAtk, u32 battlerDef, u32 move, u32 healPercent);
|
|
|
|
bool32 ShouldSetScreen(u32 battlerAtk, u32 battlerDef, u32 moveEffect);
|
|
|
|
bool32 ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 moveIndex);
|
2020-12-20 05:58:23 +01:00
|
|
|
bool32 IsRecycleEncouragedItem(u16 item);
|
2023-09-12 23:20:09 +02:00
|
|
|
bool32 ShouldRestoreHpBerry(u32 battlerAtk, u16 item);
|
2021-11-08 17:37:41 +01:00
|
|
|
bool32 IsStatBoostingBerry(u16 item);
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 CanKnockOffItem(u32 battler, u16 item);
|
|
|
|
bool32 IsAbilityOfRating(u32 ability, s8 rating);
|
|
|
|
s8 GetAbilityRating(u32 ability);
|
2021-11-04 15:43:33 +01:00
|
|
|
bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability);
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u32 move);
|
|
|
|
u32 AI_GetBattlerMoveTargetType(u32 battlerId, u32 move);
|
2023-09-12 23:20:09 +02:00
|
|
|
bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u16 chosenMove);
|
2020-12-13 23:02:21 +01:00
|
|
|
|
|
|
|
// stat stage checks
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 AnyStatIsRaised(u32 battlerId);
|
|
|
|
bool32 ShouldLowerStat(u32 battler, u32 battlerAbility, u32 stat);
|
|
|
|
bool32 BattlerStatCanRise(u32 battler, u32 battlerAbility, u32 stat);
|
|
|
|
bool32 AreBattlersStatsMaxed(u32 battler);
|
|
|
|
bool32 BattlerHasAnyStatRaised(u32 battlerId);
|
|
|
|
u32 CountPositiveStatStages(u32 battlerId);
|
|
|
|
u32 CountNegativeStatStages(u32 battlerId);
|
|
|
|
bool32 ShouldLowerAttack(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
|
|
|
bool32 ShouldLowerDefense(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
|
|
|
bool32 ShouldLowerSpeed(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
|
|
|
bool32 ShouldLowerSpAtk(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
|
|
|
bool32 ShouldLowerSpDef(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
|
|
|
bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
|
|
|
bool32 ShouldLowerEvasion(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
2020-12-13 23:02:21 +01:00
|
|
|
|
|
|
|
// move checks
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 IsAffectedByPowder(u32 battler, u32 ability, u32 holdEffect);
|
2020-12-17 06:56:10 +01:00
|
|
|
bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split);
|
2023-09-12 23:20:09 +02:00
|
|
|
s32 AI_CalcDamageSaveBattlers(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectiveness, bool32 considerZPower);
|
2023-09-13 17:28:26 +02:00
|
|
|
s32 AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectiveness, bool32 considerZPower, u32 weather);
|
2023-07-16 08:24:59 +02:00
|
|
|
u32 GetNoOfHitsToKO(u32 dmg, s32 hp);
|
2023-09-13 13:23:19 +02:00
|
|
|
void SetMoveDamageResult(u32 battlerAtk, u16 *moves);
|
|
|
|
u32 GetMoveDamageResult(u32 battlerAtk, u32 battlerDef, u32 moveIndex);
|
2023-09-12 23:20:09 +02:00
|
|
|
u32 GetCurrDamageHpPercent(u32 battlerAtk, u32 battlerDef);
|
2023-09-13 17:28:26 +02:00
|
|
|
uq4_12_t AI_GetTypeEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef);
|
|
|
|
u32 AI_GetMoveEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef);
|
2020-12-13 23:02:21 +01:00
|
|
|
u16 *GetMovesArray(u32 battler);
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 IsConfusionMoveEffect(u32 moveEffect);
|
2020-12-20 05:58:23 +01:00
|
|
|
bool32 HasMove(u32 battlerId, u32 move);
|
2021-02-14 17:37:04 +01:00
|
|
|
bool32 HasOnlyMovesWithSplit(u32 battlerId, u32 split, bool32 onlyOffensive);
|
2020-12-13 23:02:21 +01:00
|
|
|
bool32 HasMoveWithSplit(u32 battler, u32 split);
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 HasMoveWithType(u32 battler, u32 type);
|
|
|
|
bool32 HasMoveWithTypeAndSplit(u32 battler, u32 type, u32 split);
|
|
|
|
bool32 HasMoveEffect(u32 battlerId, u32 moveEffect);
|
|
|
|
bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u32 accCheck, bool32 ignoreStatus, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
|
|
|
|
bool32 IsAromaVeilProtectedMove(u32 move);
|
|
|
|
bool32 IsNonVolatileStatusMoveEffect(u32 moveEffect);
|
|
|
|
bool32 IsStatLoweringMoveEffect(u32 moveEffect);
|
|
|
|
bool32 IsMoveRedirectionPrevented(u32 move, u32 atkAbility);
|
|
|
|
bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move);
|
|
|
|
bool32 IsHazardMoveEffect(u32 moveEffect);
|
|
|
|
bool32 MoveCallsOtherMove(u32 move);
|
|
|
|
bool32 MoveRequiresRecharging(u32 move);
|
|
|
|
bool32 IsEncoreEncouragedEffect(u32 moveEffect);
|
|
|
|
void ProtectChecks(u32 battlerAtk, u32 battlerDef, u32 move, u32 predictedMove, s32 *score);
|
|
|
|
bool32 ShouldSetSandstorm(u32 battler, u32 ability, u32 holdEffect);
|
|
|
|
bool32 ShouldSetHail(u32 battler, u32 ability, u32 holdEffect);
|
|
|
|
bool32 ShouldSetSnow(u32 battler, u32 ability, u32 holdEffect);
|
|
|
|
bool32 ShouldSetRain(u32 battlerAtk, u32 ability, u32 holdEffect);
|
|
|
|
bool32 ShouldSetSun(u32 battlerAtk, u32 atkAbility, u32 holdEffect);
|
2023-09-12 23:20:09 +02:00
|
|
|
bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef);
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 IsHealingMoveEffect(u32 effect);
|
2020-12-20 05:58:23 +01:00
|
|
|
bool32 HasHealingEffect(u32 battler);
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 IsTrappingMoveEffect(u32 effect);
|
|
|
|
bool32 HasTrappingMoveEffect(u32 battler);
|
|
|
|
bool32 ShouldFakeOut(u32 battlerAtk, u32 battlerDef, u32 move);
|
|
|
|
bool32 HasThawingMove(u32 battler);
|
|
|
|
bool32 IsStatRaisingEffect(u32 effect);
|
|
|
|
bool32 IsStatLoweringEffect(u32 effect);
|
|
|
|
bool32 IsStatRaisingEffect(u32 effect);
|
|
|
|
bool32 IsAttackBoostMoveEffect(u32 effect);
|
|
|
|
bool32 IsUngroundingEffect(u32 effect);
|
|
|
|
bool32 IsSemiInvulnerable(u32 battlerDef, u32 move);
|
|
|
|
bool32 HasSoundMove(u32 battler);
|
|
|
|
bool32 HasHighCritRatioMove(u32 battler);
|
|
|
|
bool32 HasMagicCoatAffectedMove(u32 battler);
|
|
|
|
bool32 HasSnatchAffectedMove(u32 battler);
|
2020-12-13 23:02:21 +01:00
|
|
|
|
|
|
|
// status checks
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 AI_CanBeBurned(u32 battler, u32 ability);
|
|
|
|
bool32 AI_CanGetFrostbite(u32 battler, u32 ability);
|
|
|
|
bool32 AI_CanBeConfused(u32 battler, 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);
|
|
|
|
bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
|
|
|
|
bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
|
|
|
|
bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
|
|
|
bool32 ShouldBurnSelf(u32 battler, u32 ability);
|
|
|
|
bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
|
|
|
bool32 AI_CanGiveFrostbite(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
|
|
|
bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
|
|
|
bool32 AnyPartyMemberStatused(u32 battlerId, bool32 checkSoundproof);
|
|
|
|
u32 ShouldTryToFlinch(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbility, u32 move);
|
|
|
|
bool32 ShouldTrap(u32 battlerAtk, u32 battlerDef, u32 move);
|
|
|
|
bool32 IsWakeupTurn(u32 battler);
|
|
|
|
bool32 AI_IsBattlerAsleepOrComatose(u32 battlerId);
|
2020-12-13 23:02:21 +01:00
|
|
|
|
|
|
|
// partner logic
|
2023-09-13 14:04:25 +02:00
|
|
|
#define IS_TARGETING_PARTNER(battlerAtk, battlerDef)((battlerAtk) == (battlerDef ^ BIT_FLANK))
|
2023-09-13 17:28:26 +02:00
|
|
|
u32 GetAllyChosenMove(u32 battlerId);
|
2023-09-12 23:20:09 +02:00
|
|
|
bool32 IsValidDoubleBattle(u32 battlerAtk);
|
|
|
|
bool32 IsTargetingPartner(u32 battlerAtk, u32 battlerDef);
|
2023-09-13 17:28:26 +02:00
|
|
|
bool32 DoesPartnerHaveSameMoveEffect(u32 battlerAtkPartner, u32 battlerDef, u32 move, u32 partnerMove);
|
|
|
|
bool32 PartnerHasSameMoveEffectWithoutTarget(u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
|
|
|
bool32 PartnerMoveEffectIsStatusSameTarget(u32 battlerAtkPartner, u32 battlerDef, u32 partnerMove);
|
|
|
|
bool32 PartnerMoveEffectIsWeather(u32 battlerAtkPartner, u32 partnerMove);
|
|
|
|
bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u32 partnerMove);
|
|
|
|
bool32 PartnerMoveIs(u32 battlerAtkPartner, u32 partnerMove, u32 moveCheck);
|
|
|
|
bool32 PartnerMoveIsSameAsAttacker(u32 battlerAtkPartner, u32 battlerDef, u32 move, u32 partnerMove);
|
|
|
|
bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
|
|
|
bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move);
|
2020-12-11 06:10:21 +01:00
|
|
|
|
2020-12-16 05:57:33 +01:00
|
|
|
// party logic
|
2023-07-18 12:01:25 +02:00
|
|
|
struct BattlePokemon *AllocSaveBattleMons(void);
|
|
|
|
void FreeRestoreBattleMons(struct BattlePokemon *savedBattleMons);
|
2023-07-18 11:36:09 +02:00
|
|
|
s32 AI_CalcPartyMonBestMoveDamage(u32 battlerAtk, u32 battlerDef, struct Pokemon *attackerMon, struct Pokemon *targetMon);
|
2023-09-13 17:28:26 +02:00
|
|
|
s32 CountUsablePartyMons(u32 battlerId);
|
|
|
|
bool32 IsPartyFullyHealedExceptBattler(u32 battler);
|
|
|
|
bool32 PartyHasMoveSplit(u32 battlerId, u32 split);
|
|
|
|
bool32 SideHasMoveSplit(u32 battlerId, u32 split);
|
2020-12-20 05:58:23 +01:00
|
|
|
|
|
|
|
// score increases
|
2023-09-13 17:28:26 +02:00
|
|
|
void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score);
|
|
|
|
void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
|
|
|
void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
|
|
|
void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
|
|
|
void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
|
|
|
void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
|
|
|
void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
2020-12-16 05:57:33 +01:00
|
|
|
|
2023-04-24 14:05:35 +02:00
|
|
|
#endif //GUARD_BATTLE_AI_UTIL_H
|