ai weather optimization

This commit is contained in:
DizzyEggg 2023-09-13 17:28:26 +02:00
parent b7d0d37757
commit 38dcb3c66c
9 changed files with 369 additions and 358 deletions

View file

@ -70,6 +70,7 @@ Debug_BoxFilledMessage_Text:
.string "Storage boxes filled!$" .string "Storage boxes filled!$"
Debug_Script_1:: Debug_Script_1::
multi_fixed_2_vs_2 TRAINER_WALLACE, NULL, TRAINER_JUAN_5, NULL, TRAINER_STEVEN, TRAINER_BACK_PIC_STEVEN
end end
Debug_Script_2:: Debug_Script_2::

View file

@ -277,6 +277,7 @@ struct AIPartyData // Opposing battlers - party mons.
u8 count[NUM_BATTLE_SIDES]; u8 count[NUM_BATTLE_SIDES];
}; };
// Ai Data used when deciding which move to use, computed only once before each turn's start.
struct AiLogicData struct AiLogicData
{ {
u16 abilities[MAX_BATTLERS_COUNT]; u16 abilities[MAX_BATTLERS_COUNT];
@ -293,6 +294,7 @@ struct AiLogicData
u8 moveLimitations[MAX_BATTLERS_COUNT]; u8 moveLimitations[MAX_BATTLERS_COUNT];
bool8 shouldSwitchMon; // Because all available moves have no/little effect. Each bit per battler. bool8 shouldSwitchMon; // Because all available moves have no/little effect. Each bit per battler.
u8 monToSwitchId[MAX_BATTLERS_COUNT]; // ID of the mon to switch. u8 monToSwitchId[MAX_BATTLERS_COUNT]; // ID of the mon to switch.
bool8 weatherHasEffect; // WEATHER_HAS_EFFECT, so it doesn't have to be used all the time
}; };
struct AI_ThinkingStruct struct AI_ThinkingStruct

View file

@ -27,7 +27,7 @@ u8 BattleAI_ChooseMoveOrAction(void);
void Ai_InitPartyStruct(void); void Ai_InitPartyStruct(void);
void Ai_UpdateSwitchInData(u32 battler); void Ai_UpdateSwitchInData(u32 battler);
void Ai_UpdateFaintData(u32 battler); void Ai_UpdateFaintData(u32 battler);
void SetAiLogicDataForTurn(void); void SetAiLogicDataForTurn(struct AiLogicData *aiData);
extern u8 sBattler_AI; extern u8 sBattler_AI;

View file

@ -9,184 +9,184 @@
#define AI_STRIKES_FIRST(battlerAi, battlerDef, move)((AI_WhoStrikesFirst(battlerAi, battlerDef, move) == AI_IS_FASTER)) #define AI_STRIKES_FIRST(battlerAi, battlerDef, move)((AI_WhoStrikesFirst(battlerAi, battlerDef, move) == AI_IS_FASTER))
bool32 AI_RandLessThan(u8 val); bool32 AI_RandLessThan(u32 val);
bool32 IsAiVsAiBattle(void); bool32 IsAiVsAiBattle(void);
bool32 BattlerHasAi(u32 battlerId); bool32 BattlerHasAi(u32 battlerId);
bool32 IsAiBattlerAware(u32 battlerId); bool32 IsAiBattlerAware(u32 battlerId);
void ClearBattlerMoveHistory(u8 battlerId); void ClearBattlerMoveHistory(u32 battlerId);
void RecordLastUsedMoveBy(u32 battlerId, u32 move); void RecordLastUsedMoveBy(u32 battlerId, u32 move);
void RecordKnownMove(u8 battlerId, u32 move); void RecordKnownMove(u32 battlerId, u32 move);
void RecordAbilityBattle(u8 battlerId, u16 abilityId); void RecordAbilityBattle(u32 battlerId, u32 abilityId);
void ClearBattlerAbilityHistory(u8 battlerId); void ClearBattlerAbilityHistory(u32 battlerId);
void RecordItemEffectBattle(u8 battlerId, u8 itemEffect); void RecordItemEffectBattle(u32 battlerId, u32 itemEffect);
void ClearBattlerItemEffectHistory(u8 battlerId); void ClearBattlerItemEffectHistory(u32 battlerId);
void SaveBattlerData(u32 battlerId); void SaveBattlerData(u32 battlerId);
void SetBattlerData(u32 battlerId); void SetBattlerData(u32 battlerId);
void RestoreBattlerData(u32 battlerId); void RestoreBattlerData(u32 battlerId);
u16 GetAIChosenMove(u8 battlerId); u16 GetAIChosenMove(u32 battlerId);
u32 GetTotalBaseStat(u32 species); u32 GetTotalBaseStat(u32 species);
bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler); bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler);
bool32 AtMaxHp(u8 battler); bool32 AtMaxHp(u32 battler);
u32 GetHealthPercentage(u8 battler); u32 GetHealthPercentage(u32 battler);
bool32 IsBattlerTrapped(u8 battler, bool8 switching); bool32 IsBattlerTrapped(u32 battler, bool32 switching);
u32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler2, u32 moveConsidered); u32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler2, u32 moveConsidered);
bool32 CanTargetFaintAi(u32 battlerDef, u32 battlerAtk); bool32 CanTargetFaintAi(u32 battlerDef, u32 battlerAtk);
bool32 CanMoveFaintBattler(u16 move, u32 battlerDef, u32 battlerAtk, u8 nHits); bool32 CanMoveFaintBattler(u32 move, u32 battlerDef, u32 battlerAtk, u32 nHits);
bool32 CanTargetFaintAiWithMod(u32 battlerDef, u32 battlerAtk, s32 hpMod, s32 dmgMod); bool32 CanTargetFaintAiWithMod(u32 battlerDef, u32 battlerAtk, s32 hpMod, s32 dmgMod);
s32 AI_GetAbility(u32 battlerId); s32 AI_GetAbility(u32 battlerId);
u16 AI_GetHoldEffect(u32 battlerId); u16 AI_GetHoldEffect(u32 battlerId);
u32 AI_GetMoveAccuracy(u32 battlerAtk, u32 battlerDef, u16 move); u32 AI_GetMoveAccuracy(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move); bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move);
bool32 AI_WeatherHasEffect(void); u32 AI_GetWeather(struct AiLogicData *aiData);
bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u8 numHits); bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u32 numHits);
bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u8 index, u8 numHits); bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u32 index, u32 numHits);
bool32 AI_IsTerrainAffected(u8 battlerId, u32 flags); bool32 AI_IsTerrainAffected(u32 battlerId, u32 flags);
bool32 AI_IsBattlerGrounded(u8 battlerId); bool32 AI_IsBattlerGrounded(u32 battlerId);
bool32 HasDamagingMove(u8 battlerId); bool32 HasDamagingMove(u32 battlerId);
bool32 HasDamagingMoveOfType(u8 battlerId, u8 type); bool32 HasDamagingMoveOfType(u32 battlerId, u32 type);
u32 GetBattlerSecondaryDamage(u8 battlerId); u32 GetBattlerSecondaryDamage(u32 battlerId);
bool32 BattlerWillFaintFromWeather(u8 battler, u16 ability); bool32 BattlerWillFaintFromWeather(u32 battler, u32 ability);
bool32 BattlerWillFaintFromSecondaryDamage(u8 battler, u16 ability); bool32 BattlerWillFaintFromSecondaryDamage(u32 battler, u32 ability);
bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, u16 atkAbility, u16 defAbility, u16 move); bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbility, u32 move);
bool32 ShouldUseRecoilMove(u32 battlerAtk, u32 battlerDef, u32 recoilDmg, u8 moveIndex); bool32 ShouldUseRecoilMove(u32 battlerAtk, u32 battlerDef, u32 recoilDmg, u32 moveIndex);
u32 GetBattlerSideSpeedAverage(u32 battler); u32 GetBattlerSideSpeedAverage(u32 battler);
bool32 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, u16 move, s32 damage); bool32 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, u32 move, s32 damage);
bool32 ShouldRecover(u32 battlerAtk, u32 battlerDef, u16 move, u8 healPercent); bool32 ShouldRecover(u32 battlerAtk, u32 battlerDef, u32 move, u32 healPercent);
bool32 ShouldSetScreen(u32 battlerAtk, u32 battlerDef, u16 moveEffect); bool32 ShouldSetScreen(u32 battlerAtk, u32 battlerDef, u32 moveEffect);
bool32 ShouldPivot(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u8 moveIndex); bool32 ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 moveIndex);
bool32 IsRecycleEncouragedItem(u16 item); bool32 IsRecycleEncouragedItem(u16 item);
bool32 ShouldRestoreHpBerry(u32 battlerAtk, u16 item); bool32 ShouldRestoreHpBerry(u32 battlerAtk, u16 item);
bool32 IsStatBoostingBerry(u16 item); bool32 IsStatBoostingBerry(u16 item);
bool32 CanKnockOffItem(u8 battler, u16 item); bool32 CanKnockOffItem(u32 battler, u16 item);
bool32 IsAbilityOfRating(u16 ability, s8 rating); bool32 IsAbilityOfRating(u32 ability, s8 rating);
s8 GetAbilityRating(u16 ability); s8 GetAbilityRating(u32 ability);
bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability); bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability);
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move); bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u32 move);
u32 AI_GetBattlerMoveTargetType(u8 battlerId, u16 move); u32 AI_GetBattlerMoveTargetType(u32 battlerId, u32 move);
bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u16 chosenMove); bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u16 chosenMove);
// stat stage checks // stat stage checks
bool32 AnyStatIsRaised(u8 battlerId); bool32 AnyStatIsRaised(u32 battlerId);
bool32 ShouldLowerStat(u8 battler, u16 battlerAbility, u8 stat); bool32 ShouldLowerStat(u32 battler, u32 battlerAbility, u32 stat);
bool32 BattlerStatCanRise(u8 battler, u16 battlerAbility, u8 stat); bool32 BattlerStatCanRise(u32 battler, u32 battlerAbility, u32 stat);
bool32 AreBattlersStatsMaxed(u8 battler); bool32 AreBattlersStatsMaxed(u32 battler);
bool32 BattlerHasAnyStatRaised(u8 battlerId); bool32 BattlerHasAnyStatRaised(u32 battlerId);
u32 CountPositiveStatStages(u8 battlerId); u32 CountPositiveStatStages(u32 battlerId);
u32 CountNegativeStatStages(u8 battlerId); u32 CountNegativeStatStages(u32 battlerId);
bool32 ShouldLowerAttack(u32 battlerAtk, u32 battlerDef, u16 defAbility); bool32 ShouldLowerAttack(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 ShouldLowerDefense(u32 battlerAtk, u32 battlerDef, u16 defAbility); bool32 ShouldLowerDefense(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 ShouldLowerSpeed(u32 battlerAtk, u32 battlerDef, u16 defAbility); bool32 ShouldLowerSpeed(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 ShouldLowerSpAtk(u32 battlerAtk, u32 battlerDef, u16 defAbility); bool32 ShouldLowerSpAtk(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 ShouldLowerSpDef(u32 battlerAtk, u32 battlerDef, u16 defAbility); bool32 ShouldLowerSpDef(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u16 defAbility); bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 ShouldLowerEvasion(u32 battlerAtk, u32 battlerDef, u16 defAbility); bool32 ShouldLowerEvasion(u32 battlerAtk, u32 battlerDef, u32 defAbility);
// move checks // move checks
bool32 IsAffectedByPowder(u8 battler, u16 ability, u16 holdEffect); bool32 IsAffectedByPowder(u32 battler, u32 ability, u32 holdEffect);
bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split); bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split);
s32 AI_CalcDamageSaveBattlers(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectiveness, 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); s32 AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectiveness, bool32 considerZPower, u32 weather);
u32 GetNoOfHitsToKO(u32 dmg, s32 hp); u32 GetNoOfHitsToKO(u32 dmg, s32 hp);
void SetMoveDamageResult(u32 battlerAtk, u16 *moves); void SetMoveDamageResult(u32 battlerAtk, u16 *moves);
u32 GetMoveDamageResult(u32 battlerAtk, u32 battlerDef, u32 moveIndex); u32 GetMoveDamageResult(u32 battlerAtk, u32 battlerDef, u32 moveIndex);
u32 GetCurrDamageHpPercent(u32 battlerAtk, u32 battlerDef); u32 GetCurrDamageHpPercent(u32 battlerAtk, u32 battlerDef);
uq4_12_t AI_GetTypeEffectiveness(u16 move, u32 battlerAtk, u32 battlerDef); uq4_12_t AI_GetTypeEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef);
u32 AI_GetMoveEffectiveness(u16 move, u32 battlerAtk, u32 battlerDef); u32 AI_GetMoveEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef);
u16 *GetMovesArray(u32 battler); u16 *GetMovesArray(u32 battler);
bool32 IsConfusionMoveEffect(u16 moveEffect); bool32 IsConfusionMoveEffect(u32 moveEffect);
bool32 HasMove(u32 battlerId, u32 move); bool32 HasMove(u32 battlerId, u32 move);
bool32 HasOnlyMovesWithSplit(u32 battlerId, u32 split, bool32 onlyOffensive); bool32 HasOnlyMovesWithSplit(u32 battlerId, u32 split, bool32 onlyOffensive);
bool32 HasMoveWithSplit(u32 battler, u32 split); bool32 HasMoveWithSplit(u32 battler, u32 split);
bool32 HasMoveWithType(u32 battler, u8 type); bool32 HasMoveWithType(u32 battler, u32 type);
bool32 HasMoveWithTypeAndSplit(u32 battler, u8 type, u8 split); bool32 HasMoveWithTypeAndSplit(u32 battler, u32 type, u32 split);
bool32 HasMoveEffect(u32 battlerId, u16 moveEffect); bool32 HasMoveEffect(u32 battlerId, u32 moveEffect);
bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u8 accCheck, bool32 ignoreStatus, u16 atkAbility, u16 defAbility, u16 atkHoldEffect, u16 defHoldEffect); bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u32 accCheck, bool32 ignoreStatus, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
bool32 IsAromaVeilProtectedMove(u16 move); bool32 IsAromaVeilProtectedMove(u32 move);
bool32 IsNonVolatileStatusMoveEffect(u16 moveEffect); bool32 IsNonVolatileStatusMoveEffect(u32 moveEffect);
bool32 IsStatLoweringMoveEffect(u16 moveEffect); bool32 IsStatLoweringMoveEffect(u32 moveEffect);
bool32 IsMoveRedirectionPrevented(u16 move, u16 atkAbility); bool32 IsMoveRedirectionPrevented(u32 move, u32 atkAbility);
bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u16 move); bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 IsHazardMoveEffect(u16 moveEffect); bool32 IsHazardMoveEffect(u32 moveEffect);
bool32 MoveCallsOtherMove(u16 move); bool32 MoveCallsOtherMove(u32 move);
bool32 MoveRequiresRecharging(u16 move); bool32 MoveRequiresRecharging(u32 move);
bool32 IsEncoreEncouragedEffect(u16 moveEffect); bool32 IsEncoreEncouragedEffect(u32 moveEffect);
void ProtectChecks(u32 battlerAtk, u32 battlerDef, u16 move, u16 predictedMove, s32 *score); void ProtectChecks(u32 battlerAtk, u32 battlerDef, u32 move, u32 predictedMove, s32 *score);
bool32 ShouldSetSandstorm(u8 battler, u16 ability, u16 holdEffect); bool32 ShouldSetSandstorm(u32 battler, u32 ability, u32 holdEffect);
bool32 ShouldSetHail(u8 battler, u16 ability, u16 holdEffect); bool32 ShouldSetHail(u32 battler, u32 ability, u32 holdEffect);
bool32 ShouldSetSnow(u8 battler, u16 ability, u16 holdEffect); bool32 ShouldSetSnow(u32 battler, u32 ability, u32 holdEffect);
bool32 ShouldSetRain(u32 battlerAtk, u16 ability, u16 holdEffect); bool32 ShouldSetRain(u32 battlerAtk, u32 ability, u32 holdEffect);
bool32 ShouldSetSun(u32 battlerAtk, u16 atkAbility, u16 holdEffect); bool32 ShouldSetSun(u32 battlerAtk, u32 atkAbility, u32 holdEffect);
bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef); bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef);
bool32 IsHealingMoveEffect(u16 effect); bool32 IsHealingMoveEffect(u32 effect);
bool32 HasHealingEffect(u32 battler); bool32 HasHealingEffect(u32 battler);
bool32 IsTrappingMoveEffect(u16 effect); bool32 IsTrappingMoveEffect(u32 effect);
bool32 HasTrappingMoveEffect(u8 battler); bool32 HasTrappingMoveEffect(u32 battler);
bool32 ShouldFakeOut(u32 battlerAtk, u32 battlerDef, u16 move); bool32 ShouldFakeOut(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 HasThawingMove(u8 battler); bool32 HasThawingMove(u32 battler);
bool32 IsStatRaisingEffect(u16 effect); bool32 IsStatRaisingEffect(u32 effect);
bool32 IsStatLoweringEffect(u16 effect); bool32 IsStatLoweringEffect(u32 effect);
bool32 IsStatRaisingEffect(u16 effect); bool32 IsStatRaisingEffect(u32 effect);
bool32 IsAttackBoostMoveEffect(u16 effect); bool32 IsAttackBoostMoveEffect(u32 effect);
bool32 IsUngroundingEffect(u16 effect); bool32 IsUngroundingEffect(u32 effect);
bool32 IsSemiInvulnerable(u32 battlerDef, u16 move); bool32 IsSemiInvulnerable(u32 battlerDef, u32 move);
bool32 HasSoundMove(u8 battler); bool32 HasSoundMove(u32 battler);
bool32 HasHighCritRatioMove(u8 battler); bool32 HasHighCritRatioMove(u32 battler);
bool32 HasMagicCoatAffectedMove(u8 battler); bool32 HasMagicCoatAffectedMove(u32 battler);
bool32 HasSnatchAffectedMove(u8 battler); bool32 HasSnatchAffectedMove(u32 battler);
// status checks // status checks
bool32 AI_CanBeBurned(u8 battler, u16 ability); bool32 AI_CanBeBurned(u32 battler, u32 ability);
bool32 AI_CanGetFrostbite(u8 battler, u16 ability); bool32 AI_CanGetFrostbite(u32 battler, u32 ability);
bool32 AI_CanBeConfused(u8 battler, u16 ability); bool32 AI_CanBeConfused(u32 battler, u32 ability);
bool32 AI_CanSleep(u8 battler, u16 ability); bool32 AI_CanSleep(u32 battler, u32 ability);
bool32 IsBattlerIncapacitated(u8 battler, u16 ability); bool32 IsBattlerIncapacitated(u32 battler, u32 ability);
bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u16 partnerMove); bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
bool32 ShouldPoisonSelf(u8 battler, u16 ability); bool32 ShouldPoisonSelf(u32 battler, u32 ability);
bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u16 partnerMove); bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u16 partnerMove); bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u16 defAbility, u32 battlerAtkPartner, u16 move, u16 partnerMove); bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
bool32 ShouldBurnSelf(u8 battler, u16 ability); bool32 ShouldBurnSelf(u32 battler, u32 ability);
bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, u16 defAbility, u32 battlerAtkPartner, u16 move, u16 partnerMove); bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
bool32 AI_CanGiveFrostbite(u32 battlerAtk, u32 battlerDef, u16 defAbility, u32 battlerAtkPartner, u16 move, u16 partnerMove); bool32 AI_CanGiveFrostbite(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, u16 defAbility); bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof); bool32 AnyPartyMemberStatused(u32 battlerId, bool32 checkSoundproof);
u32 ShouldTryToFlinch(u32 battlerAtk, u32 battlerDef, u16 atkAbility, u16 defAbility, u16 move); u32 ShouldTryToFlinch(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbility, u32 move);
bool32 ShouldTrap(u32 battlerAtk, u32 battlerDef, u16 move); bool32 ShouldTrap(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 IsWakeupTurn(u8 battler); bool32 IsWakeupTurn(u32 battler);
bool32 AI_IsBattlerAsleepOrComatose(u8 battlerId); bool32 AI_IsBattlerAsleepOrComatose(u32 battlerId);
// partner logic // partner logic
#define IS_TARGETING_PARTNER(battlerAtk, battlerDef)((battlerAtk) == (battlerDef ^ BIT_FLANK)) #define IS_TARGETING_PARTNER(battlerAtk, battlerDef)((battlerAtk) == (battlerDef ^ BIT_FLANK))
u16 GetAllyChosenMove(u8 battlerId); u32 GetAllyChosenMove(u32 battlerId);
bool32 IsValidDoubleBattle(u32 battlerAtk); bool32 IsValidDoubleBattle(u32 battlerAtk);
bool32 IsTargetingPartner(u32 battlerAtk, u32 battlerDef); bool32 IsTargetingPartner(u32 battlerAtk, u32 battlerDef);
bool32 DoesPartnerHaveSameMoveEffect(u32 battlerAtkPartner, u32 battlerDef, u16 move, u16 partnerMove); bool32 DoesPartnerHaveSameMoveEffect(u32 battlerAtkPartner, u32 battlerDef, u32 move, u32 partnerMove);
bool32 PartnerHasSameMoveEffectWithoutTarget(u32 battlerAtkPartner, u16 move, u16 partnerMove); bool32 PartnerHasSameMoveEffectWithoutTarget(u32 battlerAtkPartner, u32 move, u32 partnerMove);
bool32 PartnerMoveEffectIsStatusSameTarget(u32 battlerAtkPartner, u32 battlerDef, u16 partnerMove); bool32 PartnerMoveEffectIsStatusSameTarget(u32 battlerAtkPartner, u32 battlerDef, u32 partnerMove);
bool32 PartnerMoveEffectIsWeather(u32 battlerAtkPartner, u16 partnerMove); bool32 PartnerMoveEffectIsWeather(u32 battlerAtkPartner, u32 partnerMove);
bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u16 partnerMove); bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u32 partnerMove);
bool32 PartnerMoveIs(u32 battlerAtkPartner, u16 partnerMove, u16 moveCheck); bool32 PartnerMoveIs(u32 battlerAtkPartner, u32 partnerMove, u32 moveCheck);
bool32 PartnerMoveIsSameAsAttacker(u32 battlerAtkPartner, u32 battlerDef, u16 move, u16 partnerMove); bool32 PartnerMoveIsSameAsAttacker(u32 battlerAtkPartner, u32 battlerDef, u32 move, u32 partnerMove);
bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u16 move, u16 partnerMove); bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u32 move, u32 partnerMove);
bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u16 move); bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move);
// party logic // party logic
struct BattlePokemon *AllocSaveBattleMons(void); struct BattlePokemon *AllocSaveBattleMons(void);
void FreeRestoreBattleMons(struct BattlePokemon *savedBattleMons); void FreeRestoreBattleMons(struct BattlePokemon *savedBattleMons);
s32 AI_CalcPartyMonBestMoveDamage(u32 battlerAtk, u32 battlerDef, struct Pokemon *attackerMon, struct Pokemon *targetMon); s32 AI_CalcPartyMonBestMoveDamage(u32 battlerAtk, u32 battlerDef, struct Pokemon *attackerMon, struct Pokemon *targetMon);
s32 CountUsablePartyMons(u8 battlerId); s32 CountUsablePartyMons(u32 battlerId);
bool32 IsPartyFullyHealedExceptBattler(u8 battler); bool32 IsPartyFullyHealedExceptBattler(u32 battler);
bool32 PartyHasMoveSplit(u8 battlerId, u8 split); bool32 PartyHasMoveSplit(u32 battlerId, u32 split);
bool32 SideHasMoveSplit(u8 battlerId, u8 split); bool32 SideHasMoveSplit(u32 battlerId, u32 split);
// score increases // score increases
void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u8 statId, s32 *score); void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score);
void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score); void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score); void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score); void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score); void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score); void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score); void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
#endif //GUARD_BATTLE_AI_UTIL_H #endif //GUARD_BATTLE_AI_UTIL_H

View file

@ -172,7 +172,7 @@ u32 GetBattlerWeight(u32 battler);
u32 CalcRolloutBasePower(u32 battlerAtk, u32 basePower, u32 rolloutTimer); u32 CalcRolloutBasePower(u32 battlerAtk, u32 basePower, u32 rolloutTimer);
u32 CalcFuryCutterBasePower(u32 basePower, u32 furyCutterCounter); u32 CalcFuryCutterBasePower(u32 basePower, u32 furyCutterCounter);
s32 CalculateMoveDamage(u32 move, u32 battlerAtk, u32 battlerDef, u32 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);
s32 CalculateMoveDamageWithEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, uq4_12_t typeEffectivenessModifier, bool32 isCrit); s32 CalculateMoveDamageWithEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, uq4_12_t typeEffectivenessModifier, bool32 isCrit, u32 weather);
uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, bool32 recordAbilities); 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 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef);
uq4_12_t GetTypeModifier(u32 atkType, u32 defType); uq4_12_t GetTypeModifier(u32 atkType, u32 defType);

View file

@ -350,14 +350,15 @@ static void SetBattlerAiData(u32 battler, struct AiLogicData *aiData)
aiData->speedStats[battler] = GetBattlerTotalSpeedStatArgs(battler, ability, holdEffect); aiData->speedStats[battler] = GetBattlerTotalSpeedStatArgs(battler, ability, holdEffect);
} }
static void SetBattlerAiMovesData(u32 battlerAtk, u32 battlersCount) static void SetBattlerAiMovesData(struct AiLogicData *aiData, u32 battlerAtk, u32 battlersCount)
{ {
u32 battlerDef, i; u32 battlerDef, i, weather;
u16 *moves; u16 *moves;
// Simulate dmg for both ai controlled mons and for player controlled mons. // Simulate dmg for both ai controlled mons and for player controlled mons.
SaveBattlerData(battlerAtk); SaveBattlerData(battlerAtk);
moves = GetMovesArray(battlerAtk); moves = GetMovesArray(battlerAtk);
weather = AI_GetWeather(aiData);
for (battlerDef = 0; battlerDef < battlersCount; battlerDef++) for (battlerDef = 0; battlerDef < battlersCount; battlerDef++)
{ {
if (battlerAtk == battlerDef) if (battlerAtk == battlerDef)
@ -373,28 +374,29 @@ static void SetBattlerAiMovesData(u32 battlerAtk, u32 battlersCount)
if (move != 0 if (move != 0
&& move != 0xFFFF && move != 0xFFFF
//&& gBattleMoves[move].power != 0 /* we want to get effectiveness of status moves */ //&& gBattleMoves[move].power != 0 /* we want to get effectiveness of status moves */
&& !(AI_DATA->moveLimitations[battlerAtk] & gBitTable[i])) { && !(aiData->moveLimitations[battlerAtk] & gBitTable[i])) {
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, TRUE); dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, TRUE, weather);
} }
AI_DATA->simulatedDmg[battlerAtk][battlerDef][i] = dmg; aiData->simulatedDmg[battlerAtk][battlerDef][i] = dmg;
AI_DATA->effectiveness[battlerAtk][battlerDef][i] = effectiveness; aiData->effectiveness[battlerAtk][battlerDef][i] = effectiveness;
} }
} }
SetMoveDamageResult(battlerAtk, moves); SetMoveDamageResult(battlerAtk, moves);
} }
void SetAiLogicDataForTurn(void) void SetAiLogicDataForTurn(struct AiLogicData *aiData)
{ {
u32 battlerAtk, battlersCount; u32 battlerAtk, battlersCount;
memset(AI_DATA, 0, sizeof(struct AiLogicData)); memset(aiData, 0, sizeof(struct AiLogicData));
if (!(gBattleTypeFlags & BATTLE_TYPE_HAS_AI) && !IsWildMonSmart()) if (!(gBattleTypeFlags & BATTLE_TYPE_HAS_AI) && !IsWildMonSmart())
return; return;
// Set delay timer to count how long it takes for AI to choose action/move
gBattleStruct->aiDelayTimer = gMain.vblankCounter1; gBattleStruct->aiDelayTimer = gMain.vblankCounter1;
aiData->weatherHasEffect = WEATHER_HAS_EFFECT;
// get/assume all battler data and simulate AI damage // get/assume all battler data and simulate AI damage
battlersCount = gBattlersCount; battlersCount = gBattlersCount;
for (battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++) for (battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++)
@ -402,8 +404,8 @@ void SetAiLogicDataForTurn(void)
if (!IsBattlerAlive(battlerAtk)) if (!IsBattlerAlive(battlerAtk))
continue; continue;
SetBattlerAiData(battlerAtk, AI_DATA); SetBattlerAiData(battlerAtk, aiData);
SetBattlerAiMovesData(battlerAtk, battlersCount); SetBattlerAiMovesData(aiData, battlerAtk, battlersCount);
} }
} }
@ -891,7 +893,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s32 score)
RETURN_SCORE_MINUS(10); RETURN_SCORE_MINUS(10);
break; break;
case ABILITY_LEAF_GUARD: case ABILITY_LEAF_GUARD:
if (AI_WeatherHasEffect() && (gBattleWeather & B_WEATHER_SUN) if ((AI_GetWeather(AI_DATA) & B_WEATHER_SUN)
&& AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_UTILITY_UMBRELLA && AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_UTILITY_UMBRELLA
&& IsNonVolatileStatusMoveEffect(moveEffect)) && IsNonVolatileStatusMoveEffect(moveEffect))
RETURN_SCORE_MINUS(10); RETURN_SCORE_MINUS(10);
@ -971,7 +973,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s32 score)
if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(battlerAtk, move)) if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(battlerAtk, move))
return 0; // Can't even select heal blocked move return 0; // Can't even select heal blocked move
// primal weather check // primal weather check
if (WEATHER_HAS_EFFECT) if (gBattleWeather && WEATHER_HAS_EFFECT)
{ {
if (gBattleWeather & B_WEATHER_PRIMAL_ANY) if (gBattleWeather & B_WEATHER_PRIMAL_ANY)
{ {
@ -1848,7 +1850,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s32 score)
case EFFECT_MORNING_SUN: case EFFECT_MORNING_SUN:
case EFFECT_SYNTHESIS: case EFFECT_SYNTHESIS:
case EFFECT_MOONLIGHT: case EFFECT_MOONLIGHT:
if (AI_WeatherHasEffect() && (gBattleWeather & (B_WEATHER_RAIN | B_WEATHER_SANDSTORM | B_WEATHER_HAIL))) if ((AI_GetWeather(AI_DATA) & (B_WEATHER_RAIN | B_WEATHER_SANDSTORM | B_WEATHER_HAIL)))
score -= 3; score -= 3;
else if (AtMaxHp(battlerAtk)) else if (AtMaxHp(battlerAtk))
score -= 10; score -= 10;
@ -2124,7 +2126,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s32 score)
break; break;
case EFFECT_SOLAR_BEAM: case EFFECT_SOLAR_BEAM:
if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_POWER_HERB if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_POWER_HERB
|| (AI_WeatherHasEffect() && gBattleWeather & B_WEATHER_SUN && AI_DATA->holdEffects[battlerAtk] != HOLD_EFFECT_UTILITY_UMBRELLA)) || ((AI_GetWeather(AI_DATA) & B_WEATHER_SUN) && AI_DATA->holdEffects[battlerAtk] != HOLD_EFFECT_UTILITY_UMBRELLA))
break; break;
if (CanTargetFaintAi(battlerDef, battlerAtk)) //Attacker can be knocked out if (CanTargetFaintAi(battlerDef, battlerAtk)) //Attacker can be knocked out
score -= 4; score -= 4;
@ -4354,17 +4356,17 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u16 move, s32 score
score += 3; score += 3;
break; break;
case HOLD_EFFECT_UTILITY_UMBRELLA: case HOLD_EFFECT_UTILITY_UMBRELLA:
if (AI_DATA->abilities[battlerAtk] != ABILITY_SOLAR_POWER && AI_DATA->abilities[battlerAtk] != ABILITY_DRY_SKIN && AI_WeatherHasEffect()) if (AI_DATA->abilities[battlerAtk] != ABILITY_SOLAR_POWER && AI_DATA->abilities[battlerAtk] != ABILITY_DRY_SKIN)
{ {
switch (AI_DATA->abilities[battlerDef]) switch (AI_DATA->abilities[battlerDef])
{ {
case ABILITY_SWIFT_SWIM: case ABILITY_SWIFT_SWIM:
if (gBattleWeather & B_WEATHER_RAIN) if (AI_GetWeather(AI_DATA) & B_WEATHER_RAIN)
score += 3; // Slow 'em down score += 3; // Slow 'em down
break; break;
case ABILITY_CHLOROPHYLL: case ABILITY_CHLOROPHYLL:
case ABILITY_FLOWER_GIFT: case ABILITY_FLOWER_GIFT:
if (gBattleWeather & B_WEATHER_SUN) if (AI_GetWeather(AI_DATA) & B_WEATHER_SUN)
score += 3; // Slow 'em down score += 3; // Slow 'em down
break; break;
} }
@ -4901,7 +4903,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u16 move, s32 score
} }
break; break;
case EFFECT_SHORE_UP: case EFFECT_SHORE_UP:
if (AI_WeatherHasEffect() && (gBattleWeather & B_WEATHER_SANDSTORM) if ((AI_GetWeather(AI_DATA) & B_WEATHER_SANDSTORM)
&& ShouldRecover(battlerAtk, battlerDef, move, 67)) && ShouldRecover(battlerAtk, battlerDef, move, 67))
score += 3; score += 3;
else if (ShouldRecover(battlerAtk, battlerDef, move, 50)) else if (ShouldRecover(battlerAtk, battlerDef, move, 50))

File diff suppressed because it is too large Load diff

View file

@ -3724,7 +3724,7 @@ static void DoBattleIntro(void)
gBattleStruct->switchInAbilitiesCounter = 0; gBattleStruct->switchInAbilitiesCounter = 0;
gBattleStruct->switchInItemsCounter = 0; gBattleStruct->switchInItemsCounter = 0;
gBattleStruct->overworldWeatherDone = FALSE; gBattleStruct->overworldWeatherDone = FALSE;
SetAiLogicDataForTurn(); // get assumed abilities, hold effects, etc of all battlers SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers
Ai_InitPartyStruct(); // Save mons party counts, and first 2/4 mons on the battlefield. Ai_InitPartyStruct(); // Save mons party counts, and first 2/4 mons on the battlefield.
gBattleMainFunc = TryDoEventsBeforeFirstTurn; gBattleMainFunc = TryDoEventsBeforeFirstTurn;
} }
@ -3857,7 +3857,7 @@ static void TryDoEventsBeforeFirstTurn(void)
gRandomTurnNumber = Random(); gRandomTurnNumber = Random();
SetAiLogicDataForTurn(); // get assumed abilities, hold effects, etc of all battlers SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers
if (gBattleTypeFlags & BATTLE_TYPE_ARENA) if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
{ {
@ -3949,7 +3949,7 @@ void BattleTurnPassed(void)
*(&gBattleStruct->absentBattlerFlags) = gAbsentBattlerFlags; *(&gBattleStruct->absentBattlerFlags) = gAbsentBattlerFlags;
BattlePutTextOnWindow(gText_EmptyString3, B_WIN_MSG); BattlePutTextOnWindow(gText_EmptyString3, B_WIN_MSG);
SetAiLogicDataForTurn(); // get assumed abilities, hold effects, etc of all battlers SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers
gBattleMainFunc = HandleTurnActionSelectionState; gBattleMainFunc = HandleTurnActionSelectionState;
gRandomTurnNumber = Random(); gRandomTurnNumber = Random();

View file

@ -9759,10 +9759,9 @@ static inline uq4_12_t GetOtherModifiers(u32 move, u32 moveType, u32 battlerAtk,
} while (0) } while (0)
static inline 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) bool32 isCrit, bool32 randomFactor, bool32 updateFlags, uq4_12_t typeEffectivenessModifier, u32 weather)
{ {
s32 dmg; s32 dmg;
u32 weather;
u32 userFinalAttack; u32 userFinalAttack;
u32 targetFinalDefense; u32 targetFinalDefense;
u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE); u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
@ -9773,12 +9772,6 @@ static inline s32 DoMoveDamageCalc(u32 move, u32 battlerAtk, u32 battlerDef, u32
if (typeEffectivenessModifier == UQ_4_12(0.0)) if (typeEffectivenessModifier == UQ_4_12(0.0))
return 0; return 0;
// Store weather in a local variable, so there's no need to call WEATHER_HAS_EFFECT every time weather is checked.
if (gBattleWeather == B_WEATHER_NONE || !WEATHER_HAS_EFFECT)
weather = B_WEATHER_NONE;
else
weather = gBattleWeather;
if (fixedBasePower) if (fixedBasePower)
gBattleMovePower = fixedBasePower; gBattleMovePower = fixedBasePower;
else else
@ -9812,16 +9805,24 @@ static inline s32 DoMoveDamageCalc(u32 move, u32 battlerAtk, u32 battlerDef, u32
#undef DAMAGE_APPLY_MODIFIER #undef DAMAGE_APPLY_MODIFIER
static u32 GetWeather(void)
{
if (gBattleWeather == B_WEATHER_NONE || !WEATHER_HAS_EFFECT)
return B_WEATHER_NONE;
else
return gBattleWeather;
}
s32 CalculateMoveDamage(u32 move, u32 battlerAtk, u32 battlerDef, u32 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, return DoMoveDamageCalc(move, battlerAtk, battlerDef, moveType, fixedBasePower, isCrit, randomFactor,
updateFlags, CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, updateFlags)); updateFlags, CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, updateFlags), GetWeather());
} }
// for AI so that typeEffectivenessModifier is calculated only once // for AI so that typeEffectivenessModifier is calculated only once
s32 CalculateMoveDamageWithEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, uq4_12_t typeEffectivenessModifier, bool32 isCrit) s32 CalculateMoveDamageWithEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, uq4_12_t typeEffectivenessModifier, bool32 isCrit, u32 weather)
{ {
return DoMoveDamageCalc(move, battlerAtk, battlerDef, moveType, fixedBasePower, isCrit, FALSE, FALSE, typeEffectivenessModifier); return DoMoveDamageCalc(move, battlerAtk, battlerDef, moveType, fixedBasePower, isCrit, FALSE, FALSE, typeEffectivenessModifier, weather);
} }
static inline void MulByTypeEffectiveness(uq4_12_t *modifier, u32 move, u32 moveType, u32 battlerDef, u32 defType, u32 battlerAtk, bool32 recordAbilities) static inline void MulByTypeEffectiveness(uq4_12_t *modifier, u32 move, u32 moveType, u32 battlerDef, u32 defType, u32 battlerAtk, bool32 recordAbilities)