mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-16 11:37:40 +01:00
ai weather optimization
This commit is contained in:
parent
b7d0d37757
commit
38dcb3c66c
@ -70,6 +70,7 @@ Debug_BoxFilledMessage_Text:
|
||||
.string "Storage boxes filled!$"
|
||||
|
||||
Debug_Script_1::
|
||||
multi_fixed_2_vs_2 TRAINER_WALLACE, NULL, TRAINER_JUAN_5, NULL, TRAINER_STEVEN, TRAINER_BACK_PIC_STEVEN
|
||||
end
|
||||
|
||||
Debug_Script_2::
|
||||
|
@ -277,6 +277,7 @@ struct AIPartyData // Opposing battlers - party mons.
|
||||
u8 count[NUM_BATTLE_SIDES];
|
||||
};
|
||||
|
||||
// Ai Data used when deciding which move to use, computed only once before each turn's start.
|
||||
struct AiLogicData
|
||||
{
|
||||
u16 abilities[MAX_BATTLERS_COUNT];
|
||||
@ -293,6 +294,7 @@ struct AiLogicData
|
||||
u8 moveLimitations[MAX_BATTLERS_COUNT];
|
||||
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.
|
||||
bool8 weatherHasEffect; // WEATHER_HAS_EFFECT, so it doesn't have to be used all the time
|
||||
};
|
||||
|
||||
struct AI_ThinkingStruct
|
||||
|
@ -27,7 +27,7 @@ u8 BattleAI_ChooseMoveOrAction(void);
|
||||
void Ai_InitPartyStruct(void);
|
||||
void Ai_UpdateSwitchInData(u32 battler);
|
||||
void Ai_UpdateFaintData(u32 battler);
|
||||
void SetAiLogicDataForTurn(void);
|
||||
void SetAiLogicDataForTurn(struct AiLogicData *aiData);
|
||||
|
||||
extern u8 sBattler_AI;
|
||||
|
||||
|
@ -9,184 +9,184 @@
|
||||
|
||||
#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 BattlerHasAi(u32 battlerId);
|
||||
bool32 IsAiBattlerAware(u32 battlerId);
|
||||
void ClearBattlerMoveHistory(u8 battlerId);
|
||||
void ClearBattlerMoveHistory(u32 battlerId);
|
||||
void RecordLastUsedMoveBy(u32 battlerId, u32 move);
|
||||
void RecordKnownMove(u8 battlerId, u32 move);
|
||||
void RecordAbilityBattle(u8 battlerId, u16 abilityId);
|
||||
void ClearBattlerAbilityHistory(u8 battlerId);
|
||||
void RecordItemEffectBattle(u8 battlerId, u8 itemEffect);
|
||||
void ClearBattlerItemEffectHistory(u8 battlerId);
|
||||
void RecordKnownMove(u32 battlerId, u32 move);
|
||||
void RecordAbilityBattle(u32 battlerId, u32 abilityId);
|
||||
void ClearBattlerAbilityHistory(u32 battlerId);
|
||||
void RecordItemEffectBattle(u32 battlerId, u32 itemEffect);
|
||||
void ClearBattlerItemEffectHistory(u32 battlerId);
|
||||
void SaveBattlerData(u32 battlerId);
|
||||
void SetBattlerData(u32 battlerId);
|
||||
void RestoreBattlerData(u32 battlerId);
|
||||
u16 GetAIChosenMove(u8 battlerId);
|
||||
u16 GetAIChosenMove(u32 battlerId);
|
||||
|
||||
u32 GetTotalBaseStat(u32 species);
|
||||
bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler);
|
||||
bool32 AtMaxHp(u8 battler);
|
||||
u32 GetHealthPercentage(u8 battler);
|
||||
bool32 IsBattlerTrapped(u8 battler, bool8 switching);
|
||||
bool32 AtMaxHp(u32 battler);
|
||||
u32 GetHealthPercentage(u32 battler);
|
||||
bool32 IsBattlerTrapped(u32 battler, bool32 switching);
|
||||
u32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler2, u32 moveConsidered);
|
||||
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);
|
||||
s32 AI_GetAbility(u32 battlerId);
|
||||
u16 AI_GetHoldEffect(u32 battlerId);
|
||||
u32 AI_GetMoveAccuracy(u32 battlerAtk, u32 battlerDef, u16 move);
|
||||
bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move);
|
||||
bool32 AI_WeatherHasEffect(void);
|
||||
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);
|
||||
bool32 HasDamagingMoveOfType(u8 battlerId, u8 type);
|
||||
u32 GetBattlerSecondaryDamage(u8 battlerId);
|
||||
bool32 BattlerWillFaintFromWeather(u8 battler, u16 ability);
|
||||
bool32 BattlerWillFaintFromSecondaryDamage(u8 battler, u16 ability);
|
||||
bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, u16 atkAbility, u16 defAbility, u16 move);
|
||||
bool32 ShouldUseRecoilMove(u32 battlerAtk, u32 battlerDef, u32 recoilDmg, u8 moveIndex);
|
||||
u32 AI_GetMoveAccuracy(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move);
|
||||
u32 AI_GetWeather(struct AiLogicData *aiData);
|
||||
bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u32 numHits);
|
||||
bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u32 index, u32 numHits);
|
||||
bool32 AI_IsTerrainAffected(u32 battlerId, u32 flags);
|
||||
bool32 AI_IsBattlerGrounded(u32 battlerId);
|
||||
bool32 HasDamagingMove(u32 battlerId);
|
||||
bool32 HasDamagingMoveOfType(u32 battlerId, u32 type);
|
||||
u32 GetBattlerSecondaryDamage(u32 battlerId);
|
||||
bool32 BattlerWillFaintFromWeather(u32 battler, u32 ability);
|
||||
bool32 BattlerWillFaintFromSecondaryDamage(u32 battler, u32 ability);
|
||||
bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbility, u32 move);
|
||||
bool32 ShouldUseRecoilMove(u32 battlerAtk, u32 battlerDef, u32 recoilDmg, u32 moveIndex);
|
||||
u32 GetBattlerSideSpeedAverage(u32 battler);
|
||||
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 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, u32 move, s32 damage);
|
||||
bool32 ShouldRecover(u32 battlerAtk, u32 battlerDef, u32 move, u32 healPercent);
|
||||
bool32 ShouldSetScreen(u32 battlerAtk, u32 battlerDef, u32 moveEffect);
|
||||
bool32 ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 moveIndex);
|
||||
bool32 IsRecycleEncouragedItem(u16 item);
|
||||
bool32 ShouldRestoreHpBerry(u32 battlerAtk, u16 item);
|
||||
bool32 IsStatBoostingBerry(u16 item);
|
||||
bool32 CanKnockOffItem(u8 battler, u16 item);
|
||||
bool32 IsAbilityOfRating(u16 ability, s8 rating);
|
||||
s8 GetAbilityRating(u16 ability);
|
||||
bool32 CanKnockOffItem(u32 battler, u16 item);
|
||||
bool32 IsAbilityOfRating(u32 ability, s8 rating);
|
||||
s8 GetAbilityRating(u32 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 AI_MoveMakesContact(u32 ability, u32 holdEffect, u32 move);
|
||||
u32 AI_GetBattlerMoveTargetType(u32 battlerId, u32 move);
|
||||
bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u16 chosenMove);
|
||||
|
||||
// stat stage checks
|
||||
bool32 AnyStatIsRaised(u8 battlerId);
|
||||
bool32 ShouldLowerStat(u8 battler, u16 battlerAbility, u8 stat);
|
||||
bool32 BattlerStatCanRise(u8 battler, u16 battlerAbility, u8 stat);
|
||||
bool32 AreBattlersStatsMaxed(u8 battler);
|
||||
bool32 BattlerHasAnyStatRaised(u8 battlerId);
|
||||
u32 CountPositiveStatStages(u8 battlerId);
|
||||
u32 CountNegativeStatStages(u8 battlerId);
|
||||
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);
|
||||
bool32 AnyStatIsRaised(u32 battlerId);
|
||||
bool32 ShouldLowerStat(u32 battler, u32 battlerAbility, u32 stat);
|
||||
bool32 BattlerStatCanRise(u32 battler, u32 battlerAbility, u32 stat);
|
||||
bool32 AreBattlersStatsMaxed(u32 battler);
|
||||
bool32 BattlerHasAnyStatRaised(u32 battlerId);
|
||||
u32 CountPositiveStatStages(u32 battlerId);
|
||||
u32 CountNegativeStatStages(u32 battlerId);
|
||||
bool32 ShouldLowerAttack(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerDefense(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerSpeed(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerSpAtk(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerSpDef(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 ShouldLowerEvasion(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
|
||||
// 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);
|
||||
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);
|
||||
void SetMoveDamageResult(u32 battlerAtk, u16 *moves);
|
||||
u32 GetMoveDamageResult(u32 battlerAtk, u32 battlerDef, u32 moveIndex);
|
||||
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);
|
||||
uq4_12_t AI_GetTypeEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef);
|
||||
u32 AI_GetMoveEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef);
|
||||
u16 *GetMovesArray(u32 battler);
|
||||
bool32 IsConfusionMoveEffect(u16 moveEffect);
|
||||
bool32 IsConfusionMoveEffect(u32 moveEffect);
|
||||
bool32 HasMove(u32 battlerId, u32 move);
|
||||
bool32 HasOnlyMovesWithSplit(u32 battlerId, u32 split, bool32 onlyOffensive);
|
||||
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(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(u32 battlerAtk, u32 battlerDef, u16 move);
|
||||
bool32 IsHazardMoveEffect(u16 moveEffect);
|
||||
bool32 MoveCallsOtherMove(u16 move);
|
||||
bool32 MoveRequiresRecharging(u16 move);
|
||||
bool32 IsEncoreEncouragedEffect(u16 moveEffect);
|
||||
void ProtectChecks(u32 battlerAtk, u32 battlerDef, u16 move, u16 predictedMove, s32 *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(u32 battlerAtk, u16 ability, u16 holdEffect);
|
||||
bool32 ShouldSetSun(u32 battlerAtk, u16 atkAbility, u16 holdEffect);
|
||||
bool32 HasMoveWithType(u32 battler, u32 type);
|
||||
bool32 HasMoveWithTypeAndSplit(u32 battler, u32 type, u32 split);
|
||||
bool32 HasMoveEffect(u32 battlerId, u32 moveEffect);
|
||||
bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u32 accCheck, bool32 ignoreStatus, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
|
||||
bool32 IsAromaVeilProtectedMove(u32 move);
|
||||
bool32 IsNonVolatileStatusMoveEffect(u32 moveEffect);
|
||||
bool32 IsStatLoweringMoveEffect(u32 moveEffect);
|
||||
bool32 IsMoveRedirectionPrevented(u32 move, u32 atkAbility);
|
||||
bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 IsHazardMoveEffect(u32 moveEffect);
|
||||
bool32 MoveCallsOtherMove(u32 move);
|
||||
bool32 MoveRequiresRecharging(u32 move);
|
||||
bool32 IsEncoreEncouragedEffect(u32 moveEffect);
|
||||
void ProtectChecks(u32 battlerAtk, u32 battlerDef, u32 move, u32 predictedMove, s32 *score);
|
||||
bool32 ShouldSetSandstorm(u32 battler, u32 ability, u32 holdEffect);
|
||||
bool32 ShouldSetHail(u32 battler, u32 ability, u32 holdEffect);
|
||||
bool32 ShouldSetSnow(u32 battler, u32 ability, u32 holdEffect);
|
||||
bool32 ShouldSetRain(u32 battlerAtk, u32 ability, u32 holdEffect);
|
||||
bool32 ShouldSetSun(u32 battlerAtk, u32 atkAbility, u32 holdEffect);
|
||||
bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 IsHealingMoveEffect(u16 effect);
|
||||
bool32 IsHealingMoveEffect(u32 effect);
|
||||
bool32 HasHealingEffect(u32 battler);
|
||||
bool32 IsTrappingMoveEffect(u16 effect);
|
||||
bool32 HasTrappingMoveEffect(u8 battler);
|
||||
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(u32 battlerDef, u16 move);
|
||||
bool32 HasSoundMove(u8 battler);
|
||||
bool32 HasHighCritRatioMove(u8 battler);
|
||||
bool32 HasMagicCoatAffectedMove(u8 battler);
|
||||
bool32 HasSnatchAffectedMove(u8 battler);
|
||||
bool32 IsTrappingMoveEffect(u32 effect);
|
||||
bool32 HasTrappingMoveEffect(u32 battler);
|
||||
bool32 ShouldFakeOut(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 HasThawingMove(u32 battler);
|
||||
bool32 IsStatRaisingEffect(u32 effect);
|
||||
bool32 IsStatLoweringEffect(u32 effect);
|
||||
bool32 IsStatRaisingEffect(u32 effect);
|
||||
bool32 IsAttackBoostMoveEffect(u32 effect);
|
||||
bool32 IsUngroundingEffect(u32 effect);
|
||||
bool32 IsSemiInvulnerable(u32 battlerDef, u32 move);
|
||||
bool32 HasSoundMove(u32 battler);
|
||||
bool32 HasHighCritRatioMove(u32 battler);
|
||||
bool32 HasMagicCoatAffectedMove(u32 battler);
|
||||
bool32 HasSnatchAffectedMove(u32 battler);
|
||||
|
||||
// status checks
|
||||
bool32 AI_CanBeBurned(u8 battler, u16 ability);
|
||||
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(u32 battlerAtk, u32 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
|
||||
bool32 ShouldPoisonSelf(u8 battler, u16 ability);
|
||||
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(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(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);
|
||||
bool32 AI_CanBeBurned(u32 battler, u32 ability);
|
||||
bool32 AI_CanGetFrostbite(u32 battler, u32 ability);
|
||||
bool32 AI_CanBeConfused(u32 battler, u32 ability);
|
||||
bool32 AI_CanSleep(u32 battler, u32 ability);
|
||||
bool32 IsBattlerIncapacitated(u32 battler, u32 ability);
|
||||
bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
|
||||
bool32 ShouldPoisonSelf(u32 battler, u32 ability);
|
||||
bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
|
||||
bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
|
||||
bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
||||
bool32 ShouldBurnSelf(u32 battler, u32 ability);
|
||||
bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
||||
bool32 AI_CanGiveFrostbite(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
||||
bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, u32 defAbility);
|
||||
bool32 AnyPartyMemberStatused(u32 battlerId, bool32 checkSoundproof);
|
||||
u32 ShouldTryToFlinch(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbility, u32 move);
|
||||
bool32 ShouldTrap(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 IsWakeupTurn(u32 battler);
|
||||
bool32 AI_IsBattlerAsleepOrComatose(u32 battlerId);
|
||||
|
||||
// partner logic
|
||||
#define IS_TARGETING_PARTNER(battlerAtk, battlerDef)((battlerAtk) == (battlerDef ^ BIT_FLANK))
|
||||
u16 GetAllyChosenMove(u8 battlerId);
|
||||
u32 GetAllyChosenMove(u32 battlerId);
|
||||
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);
|
||||
bool32 DoesPartnerHaveSameMoveEffect(u32 battlerAtkPartner, u32 battlerDef, u32 move, u32 partnerMove);
|
||||
bool32 PartnerHasSameMoveEffectWithoutTarget(u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
||||
bool32 PartnerMoveEffectIsStatusSameTarget(u32 battlerAtkPartner, u32 battlerDef, u32 partnerMove);
|
||||
bool32 PartnerMoveEffectIsWeather(u32 battlerAtkPartner, u32 partnerMove);
|
||||
bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u32 partnerMove);
|
||||
bool32 PartnerMoveIs(u32 battlerAtkPartner, u32 partnerMove, u32 moveCheck);
|
||||
bool32 PartnerMoveIsSameAsAttacker(u32 battlerAtkPartner, u32 battlerDef, u32 move, u32 partnerMove);
|
||||
bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u32 move, u32 partnerMove);
|
||||
bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
|
||||
// party logic
|
||||
struct BattlePokemon *AllocSaveBattleMons(void);
|
||||
void FreeRestoreBattleMons(struct BattlePokemon *savedBattleMons);
|
||||
s32 AI_CalcPartyMonBestMoveDamage(u32 battlerAtk, u32 battlerDef, struct Pokemon *attackerMon, struct Pokemon *targetMon);
|
||||
s32 CountUsablePartyMons(u8 battlerId);
|
||||
bool32 IsPartyFullyHealedExceptBattler(u8 battler);
|
||||
bool32 PartyHasMoveSplit(u8 battlerId, u8 split);
|
||||
bool32 SideHasMoveSplit(u8 battlerId, u8 split);
|
||||
s32 CountUsablePartyMons(u32 battlerId);
|
||||
bool32 IsPartyFullyHealedExceptBattler(u32 battler);
|
||||
bool32 PartyHasMoveSplit(u32 battlerId, u32 split);
|
||||
bool32 SideHasMoveSplit(u32 battlerId, u32 split);
|
||||
|
||||
// score increases
|
||||
void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u8 statId, s32 *score);
|
||||
void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score);
|
||||
void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score);
|
||||
void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score);
|
||||
void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score);
|
||||
void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score);
|
||||
void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score);
|
||||
void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score);
|
||||
void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
|
||||
#endif //GUARD_BATTLE_AI_UTIL_H
|
||||
|
@ -172,7 +172,7 @@ u32 GetBattlerWeight(u32 battler);
|
||||
u32 CalcRolloutBasePower(u32 battlerAtk, u32 basePower, u32 rolloutTimer);
|
||||
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 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 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef);
|
||||
uq4_12_t GetTypeModifier(u32 atkType, u32 defType);
|
||||
|
@ -350,14 +350,15 @@ static void SetBattlerAiData(u32 battler, struct AiLogicData *aiData)
|
||||
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;
|
||||
|
||||
// Simulate dmg for both ai controlled mons and for player controlled mons.
|
||||
SaveBattlerData(battlerAtk);
|
||||
moves = GetMovesArray(battlerAtk);
|
||||
weather = AI_GetWeather(aiData);
|
||||
for (battlerDef = 0; battlerDef < battlersCount; battlerDef++)
|
||||
{
|
||||
if (battlerAtk == battlerDef)
|
||||
@ -373,28 +374,29 @@ static void SetBattlerAiMovesData(u32 battlerAtk, u32 battlersCount)
|
||||
if (move != 0
|
||||
&& move != 0xFFFF
|
||||
//&& gBattleMoves[move].power != 0 /* we want to get effectiveness of status moves */
|
||||
&& !(AI_DATA->moveLimitations[battlerAtk] & gBitTable[i])) {
|
||||
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, TRUE);
|
||||
&& !(aiData->moveLimitations[battlerAtk] & gBitTable[i])) {
|
||||
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, TRUE, weather);
|
||||
}
|
||||
|
||||
AI_DATA->simulatedDmg[battlerAtk][battlerDef][i] = dmg;
|
||||
AI_DATA->effectiveness[battlerAtk][battlerDef][i] = effectiveness;
|
||||
aiData->simulatedDmg[battlerAtk][battlerDef][i] = dmg;
|
||||
aiData->effectiveness[battlerAtk][battlerDef][i] = effectiveness;
|
||||
}
|
||||
}
|
||||
SetMoveDamageResult(battlerAtk, moves);
|
||||
}
|
||||
|
||||
void SetAiLogicDataForTurn(void)
|
||||
void SetAiLogicDataForTurn(struct AiLogicData *aiData)
|
||||
{
|
||||
u32 battlerAtk, battlersCount;
|
||||
|
||||
memset(AI_DATA, 0, sizeof(struct AiLogicData));
|
||||
|
||||
memset(aiData, 0, sizeof(struct AiLogicData));
|
||||
if (!(gBattleTypeFlags & BATTLE_TYPE_HAS_AI) && !IsWildMonSmart())
|
||||
return;
|
||||
|
||||
// Set delay timer to count how long it takes for AI to choose action/move
|
||||
gBattleStruct->aiDelayTimer = gMain.vblankCounter1;
|
||||
|
||||
aiData->weatherHasEffect = WEATHER_HAS_EFFECT;
|
||||
// get/assume all battler data and simulate AI damage
|
||||
battlersCount = gBattlersCount;
|
||||
for (battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++)
|
||||
@ -402,8 +404,8 @@ void SetAiLogicDataForTurn(void)
|
||||
if (!IsBattlerAlive(battlerAtk))
|
||||
continue;
|
||||
|
||||
SetBattlerAiData(battlerAtk, AI_DATA);
|
||||
SetBattlerAiMovesData(battlerAtk, battlersCount);
|
||||
SetBattlerAiData(battlerAtk, aiData);
|
||||
SetBattlerAiMovesData(aiData, battlerAtk, battlersCount);
|
||||
}
|
||||
}
|
||||
|
||||
@ -891,7 +893,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s32 score)
|
||||
RETURN_SCORE_MINUS(10);
|
||||
break;
|
||||
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
|
||||
&& IsNonVolatileStatusMoveEffect(moveEffect))
|
||||
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))
|
||||
return 0; // Can't even select heal blocked move
|
||||
// primal weather check
|
||||
if (WEATHER_HAS_EFFECT)
|
||||
if (gBattleWeather && WEATHER_HAS_EFFECT)
|
||||
{
|
||||
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_SYNTHESIS:
|
||||
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;
|
||||
else if (AtMaxHp(battlerAtk))
|
||||
score -= 10;
|
||||
@ -2124,7 +2126,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s32 score)
|
||||
break;
|
||||
case EFFECT_SOLAR_BEAM:
|
||||
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;
|
||||
if (CanTargetFaintAi(battlerDef, battlerAtk)) //Attacker can be knocked out
|
||||
score -= 4;
|
||||
@ -4354,17 +4356,17 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u16 move, s32 score
|
||||
score += 3;
|
||||
break;
|
||||
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])
|
||||
{
|
||||
case ABILITY_SWIFT_SWIM:
|
||||
if (gBattleWeather & B_WEATHER_RAIN)
|
||||
if (AI_GetWeather(AI_DATA) & B_WEATHER_RAIN)
|
||||
score += 3; // Slow 'em down
|
||||
break;
|
||||
case ABILITY_CHLOROPHYLL:
|
||||
case ABILITY_FLOWER_GIFT:
|
||||
if (gBattleWeather & B_WEATHER_SUN)
|
||||
if (AI_GetWeather(AI_DATA) & B_WEATHER_SUN)
|
||||
score += 3; // Slow 'em down
|
||||
break;
|
||||
}
|
||||
@ -4901,7 +4903,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u16 move, s32 score
|
||||
}
|
||||
break;
|
||||
case EFFECT_SHORE_UP:
|
||||
if (AI_WeatherHasEffect() && (gBattleWeather & B_WEATHER_SANDSTORM)
|
||||
if ((AI_GetWeather(AI_DATA) & B_WEATHER_SANDSTORM)
|
||||
&& ShouldRecover(battlerAtk, battlerDef, move, 67))
|
||||
score += 3;
|
||||
else if (ShouldRecover(battlerAtk, battlerDef, move, 50))
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3724,7 +3724,7 @@ static void DoBattleIntro(void)
|
||||
gBattleStruct->switchInAbilitiesCounter = 0;
|
||||
gBattleStruct->switchInItemsCounter = 0;
|
||||
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.
|
||||
gBattleMainFunc = TryDoEventsBeforeFirstTurn;
|
||||
}
|
||||
@ -3857,7 +3857,7 @@ static void TryDoEventsBeforeFirstTurn(void)
|
||||
|
||||
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)
|
||||
{
|
||||
@ -3949,7 +3949,7 @@ void BattleTurnPassed(void)
|
||||
|
||||
*(&gBattleStruct->absentBattlerFlags) = gAbsentBattlerFlags;
|
||||
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;
|
||||
gRandomTurnNumber = Random();
|
||||
|
||||
|
@ -9759,10 +9759,9 @@ static inline uq4_12_t GetOtherModifiers(u32 move, u32 moveType, u32 battlerAtk,
|
||||
} while (0)
|
||||
|
||||
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;
|
||||
u32 weather;
|
||||
u32 userFinalAttack;
|
||||
u32 targetFinalDefense;
|
||||
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))
|
||||
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)
|
||||
gBattleMovePower = fixedBasePower;
|
||||
else
|
||||
@ -9812,16 +9805,24 @@ static inline s32 DoMoveDamageCalc(u32 move, u32 battlerAtk, u32 battlerDef, u32
|
||||
|
||||
#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)
|
||||
{
|
||||
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
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user