mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-25 19:24:16 +01:00
optimize dmg calc and ai dmg calc to reduce lag
This commit is contained in:
parent
2d9cbef684
commit
44bd830d2a
@ -8,7 +8,6 @@
|
||||
#define FOE(battler) ((BATTLE_OPPOSITE(battler)) & BIT_SIDE)
|
||||
|
||||
bool32 AI_RandLessThan(u8 val);
|
||||
void RecordLastUsedMoveByTarget(void);
|
||||
bool32 IsAiVsAiBattle(void);
|
||||
bool32 BattlerHasAi(u32 battlerId);
|
||||
bool32 IsAiBattlerAware(u32 battlerId);
|
||||
@ -19,9 +18,9 @@ void RecordAbilityBattle(u8 battlerId, u16 abilityId);
|
||||
void ClearBattlerAbilityHistory(u8 battlerId);
|
||||
void RecordItemEffectBattle(u8 battlerId, u8 itemEffect);
|
||||
void ClearBattlerItemEffectHistory(u8 battlerId);
|
||||
void SaveBattlerData(u8 battlerId);
|
||||
void SetBattlerData(u8 battlerId);
|
||||
void RestoreBattlerData(u8 battlerId);
|
||||
void SaveBattlerData(u32 battlerId);
|
||||
void SetBattlerData(u32 battlerId);
|
||||
void RestoreBattlerData(u32 battlerId);
|
||||
u16 GetAIChosenMove(u8 battlerId);
|
||||
|
||||
bool32 WillAIStrikeFirst(void);
|
||||
@ -31,16 +30,16 @@ bool32 AtMaxHp(u8 battler);
|
||||
u32 GetHealthPercentage(u8 battler);
|
||||
bool32 IsBattlerTrapped(u8 battler, bool8 switching);
|
||||
u8 AI_WhoStrikesFirst(u8 battlerAI, u8 battler2, u16 consideredMove);
|
||||
bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk);
|
||||
bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits);
|
||||
bool32 CanTargetFaintAiWithMod(u8 battlerDef, u8 battlerAtk, s32 hpMod, s32 dmgMod);
|
||||
bool32 CanTargetFaintAi(u32 battlerDef, u32 battlerAtk);
|
||||
bool32 CanMoveFaintBattler(u16 move, u32 battlerDef, u32 battlerAtk, u8 nHits);
|
||||
bool32 CanTargetFaintAiWithMod(u32 battlerDef, u32 battlerAtk, s32 hpMod, s32 dmgMod);
|
||||
s32 AI_GetAbility(u32 battlerId);
|
||||
u16 AI_GetHoldEffect(u32 battlerId);
|
||||
u32 AI_GetMoveAccuracy(u8 battlerAtk, u8 battlerDef, u16 move);
|
||||
u32 AI_GetMoveAccuracy(u32 battlerAtk, u32 battlerDef, u16 move);
|
||||
bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move);
|
||||
bool32 AI_WeatherHasEffect(void);
|
||||
bool32 CanAIFaintTarget(u8 battlerAtk, u8 battlerDef, u8 numHits);
|
||||
bool32 CanIndexMoveFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits);
|
||||
bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u8 numHits);
|
||||
bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u8 index, u8 numHits);
|
||||
bool32 AI_IsTerrainAffected(u8 battlerId, u32 flags);
|
||||
bool32 AI_IsBattlerGrounded(u8 battlerId);
|
||||
bool32 HasDamagingMove(u8 battlerId);
|
||||
@ -48,15 +47,15 @@ bool32 HasDamagingMoveOfType(u8 battlerId, u8 type);
|
||||
u32 GetBattlerSecondaryDamage(u8 battlerId);
|
||||
bool32 BattlerWillFaintFromWeather(u8 battler, u16 ability);
|
||||
bool32 BattlerWillFaintFromSecondaryDamage(u8 battler, u16 ability);
|
||||
bool32 ShouldTryOHKO(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move);
|
||||
bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 battlerDef, u32 recoilDmg, u8 moveIndex);
|
||||
bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, u16 atkAbility, u16 defAbility, u16 move);
|
||||
bool32 ShouldUseRecoilMove(u32 battlerAtk, u32 battlerDef, u32 recoilDmg, u8 moveIndex);
|
||||
u16 GetBattlerSideSpeedAverage(u8 battler);
|
||||
bool32 ShouldAbsorb(u8 battlerAtk, u8 battlerDef, u16 move, s32 damage);
|
||||
bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, u8 healPercent);
|
||||
bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect);
|
||||
bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 moveIndex);
|
||||
bool32 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, u16 move, s32 damage);
|
||||
bool32 ShouldRecover(u32 battlerAtk, u32 battlerDef, u16 move, u8 healPercent);
|
||||
bool32 ShouldSetScreen(u32 battlerAtk, u32 battlerDef, u16 moveEffect);
|
||||
bool32 ShouldPivot(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u8 moveIndex);
|
||||
bool32 IsRecycleEncouragedItem(u16 item);
|
||||
bool32 ShouldRestoreHpBerry(u8 battlerAtk, u16 item);
|
||||
bool32 ShouldRestoreHpBerry(u32 battlerAtk, u16 item);
|
||||
bool32 IsStatBoostingBerry(u16 item);
|
||||
bool32 CanKnockOffItem(u8 battler, u16 item);
|
||||
bool32 IsAbilityOfRating(u16 ability, s8 rating);
|
||||
@ -64,7 +63,7 @@ s8 GetAbilityRating(u16 ability);
|
||||
bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability);
|
||||
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move);
|
||||
u32 AI_GetBattlerMoveTargetType(u8 battlerId, u16 move);
|
||||
bool32 ShouldUseZMove(u8 activeId, u8 targetId, u16 chosenMove);
|
||||
bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u16 chosenMove);
|
||||
|
||||
// stat stage checks
|
||||
bool32 AnyStatIsRaised(u8 battlerId);
|
||||
@ -74,23 +73,24 @@ bool32 AreBattlersStatsMaxed(u8 battler);
|
||||
bool32 BattlerHasAnyStatRaised(u8 battlerId);
|
||||
u32 CountPositiveStatStages(u8 battlerId);
|
||||
u32 CountNegativeStatStages(u8 battlerId);
|
||||
bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerAttack(u32 battlerAtk, u32 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerDefense(u32 battlerAtk, u32 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerSpeed(u32 battlerAtk, u32 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerSpAtk(u32 battlerAtk, u32 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerSpDef(u32 battlerAtk, u32 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u16 defAbility);
|
||||
bool32 ShouldLowerEvasion(u32 battlerAtk, u32 battlerDef, u16 defAbility);
|
||||
|
||||
// move checks
|
||||
bool32 IsAffectedByPowder(u8 battler, u16 ability, u16 holdEffect);
|
||||
bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split);
|
||||
s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *effectiveness, bool32 considerZPower);
|
||||
s32 AI_CalcDamageSaveBattlers(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectiveness, bool32 considerZPower);
|
||||
s32 AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectiveness, bool32 considerZPower);
|
||||
u32 GetNoOfHitsToKO(u32 dmg, s32 hp);
|
||||
u8 GetMoveDamageResult(u16 move);
|
||||
u32 GetCurrDamageHpPercent(u8 battlerAtk, u8 battlerDef);
|
||||
uq4_12_t AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef);
|
||||
u32 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef);
|
||||
u32 GetCurrDamageHpPercent(u32 battlerAtk, u32 battlerDef);
|
||||
uq4_12_t AI_GetTypeEffectiveness(u16 move, u32 battlerAtk, u32 battlerDef);
|
||||
u32 AI_GetMoveEffectiveness(u16 move, u32 battlerAtk, u32 battlerDef);
|
||||
u16 *GetMovesArray(u32 battler);
|
||||
bool32 IsConfusionMoveEffect(u16 moveEffect);
|
||||
bool32 HasMove(u32 battlerId, u32 move);
|
||||
@ -99,35 +99,35 @@ bool32 HasMoveWithSplit(u32 battler, u32 split);
|
||||
bool32 HasMoveWithType(u32 battler, u8 type);
|
||||
bool32 HasMoveWithTypeAndSplit(u32 battler, u8 type, u8 split);
|
||||
bool32 HasMoveEffect(u32 battlerId, u16 moveEffect);
|
||||
bool32 HasMoveWithLowAccuracy(u8, u8, u8, bool32, u16, u16, u16, u16);
|
||||
bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u8 accCheck, bool32 ignoreStatus, u16 atkAbility, u16 defAbility, u16 atkHoldEffect, u16 defHoldEffect);
|
||||
bool32 IsAromaVeilProtectedMove(u16 move);
|
||||
bool32 IsNonVolatileStatusMoveEffect(u16 moveEffect);
|
||||
bool32 IsStatLoweringMoveEffect(u16 moveEffect);
|
||||
bool32 IsMoveRedirectionPrevented(u16 move, u16 atkAbility);
|
||||
bool32 IsMoveEncouragedToHit(u8 battlerAtk, u8 battlerDef, u16 move);
|
||||
bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u16 move);
|
||||
bool32 IsHazardMoveEffect(u16 moveEffect);
|
||||
bool32 MoveCallsOtherMove(u16 move);
|
||||
bool32 MoveRequiresRecharging(u16 move);
|
||||
bool32 IsEncoreEncouragedEffect(u16 moveEffect);
|
||||
void ProtectChecks(u8 battlerAtk, u8 battlerDef, u16 move, u16 predictedMove, s16 *score);
|
||||
void ProtectChecks(u32 battlerAtk, u32 battlerDef, u16 move, u16 predictedMove, s16 *score);
|
||||
bool32 ShouldSetSandstorm(u8 battler, u16 ability, u16 holdEffect);
|
||||
bool32 ShouldSetHail(u8 battler, u16 ability, u16 holdEffect);
|
||||
bool32 ShouldSetSnow(u8 battler, u16 ability, u16 holdEffect);
|
||||
bool32 ShouldSetRain(u8 battlerAtk, u16 ability, u16 holdEffect);
|
||||
bool32 ShouldSetSun(u8 battlerAtk, u16 atkAbility, u16 holdEffect);
|
||||
bool32 HasSleepMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef);
|
||||
bool32 ShouldSetRain(u32 battlerAtk, u16 ability, u16 holdEffect);
|
||||
bool32 ShouldSetSun(u32 battlerAtk, u16 atkAbility, u16 holdEffect);
|
||||
bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 IsHealingMoveEffect(u16 effect);
|
||||
bool32 HasHealingEffect(u32 battler);
|
||||
bool32 IsTrappingMoveEffect(u16 effect);
|
||||
bool32 HasTrappingMoveEffect(u8 battler);
|
||||
bool32 ShouldFakeOut(u8 battlerAtk, u8 battlerDef, u16 move);
|
||||
bool32 ShouldFakeOut(u32 battlerAtk, u32 battlerDef, u16 move);
|
||||
bool32 HasThawingMove(u8 battler);
|
||||
bool32 IsStatRaisingEffect(u16 effect);
|
||||
bool32 IsStatLoweringEffect(u16 effect);
|
||||
bool32 IsStatRaisingEffect(u16 effect);
|
||||
bool32 IsAttackBoostMoveEffect(u16 effect);
|
||||
bool32 IsUngroundingEffect(u16 effect);
|
||||
bool32 IsSemiInvulnerable(u8 battlerDef, u16 move);
|
||||
bool32 IsSemiInvulnerable(u32 battlerDef, u16 move);
|
||||
bool32 HasSoundMove(u8 battler);
|
||||
bool32 HasHighCritRatioMove(u8 battler);
|
||||
bool32 HasMagicCoatAffectedMove(u8 battler);
|
||||
@ -139,34 +139,34 @@ 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);
|
||||
bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
|
||||
bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
|
||||
bool32 ShouldPoisonSelf(u8 battler, u16 ability);
|
||||
bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
|
||||
bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
|
||||
bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
|
||||
bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
|
||||
bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
|
||||
bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u16 defAbility, u32 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);
|
||||
bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, u16 defAbility, u32 battlerAtkPartner, u16 move, u16 partnerMove);
|
||||
bool32 AI_CanGiveFrostbite(u32 battlerAtk, u32 battlerDef, u16 defAbility, u32 battlerAtkPartner, u16 move, u16 partnerMove);
|
||||
bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, u16 defAbility);
|
||||
bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof);
|
||||
u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move);
|
||||
bool32 ShouldTrap(u8 battlerAtk, u8 battlerDef, u16 move);
|
||||
u32 ShouldTryToFlinch(u32 battlerAtk, u32 battlerDef, u16 atkAbility, u16 defAbility, u16 move);
|
||||
bool32 ShouldTrap(u32 battlerAtk, u32 battlerDef, u16 move);
|
||||
bool32 IsWakeupTurn(u8 battler);
|
||||
bool32 AI_IsBattlerAsleepOrComatose(u8 battlerId);
|
||||
|
||||
// partner logic
|
||||
u16 GetAllyChosenMove(u8 battlerId);
|
||||
bool32 IsValidDoubleBattle(u8 battlerAtk);
|
||||
bool32 IsTargetingPartner(u8 battlerAtk, u8 battlerDef);
|
||||
bool32 DoesPartnerHaveSameMoveEffect(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove);
|
||||
bool32 PartnerHasSameMoveEffectWithoutTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove);
|
||||
bool32 PartnerMoveEffectIsStatusSameTarget(u8 battlerAtkPartner, u8 battlerDef, u16 partnerMove);
|
||||
bool32 PartnerMoveEffectIsWeather(u8 battlerAtkPartner, u16 partnerMove);
|
||||
bool32 PartnerMoveEffectIsTerrain(u8 battlerAtkPartner, u16 partnerMove);
|
||||
bool32 PartnerMoveIs(u8 battlerAtkPartner, u16 partnerMove, u16 moveCheck);
|
||||
bool32 PartnerMoveIsSameAsAttacker(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove);
|
||||
bool32 PartnerMoveIsSameNoTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove);
|
||||
bool32 ShouldUseWishAromatherapy(u8 battlerAtk, u8 battlerDef, u16 move);
|
||||
bool32 IsValidDoubleBattle(u32 battlerAtk);
|
||||
bool32 IsTargetingPartner(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 DoesPartnerHaveSameMoveEffect(u32 battlerAtkPartner, u32 battlerDef, u16 move, u16 partnerMove);
|
||||
bool32 PartnerHasSameMoveEffectWithoutTarget(u32 battlerAtkPartner, u16 move, u16 partnerMove);
|
||||
bool32 PartnerMoveEffectIsStatusSameTarget(u32 battlerAtkPartner, u32 battlerDef, u16 partnerMove);
|
||||
bool32 PartnerMoveEffectIsWeather(u32 battlerAtkPartner, u16 partnerMove);
|
||||
bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u16 partnerMove);
|
||||
bool32 PartnerMoveIs(u32 battlerAtkPartner, u16 partnerMove, u16 moveCheck);
|
||||
bool32 PartnerMoveIsSameAsAttacker(u32 battlerAtkPartner, u32 battlerDef, u16 move, u16 partnerMove);
|
||||
bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u16 move, u16 partnerMove);
|
||||
bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u16 move);
|
||||
|
||||
// party logic
|
||||
struct BattlePokemon *AllocSaveBattleMons(void);
|
||||
@ -178,12 +178,12 @@ bool32 PartyHasMoveSplit(u8 battlerId, u8 split);
|
||||
bool32 SideHasMoveSplit(u8 battlerId, u8 split);
|
||||
|
||||
// score increases
|
||||
void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score);
|
||||
void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
|
||||
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);
|
||||
void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u8 statId, s16 *score);
|
||||
void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score);
|
||||
void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score);
|
||||
void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score);
|
||||
void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score);
|
||||
void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score);
|
||||
void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score);
|
||||
|
||||
#endif //GUARD_BATTLE_AI_UTIL_H
|
||||
|
@ -67,7 +67,7 @@ void RunBattleScriptCommands_PopCallbacksStack(void);
|
||||
void RunBattleScriptCommands(void);
|
||||
bool8 TryRunFromBattle(u8 battlerId);
|
||||
void SpecialStatusesClear(void);
|
||||
void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk);
|
||||
void SetTypeBeforeUsingMove(u16 move, u32 battlerAtk);
|
||||
bool32 IsWildMonSmart(void);
|
||||
u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer *trainer, bool32 firstTrainer, u32 battleTypeFlags);
|
||||
void ModifyPersonalityForNature(u32 *personality, u32 newNature);
|
||||
|
@ -16,8 +16,8 @@ struct StatFractions
|
||||
u8 divisor;
|
||||
};
|
||||
|
||||
s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbility);
|
||||
s8 GetInverseCritChance(u8 battlerAtk, u8 battlerDef, u32 move);
|
||||
s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility);
|
||||
s8 GetInverseCritChance(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
|
||||
u8 GetBattlerTurnOrderNum(u8 battlerId);
|
||||
bool32 NoAliveMonsForEitherParty(void);
|
||||
@ -28,8 +28,8 @@ void BattleCreateYesNoCursorAt(u8 cursorPosition);
|
||||
void BufferMoveToLearnIntoBattleTextBuff2(void);
|
||||
void HandleBattleWindow(u8 xStart, u8 yStart, u8 xEnd, u8 yEnd, u8 flags);
|
||||
bool8 UproarWakeUpCheck(u8 battlerId);
|
||||
bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move);
|
||||
bool32 DoesDisguiseBlockMove(u8 battlerAtk, u8 battlerDef, u32 move);
|
||||
bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 DoesDisguiseBlockMove(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget);
|
||||
bool32 CanParalyzeType(u8 battlerAttacker, u8 battlerTarget);
|
||||
bool32 CanUseLastResort(u8 battlerId);
|
||||
|
@ -161,20 +161,20 @@ void HandleAction_RunBattleScript(void);
|
||||
u32 SetRandomTarget(u32 battler);
|
||||
u32 GetMoveTarget(u16 move, u8 setTarget);
|
||||
u8 IsMonDisobedient(void);
|
||||
u32 GetBattlerHoldEffect(u8 battler, bool32 checkNegating);
|
||||
u32 GetBattlerHoldEffect(u32 battler, bool32 checkNegating);
|
||||
u32 GetBattlerHoldEffectParam(u8 battler);
|
||||
bool32 IsMoveMakingContact(u16 move, u8 battlerAtk);
|
||||
bool32 IsMoveMakingContact(u16 move, u32 battlerAtk);
|
||||
bool32 IsBattlerGrounded(u8 battler);
|
||||
bool32 IsBattlerAlive(u8 battler);
|
||||
u8 GetBattleMonMoveSlot(struct BattlePokemon *battleMon, u16 move);
|
||||
u32 GetBattlerWeight(u8 battler);
|
||||
u32 CalcRolloutBasePower(u32 battlerAtk, u32 basePower, u32 rolloutTimer);
|
||||
u32 CalcFuryCutterBasePower(u32 basePower, u32 furyCutterCounter);
|
||||
s32 CalculateMoveDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32 fixedBasePower, bool32 isCrit, bool32 randomFactor, bool32 updateFlags);
|
||||
s32 CalculateMoveDamageAndEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32 fixedBasePower, uq4_12_t *typeEffectivenessModifier);
|
||||
uq4_12_t CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 battlerDef, bool32 recordAbilities);
|
||||
s32 CalculateMoveDamage(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, bool32 isCrit, bool32 randomFactor, bool32 updateFlags);
|
||||
s32 CalculateMoveDamageAndEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, uq4_12_t *typeEffectivenessModifier);
|
||||
uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, bool32 recordAbilities);
|
||||
uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef);
|
||||
uq4_12_t GetTypeModifier(u8 atkType, u8 defType);
|
||||
uq4_12_t GetTypeModifier(u32 atkType, u32 defType);
|
||||
s32 GetStealthHazardDamage(u8 hazardType, u8 battler);
|
||||
s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp);
|
||||
bool32 CanMegaEvolve(u8 battler);
|
||||
@ -209,11 +209,11 @@ void SortBattlersBySpeed(u8 *battlers, bool8 slowToFast);
|
||||
bool32 CompareStat(u8 battler, u8 statId, u8 cmpTo, u8 cmpKind);
|
||||
bool32 TryRoomService(u8 battler);
|
||||
void BufferStatChange(u8 battler, u8 statId, u8 stringId);
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget);
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u32 battlerDef, bool32 checkTarget);
|
||||
u16 GetUsedHeldItem(u8 battler);
|
||||
bool32 IsBattlerWeatherAffected(u8 battler, u32 weatherFlags);
|
||||
u32 GetBattlerMoveTargetType(u8 battler, u16 move);
|
||||
bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move);
|
||||
bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, u16 move);
|
||||
bool8 IsMoveAffectedByParentalBond(u16 move, u8 battler);
|
||||
void CopyMonLevelAndBaseStatsToBattleMon(u32 battler, struct Pokemon *mon);
|
||||
void CopyMonAbilityAndTypesToBattleMon(u32 battler, struct Pokemon *mon);
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
// Battle Debug Menu
|
||||
#define DEBUG_BATTLE_MENU TRUE // If set to TRUE, enables a debug menu to use in battles by pressing the Select button.
|
||||
#define DEBUG_AI_DELAY_TIMER FALSE // If set to TRUE, displays the number of frames it takes for the AI to choose a move. Replaces the "What will PKMN do" text. Useful for devs or anyone who modifies the AI code and wants to see if it doesn't take too long to run.
|
||||
#define DEBUG_AI_DELAY_TIMER TRUE // If set to TRUE, displays the number of frames it takes for the AI to choose a move. Replaces the "What will PKMN do" text. Useful for devs or anyone who modifies the AI code and wants to see if it doesn't take too long to run.
|
||||
|
||||
// Pokémon Debug
|
||||
#define DEBUG_POKEMON_MENU TRUE // Enables a debug menu for pokemon sprites and icons, accessed by pressing SELECT in the summary screen.
|
||||
|
@ -47,20 +47,20 @@ EWRAM_DATA const u8 *gAIScriptPtr = NULL; // Still used in contests
|
||||
EWRAM_DATA u8 sBattler_AI = 0;
|
||||
|
||||
// const rom data
|
||||
static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_Risky(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_PreferStrongestMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_Roaming(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_Safari(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_FirstBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_Risky(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_PreferStrongestMove(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_HPAware(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_Roaming(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_Safari(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_FirstBattle(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
static s16 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u16 move, s16 score);
|
||||
|
||||
static s16 (*const sBattleAiFuncTable[])(u8, u8, u16, s16) =
|
||||
static s16 (*const sBattleAiFuncTable[])(u32, u32, u16, s16) =
|
||||
{
|
||||
[0] = AI_CheckBadMove, // AI_FLAG_CHECK_BAD_MOVE
|
||||
[1] = AI_TryToFaint, // AI_FLAG_TRY_TO_FAINT
|
||||
@ -349,9 +349,7 @@ static void SetBattlerAiData(u32 battler)
|
||||
|
||||
void SetAiLogicDataForTurn(void)
|
||||
{
|
||||
u32 battlerAtk, battlerDef, i, move;
|
||||
u8 effectiveness;
|
||||
s32 dmg;
|
||||
u32 battlerAtk, battlerDef, i, battlersCount;
|
||||
|
||||
memset(AI_DATA, 0, sizeof(struct AiLogicData));
|
||||
|
||||
@ -360,33 +358,29 @@ void SetAiLogicDataForTurn(void)
|
||||
|
||||
gBattleStruct->aiDelayTimer = gMain.vblankCounter1;
|
||||
|
||||
// get/assume all battler data
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
// get/assume all battler data and simulate AI damage
|
||||
battlersCount = gBattlersCount;
|
||||
for (battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++)
|
||||
{
|
||||
if (IsBattlerAlive(i)) {
|
||||
SetBattlerAiData(i);
|
||||
}
|
||||
}
|
||||
|
||||
// simulate AI damage
|
||||
for (battlerAtk = 0; battlerAtk < gBattlersCount; battlerAtk++)
|
||||
{
|
||||
if (!IsBattlerAlive(battlerAtk)
|
||||
|| !IsAiBattlerAware(battlerAtk)) {
|
||||
if (!IsBattlerAlive(battlerAtk))
|
||||
continue;
|
||||
}
|
||||
|
||||
for (battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
||||
SetBattlerAiData(battlerAtk);
|
||||
if (!IsAiBattlerAware(battlerAtk))
|
||||
continue;
|
||||
|
||||
SaveBattlerData(battlerAtk);
|
||||
for (battlerDef = 0; battlerDef < battlersCount; battlerDef++)
|
||||
{
|
||||
if (battlerAtk == battlerDef)
|
||||
continue;
|
||||
|
||||
RecordKnownMove(battlerDef, gLastMoves[battlerDef]);
|
||||
SaveBattlerData(battlerDef);
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
dmg = 0;
|
||||
effectiveness = AI_EFFECTIVENESS_x0;
|
||||
move = gBattleMons[battlerAtk].moves[i];
|
||||
s32 dmg = 0;
|
||||
u8 effectiveness = AI_EFFECTIVENESS_x0;
|
||||
u32 move = gBattleMons[battlerAtk].moves[i];
|
||||
|
||||
if (move != 0
|
||||
&& move != 0xFFFF
|
||||
@ -562,8 +556,6 @@ static u8 ChooseMoveOrAction_Doubles(void)
|
||||
BattleAI_SetupAIData(0xF, sBattler_AI);
|
||||
|
||||
gBattlerTarget = i;
|
||||
if ((i & BIT_SIDE) != (sBattler_AI & BIT_SIDE))
|
||||
RecordLastUsedMoveByTarget();
|
||||
|
||||
AI_DATA->partnerMove = GetAllyChosenMove(i);
|
||||
AI_THINKING_STRUCT->aiLogicId = 0;
|
||||
@ -710,7 +702,7 @@ static void BattleAI_DoAIProcessing(void)
|
||||
|
||||
// AI Score Functions
|
||||
// AI_FLAG_CHECK_BAD_MOVE - decreases move scores
|
||||
static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
// move data
|
||||
u8 atkPriority = GetMovePriority(battlerAtk, move);
|
||||
@ -2694,7 +2686,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
return score;
|
||||
}
|
||||
|
||||
static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||
return score;
|
||||
@ -2749,14 +2741,14 @@ static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
|
||||
// double battle logic
|
||||
static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
// move data
|
||||
u8 moveType = gBattleMoves[move].type;
|
||||
u16 effect = gBattleMoves[move].effect;
|
||||
u16 moveTarget = AI_GetBattlerMoveTargetType(battlerAtk, move);
|
||||
// ally data
|
||||
u8 battlerAtkPartner = BATTLE_PARTNER(battlerAtk);
|
||||
u32 battlerAtkPartner = BATTLE_PARTNER(battlerAtk);
|
||||
u16 atkPartnerAbility = AI_DATA->abilities[BATTLE_PARTNER(battlerAtk)];
|
||||
u16 atkPartnerHoldEffect = AI_DATA->holdEffects[BATTLE_PARTNER(battlerAtk)];
|
||||
bool32 partnerProtecting = (gBattleMoves[AI_DATA->partnerMove].effect == EFFECT_PROTECT);
|
||||
@ -3148,7 +3140,7 @@ static bool32 IsPinchBerryItemEffect(u16 holdEffect)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static u32 GetAIMostDamagingMoveId(u8 battlerAtk, u8 battlerDef)
|
||||
static u32 GetAIMostDamagingMoveId(u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
u32 i, id = 0;
|
||||
u32 mostDmg = 0;
|
||||
@ -3162,7 +3154,7 @@ static u32 GetAIMostDamagingMoveId(u8 battlerAtk, u8 battlerDef)
|
||||
}
|
||||
|
||||
// AI_FLAG_CHECK_VIABILITY - a weird mix of increasing and decreasing scores
|
||||
static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
// move data
|
||||
u16 moveEffect = gBattleMoves[move].effect;
|
||||
@ -4964,7 +4956,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
|
||||
// Effects that are encouraged on the first turn of battle
|
||||
static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
if (IsTargetingPartner(battlerAtk, battlerDef)
|
||||
|| gBattleResults.battleTurnCounter != 0)
|
||||
@ -5075,7 +5067,7 @@ static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
|
||||
// Adds score bonus to 'riskier' move effects and high crit moves
|
||||
static s16 AI_Risky(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_Risky(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||
return score;
|
||||
@ -5114,7 +5106,7 @@ static s16 AI_Risky(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
|
||||
// Adds score bonus to best powered move
|
||||
static s16 AI_PreferStrongestMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_PreferStrongestMove(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||
return score;
|
||||
@ -5126,7 +5118,7 @@ static s16 AI_PreferStrongestMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 sc
|
||||
}
|
||||
|
||||
// Prefers moves that are good for baton pass
|
||||
static s16 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
@ -5181,7 +5173,7 @@ static s16 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
return score;
|
||||
}
|
||||
|
||||
static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_HPAware(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
u16 effect = gBattleMoves[move].effect;
|
||||
u8 moveType = gBattleMoves[move].type;
|
||||
@ -5384,7 +5376,7 @@ static void AI_Watch(void)
|
||||
}
|
||||
|
||||
// Roaming pokemon logic
|
||||
static s16 AI_Roaming(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_Roaming(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
if (IsBattlerTrapped(battlerAtk, FALSE))
|
||||
return score;
|
||||
@ -5394,7 +5386,7 @@ static s16 AI_Roaming(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
|
||||
// Safari pokemon logic
|
||||
static s16 AI_Safari(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_Safari(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
u8 safariFleeRate = gBattleStruct->safariEscapeFactor * 5; // Safari flee rate, from 0-20.
|
||||
|
||||
@ -5407,7 +5399,7 @@ static s16 AI_Safari(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
|
||||
// First battle logic
|
||||
static s16 AI_FirstBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
static s16 AI_FirstBattle(u32 battlerAtk, u32 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
if (AI_DATA->hpPercents[battlerDef] <= 20)
|
||||
AI_Flee();
|
||||
|
@ -436,11 +436,6 @@ bool32 AI_RandLessThan(u8 val)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void RecordLastUsedMoveByTarget(void)
|
||||
{
|
||||
RecordKnownMove(gBattlerTarget, gLastMoves[gBattlerTarget]);
|
||||
}
|
||||
|
||||
bool32 IsAiVsAiBattle(void)
|
||||
{
|
||||
return (B_FLAG_AI_VS_AI_BATTLE && FlagGet(B_FLAG_AI_VS_AI_BATTLE));
|
||||
@ -529,7 +524,7 @@ void ClearBattlerItemEffectHistory(u8 battlerId)
|
||||
BATTLE_HISTORY->itemEffects[battlerId] = 0;
|
||||
}
|
||||
|
||||
void SaveBattlerData(u8 battlerId)
|
||||
void SaveBattlerData(u32 battlerId)
|
||||
{
|
||||
if (!BattlerHasAi(battlerId))
|
||||
{
|
||||
@ -580,7 +575,7 @@ static bool32 ShouldFailForIllusion(u16 illusionSpecies, u32 battlerId)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void SetBattlerData(u8 battlerId)
|
||||
void SetBattlerData(u32 battlerId)
|
||||
{
|
||||
if (!BattlerHasAi(battlerId))
|
||||
{
|
||||
@ -624,7 +619,7 @@ void SetBattlerData(u8 battlerId)
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreBattlerData(u8 battlerId)
|
||||
void RestoreBattlerData(u32 battlerId)
|
||||
{
|
||||
if (!BattlerHasAi(battlerId))
|
||||
{
|
||||
@ -741,7 +736,7 @@ bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split)
|
||||
return (usable == 0);
|
||||
}
|
||||
|
||||
static bool32 AI_GetIfCrit(u32 move, u8 battlerAtk, u8 battlerDef)
|
||||
static bool32 AI_GetIfCrit(u32 move, u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
bool32 isCrit;
|
||||
|
||||
@ -776,12 +771,23 @@ static bool32 AI_GetIfCrit(u32 move, u8 battlerAtk, u8 battlerDef)
|
||||
return isCrit;
|
||||
}
|
||||
|
||||
s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *typeEffectiveness, bool32 considerZPower)
|
||||
// To save computation time this function has 2 variants. One saves, sets and restores battlers, while the other doesn't.
|
||||
s32 AI_CalcDamageSaveBattlers(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectiveness, bool32 considerZPower)
|
||||
{
|
||||
SaveBattlerData(battlerAtk);
|
||||
SaveBattlerData(battlerDef);
|
||||
AI_CalcDamage(move, battlerAtk, battlerDef, typeEffectiveness, considerZPower);
|
||||
}
|
||||
|
||||
s32 AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectiveness, bool32 considerZPower)
|
||||
{
|
||||
s32 dmg, moveType, critDmg, normalDmg, fixedBasePower, n;
|
||||
s8 critChance;
|
||||
uq4_12_t effectivenessMultiplier;
|
||||
|
||||
SetBattlerData(battlerAtk);
|
||||
SetBattlerData(battlerDef);
|
||||
|
||||
if (considerZPower && IsViableZMove(battlerAtk, move))
|
||||
{
|
||||
//temporarily enable z moves for damage calcs
|
||||
@ -789,12 +795,6 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *typeEffectiveness,
|
||||
gBattleStruct->zmove.active = TRUE;
|
||||
}
|
||||
|
||||
SaveBattlerData(battlerAtk);
|
||||
SaveBattlerData(battlerDef);
|
||||
|
||||
SetBattlerData(battlerAtk);
|
||||
SetBattlerData(battlerDef);
|
||||
|
||||
gBattleStruct->dynamicMoveType = 0;
|
||||
|
||||
if (move == MOVE_NATURE_POWER)
|
||||
@ -1026,14 +1026,14 @@ u8 GetMoveDamageResult(u16 move)
|
||||
return AI_THINKING_STRUCT->funcResult;
|
||||
}
|
||||
|
||||
u32 GetCurrDamageHpPercent(u8 battlerAtk, u8 battlerDef)
|
||||
u32 GetCurrDamageHpPercent(u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
int bestDmg = AI_DATA->simulatedDmg[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex];
|
||||
|
||||
return (bestDmg * 100) / gBattleMons[battlerDef].maxHP;
|
||||
}
|
||||
|
||||
uq4_12_t AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
uq4_12_t AI_GetTypeEffectiveness(u16 move, u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
uq4_12_t typeEffectiveness;
|
||||
u16 moveType;
|
||||
@ -1055,7 +1055,7 @@ uq4_12_t AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
return typeEffectiveness;
|
||||
}
|
||||
|
||||
u32 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
u32 AI_GetMoveEffectiveness(u16 move, u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
gMoveResultFlags = 0;
|
||||
return AI_GetEffectiveness(AI_GetTypeEffectiveness(move, battlerAtk, battlerDef));
|
||||
@ -1134,7 +1134,7 @@ u8 AI_WhoStrikesFirst(u8 battlerAI, u8 battler2, u16 moveConsidered)
|
||||
}
|
||||
|
||||
// Check if target has means to faint ai mon.
|
||||
bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk)
|
||||
bool32 CanTargetFaintAi(u32 battlerDef, u32 battlerAtk)
|
||||
{
|
||||
s32 i, dmg;
|
||||
u32 unusable = AI_DATA->moveLimitations[battlerDef];
|
||||
@ -1154,7 +1154,7 @@ bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk)
|
||||
|
||||
// Check if AI mon has the means to faint the target with any of its moves.
|
||||
// If numHits > 1, check if the target will be KO'ed by that number of hits (ignoring healing effects)
|
||||
bool32 CanAIFaintTarget(u8 battlerAtk, u8 battlerDef, u8 numHits)
|
||||
bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u8 numHits)
|
||||
{
|
||||
s32 i, dmg;
|
||||
u32 moveLimitations = AI_DATA->moveLimitations[battlerAtk];
|
||||
@ -1178,7 +1178,7 @@ bool32 CanAIFaintTarget(u8 battlerAtk, u8 battlerDef, u8 numHits)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits)
|
||||
bool32 CanMoveFaintBattler(u16 move, u32 battlerDef, u32 battlerAtk, u8 nHits)
|
||||
{
|
||||
s32 i, dmg;
|
||||
u8 effectiveness;
|
||||
@ -1187,14 +1187,14 @@ bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits)
|
||||
if (move != MOVE_NONE
|
||||
&& move != 0xFFFF
|
||||
&& !(unusable & gBitTable[i])
|
||||
&& AI_CalcDamage(move, battlerDef, battlerAtk, &effectiveness, FALSE) >= gBattleMons[battlerAtk].hp)
|
||||
&& AI_CalcDamageSaveBattlers(move, battlerDef, battlerAtk, &effectiveness, FALSE) >= gBattleMons[battlerAtk].hp)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check if target has means to faint ai mon after modding hp/dmg
|
||||
bool32 CanTargetFaintAiWithMod(u8 battlerDef, u8 battlerAtk, s32 hpMod, s32 dmgMod)
|
||||
bool32 CanTargetFaintAiWithMod(u32 battlerDef, u32 battlerAtk, s32 hpMod, s32 dmgMod)
|
||||
{
|
||||
u32 i;
|
||||
u32 unusable = AI_DATA->moveLimitations[battlerDef];
|
||||
@ -1466,13 +1466,13 @@ bool32 IsMoveRedirectionPrevented(u16 move, u16 atkAbility)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u32 AI_GetMoveAccuracy(u8 battlerAtk, u8 battlerDef, u16 move)
|
||||
u32 AI_GetMoveAccuracy(u32 battlerAtk, u32 battlerDef, u16 move)
|
||||
{
|
||||
return GetTotalAccuracy(battlerAtk, battlerDef, move, AI_DATA->abilities[battlerAtk], AI_DATA->abilities[battlerDef],
|
||||
AI_DATA->holdEffects[battlerAtk], AI_DATA->holdEffects[battlerDef]);
|
||||
}
|
||||
|
||||
bool32 IsSemiInvulnerable(u8 battlerDef, u16 move)
|
||||
bool32 IsSemiInvulnerable(u32 battlerDef, u16 move)
|
||||
{
|
||||
if (gStatuses3[battlerDef] & STATUS3_PHANTOM_FORCE)
|
||||
return TRUE;
|
||||
@ -1486,7 +1486,7 @@ bool32 IsSemiInvulnerable(u8 battlerDef, u16 move)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsMoveEncouragedToHit(u8 battlerAtk, u8 battlerDef, u16 move)
|
||||
bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u16 move)
|
||||
{
|
||||
if (IsSemiInvulnerable(battlerDef, move))
|
||||
return FALSE;
|
||||
@ -1526,7 +1526,7 @@ bool32 IsMoveEncouragedToHit(u8 battlerAtk, u8 battlerDef, u16 move)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldTryOHKO(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move)
|
||||
bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, u16 atkAbility, u16 defAbility, u16 move)
|
||||
{
|
||||
u32 holdEffect = AI_DATA->holdEffects[battlerDef];
|
||||
u32 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, move);
|
||||
@ -1608,7 +1608,7 @@ bool32 ShouldSetHail(u8 battler, u16 ability, u16 holdEffect)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldSetRain(u8 battlerAtk, u16 atkAbility, u16 holdEffect)
|
||||
bool32 ShouldSetRain(u32 battlerAtk, u16 atkAbility, u16 holdEffect)
|
||||
{
|
||||
if (!AI_WeatherHasEffect())
|
||||
return FALSE;
|
||||
@ -1631,7 +1631,7 @@ bool32 ShouldSetRain(u8 battlerAtk, u16 atkAbility, u16 holdEffect)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldSetSun(u8 battlerAtk, u16 atkAbility, u16 holdEffect)
|
||||
bool32 ShouldSetSun(u32 battlerAtk, u16 atkAbility, u16 holdEffect)
|
||||
{
|
||||
if (!AI_WeatherHasEffect())
|
||||
return FALSE;
|
||||
@ -1679,7 +1679,7 @@ bool32 ShouldSetSnow(u8 battler, u16 ability, u16 holdEffect)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void ProtectChecks(u8 battlerAtk, u8 battlerDef, u16 move, u16 predictedMove, s16 *score)
|
||||
void ProtectChecks(u32 battlerAtk, u32 battlerDef, u16 move, u16 predictedMove, s16 *score)
|
||||
{
|
||||
// TODO more sophisticated logic
|
||||
u16 predictedEffect = gBattleMoves[predictedMove].effect;
|
||||
@ -1793,7 +1793,7 @@ u32 CountNegativeStatStages(u8 battlerId)
|
||||
return count;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
bool32 ShouldLowerAttack(u32 battlerAtk, u32 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
@ -1810,7 +1810,7 @@ bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
bool32 ShouldLowerDefense(u32 battlerAtk, u32 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
@ -1827,7 +1827,7 @@ bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
bool32 ShouldLowerSpeed(u32 battlerAtk, u32 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
@ -1842,7 +1842,7 @@ bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
bool32 ShouldLowerSpAtk(u32 battlerAtk, u32 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
@ -1858,7 +1858,7 @@ bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
bool32 ShouldLowerSpDef(u32 battlerAtk, u32 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
@ -1874,7 +1874,7 @@ bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
@ -1889,7 +1889,7 @@ bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
bool32 ShouldLowerEvasion(u32 battlerAtk, u32 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
@ -1904,7 +1904,7 @@ bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanIndexMoveFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits)
|
||||
bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u8 index, u8 numHits)
|
||||
{
|
||||
s32 dmg = AI_DATA->simulatedDmg[battlerAtk][battlerDef][index];
|
||||
|
||||
@ -1996,7 +1996,7 @@ bool32 HasMove(u32 battlerId, u32 move)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 HasMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef, u8 accCheck, bool32 ignoreStatus, u16 atkAbility, u16 defAbility, u16 atkHoldEffect, u16 defHoldEffect)
|
||||
bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u8 accCheck, bool32 ignoreStatus, u16 atkAbility, u16 defAbility, u16 atkHoldEffect, u16 defHoldEffect)
|
||||
{
|
||||
s32 i;
|
||||
u16 *moves = GetMovesArray(battlerAtk);
|
||||
@ -2023,7 +2023,7 @@ bool32 HasMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef, u8 accCheck, bool32
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 HasSleepMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef)
|
||||
bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
u8 moveLimitations = AI_DATA->moveLimitations[battlerAtk];
|
||||
u32 i;
|
||||
@ -2560,7 +2560,7 @@ enum {
|
||||
CAN_TRY_PIVOT,
|
||||
PIVOT,
|
||||
};
|
||||
bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 moveIndex)
|
||||
bool32 ShouldPivot(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u8 moveIndex)
|
||||
{
|
||||
bool8 hasStatBoost = AnyUsefulStatIsRaised(battlerAtk) || gBattleMons[battlerDef].statStages[STAT_EVASION] >= 9; //Significant boost in evasion for any class
|
||||
bool32 shouldSwitch;
|
||||
@ -2789,7 +2789,7 @@ bool32 AI_CanSleep(u8 battler, u16 ability)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
||||
bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!AI_CanSleep(battlerDef, defAbility)
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
@ -2804,7 +2804,7 @@ static bool32 AI_CanPoisonType(u8 battlerAttacker, u8 battlerTarget)
|
||||
|| !(IS_BATTLER_OF_TYPE(battlerTarget, TYPE_POISON) || IS_BATTLER_OF_TYPE(battlerTarget, TYPE_STEEL)));
|
||||
}
|
||||
|
||||
static bool32 AI_CanBePoisoned(u8 battlerAtk, u8 battlerDef)
|
||||
static bool32 AI_CanBePoisoned(u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
u16 ability = AI_DATA->abilities[battlerDef];
|
||||
|
||||
@ -2836,7 +2836,7 @@ bool32 ShouldPoisonSelf(u8 battler, u16 ability)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
||||
bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!AI_CanBePoisoned(battlerAtk, battlerDef)
|
||||
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|
||||
@ -2862,7 +2862,7 @@ static bool32 AI_CanBeParalyzed(u8 battler, u16 ability)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
||||
bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!AI_CanBeParalyzed(battlerDef, defAbility)
|
||||
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|
||||
@ -2882,7 +2882,7 @@ bool32 AI_CanBeConfused(u8 battler, u16 ability)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove)
|
||||
bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u16 defAbility, u32 battlerAtkPartner, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!AI_CanBeConfused(battlerDef, defAbility)
|
||||
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|
||||
@ -2935,7 +2935,7 @@ bool32 ShouldBurnSelf(u8 battler, u16 ability)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove)
|
||||
bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, u16 defAbility, u32 battlerAtkPartner, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!AI_CanBeBurned(battlerDef, defAbility)
|
||||
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|
||||
@ -2947,7 +2947,7 @@ 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)
|
||||
bool32 AI_CanGiveFrostbite(u32 battlerAtk, u32 battlerDef, u16 defAbility, u32 battlerAtkPartner, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!AI_CanGetFrostbite(battlerDef, defAbility)
|
||||
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|
||||
@ -2959,7 +2959,7 @@ bool32 AI_CanGiveFrostbite(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 batt
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, u16 defAbility)
|
||||
{
|
||||
if ((gBattleMons[battlerDef].status2 & STATUS2_INFATUATION)
|
||||
|| AI_GetMoveEffectiveness(AI_THINKING_STRUCT->moveConsidered, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|
||||
@ -2970,7 +2970,7 @@ bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move)
|
||||
u32 ShouldTryToFlinch(u32 battlerAtk, u32 battlerDef, u16 atkAbility, u16 defAbility, u16 move)
|
||||
{
|
||||
if (((AI_DATA->abilities[battlerAtk] != ABILITY_MOLD_BREAKER && (defAbility == ABILITY_SHIELD_DUST || defAbility == ABILITY_INNER_FOCUS))
|
||||
|| AI_GetHoldEffect(battlerDef) == HOLD_EFFECT_COVERT_CLOAK
|
||||
@ -2991,7 +2991,7 @@ u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbili
|
||||
return 0; // don't try to flinch
|
||||
}
|
||||
|
||||
bool32 ShouldTrap(u8 battlerAtk, u8 battlerDef, u16 move)
|
||||
bool32 ShouldTrap(u32 battlerAtk, u32 battlerDef, u16 move)
|
||||
{
|
||||
if (BattlerWillFaintFromSecondaryDamage(battlerDef, AI_DATA->abilities[battlerDef]))
|
||||
return TRUE; // battler is taking secondary damage with low HP
|
||||
@ -3005,7 +3005,7 @@ bool32 ShouldTrap(u8 battlerAtk, u8 battlerDef, u16 move)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldFakeOut(u8 battlerAtk, u8 battlerDef, u16 move)
|
||||
bool32 ShouldFakeOut(u32 battlerAtk, u32 battlerDef, u16 move)
|
||||
{
|
||||
if (!gDisableStructs[battlerAtk].isFirstTurn
|
||||
|| AI_DATA->abilities[battlerAtk] == ABILITY_GORILLA_TACTICS
|
||||
@ -3082,7 +3082,7 @@ u16 GetBattlerSideSpeedAverage(u8 battler)
|
||||
return (speed1 + speed2) / numBattlersAlive;
|
||||
}
|
||||
|
||||
bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 battlerDef, u32 recoilDmg, u8 moveIndex)
|
||||
bool32 ShouldUseRecoilMove(u32 battlerAtk, u32 battlerDef, u32 recoilDmg, u8 moveIndex)
|
||||
{
|
||||
if (recoilDmg >= gBattleMons[battlerAtk].hp //Recoil kills attacker
|
||||
&& CountUsablePartyMons(battlerDef) != 0) //Foe has more than 1 target left
|
||||
@ -3096,7 +3096,7 @@ bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 battlerDef, u32 recoilDmg, u8 moveI
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 ShouldAbsorb(u8 battlerAtk, u8 battlerDef, u16 move, s32 damage)
|
||||
bool32 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, u16 move, s32 damage)
|
||||
{
|
||||
if (move == 0xFFFF || AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_FASTER)
|
||||
{
|
||||
@ -3123,7 +3123,7 @@ bool32 ShouldAbsorb(u8 battlerAtk, u8 battlerDef, u16 move, s32 damage)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, u8 healPercent)
|
||||
bool32 ShouldRecover(u32 battlerAtk, u32 battlerDef, u16 move, u8 healPercent)
|
||||
{
|
||||
if (move == 0xFFFF || AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_FASTER)
|
||||
{
|
||||
@ -3142,7 +3142,7 @@ bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, u8 healPercent)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect)
|
||||
bool32 ShouldSetScreen(u32 battlerAtk, u32 battlerDef, u16 moveEffect)
|
||||
{
|
||||
u8 atkSide = GetBattlerSide(battlerAtk);
|
||||
switch (moveEffect)
|
||||
@ -3171,7 +3171,7 @@ bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect)
|
||||
}
|
||||
|
||||
// Partner Logic
|
||||
bool32 IsValidDoubleBattle(u8 battlerAtk)
|
||||
bool32 IsValidDoubleBattle(u32 battlerAtk)
|
||||
{
|
||||
if (IsDoubleBattle()
|
||||
&& ((IsBattlerAlive(BATTLE_OPPOSITE(battlerAtk)) && IsBattlerAlive(BATTLE_PARTNER(BATTLE_OPPOSITE(battlerAtk)))) || IsBattlerAlive(BATTLE_PARTNER(battlerAtk))))
|
||||
@ -3191,7 +3191,7 @@ u16 GetAllyChosenMove(u8 battlerId)
|
||||
return gBattleMons[partnerBattler].moves[gBattleStruct->chosenMovePositions[partnerBattler]];
|
||||
}
|
||||
|
||||
bool32 IsTargetingPartner(u8 battlerAtk, u8 battlerDef)
|
||||
bool32 IsTargetingPartner(u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
if ((battlerAtk & BIT_SIDE) == (battlerDef & BIT_SIDE))
|
||||
return TRUE;
|
||||
@ -3200,7 +3200,7 @@ bool32 IsTargetingPartner(u8 battlerAtk, u8 battlerDef)
|
||||
}
|
||||
|
||||
//PARTNER_MOVE_EFFECT_IS_SAME
|
||||
bool32 DoesPartnerHaveSameMoveEffect(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove)
|
||||
bool32 DoesPartnerHaveSameMoveEffect(u32 battlerAtkPartner, u32 battlerDef, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!IsDoubleBattle())
|
||||
return FALSE;
|
||||
@ -3215,7 +3215,7 @@ bool32 DoesPartnerHaveSameMoveEffect(u8 battlerAtkPartner, u8 battlerDef, u16 mo
|
||||
}
|
||||
|
||||
//PARTNER_MOVE_EFFECT_IS_SAME_NO_TARGET
|
||||
bool32 PartnerHasSameMoveEffectWithoutTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove)
|
||||
bool32 PartnerHasSameMoveEffectWithoutTarget(u32 battlerAtkPartner, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!IsDoubleBattle())
|
||||
return FALSE;
|
||||
@ -3227,7 +3227,7 @@ bool32 PartnerHasSameMoveEffectWithoutTarget(u8 battlerAtkPartner, u16 move, u16
|
||||
}
|
||||
|
||||
//PARTNER_MOVE_EFFECT_IS_STATUS_SAME_TARGET
|
||||
bool32 PartnerMoveEffectIsStatusSameTarget(u8 battlerAtkPartner, u8 battlerDef, u16 partnerMove)
|
||||
bool32 PartnerMoveEffectIsStatusSameTarget(u32 battlerAtkPartner, u32 battlerDef, u16 partnerMove)
|
||||
{
|
||||
if (!IsDoubleBattle())
|
||||
return FALSE;
|
||||
@ -3245,7 +3245,7 @@ bool32 PartnerMoveEffectIsStatusSameTarget(u8 battlerAtkPartner, u8 battlerDef,
|
||||
}
|
||||
|
||||
//PARTNER_MOVE_EFFECT_IS_WEATHER
|
||||
bool32 PartnerMoveEffectIsWeather(u8 battlerAtkPartner, u16 partnerMove)
|
||||
bool32 PartnerMoveEffectIsWeather(u32 battlerAtkPartner, u16 partnerMove)
|
||||
{
|
||||
if (!IsDoubleBattle())
|
||||
return FALSE;
|
||||
@ -3262,7 +3262,7 @@ bool32 PartnerMoveEffectIsWeather(u8 battlerAtkPartner, u16 partnerMove)
|
||||
}
|
||||
|
||||
//PARTNER_MOVE_EFFECT_IS_TERRAIN
|
||||
bool32 PartnerMoveEffectIsTerrain(u8 battlerAtkPartner, u16 partnerMove)
|
||||
bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u16 partnerMove)
|
||||
{
|
||||
if (!IsDoubleBattle())
|
||||
return FALSE;
|
||||
@ -3278,7 +3278,7 @@ bool32 PartnerMoveEffectIsTerrain(u8 battlerAtkPartner, u16 partnerMove)
|
||||
}
|
||||
|
||||
//PARTNER_MOVE_IS_TAILWIND_TRICKROOM
|
||||
bool32 PartnerMoveIs(u8 battlerAtkPartner, u16 partnerMove, u16 moveCheck)
|
||||
bool32 PartnerMoveIs(u32 battlerAtkPartner, u16 partnerMove, u16 moveCheck)
|
||||
{
|
||||
if (!IsDoubleBattle())
|
||||
return FALSE;
|
||||
@ -3289,7 +3289,7 @@ bool32 PartnerMoveIs(u8 battlerAtkPartner, u16 partnerMove, u16 moveCheck)
|
||||
}
|
||||
|
||||
//PARTNER_MOVE_IS_SAME
|
||||
bool32 PartnerMoveIsSameAsAttacker(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove)
|
||||
bool32 PartnerMoveIsSameAsAttacker(u32 battlerAtkPartner, u32 battlerDef, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!IsDoubleBattle())
|
||||
return FALSE;
|
||||
@ -3300,7 +3300,7 @@ bool32 PartnerMoveIsSameAsAttacker(u8 battlerAtkPartner, u8 battlerDef, u16 move
|
||||
}
|
||||
|
||||
//PARTNER_MOVE_IS_SAME_NO_TARGET
|
||||
bool32 PartnerMoveIsSameNoTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove)
|
||||
bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!IsDoubleBattle())
|
||||
return FALSE;
|
||||
@ -3309,7 +3309,7 @@ bool32 PartnerMoveIsSameNoTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldUseWishAromatherapy(u8 battlerAtk, u8 battlerDef, u16 move)
|
||||
bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u16 move)
|
||||
{
|
||||
u32 i;
|
||||
u32 firstId, lastId;
|
||||
@ -3413,7 +3413,7 @@ s32 AI_CalcPartyMonBestMoveDamage(u32 battlerAtk, u32 battlerDef, struct Pokemon
|
||||
|
||||
if (move != MOVE_NONE && gBattleMoves[move].power != 0)
|
||||
{
|
||||
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, FALSE);
|
||||
dmg = AI_CalcDamageSaveBattlers(move, battlerAtk, battlerDef, &effectiveness, FALSE);
|
||||
if (dmg > bestDmg)
|
||||
bestDmg = dmg;
|
||||
}
|
||||
@ -3568,7 +3568,7 @@ bool32 IsStatBoostingBerry(u16 item)
|
||||
}
|
||||
}
|
||||
|
||||
bool32 ShouldRestoreHpBerry(u8 battlerAtk, u16 item)
|
||||
bool32 ShouldRestoreHpBerry(u32 battlerAtk, u16 item)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
@ -3602,7 +3602,7 @@ bool32 IsRecycleEncouragedItem(u16 item)
|
||||
// score increases
|
||||
#define STAT_UP_2_STAGE 8
|
||||
#define STAT_UP_STAGE 10
|
||||
void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score)
|
||||
void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u8 statId, s16 *score)
|
||||
{
|
||||
if (AI_DATA->abilities[battlerAtk] == ABILITY_CONTRARY)
|
||||
return;
|
||||
@ -3682,7 +3682,7 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score)
|
||||
}
|
||||
}
|
||||
|
||||
void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PSN || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS)
|
||||
@ -3706,7 +3706,7 @@ void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
}
|
||||
}
|
||||
|
||||
void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_BRN || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS)
|
||||
@ -3726,7 +3726,7 @@ void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
}
|
||||
}
|
||||
|
||||
void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PAR || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS)
|
||||
@ -3748,7 +3748,7 @@ void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
}
|
||||
}
|
||||
|
||||
void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_SLP || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS)
|
||||
@ -3767,7 +3767,7 @@ void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
(*score)++;
|
||||
}
|
||||
|
||||
void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_CONFUSION || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS)
|
||||
@ -3786,7 +3786,7 @@ void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
}
|
||||
}
|
||||
|
||||
void IncreaseFrostbiteScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return;
|
||||
@ -3815,7 +3815,7 @@ bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move)
|
||||
}
|
||||
|
||||
//TODO - this could use some more sophisticated logic
|
||||
bool32 ShouldUseZMove(u8 battlerAtk, u8 battlerDef, u16 chosenMove)
|
||||
bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u16 chosenMove)
|
||||
{
|
||||
// simple logic. just upgrades chosen move to z move if possible, unless regular move would kill opponent
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && battlerDef == BATTLE_PARTNER(battlerAtk))
|
||||
@ -3837,7 +3837,7 @@ bool32 ShouldUseZMove(u8 battlerAtk, u8 battlerDef, u16 chosenMove)
|
||||
else if (!IS_MOVE_STATUS(chosenMove) && IS_MOVE_STATUS(gBattleStruct->zmove.chosenZMove))
|
||||
return FALSE;
|
||||
|
||||
if (!IS_MOVE_STATUS(chosenMove) && AI_CalcDamage(chosenMove, battlerAtk, battlerDef, &effectiveness, FALSE) >= gBattleMons[battlerDef].hp)
|
||||
if (!IS_MOVE_STATUS(chosenMove) && AI_CalcDamageSaveBattlers(chosenMove, battlerAtk, battlerDef, &effectiveness, FALSE) >= gBattleMons[battlerDef].hp)
|
||||
return FALSE; // don't waste damaging z move if can otherwise faint target
|
||||
|
||||
return TRUE;
|
||||
|
@ -5575,7 +5575,7 @@ void RunBattleScriptCommands(void)
|
||||
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
|
||||
}
|
||||
|
||||
void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
|
||||
void SetTypeBeforeUsingMove(u16 move, u32 battlerAtk)
|
||||
{
|
||||
u32 moveType, ateType, attackerAbility;
|
||||
u16 holdEffect = GetBattlerHoldEffect(battlerAtk, TRUE);
|
||||
|
@ -1907,7 +1907,7 @@ static void Cmd_ppreduce(void)
|
||||
#endif // B_CRIT_CHANCE
|
||||
|
||||
#define BENEFITS_FROM_LEEK(battler, holdEffect)((holdEffect == HOLD_EFFECT_LEEK) && (GET_BASE_SPECIES_ID(gBattleMons[battler].species) == SPECIES_FARFETCHD || gBattleMons[battler].species == SPECIES_SIRFETCHD))
|
||||
s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbility)
|
||||
s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility)
|
||||
{
|
||||
s32 critChance = 0;
|
||||
u32 abilityAtk = GetBattlerAbility(gBattlerAttacker);
|
||||
@ -1952,7 +1952,7 @@ s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbi
|
||||
}
|
||||
#undef BENEFITS_FROM_LEEK
|
||||
|
||||
s8 GetInverseCritChance(u8 battlerAtk, u8 battlerDef, u32 move)
|
||||
s8 GetInverseCritChance(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
{
|
||||
s32 critChanceIndex = CalcCritChanceStage(battlerAtk, battlerDef, move, FALSE);
|
||||
if(critChanceIndex < 0)
|
||||
@ -5657,6 +5657,7 @@ static void Cmd_moveend(void)
|
||||
if (!gSpecialStatuses[gBattlerAttacker].dancerUsedMove)
|
||||
{
|
||||
gLastMoves[gBattlerAttacker] = gChosenMove;
|
||||
RecordKnownMove(gBattlerAttacker, gChosenMove);
|
||||
gLastResultingMoves[gBattlerAttacker] = gCurrentMove;
|
||||
}
|
||||
}
|
||||
@ -8242,7 +8243,7 @@ static void RemoveAllTerrains(void)
|
||||
} \
|
||||
}
|
||||
|
||||
static bool32 TryDefogClear(u8 battlerAtk, bool32 clear)
|
||||
static bool32 TryDefogClear(u32 battlerAtk, bool32 clear)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < 2; i++)
|
||||
@ -14760,7 +14761,7 @@ static void Cmd_settypebasedhalvers(void)
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
|
||||
bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move)
|
||||
bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
{
|
||||
if (!(gBattleMons[battlerDef].status2 & STATUS2_SUBSTITUTE))
|
||||
return FALSE;
|
||||
@ -14776,7 +14777,7 @@ bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 DoesDisguiseBlockMove(u8 battlerAtk, u8 battlerDef, u32 move)
|
||||
bool32 DoesDisguiseBlockMove(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
{
|
||||
if (gBattleMons[battlerDef].species != SPECIES_MIMIKYU
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED
|
||||
|
@ -4244,7 +4244,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
gBattleWeather = B_WEATHER_SNOW;
|
||||
gBattleScripting.animArg1 = B_ANIM_SNOW_CONTINUES;
|
||||
effect++;
|
||||
#else
|
||||
#else
|
||||
gBattleWeather = B_WEATHER_HAIL;
|
||||
gBattleScripting.animArg1 = B_ANIM_HAIL_CONTINUES;
|
||||
effect++;
|
||||
@ -8100,7 +8100,7 @@ u8 IsMonDisobedient(void)
|
||||
}
|
||||
}
|
||||
|
||||
u32 GetBattlerHoldEffect(u8 battler, bool32 checkNegating)
|
||||
u32 GetBattlerHoldEffect(u32 battler, bool32 checkNegating)
|
||||
{
|
||||
if (checkNegating)
|
||||
{
|
||||
@ -8136,7 +8136,7 @@ u32 GetBattlerHoldEffectParam(u8 battler)
|
||||
return ItemId_GetHoldEffectParam(gBattleMons[battler].item);
|
||||
}
|
||||
|
||||
bool32 IsMoveMakingContact(u16 move, u8 battlerAtk)
|
||||
bool32 IsMoveMakingContact(u16 move, u32 battlerAtk)
|
||||
{
|
||||
u16 atkHoldEffect = GetBattlerHoldEffect(battlerAtk, TRUE);
|
||||
|
||||
@ -8321,7 +8321,7 @@ u32 CountBattlerStatIncreases(u8 battler, bool32 countEvasionAcc)
|
||||
return count;
|
||||
}
|
||||
|
||||
u32 GetMoveTargetCount(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
u32 GetMoveTargetCount(u16 move, u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
switch (GetBattlerMoveTargetType(gBattlerAttacker, move))
|
||||
{
|
||||
@ -8460,7 +8460,7 @@ u32 CalcFuryCutterBasePower(u32 basePower, u32 furyCutterCounter)
|
||||
return basePower;
|
||||
}
|
||||
|
||||
static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
static inline u16 CalcMoveBasePower(u16 move, u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
||||
{
|
||||
u32 i;
|
||||
u16 basePower = gBattleMoves[move].power;
|
||||
@ -8535,7 +8535,7 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
basePower = gNaturalGiftTable[ITEM_TO_BERRY(gBattleMons[battlerAtk].item)].power;
|
||||
break;
|
||||
case EFFECT_WAKE_UP_SLAP:
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_SLEEP || GetBattlerAbility(battlerDef) == ABILITY_COMATOSE)
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_SLEEP || abilityDef == ABILITY_COMATOSE)
|
||||
basePower *= 2;
|
||||
break;
|
||||
case EFFECT_SMELLINGSALT:
|
||||
@ -8547,7 +8547,7 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
break;
|
||||
case EFFECT_HEX:
|
||||
case EFFECT_INFERNAL_PARADE:
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_ANY || GetBattlerAbility(battlerDef) == ABILITY_COMATOSE)
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_ANY || abilityDef == ABILITY_COMATOSE)
|
||||
basePower *= 2;
|
||||
break;
|
||||
case EFFECT_ASSURANCE:
|
||||
@ -8716,16 +8716,14 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
return basePower;
|
||||
}
|
||||
|
||||
static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, bool32 updateFlags)
|
||||
static inline u32 CalcMoveBasePowerAfterModifiers(u16 move, u32 battlerAtk, u32 battlerDef, u8 moveType, bool32 updateFlags, u32 atkAbility, u32 defAbility, u32 holdEffectAtk)
|
||||
{
|
||||
u32 i;
|
||||
u32 holdEffectAtk, holdEffectParamAtk;
|
||||
u16 basePower = CalcMoveBasePower(move, battlerAtk, battlerDef);
|
||||
u32 holdEffectParamAtk;
|
||||
u16 basePower = CalcMoveBasePower(move, battlerAtk, battlerDef, defAbility);
|
||||
uq4_12_t holdEffectModifier;
|
||||
uq4_12_t modifier = UQ_4_12(1.0);
|
||||
u32 atkSide = GET_BATTLER_SIDE(battlerAtk);
|
||||
u16 atkAbility = GetBattlerAbility(battlerAtk);
|
||||
u16 defAbility = GetBattlerAbility(battlerDef);
|
||||
|
||||
// move effect
|
||||
switch (gBattleMoves[move].effect)
|
||||
@ -9020,7 +9018,6 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
||||
break;
|
||||
}
|
||||
|
||||
holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
|
||||
holdEffectParamAtk = GetBattlerHoldEffectParam(battlerAtk);
|
||||
if (holdEffectParamAtk > 100)
|
||||
holdEffectParamAtk = 100;
|
||||
@ -9099,7 +9096,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
||||
}
|
||||
#undef TERRAIN_TYPE_BOOST
|
||||
|
||||
static u32 CalcAttackStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, bool32 isCrit, bool32 updateFlags)
|
||||
static inline u32 CalcAttackStat(u16 move, u32 battlerAtk, u32 battlerDef, u8 moveType, bool32 isCrit, bool32 updateFlags, u32 atkAbility, u32 defAbility, u32 holdEffectAtk)
|
||||
{
|
||||
u8 atkStage;
|
||||
u32 atkStat;
|
||||
@ -9144,7 +9141,7 @@ static u32 CalcAttackStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, b
|
||||
if (isCrit && atkStage < DEFAULT_STAT_STAGE)
|
||||
atkStage = DEFAULT_STAT_STAGE;
|
||||
// pokemon with unaware ignore attack stat changes while taking damage
|
||||
if (GetBattlerAbility(battlerDef) == ABILITY_UNAWARE)
|
||||
if (defAbility == ABILITY_UNAWARE)
|
||||
atkStage = DEFAULT_STAT_STAGE;
|
||||
|
||||
atkStat *= gStatStageRatios[atkStage][0];
|
||||
@ -9154,7 +9151,7 @@ static u32 CalcAttackStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, b
|
||||
modifier = UQ_4_12(1.0);
|
||||
|
||||
// attacker's abilities
|
||||
switch (GetBattlerAbility(battlerAtk))
|
||||
switch (atkAbility)
|
||||
{
|
||||
case ABILITY_HUGE_POWER:
|
||||
case ABILITY_PURE_POWER:
|
||||
@ -9232,7 +9229,7 @@ static u32 CalcAttackStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, b
|
||||
}
|
||||
|
||||
// target's abilities
|
||||
switch (GetBattlerAbility(battlerDef))
|
||||
switch (defAbility)
|
||||
{
|
||||
case ABILITY_THICK_FAT:
|
||||
if (moveType == TYPE_FIRE || moveType == TYPE_ICE)
|
||||
@ -9257,7 +9254,7 @@ static u32 CalcAttackStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, b
|
||||
}
|
||||
|
||||
// attacker's hold effect
|
||||
switch (GetBattlerHoldEffect(battlerAtk, TRUE))
|
||||
switch (holdEffectAtk)
|
||||
{
|
||||
case HOLD_EFFECT_THICK_CLUB:
|
||||
if ((atkBaseSpeciesId == SPECIES_CUBONE || atkBaseSpeciesId == SPECIES_MAROWAK) && IS_MOVE_PHYSICAL(move))
|
||||
@ -9303,7 +9300,7 @@ static bool32 CanEvolve(u32 species)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static u32 CalcDefenseStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, bool32 isCrit, bool32 updateFlags)
|
||||
static inline u32 CalcDefenseStat(u16 move, u32 battlerAtk, u32 battlerDef, u8 moveType, bool32 isCrit, bool32 updateFlags, u32 atkAbility, u32 defAbility, u32 holdEffectDef)
|
||||
{
|
||||
bool32 usesDefStat;
|
||||
u8 defStage;
|
||||
@ -9344,7 +9341,7 @@ static u32 CalcDefenseStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType,
|
||||
if (isCrit && defStage > DEFAULT_STAT_STAGE)
|
||||
defStage = DEFAULT_STAT_STAGE;
|
||||
// pokemon with unaware ignore defense stat changes while dealing damage
|
||||
if (GetBattlerAbility(battlerAtk) == ABILITY_UNAWARE)
|
||||
if (atkAbility == ABILITY_UNAWARE)
|
||||
defStage = DEFAULT_STAT_STAGE;
|
||||
// certain moves also ignore stat changes
|
||||
if (gBattleMoves[move].ignoresTargetDefenseEvasionStages)
|
||||
@ -9357,7 +9354,7 @@ static u32 CalcDefenseStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType,
|
||||
modifier = UQ_4_12(1.0);
|
||||
|
||||
// target's abilities
|
||||
switch (GetBattlerAbility(battlerDef))
|
||||
switch (defAbility)
|
||||
{
|
||||
case ABILITY_MARVEL_SCALE:
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_ANY && usesDefStat)
|
||||
@ -9406,7 +9403,7 @@ static u32 CalcDefenseStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType,
|
||||
}
|
||||
|
||||
// target's hold effects
|
||||
switch (GetBattlerHoldEffect(battlerDef, TRUE))
|
||||
switch (holdEffectDef)
|
||||
{
|
||||
case HOLD_EFFECT_DEEP_SEA_SCALE:
|
||||
if (gBattleMons[battlerDef].species == SPECIES_CLAMPERL && !usesDefStat)
|
||||
@ -9582,13 +9579,12 @@ static inline uq4_12_t GetAirborneModifier(u32 move, u32 battlerDef)
|
||||
return UQ_4_12(1.0);
|
||||
}
|
||||
|
||||
static inline uq4_12_t GetScreensModifier(u32 move, u32 battlerAtk, u32 battlerDef, bool32 isCrit)
|
||||
static inline uq4_12_t GetScreensModifier(u32 move, u32 battlerAtk, u32 battlerDef, bool32 isCrit, u32 abilityAtk)
|
||||
{
|
||||
u32 sideStatus = gSideStatuses[GET_BATTLER_SIDE(battlerDef)];
|
||||
bool32 lightScreen = (sideStatus & SIDE_STATUS_LIGHTSCREEN) && IS_MOVE_SPECIAL(move);
|
||||
bool32 reflect = (sideStatus & SIDE_STATUS_REFLECT) && IS_MOVE_PHYSICAL(move);
|
||||
bool32 auroraVeil = sideStatus & SIDE_STATUS_AURORA_VEIL;
|
||||
u32 abilityAtk = GetBattlerAbility(battlerAtk);
|
||||
|
||||
if (isCrit || abilityAtk == ABILITY_INFILTRATOR || gProtectStructs[battlerAtk].confusionSelfDmg)
|
||||
return UQ_4_12(1.0);
|
||||
@ -9604,9 +9600,8 @@ static inline uq4_12_t GetCollisionCourseElectroDriftModifier(u32 move, uq4_12_t
|
||||
return UQ_4_12(1.0);
|
||||
}
|
||||
|
||||
static inline uq4_12_t GetAttackerAbilitiesModifier(u32 battlerAtk, uq4_12_t typeEffectivenessModifier, bool32 isCrit)
|
||||
static inline uq4_12_t GetAttackerAbilitiesModifier(u32 battlerAtk, uq4_12_t typeEffectivenessModifier, bool32 isCrit, u32 abilityAtk)
|
||||
{
|
||||
u32 abilityAtk = GetBattlerAbility(battlerAtk);
|
||||
switch (abilityAtk)
|
||||
{
|
||||
case ABILITY_NEUROFORCE:
|
||||
@ -9625,9 +9620,8 @@ static inline uq4_12_t GetAttackerAbilitiesModifier(u32 battlerAtk, uq4_12_t typ
|
||||
return UQ_4_12(1.0);
|
||||
}
|
||||
|
||||
static inline uq4_12_t GetDefenderAbilitiesModifier(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, uq4_12_t typeEffectivenessModifier)
|
||||
static inline uq4_12_t GetDefenderAbilitiesModifier(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, uq4_12_t typeEffectivenessModifier, u32 abilityDef)
|
||||
{
|
||||
u32 abilityDef = GetBattlerAbility(battlerDef);
|
||||
switch (abilityDef)
|
||||
{
|
||||
case ABILITY_MULTISCALE:
|
||||
@ -9673,9 +9667,8 @@ static inline uq4_12_t GetDefenderPartnerAbilitiesModifier(u32 battlerPartnerDef
|
||||
return UQ_4_12(1.0);
|
||||
}
|
||||
|
||||
static inline uq4_12_t GetAttackerItemsModifier(u32 battlerAtk, uq4_12_t typeEffectivenessModifier)
|
||||
static inline uq4_12_t GetAttackerItemsModifier(u32 battlerAtk, uq4_12_t typeEffectivenessModifier, u32 holdEffectAtk)
|
||||
{
|
||||
u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
|
||||
u32 percentBoost;
|
||||
switch (holdEffectAtk)
|
||||
{
|
||||
@ -9694,12 +9687,10 @@ static inline uq4_12_t GetAttackerItemsModifier(u32 battlerAtk, uq4_12_t typeEff
|
||||
return UQ_4_12(1.0);
|
||||
}
|
||||
|
||||
static inline uq4_12_t GetDefenderItemsModifier(u32 moveType, u32 battlerDef, uq4_12_t typeEffectivenessModifier, bool32 updateFlags)
|
||||
static inline uq4_12_t GetDefenderItemsModifier(u32 moveType, u32 battlerDef, uq4_12_t typeEffectivenessModifier, bool32 updateFlags, u32 abilityDef, u32 holdEffectDef)
|
||||
{
|
||||
u32 holdEffectDef = GetBattlerHoldEffect(battlerDef, TRUE);
|
||||
u32 holdEffectDefParam = GetBattlerHoldEffectParam(battlerDef);
|
||||
u32 itemDef = gBattleMons[battlerDef].item;
|
||||
u32 abilityDef = GetBattlerAbility(battlerDef);
|
||||
|
||||
switch (holdEffectDef)
|
||||
{
|
||||
@ -9727,9 +9718,9 @@ static inline uq4_12_t GetDefenderItemsModifier(u32 moveType, u32 battlerDef, uq
|
||||
// https://bulbapedia.bulbagarden.net/wiki/Damage#Generation_V_onward
|
||||
// Please Note: Fixed Point Multiplication is not associative.
|
||||
// The order of operations is relevant.
|
||||
static uq4_12_t GetOtherModifiers(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, bool32 isCrit, uq4_12_t typeEffectivenessModifier, bool32 updateFlags)
|
||||
static inline uq4_12_t GetOtherModifiers(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, bool32 isCrit, uq4_12_t typeEffectivenessModifier, bool32 updateFlags,
|
||||
u32 abilityAtk, u32 abilityDef, u32 holdEffectAtk, u32 holdEffectDef)
|
||||
{
|
||||
u32 abilityAtk = GetBattlerAbility(battlerAtk);
|
||||
uq4_12_t finalModifier = UQ_4_12(1.0);
|
||||
u32 battlerDefPartner = BATTLE_PARTNER(battlerDef);
|
||||
u32 unmodifiedAttackerSpeed = gBattleMons[battlerAtk].speed;
|
||||
@ -9739,24 +9730,24 @@ static uq4_12_t GetOtherModifiers(u32 move, u32 moveType, u32 battlerAtk, u32 ba
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetUndergroundModifier(move, battlerDef));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetDiveModifier(move, battlerDef));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetAirborneModifier(move, battlerDef));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetScreensModifier(move, battlerAtk, battlerDef, isCrit));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetScreensModifier(move, battlerAtk, battlerDef, isCrit, abilityAtk));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetCollisionCourseElectroDriftModifier(move, typeEffectivenessModifier));
|
||||
|
||||
if (unmodifiedAttackerSpeed >= unmodifiedDefenderSpeed)
|
||||
{
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetAttackerAbilitiesModifier(battlerAtk, typeEffectivenessModifier, isCrit));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetDefenderAbilitiesModifier(move, moveType, battlerAtk, battlerDef, typeEffectivenessModifier));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetAttackerAbilitiesModifier(battlerAtk, typeEffectivenessModifier, isCrit, abilityAtk));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetDefenderAbilitiesModifier(move, moveType, battlerAtk, battlerDef, typeEffectivenessModifier, abilityDef));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetDefenderPartnerAbilitiesModifier(battlerDefPartner));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetAttackerItemsModifier(battlerAtk, typeEffectivenessModifier));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetDefenderItemsModifier(moveType, battlerDef, typeEffectivenessModifier, updateFlags));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetAttackerItemsModifier(battlerAtk, typeEffectivenessModifier, holdEffectAtk));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetDefenderItemsModifier(moveType, battlerDef, typeEffectivenessModifier, updateFlags, abilityDef, holdEffectDef));
|
||||
}
|
||||
else
|
||||
{
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetDefenderAbilitiesModifier(move, moveType, battlerAtk, battlerDef, typeEffectivenessModifier));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetDefenderAbilitiesModifier(move, moveType, battlerAtk, battlerDef, typeEffectivenessModifier, abilityDef));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetDefenderPartnerAbilitiesModifier(battlerDefPartner));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetAttackerAbilitiesModifier(battlerAtk, typeEffectivenessModifier, isCrit));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetDefenderItemsModifier(moveType, battlerDef, typeEffectivenessModifier, updateFlags));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetAttackerItemsModifier(battlerAtk, typeEffectivenessModifier));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetAttackerAbilitiesModifier(battlerAtk, typeEffectivenessModifier, isCrit, abilityAtk));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetDefenderItemsModifier(moveType, battlerDef, typeEffectivenessModifier, updateFlags, abilityDef, holdEffectDef));
|
||||
DAMAGE_MULTIPLY_MODIFIER(GetAttackerItemsModifier(battlerAtk, typeEffectivenessModifier, holdEffectAtk));
|
||||
}
|
||||
return finalModifier;
|
||||
}
|
||||
@ -9767,7 +9758,7 @@ static uq4_12_t GetOtherModifiers(u32 move, u32 moveType, u32 battlerAtk, u32 ba
|
||||
dmg = uq4_12_multiply_by_int_half_down(modifier, dmg); \
|
||||
} while (0)
|
||||
|
||||
static s32 DoMoveDamageCalc(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower,
|
||||
static inline s32 DoMoveDamageCalc(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower,
|
||||
bool32 isCrit, bool32 randomFactor, bool32 updateFlags, uq4_12_t typeEffectivenessModifier)
|
||||
{
|
||||
s32 dmg;
|
||||
@ -9776,6 +9767,7 @@ static s32 DoMoveDamageCalc(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveTy
|
||||
u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
|
||||
u32 holdEffectDef = GetBattlerHoldEffect(battlerDef, TRUE);
|
||||
u32 abilityAtk = GetBattlerAbility(battlerAtk);
|
||||
u32 abilityDef = GetBattlerAbility(battlerDef);
|
||||
|
||||
if (typeEffectivenessModifier == UQ_4_12(0.0))
|
||||
return 0;
|
||||
@ -9783,10 +9775,10 @@ static s32 DoMoveDamageCalc(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveTy
|
||||
if (fixedBasePower)
|
||||
gBattleMovePower = fixedBasePower;
|
||||
else
|
||||
gBattleMovePower = CalcMoveBasePowerAfterModifiers(move, battlerAtk, battlerDef, moveType, updateFlags);
|
||||
gBattleMovePower = CalcMoveBasePowerAfterModifiers(move, battlerAtk, battlerDef, moveType, updateFlags, abilityAtk, abilityDef, holdEffectAtk);
|
||||
|
||||
userFinalAttack = CalcAttackStat(move, battlerAtk, battlerDef, moveType, isCrit, updateFlags);
|
||||
targetFinalDefense = CalcDefenseStat(move, battlerAtk, battlerDef, moveType, isCrit, updateFlags);
|
||||
userFinalAttack = CalcAttackStat(move, battlerAtk, battlerDef, moveType, isCrit, updateFlags, abilityAtk, abilityDef, holdEffectAtk);
|
||||
targetFinalDefense = CalcDefenseStat(move, battlerAtk, battlerDef, moveType, isCrit, updateFlags, abilityAtk, abilityDef, holdEffectDef);
|
||||
|
||||
dmg = CalculateBaseDamage(gBattleMovePower, userFinalAttack, gBattleMons[battlerAtk].level, targetFinalDefense);
|
||||
DAMAGE_APPLY_MODIFIER(GetTargetDamageModifier(move, battlerAtk, battlerDef));
|
||||
@ -9804,7 +9796,7 @@ static s32 DoMoveDamageCalc(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveTy
|
||||
DAMAGE_APPLY_MODIFIER(typeEffectivenessModifier);
|
||||
DAMAGE_APPLY_MODIFIER(GetBurnOrFrostBiteModifier(battlerAtk, move, abilityAtk));
|
||||
DAMAGE_APPLY_MODIFIER(GetZMoveAgainstProtectionModifier(battlerDef));
|
||||
DAMAGE_APPLY_MODIFIER(GetOtherModifiers(move, moveType, battlerAtk, battlerDef, isCrit, typeEffectivenessModifier, updateFlags));
|
||||
DAMAGE_APPLY_MODIFIER(GetOtherModifiers(move, moveType, battlerAtk, battlerDef, isCrit, typeEffectivenessModifier, updateFlags, abilityAtk, abilityDef, holdEffectAtk, holdEffectDef));
|
||||
|
||||
if (dmg == 0)
|
||||
dmg = 1;
|
||||
@ -9813,20 +9805,20 @@ static s32 DoMoveDamageCalc(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveTy
|
||||
|
||||
#undef DAMAGE_APPLY_MODIFIER
|
||||
|
||||
s32 CalculateMoveDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32 fixedBasePower, bool32 isCrit, bool32 randomFactor, bool32 updateFlags)
|
||||
s32 CalculateMoveDamage(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, bool32 isCrit, bool32 randomFactor, bool32 updateFlags)
|
||||
{
|
||||
return DoMoveDamageCalc(move, battlerAtk, battlerDef, moveType, fixedBasePower, isCrit, randomFactor,
|
||||
updateFlags, CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, updateFlags));
|
||||
}
|
||||
|
||||
// for AI - get move damage and effectiveness with one function call
|
||||
s32 CalculateMoveDamageAndEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32 fixedBasePower, uq4_12_t *typeEffectivenessModifier)
|
||||
s32 CalculateMoveDamageAndEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, uq4_12_t *typeEffectivenessModifier)
|
||||
{
|
||||
*typeEffectivenessModifier = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, FALSE);
|
||||
return DoMoveDamageCalc(move, battlerAtk, battlerDef, moveType, fixedBasePower, FALSE, FALSE, FALSE, *typeEffectivenessModifier);
|
||||
}
|
||||
|
||||
static void MulByTypeEffectiveness(uq4_12_t *modifier, u16 move, u8 moveType, u8 battlerDef, u8 defType, u8 battlerAtk, bool32 recordAbilities)
|
||||
static inline void MulByTypeEffectiveness(uq4_12_t *modifier, u32 move, u32 moveType, u32 battlerDef, u32 defType, u32 battlerAtk, bool32 recordAbilities)
|
||||
{
|
||||
uq4_12_t mod = GetTypeModifier(moveType, defType);
|
||||
|
||||
@ -9866,7 +9858,7 @@ static void MulByTypeEffectiveness(uq4_12_t *modifier, u16 move, u8 moveType, u8
|
||||
*modifier = uq4_12_multiply(*modifier, mod);
|
||||
}
|
||||
|
||||
static void TryNoticeIllusionInTypeEffectiveness(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, uq4_12_t resultingModifier, u32 illusionSpecies)
|
||||
static inline void TryNoticeIllusionInTypeEffectiveness(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, uq4_12_t resultingModifier, u32 illusionSpecies)
|
||||
{
|
||||
// Check if the type effectiveness would've been different if the pokemon really had the types as the disguise.
|
||||
uq4_12_t presumedModifier = UQ_4_12(1.0);
|
||||
@ -9901,10 +9893,9 @@ static void UpdateMoveResultFlags(uq4_12_t modifier)
|
||||
}
|
||||
}
|
||||
|
||||
static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 battlerAtk, u8 battlerDef, bool32 recordAbilities, uq4_12_t modifier)
|
||||
static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, bool32 recordAbilities, uq4_12_t modifier, u32 defAbility)
|
||||
{
|
||||
u32 illusionSpecies;
|
||||
u16 defAbility = GetBattlerAbility(battlerDef);
|
||||
|
||||
MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, gBattleMons[battlerDef].type1, battlerAtk, recordAbilities);
|
||||
if (gBattleMons[battlerDef].type2 != gBattleMons[battlerDef].type1)
|
||||
@ -9974,15 +9965,16 @@ static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 bat
|
||||
return modifier;
|
||||
}
|
||||
|
||||
uq4_12_t CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 battlerDef, bool32 recordAbilities)
|
||||
uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, bool32 recordAbilities)
|
||||
{
|
||||
uq4_12_t modifier = UQ_4_12(1.0);
|
||||
|
||||
if (move != MOVE_STRUGGLE && moveType != TYPE_MYSTERY)
|
||||
{
|
||||
modifier = CalcTypeEffectivenessMultiplierInternal(move, moveType, battlerAtk, battlerDef, recordAbilities, modifier);
|
||||
u32 defAbility = GetBattlerAbility(defAbility);
|
||||
modifier = CalcTypeEffectivenessMultiplierInternal(move, moveType, battlerAtk, battlerDef, recordAbilities, modifier, defAbility);
|
||||
if (gBattleMoves[move].effect == EFFECT_TWO_TYPED_MOVE)
|
||||
modifier = CalcTypeEffectivenessMultiplierInternal(move, gBattleMoves[move].argument, battlerAtk, battlerDef, recordAbilities, modifier);
|
||||
modifier = CalcTypeEffectivenessMultiplierInternal(move, gBattleMoves[move].argument, battlerAtk, battlerDef, recordAbilities, modifier, defAbility);
|
||||
}
|
||||
|
||||
if (recordAbilities)
|
||||
@ -10026,7 +10018,7 @@ static uq4_12_t GetInverseTypeMultiplier(uq4_12_t multiplier)
|
||||
}
|
||||
}
|
||||
|
||||
uq4_12_t GetTypeModifier(u8 atkType, u8 defType)
|
||||
uq4_12_t GetTypeModifier(u32 atkType, u32 defType)
|
||||
{
|
||||
#if B_FLAG_INVERSE_BATTLE != 0
|
||||
if (FlagGet(B_FLAG_INVERSE_BATTLE))
|
||||
@ -10959,7 +10951,7 @@ bool32 TryRoomService(u8 battler)
|
||||
}
|
||||
}
|
||||
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget)
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u32 battlerDef, bool32 checkTarget)
|
||||
{
|
||||
#if B_PRANKSTER_DARK_TYPES >= GEN_7
|
||||
if (!gProtectStructs[battlerPrankster].pranksterElevated)
|
||||
@ -11009,7 +11001,7 @@ u32 GetBattlerMoveTargetType(u8 battler, u16 move)
|
||||
return gBattleMoves[move].target;
|
||||
}
|
||||
|
||||
bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move)
|
||||
bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, u16 move)
|
||||
{
|
||||
if (gBattleMoves[move].effect == EFFECT_HIT_ENEMY_HEAL_ALLY
|
||||
&& GetBattlerSide(battlerAtk) == GetBattlerSide(battlerDef)
|
||||
|
Loading…
Reference in New Issue
Block a user