mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 03:34:15 +01:00
Greatly reduce AI lag (#3308)
This commit is contained in:
commit
de577f955a
@ -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];
|
||||
@ -286,11 +287,14 @@ struct AiLogicData
|
||||
u16 predictedMoves[MAX_BATTLERS_COUNT];
|
||||
u8 hpPercents[MAX_BATTLERS_COUNT];
|
||||
u16 partnerMove;
|
||||
u16 speedStats[MAX_BATTLERS_COUNT]; // Speed stats for all battles, calculated only once, same way as damages
|
||||
u8 moveDmgResult[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // MOVE_POWER defines for GetMoveDamageResult ; attacker, target, moveIndex
|
||||
s32 simulatedDmg[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // attacker, target, moveIndex
|
||||
u8 effectiveness[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // attacker, target, moveIndex
|
||||
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; // The same as WEATHER_HAS_EFFECT. Stored here, so it's called only once.
|
||||
};
|
||||
|
||||
struct AI_ThinkingStruct
|
||||
@ -298,7 +302,7 @@ struct AI_ThinkingStruct
|
||||
u8 aiState;
|
||||
u8 movesetIndex;
|
||||
u16 moveConsidered;
|
||||
s8 score[MAX_MON_MOVES];
|
||||
s32 score[MAX_MON_MOVES];
|
||||
u32 funcResult;
|
||||
u32 aiFlags;
|
||||
u8 aiAction;
|
||||
@ -640,7 +644,7 @@ struct BattleStruct
|
||||
u16 hpBefore[MAX_BATTLERS_COUNT]; // Hp of battlers before using a move. For Berserk
|
||||
bool8 spriteIgnore0Hp;
|
||||
struct Illusion illusion[MAX_BATTLERS_COUNT];
|
||||
s8 aiFinalScore[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // AI, target, moves to make debugging easier
|
||||
s32 aiFinalScore[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // AI, target, moves to make debugging easier
|
||||
u8 aiMoveOrAction[MAX_BATTLERS_COUNT];
|
||||
u8 aiChosenTarget[MAX_BATTLERS_COUNT];
|
||||
u8 soulheartBattlerId;
|
||||
|
@ -19,15 +19,15 @@
|
||||
return score; \
|
||||
}
|
||||
|
||||
u8 ComputeBattleAiScores(u8 battler);
|
||||
u32 ComputeBattleAiScores(u32 battler);
|
||||
void BattleAI_SetupItems(void);
|
||||
void BattleAI_SetupFlags(void);
|
||||
void BattleAI_SetupAIData(u8 defaultScoreMoves, u32 battler);
|
||||
u8 BattleAI_ChooseMoveOrAction(void);
|
||||
u32 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;
|
||||
|
||||
|
@ -7,184 +7,186 @@
|
||||
|
||||
#define FOE(battler) ((BATTLE_OPPOSITE(battler)) & BIT_SIDE)
|
||||
|
||||
bool32 AI_RandLessThan(u8 val);
|
||||
void RecordLastUsedMoveByTarget(void);
|
||||
#define AI_STRIKES_FIRST(battlerAi, battlerDef, move)((AI_WhoStrikesFirst(battlerAi, battlerDef, move) == AI_IS_FASTER))
|
||||
|
||||
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 RecordAllMoves(u32 battler);
|
||||
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 SaveBattlerData(u8 battlerId);
|
||||
void SetBattlerData(u8 battlerId);
|
||||
void RestoreBattlerData(u8 battlerId);
|
||||
u16 GetAIChosenMove(u8 battlerId);
|
||||
|
||||
bool32 WillAIStrikeFirst(void);
|
||||
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);
|
||||
u32 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);
|
||||
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 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 CanTargetMoveFaintAi(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(u8 battlerAtk, u8 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 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(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move);
|
||||
bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 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 IsRecycleEncouragedItem(u16 item);
|
||||
bool32 ShouldRestoreHpBerry(u8 battlerAtk, u16 item);
|
||||
bool32 IsStatBoostingBerry(u16 item);
|
||||
bool32 CanKnockOffItem(u8 battler, u16 item);
|
||||
bool32 IsAbilityOfRating(u16 ability, s8 rating);
|
||||
s8 GetAbilityRating(u16 ability);
|
||||
u32 AI_GetHoldEffect(u32 battlerId);
|
||||
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, 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(u32 item);
|
||||
bool32 ShouldRestoreHpBerry(u32 battlerAtk, u32 item);
|
||||
bool32 IsStatBoostingBerry(u32 item);
|
||||
bool32 CanKnockOffItem(u32 battler, u32 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 ShouldUseZMove(u8 activeId, u8 targetId, u16 chosenMove);
|
||||
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u32 move);
|
||||
u32 AI_GetBattlerMoveTargetType(u32 battlerId, u32 move);
|
||||
bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u32 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(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 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_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 weather);
|
||||
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);
|
||||
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(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(u8, u8, u8, bool32, u16, u16, u16, u16);
|
||||
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 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);
|
||||
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 IsHealingMoveEffect(u16 effect);
|
||||
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(u32 effect);
|
||||
bool32 HasHealingEffect(u32 battler);
|
||||
bool32 IsTrappingMoveEffect(u16 effect);
|
||||
bool32 HasTrappingMoveEffect(u8 battler);
|
||||
bool32 ShouldFakeOut(u8 battlerAtk, u8 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 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(u8 battlerAtk, u8 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 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 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);
|
||||
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
|
||||
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);
|
||||
#define IS_TARGETING_PARTNER(battlerAtk, battlerDef)((battlerAtk) == (battlerDef ^ BIT_FLANK))
|
||||
u32 GetAllyChosenMove(u32 battlerId);
|
||||
bool32 IsValidDoubleBattle(u32 battlerAtk);
|
||||
bool32 IsTargetingPartner(u32 battlerAtk, u32 battlerDef);
|
||||
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(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, 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
|
||||
|
@ -57,17 +57,19 @@ void SwitchInClearSetData(u32 battler);
|
||||
void FaintClearSetData(u32 battler);
|
||||
void BattleTurnPassed(void);
|
||||
u8 IsRunningFromBattleImpossible(u32 battler);
|
||||
void SwitchPartyOrder(u8 battlerId);
|
||||
void SwitchPartyOrder(u32 battlerId);
|
||||
void SwapTurnOrder(u8 id1, u8 id2);
|
||||
u32 GetBattlerTotalSpeedStat(u8 battlerId);
|
||||
u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect);
|
||||
u32 GetBattlerTotalSpeedStat(u32 battler);
|
||||
s8 GetChosenMovePriority(u32 battlerId);
|
||||
s8 GetMovePriority(u32 battlerId, u16 move);
|
||||
u8 GetWhoStrikesFirst(u8 battlerId1, u8 battlerId2, bool8 ignoreChosenMoves);
|
||||
u32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMoves, u32 ability1, u32 ability2,
|
||||
u32 holdEffectBattler1, u32 holdEffectBattler2, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2);
|
||||
u32 GetWhichBattlerFaster(u32 battler1, u32 battler2, bool32 ignoreChosenMoves);
|
||||
void RunBattleScriptCommands_PopCallbacksStack(void);
|
||||
void RunBattleScriptCommands(void);
|
||||
bool8 TryRunFromBattle(u8 battlerId);
|
||||
void SpecialStatusesClear(void);
|
||||
void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk);
|
||||
void SetTypeBeforeUsingMove(u32 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,9 @@ struct StatFractions
|
||||
u8 divisor;
|
||||
};
|
||||
|
||||
s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbility);
|
||||
s8 GetInverseCritChance(u8 battlerAtk, u8 battlerDef, u32 move);
|
||||
s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility, u32 abilityAtk, u32 abilityDef, u32 holdEffectAtk);
|
||||
s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility);
|
||||
s32 GetCritHitChance(s32 critChanceIndex);
|
||||
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 +29,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);
|
||||
@ -47,6 +48,7 @@ u32 GetHighestStatId(u32 battlerId);
|
||||
bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType);
|
||||
bool32 DoSwitchInAbilitiesItems(u32 battlerId);
|
||||
u8 GetFirstFaintedPartyIndex(u8 battlerId);
|
||||
bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler);
|
||||
|
||||
extern void (* const gBattleScriptingCommandsTable[])(void);
|
||||
extern const u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4];
|
||||
|
@ -102,6 +102,7 @@ bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move);
|
||||
void HandleAction_UseMove(void);
|
||||
void HandleAction_Switch(void);
|
||||
void HandleAction_UseItem(void);
|
||||
bool32 TryRunFromBattle(u32 battler);
|
||||
void HandleAction_Run(void);
|
||||
void HandleAction_WatchesCarefully(void);
|
||||
void HandleAction_SafariZoneBallThrow(void);
|
||||
@ -116,106 +117,106 @@ u8 GetBattlerForBattleScript(u8 caseId);
|
||||
void PressurePPLose(u8 target, u8 attacker, u16 move);
|
||||
void PressurePPLoseOnUsingPerishSong(u8 attacker);
|
||||
void PressurePPLoseOnUsingImprison(u8 attacker);
|
||||
bool32 IsBattlerMarkedForControllerExec(u8 battler);
|
||||
void MarkBattlerForControllerExec(u8 battler);
|
||||
void MarkBattlerReceivedLinkData(u8 battler);
|
||||
void CancelMultiTurnMoves(u8 battler);
|
||||
bool8 WasUnableToUseMove(u8 battler);
|
||||
void PrepareStringBattle(u16 stringId, u8 battler);
|
||||
bool32 IsBattlerMarkedForControllerExec(u32 battler);
|
||||
void MarkBattlerForControllerExec(u32 battler);
|
||||
void MarkBattlerReceivedLinkData(u32 battler);
|
||||
void CancelMultiTurnMoves(u32 battler);
|
||||
bool32 WasUnableToUseMove(u32 battler);
|
||||
void PrepareStringBattle(u16 stringId, u32 battler);
|
||||
void ResetSentPokesToOpponentValue(void);
|
||||
void OpponentSwitchInResetSentPokesToOpponentValue(u8 battler);
|
||||
void UpdateSentPokesToOpponentValue(u8 battler);
|
||||
void OpponentSwitchInResetSentPokesToOpponentValue(u32 battler);
|
||||
void UpdateSentPokesToOpponentValue(u32 battler);
|
||||
void BattleScriptPush(const u8 *bsPtr);
|
||||
void BattleScriptPushCursor(void);
|
||||
void BattleScriptPop(void);
|
||||
u32 TrySetCantSelectMoveBattleScript(u32 battler);
|
||||
u8 CheckMoveLimitations(u8 battler, u8 unusableMoves, u16 check);
|
||||
u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check);
|
||||
bool32 AreAllMovesUnusable(u32 battler);
|
||||
u8 GetImprisonedMovesCount(u8 battler, u16 move);
|
||||
u8 GetImprisonedMovesCount(u32 battler, u16 move);
|
||||
u8 DoFieldEndTurnEffects(void);
|
||||
s32 GetDrainedBigRootHp(u32 battler, s32 hp);
|
||||
u8 DoBattlerEndTurnEffects(void);
|
||||
bool8 HandleWishPerishSongOnTurnEnd(void);
|
||||
bool8 HandleFaintedMonActions(void);
|
||||
bool32 HandleWishPerishSongOnTurnEnd(void);
|
||||
bool32 HandleFaintedMonActions(void);
|
||||
void TryClearRageAndFuryCutter(void);
|
||||
u8 AtkCanceller_UnableToUseMove(u32 moveType);
|
||||
void SetAtkCancellerForCalledMove(void);
|
||||
u8 AtkCanceller_UnableToUseMove2(void);
|
||||
bool8 HasNoMonsToSwitch(u8 battler, u8 r1, u8 r2);
|
||||
bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility);
|
||||
u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 moveArg);
|
||||
bool32 TryPrimalReversion(u8 battler);
|
||||
bool32 HasNoMonsToSwitch(u32 battler, u8 r1, u8 r2);
|
||||
bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility);
|
||||
u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg);
|
||||
bool32 TryPrimalReversion(u32 battler);
|
||||
bool32 IsNeutralizingGasOnField(void);
|
||||
u32 GetBattlerAbility(u8 battler);
|
||||
u32 GetBattlerAbility(u32 battler);
|
||||
u32 IsAbilityOnSide(u32 battler, u32 ability);
|
||||
u32 IsAbilityOnOpposingSide(u32 battler, u32 ability);
|
||||
u32 IsAbilityOnField(u32 ability);
|
||||
u32 IsAbilityOnFieldExcept(u32 battler, u32 ability);
|
||||
u32 IsAbilityPreventingEscape(u32 battler);
|
||||
bool32 IsBattlerProtected(u8 battler, u16 move);
|
||||
bool32 IsBattlerProtected(u32 battler, u32 move);
|
||||
bool32 CanBattlerEscape(u32 battler); // no ability check
|
||||
void BattleScriptExecute(const u8 *BS_ptr);
|
||||
void BattleScriptPushCursorAndCallback(const u8 *BS_ptr);
|
||||
u8 ItemBattleEffects(u8 caseID, u8 battler, bool8 moveTurn);
|
||||
void ClearFuryCutterDestinyBondGrudge(u8 battler);
|
||||
u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn);
|
||||
void ClearFuryCutterDestinyBondGrudge(u32 battler);
|
||||
void HandleAction_RunBattleScript(void);
|
||||
u32 SetRandomTarget(u32 battler);
|
||||
u32 GetMoveTarget(u16 move, u8 setTarget);
|
||||
u8 IsMonDisobedient(void);
|
||||
u32 GetBattlerHoldEffect(u8 battler, bool32 checkNegating);
|
||||
u32 GetBattlerHoldEffectParam(u8 battler);
|
||||
bool32 IsMoveMakingContact(u16 move, u8 battlerAtk);
|
||||
bool32 IsBattlerGrounded(u8 battler);
|
||||
bool32 IsBattlerAlive(u8 battler);
|
||||
u8 GetBattleMonMoveSlot(struct BattlePokemon *battleMon, u16 move);
|
||||
u32 GetBattlerWeight(u8 battler);
|
||||
u32 GetBattlerHoldEffect(u32 battler, bool32 checkNegating);
|
||||
u32 GetBattlerHoldEffectParam(u32 battler);
|
||||
bool32 IsMoveMakingContact(u32 move, u32 battlerAtk);
|
||||
bool32 IsBattlerGrounded(u32 battler);
|
||||
bool32 IsBattlerAlive(u32 battler);
|
||||
u32 GetMoveSlot(u16 *moves, u32 move);
|
||||
u32 GetBattlerWeight(u32 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 CalculateMoveDamageVars(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, uq4_12_t typeEffectivenessModifier,
|
||||
u32 weather, bool32 isCrit, u32 holdEffectAtk, u32 holdEffectDef, u32 abilityAtk, u32 abilityDef);
|
||||
uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, u32 defAbility, bool32 recordAbilities);
|
||||
uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef);
|
||||
uq4_12_t GetTypeModifier(u8 atkType, u8 defType);
|
||||
s32 GetStealthHazardDamage(u8 hazardType, u8 battler);
|
||||
uq4_12_t GetTypeModifier(u32 atkType, u32 defType);
|
||||
s32 GetStealthHazardDamage(u8 hazardType, u32 battler);
|
||||
s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp);
|
||||
bool32 CanMegaEvolve(u8 battler);
|
||||
bool32 CanUltraBurst(u8 battler);
|
||||
bool32 IsBattlerMegaEvolved(u8 battler);
|
||||
bool32 IsBattlerPrimalReverted(u8 battler);
|
||||
bool32 IsBattlerUltraBursted(u8 battler);
|
||||
u16 GetBattleFormChangeTargetSpecies(u8 battler, u16 method);
|
||||
bool32 TryBattleFormChange(u8 battler, u16 method);
|
||||
bool32 CanMegaEvolve(u32 battler);
|
||||
bool32 CanUltraBurst(u32 battler);
|
||||
bool32 IsBattlerMegaEvolved(u32 battler);
|
||||
bool32 IsBattlerPrimalReverted(u32 battler);
|
||||
bool32 IsBattlerUltraBursted(u32 battler);
|
||||
u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method);
|
||||
bool32 TryBattleFormChange(u32 battler, u16 method);
|
||||
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
|
||||
bool32 CanBattlerGetOrLoseItem(u8 battler, u16 itemId);
|
||||
bool32 CanBattlerGetOrLoseItem(u32 battler, u16 itemId);
|
||||
u32 GetIllusionMonSpecies(u32 battler);
|
||||
struct Pokemon *GetIllusionMonPtr(u32 battler);
|
||||
void ClearIllusionMon(u32 battler);
|
||||
bool32 SetIllusionMon(struct Pokemon *mon, u32 battler);
|
||||
bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battler);
|
||||
bool32 ShouldGetStatBadgeBoost(u16 flagId, u32 battler);
|
||||
u8 GetBattleMoveSplit(u32 moveId);
|
||||
bool32 CanFling(u32 battler);
|
||||
bool32 IsTelekinesisBannedSpecies(u16 species);
|
||||
bool32 IsHealBlockPreventingMove(u32 battler, u32 move);
|
||||
bool32 HasEnoughHpToEatBerry(u32 battler, u32 hpFraction, u32 itemId);
|
||||
bool32 IsPartnerMonFromSameTrainer(u8 battler);
|
||||
u8 GetSplitBasedOnStats(u8 battler);
|
||||
bool32 TestSheerForceFlag(u8 battler, u16 move);
|
||||
bool32 IsPartnerMonFromSameTrainer(u32 battler);
|
||||
u8 GetSplitBasedOnStats(u32 battler);
|
||||
bool32 TestSheerForceFlag(u32 battler, u16 move);
|
||||
void TryRestoreHeldItems(void);
|
||||
bool32 CanStealItem(u8 battlerStealing, u8 battlerItem, u16 item);
|
||||
void TrySaveExchangedItem(u8 battler, u16 stolenItem);
|
||||
bool32 IsPartnerMonFromSameTrainer(u8 battler);
|
||||
u8 TryHandleSeed(u8 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 execute);
|
||||
bool32 IsBattlerAffectedByHazards(u8 battler, bool32 toxicSpikes);
|
||||
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);
|
||||
u16 GetUsedHeldItem(u8 battler);
|
||||
bool32 IsBattlerWeatherAffected(u8 battler, u32 weatherFlags);
|
||||
u32 GetBattlerMoveTargetType(u8 battler, u16 move);
|
||||
bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move);
|
||||
bool8 IsMoveAffectedByParentalBond(u16 move, u8 battler);
|
||||
bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item);
|
||||
void TrySaveExchangedItem(u32 battler, u16 stolenItem);
|
||||
bool32 IsPartnerMonFromSameTrainer(u32 battler);
|
||||
u8 TryHandleSeed(u32 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 execute);
|
||||
bool32 IsBattlerAffectedByHazards(u32 battler, bool32 toxicSpikes);
|
||||
void SortBattlersBySpeed(u8 *battlers, bool32 slowToFast);
|
||||
bool32 CompareStat(u32 battler, u8 statId, u8 cmpTo, u8 cmpKind);
|
||||
bool32 TryRoomService(u32 battler);
|
||||
void BufferStatChange(u32 battler, u8 statId, u8 stringId);
|
||||
bool32 BlocksPrankster(u16 move, u32 battlerPrankster, u32 battlerDef, bool32 checkTarget);
|
||||
u16 GetUsedHeldItem(u32 battler);
|
||||
bool32 IsBattlerWeatherAffected(u32 battler, u32 weatherFlags);
|
||||
u32 GetBattlerMoveTargetType(u32 battler, u32 move);
|
||||
bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, u16 move);
|
||||
void CopyMonLevelAndBaseStatsToBattleMon(u32 battler, struct Pokemon *mon);
|
||||
void CopyMonAbilityAndTypesToBattleMon(u32 battler, struct Pokemon *mon);
|
||||
void RecalcBattlerStats(u32 battler, struct Pokemon *mon);
|
||||
@ -231,21 +232,21 @@ bool32 IsGastroAcidBannedAbility(u16 ability);
|
||||
bool32 IsEntrainmentBannedAbilityAttacker(u16 ability);
|
||||
bool32 IsEntrainmentTargetOrSimpleBeamBannedAbility(u16 ability);
|
||||
|
||||
bool32 CanSleep(u8 battler);
|
||||
bool32 CanBePoisoned(u8 battlerAttacker, u8 battlerTarget);
|
||||
bool32 CanBeBurned(u8 battler);
|
||||
bool32 CanBeParalyzed(u8 battler);
|
||||
bool32 CanBeFrozen(u8 battler);
|
||||
bool32 CanGetFrostbite(u8 battler);
|
||||
bool32 CanBeConfused(u8 battler);
|
||||
bool32 IsBattlerTerrainAffected(u8 battler, u32 terrainFlag);
|
||||
u32 GetBattlerFriendshipScore(u8 battler);
|
||||
u32 CountBattlerStatIncreases(u8 battler, bool32 countEvasionAcc);
|
||||
bool32 CanSleep(u32 battler);
|
||||
bool32 CanBePoisoned(u32 battlerAttacker, u32 battlerTarget);
|
||||
bool32 CanBeBurned(u32 battler);
|
||||
bool32 CanBeParalyzed(u32 battler);
|
||||
bool32 CanBeFrozen(u32 battler);
|
||||
bool32 CanGetFrostbite(u32 battler);
|
||||
bool32 CanBeConfused(u32 battler);
|
||||
bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag);
|
||||
u32 GetBattlerFriendshipScore(u32 battler);
|
||||
u32 CountBattlerStatIncreases(u32 battler, bool32 countEvasionAcc);
|
||||
bool32 IsMyceliumMightOnField(void);
|
||||
bool8 ChangeTypeBasedOnTerrain(u8 battler);
|
||||
void RemoveConfusionStatus(u8 battler);
|
||||
u8 GetBattlerGender(u8 battler);
|
||||
bool8 AreBattlersOfOppositeGender(u8 battler1, u8 battler2);
|
||||
u32 CalcSecondaryEffectChance(u8 battler, u8 secondaryEffectChance);
|
||||
bool32 ChangeTypeBasedOnTerrain(u32 battler);
|
||||
void RemoveConfusionStatus(u32 battler);
|
||||
u8 GetBattlerGender(u32 battler);
|
||||
bool32 AreBattlersOfOppositeGender(u32 battler1, u32 battler2);
|
||||
u32 CalcSecondaryEffectChance(u32 battler, u8 secondaryEffectChance);
|
||||
|
||||
#endif // GUARD_BATTLE_UTIL_H
|
||||
|
@ -63,8 +63,8 @@ bool8 AddPyramidBagItem(u16 itemId, u16 count);
|
||||
bool8 RemovePyramidBagItem(u16 itemId, u16 count);
|
||||
const u8 *ItemId_GetName(u16 itemId);
|
||||
u16 ItemId_GetPrice(u16 itemId);
|
||||
u8 ItemId_GetHoldEffect(u16 itemId);
|
||||
u8 ItemId_GetHoldEffectParam(u16 itemId);
|
||||
u32 ItemId_GetHoldEffect(u32 itemId);
|
||||
u32 ItemId_GetHoldEffectParam(u32 itemId);
|
||||
const u8 *ItemId_GetDescription(u16 itemId);
|
||||
u8 ItemId_GetImportance(u16 itemId);
|
||||
u8 ItemId_GetPocket(u16 itemId);
|
||||
@ -72,7 +72,7 @@ u8 ItemId_GetType(u16 itemId);
|
||||
ItemUseFunc ItemId_GetFieldFunc(u16 itemId);
|
||||
u8 ItemId_GetBattleUsage(u16 itemId);
|
||||
u8 ItemId_GetSecondaryId(u16 itemId);
|
||||
u8 ItemId_GetFlingPower(u16 itemId);
|
||||
u32 ItemId_GetFlingPower(u32 itemId);
|
||||
u32 GetItemStatus1Mask(u16 itemId);
|
||||
u32 GetItemStatus2Mask(u16 itemId);
|
||||
|
||||
|
1397
src/battle_ai_main.c
1397
src/battle_ai_main.c
File diff suppressed because it is too large
Load Diff
@ -400,7 +400,7 @@ static bool8 ShouldSwitchIfGameStatePrompt(u32 battler)
|
||||
&& AnyStatIsRaised(battler))
|
||||
switchMon = FALSE;
|
||||
if (AiExpectsToFaintPlayer(battler)
|
||||
&& !WillAIStrikeFirst()
|
||||
&& !AI_STRIKES_FIRST(battler, opposingBattler, 0)
|
||||
&& !AI_OpponentCanFaintAiWithMod(battler, 0))
|
||||
switchMon = FALSE;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -750,7 +750,7 @@ static void SetAllPlayersBerryData(void)
|
||||
{
|
||||
s32 numPlayers;
|
||||
struct BattleEnigmaBerry *src;
|
||||
u8 battler;
|
||||
u32 battler;
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
|
||||
{
|
||||
@ -2267,7 +2267,7 @@ static void EndLinkBattleInSteps(void)
|
||||
case 2:
|
||||
if (!gPaletteFade.active)
|
||||
{
|
||||
u8 battlerCount;
|
||||
u32 battlerCount;
|
||||
|
||||
gMain.anyLinkBattlerHasFrontierPass = RecordedBattle_GetFrontierPassFlag();
|
||||
|
||||
@ -3723,7 +3723,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;
|
||||
}
|
||||
@ -3770,7 +3770,7 @@ static void TryDoEventsBeforeFirstTurn(void)
|
||||
{
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
{
|
||||
if (GetWhoStrikesFirst(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], TRUE) != 0)
|
||||
if (GetWhichBattlerFaster(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], TRUE) != 0)
|
||||
SwapTurnOrder(i, j);
|
||||
}
|
||||
}
|
||||
@ -3856,7 +3856,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)
|
||||
{
|
||||
@ -3948,7 +3948,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();
|
||||
|
||||
@ -4020,11 +4020,10 @@ u8 IsRunningFromBattleImpossible(u32 battler)
|
||||
return BATTLE_RUN_SUCCESS;
|
||||
}
|
||||
|
||||
void SwitchPartyOrder(u8 battler)
|
||||
void SwitchPartyOrder(u32 battler)
|
||||
{
|
||||
s32 i;
|
||||
u8 partyId1;
|
||||
u8 partyId2;
|
||||
u32 partyId1, partyId2;
|
||||
|
||||
for (i = 0; i < (int)ARRAY_COUNT(gBattlePartyCurrentOrder); i++)
|
||||
gBattlePartyCurrentOrder[i] = *(battler * 3 + i + (u8 *)(gBattleStruct->battlerPartyOrders));
|
||||
@ -4070,7 +4069,7 @@ static void HandleTurnActionSelectionState(void)
|
||||
gBattleCommunication[ACTIONS_CONFIRMED_COUNT] = 0;
|
||||
for (battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
u8 position = GetBattlerPosition(battler);
|
||||
u32 position = GetBattlerPosition(battler);
|
||||
switch (gBattleCommunication[battler])
|
||||
{
|
||||
case STATE_TURN_START_RECORD: // Recorded battle related action on start of every turn.
|
||||
@ -4083,7 +4082,7 @@ static void HandleTurnActionSelectionState(void)
|
||||
{
|
||||
gBattleStruct->aiMoveOrAction[battler] = ComputeBattleAiScores(battler);
|
||||
}
|
||||
break;
|
||||
// fallthrough
|
||||
case STATE_BEFORE_ACTION_CHOSEN: // Choose an action.
|
||||
*(gBattleStruct->monToSwitchIntoId + battler) = PARTY_SIZE;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_MULTI
|
||||
@ -4597,11 +4596,10 @@ void SwapTurnOrder(u8 id1, u8 id2)
|
||||
SWAP(gBattlerByTurnOrder[id1], gBattlerByTurnOrder[id2], temp);
|
||||
}
|
||||
|
||||
u32 GetBattlerTotalSpeedStat(u8 battler)
|
||||
// For AI, so it doesn't 'cheat' by knowing player's ability
|
||||
u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect)
|
||||
{
|
||||
u32 speed = gBattleMons[battler].speed;
|
||||
u32 ability = GetBattlerAbility(battler);
|
||||
u32 holdEffect = GetBattlerHoldEffect(battler, TRUE);
|
||||
u32 highestStat = GetHighestStatId(battler);
|
||||
|
||||
// weather abilities
|
||||
@ -4668,6 +4666,13 @@ u32 GetBattlerTotalSpeedStat(u8 battler)
|
||||
return speed;
|
||||
}
|
||||
|
||||
u32 GetBattlerTotalSpeedStat(u32 battler)
|
||||
{
|
||||
u32 ability = GetBattlerAbility(battler);
|
||||
u32 holdEffect = GetBattlerHoldEffect(battler, TRUE);
|
||||
return GetBattlerTotalSpeedStatArgs(battler, ability, holdEffect);
|
||||
}
|
||||
|
||||
s8 GetChosenMovePriority(u32 battler)
|
||||
{
|
||||
u16 move;
|
||||
@ -4732,17 +4737,13 @@ s8 GetMovePriority(u32 battler, u16 move)
|
||||
return priority;
|
||||
}
|
||||
|
||||
u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
|
||||
// Function for AI with variables provided as arguments to speed the computation time
|
||||
u32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMoves, u32 ability1, u32 ability2,
|
||||
u32 holdEffectBattler1, u32 holdEffectBattler2, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2)
|
||||
{
|
||||
u8 strikesFirst = 0;
|
||||
u32 speedBattler1 = 0, speedBattler2 = 0;
|
||||
u32 holdEffectBattler1 = 0, holdEffectBattler2 = 0;
|
||||
s8 priority1 = 0, priority2 = 0;
|
||||
u16 ability1 = GetBattlerAbility(battler1), ability2 = GetBattlerAbility(battler2);
|
||||
u32 strikesFirst = 0;
|
||||
|
||||
// Battler 1
|
||||
speedBattler1 = GetBattlerTotalSpeedStat(battler1);
|
||||
holdEffectBattler1 = GetBattlerHoldEffect(battler1, TRUE);
|
||||
// Quick Draw
|
||||
if (!ignoreChosenMoves && ability1 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && Random() % 100 < 30)
|
||||
gProtectStructs[battler1].quickDraw = TRUE;
|
||||
@ -4753,8 +4754,6 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
|
||||
gProtectStructs[battler1].usedCustapBerry = TRUE;
|
||||
|
||||
// Battler 2
|
||||
speedBattler2 = GetBattlerTotalSpeedStat(battler2);
|
||||
holdEffectBattler2 = GetBattlerHoldEffect(battler2, TRUE);
|
||||
// Quick Draw
|
||||
if (!ignoreChosenMoves && ability2 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && Random() % 100 < 30)
|
||||
gProtectStructs[battler2].quickDraw = TRUE;
|
||||
@ -4764,14 +4763,6 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
|
||||
|| (holdEffectBattler2 == HOLD_EFFECT_CUSTAP_BERRY && HasEnoughHpToEatBerry(battler2, 4, gBattleMons[battler2].item))))
|
||||
gProtectStructs[battler2].usedCustapBerry = TRUE;
|
||||
|
||||
if (!ignoreChosenMoves)
|
||||
{
|
||||
if (gChosenActionByBattler[battler1] == B_ACTION_USE_MOVE)
|
||||
priority1 = GetChosenMovePriority(battler1);
|
||||
if (gChosenActionByBattler[battler2] == B_ACTION_USE_MOVE)
|
||||
priority2 = GetChosenMovePriority(battler2);
|
||||
}
|
||||
|
||||
if (priority1 == priority2)
|
||||
{
|
||||
// QUICK CLAW / CUSTAP - always first
|
||||
@ -4834,6 +4825,28 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
|
||||
return strikesFirst;
|
||||
}
|
||||
|
||||
u32 GetWhichBattlerFaster(u32 battler1, u32 battler2, bool32 ignoreChosenMoves)
|
||||
{
|
||||
s32 priority1 = 0, priority2 = 0;
|
||||
u32 ability1 = GetBattlerAbility(battler1);
|
||||
u32 speedBattler1 = GetBattlerTotalSpeedStat(battler1);
|
||||
u32 holdEffectBattler1 = GetBattlerHoldEffect(battler1, TRUE);
|
||||
u32 speedBattler2 = GetBattlerTotalSpeedStat(battler2);
|
||||
u32 holdEffectBattler2 = GetBattlerHoldEffect(battler2, TRUE);
|
||||
u32 ability2 = GetBattlerAbility(battler2);
|
||||
|
||||
if (!ignoreChosenMoves)
|
||||
{
|
||||
if (gChosenActionByBattler[battler1] == B_ACTION_USE_MOVE)
|
||||
priority1 = GetChosenMovePriority(battler1);
|
||||
if (gChosenActionByBattler[battler2] == B_ACTION_USE_MOVE)
|
||||
priority2 = GetChosenMovePriority(battler2);
|
||||
}
|
||||
|
||||
return GetWhichBattlerFasterArgs(battler1, battler2, ignoreChosenMoves, ability1, ability2,
|
||||
holdEffectBattler1, holdEffectBattler2, speedBattler1, speedBattler2, priority1, priority2);
|
||||
}
|
||||
|
||||
static void SetActionsAndBattlersTurnOrder(void)
|
||||
{
|
||||
s32 turnOrderId = 0;
|
||||
@ -4927,7 +4940,7 @@ static void SetActionsAndBattlersTurnOrder(void)
|
||||
&& gActionsByTurnOrder[i] != B_ACTION_THROW_BALL
|
||||
&& gActionsByTurnOrder[j] != B_ACTION_THROW_BALL)
|
||||
{
|
||||
if (GetWhoStrikesFirst(battler1, battler2, FALSE))
|
||||
if (GetWhichBattlerFaster(battler1, battler2, FALSE))
|
||||
SwapTurnOrder(i, j);
|
||||
}
|
||||
}
|
||||
@ -5091,7 +5104,7 @@ static void TryChangeTurnOrder(void)
|
||||
if (gActionsByTurnOrder[i] == B_ACTION_USE_MOVE
|
||||
&& gActionsByTurnOrder[j] == B_ACTION_USE_MOVE)
|
||||
{
|
||||
if (GetWhoStrikesFirst(battler1, battler2, FALSE))
|
||||
if (GetWhichBattlerFaster(battler1, battler2, FALSE))
|
||||
SwapTurnOrder(i, j);
|
||||
}
|
||||
}
|
||||
@ -5574,7 +5587,7 @@ void RunBattleScriptCommands(void)
|
||||
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
|
||||
}
|
||||
|
||||
void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
|
||||
void SetTypeBeforeUsingMove(u32 move, u32 battlerAtk)
|
||||
{
|
||||
u32 moveType, ateType, attackerAbility;
|
||||
u16 holdEffect = GetBattlerHoldEffect(battlerAtk, TRUE);
|
||||
@ -5713,8 +5726,8 @@ void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
|
||||
// var8001 - var8007: stat changes
|
||||
void SetTotemBoost(void)
|
||||
{
|
||||
u8 battler = gSpecialVar_0x8000;
|
||||
u8 i;
|
||||
u32 battler = gSpecialVar_0x8000;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < (NUM_BATTLE_STATS - 1); i++)
|
||||
{
|
||||
|
@ -1753,10 +1753,11 @@ static void Cmd_accuracycheck(void)
|
||||
{
|
||||
CMD_ARGS(const u8 *failInstr, u16 move);
|
||||
|
||||
u16 type, move = cmd->move;
|
||||
u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, move);
|
||||
u16 gBattlerAttackerAbility = GetBattlerAbility(gBattlerAttacker);
|
||||
u8 gBattlerAttackerHoldEffect = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
|
||||
u32 type, move = cmd->move;
|
||||
u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, move);
|
||||
u32 abilityAtk = GetBattlerAbility(gBattlerAttacker);
|
||||
u32 abilityDef = GetBattlerAbility(gBattlerTarget);
|
||||
u32 holdEffectAtk = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
|
||||
|
||||
if (move == ACC_CURR_MOVE)
|
||||
move = gCurrentMove;
|
||||
@ -1772,7 +1773,7 @@ static void Cmd_accuracycheck(void)
|
||||
}
|
||||
else if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_2ND_HIT
|
||||
|| (gSpecialStatuses[gBattlerAttacker].multiHitOn
|
||||
&& (gBattlerAttackerAbility == ABILITY_SKILL_LINK || gBattlerAttackerHoldEffect == HOLD_EFFECT_LOADED_DICE
|
||||
&& (abilityAtk == ABILITY_SKILL_LINK || holdEffectAtk == HOLD_EFFECT_LOADED_DICE
|
||||
|| !(gBattleMoves[move].effect == EFFECT_TRIPLE_KICK || gBattleMoves[move].effect == EFFECT_POPULATION_BOMB))))
|
||||
{
|
||||
// No acc checks for second hit of Parental Bond or multi hit moves, except Triple Kick/Triple Axel/Population Bomb
|
||||
@ -1792,16 +1793,16 @@ static void Cmd_accuracycheck(void)
|
||||
gBattlerAttacker,
|
||||
gBattlerTarget,
|
||||
move,
|
||||
gBattlerAttackerAbility,
|
||||
GetBattlerAbility(gBattlerTarget),
|
||||
gBattlerAttackerHoldEffect,
|
||||
abilityAtk,
|
||||
abilityDef,
|
||||
holdEffectAtk,
|
||||
GetBattlerHoldEffect(gBattlerTarget, TRUE)
|
||||
);
|
||||
|
||||
if (!RandomPercentage(RNG_ACCURACY, accuracy))
|
||||
{
|
||||
gMoveResultFlags |= MOVE_RESULT_MISSED;
|
||||
if (gBattlerAttackerHoldEffect == HOLD_EFFECT_BLUNDER_POLICY)
|
||||
if (holdEffectAtk == HOLD_EFFECT_BLUNDER_POLICY)
|
||||
gBattleStruct->blunderPolicy = TRUE; // Only activates from missing through acc/evasion checks
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE &&
|
||||
@ -1811,7 +1812,7 @@ static void Cmd_accuracycheck(void)
|
||||
gBattleCommunication[MISS_TYPE] = B_MSG_MISSED;
|
||||
|
||||
if (gBattleMoves[move].power)
|
||||
CalcTypeEffectivenessMultiplier(move, type, gBattlerAttacker, gBattlerTarget, TRUE);
|
||||
CalcTypeEffectivenessMultiplier(move, type, gBattlerAttacker, gBattlerTarget, abilityDef, TRUE);
|
||||
}
|
||||
JumpIfMoveFailed(7, move);
|
||||
}
|
||||
@ -1908,24 +1909,15 @@ 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 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility, u32 abilityAtk, u32 abilityDef, u32 holdEffectAtk)
|
||||
{
|
||||
s32 critChance = 0;
|
||||
u32 abilityAtk = GetBattlerAbility(gBattlerAttacker);
|
||||
u32 abilityDef = GetBattlerAbility(gBattlerTarget);
|
||||
u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
|
||||
|
||||
if (gSideStatuses[battlerDef] & SIDE_STATUS_LUCKY_CHANT
|
||||
|| gStatuses3[gBattlerAttacker] & STATUS3_CANT_SCORE_A_CRIT)
|
||||
|| gStatuses3[battlerAtk] & STATUS3_CANT_SCORE_A_CRIT)
|
||||
{
|
||||
critChance = -1;
|
||||
}
|
||||
else if (abilityDef == ABILITY_BATTLE_ARMOR || abilityDef == ABILITY_SHELL_ARMOR)
|
||||
{
|
||||
if (recordAbility)
|
||||
RecordAbilityBattle(battlerDef, abilityDef);
|
||||
critChance = -1;
|
||||
}
|
||||
else if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS
|
||||
|| gBattleMoves[move].effect == EFFECT_ALWAYS_CRIT
|
||||
|| (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)
|
||||
@ -1935,28 +1927,42 @@ s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbi
|
||||
}
|
||||
else
|
||||
{
|
||||
critChance = 2 * ((gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY) != 0)
|
||||
critChance = 2 * ((gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY) != 0)
|
||||
+ (gBattleMoves[gCurrentMove].highCritRatio)
|
||||
+ (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS)
|
||||
+ 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBattlerAttacker].species == SPECIES_CHANSEY)
|
||||
+ 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[battlerAtk].species == SPECIES_CHANSEY)
|
||||
+ 2 * BENEFITS_FROM_LEEK(battlerAtk, holdEffectAtk)
|
||||
#if B_AFFECTION_MECHANICS == TRUE
|
||||
+ 2 * (GetBattlerFriendshipScore(gBattlerAttacker) >= FRIENDSHIP_200_TO_254)
|
||||
+ 2 * (GetBattlerFriendshipScore(battlerAtk) >= FRIENDSHIP_200_TO_254)
|
||||
#endif
|
||||
+ (abilityAtk == ABILITY_SUPER_LUCK);
|
||||
|
||||
if (abilityDef == ABILITY_BATTLE_ARMOR || abilityDef == ABILITY_SHELL_ARMOR)
|
||||
{
|
||||
if (recordAbility && critChance >= 2) // Record ability only if move had at least +1 chance to get a crit.
|
||||
RecordAbilityBattle(battlerDef, abilityDef);
|
||||
critChance = -1;
|
||||
}
|
||||
|
||||
if (critChance >= ARRAY_COUNT(sCriticalHitChance))
|
||||
critChance = ARRAY_COUNT(sCriticalHitChance) - 1;
|
||||
}
|
||||
|
||||
return critChance;
|
||||
}
|
||||
|
||||
s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility)
|
||||
{
|
||||
u32 abilityAtk = GetBattlerAbility(gBattlerAttacker);
|
||||
u32 abilityDef = GetBattlerAbility(gBattlerTarget);
|
||||
u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
|
||||
return CalcCritChanceStageArgs(battlerAtk, battlerDef, move, recordAbility, abilityAtk, abilityDef, holdEffectAtk);
|
||||
}
|
||||
#undef BENEFITS_FROM_LEEK
|
||||
|
||||
s8 GetInverseCritChance(u8 battlerAtk, u8 battlerDef, u32 move)
|
||||
s32 GetCritHitChance(s32 critChanceIndex)
|
||||
{
|
||||
s32 critChanceIndex = CalcCritChanceStage(battlerAtk, battlerDef, move, FALSE);
|
||||
if(critChanceIndex < 0)
|
||||
if (critChanceIndex < 0)
|
||||
return -1;
|
||||
else
|
||||
return sCriticalHitChance[critChanceIndex];
|
||||
@ -2006,7 +2012,7 @@ static void Cmd_typecalc(void)
|
||||
u8 moveType;
|
||||
|
||||
GET_MOVE_TYPE(gCurrentMove, moveType);
|
||||
CalcTypeEffectivenessMultiplier(gCurrentMove, moveType, gBattlerAttacker, gBattlerTarget, TRUE);
|
||||
CalcTypeEffectivenessMultiplier(gCurrentMove, moveType, gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget), TRUE);
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
@ -5679,6 +5685,7 @@ static void Cmd_moveend(void)
|
||||
if (!gSpecialStatuses[gBattlerAttacker].dancerUsedMove)
|
||||
{
|
||||
gLastMoves[gBattlerAttacker] = gChosenMove;
|
||||
RecordKnownMove(gBattlerAttacker, gChosenMove);
|
||||
gLastResultingMoves[gBattlerAttacker] = gCurrentMove;
|
||||
}
|
||||
}
|
||||
@ -8197,7 +8204,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++)
|
||||
@ -14703,7 +14710,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;
|
||||
@ -14719,7 +14726,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
|
||||
@ -15781,7 +15788,7 @@ static const u16 sParentalBondBannedEffects[] =
|
||||
EFFECT_UPROAR,
|
||||
};
|
||||
|
||||
bool8 IsMoveAffectedByParentalBond(u16 move, u8 battler)
|
||||
bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler)
|
||||
{
|
||||
if (move != MOVE_NONE && move != MOVE_STRUGGLE
|
||||
&& gBattleMoves[move].split != SPLIT_STATUS
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -884,12 +884,12 @@ u16 ItemId_GetPrice(u16 itemId)
|
||||
return gItems[SanitizeItemId(itemId)].price;
|
||||
}
|
||||
|
||||
u8 ItemId_GetHoldEffect(u16 itemId)
|
||||
u32 ItemId_GetHoldEffect(u32 itemId)
|
||||
{
|
||||
return gItems[SanitizeItemId(itemId)].holdEffect;
|
||||
}
|
||||
|
||||
u8 ItemId_GetHoldEffectParam(u16 itemId)
|
||||
u32 ItemId_GetHoldEffectParam(u32 itemId)
|
||||
{
|
||||
return gItems[SanitizeItemId(itemId)].holdEffectParam;
|
||||
}
|
||||
@ -956,7 +956,7 @@ u8 ItemId_GetSecondaryId(u16 itemId)
|
||||
return gItems[SanitizeItemId(itemId)].secondaryId;
|
||||
}
|
||||
|
||||
u8 ItemId_GetFlingPower(u16 itemId)
|
||||
u32 ItemId_GetFlingPower(u32 itemId)
|
||||
{
|
||||
return gItems[SanitizeItemId(itemId)].flingPower;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user