diff --git a/include/battle.h b/include/battle.h index eb878b2a5..173c16c76 100644 --- a/include/battle.h +++ b/include/battle.h @@ -301,7 +301,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; @@ -639,7 +639,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; diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index ecd3c43cc..f97569c97 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -109,7 +109,7 @@ 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, s16 *score); +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); @@ -178,12 +178,12 @@ bool32 PartyHasMoveSplit(u8 battlerId, u8 split); bool32 SideHasMoveSplit(u8 battlerId, u8 split); // score increases -void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u8 statId, s16 *score); -void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score); -void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score); -void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score); -void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score); -void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score); -void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score); +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); #endif //GUARD_BATTLE_AI_UTIL_H diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index 9d24b457d..a7bfdf8c1 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -47,6 +47,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]; diff --git a/include/battle_util.h b/include/battle_util.h index 678585e1d..016499362 100644 --- a/include/battle_util.h +++ b/include/battle_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 CalculateMoveDamageAndEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, uq4_12_t *typeEffectivenessModifier); +s32 CalculateMoveDamageWithEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, uq4_12_t typeEffectivenessModifier, bool32 isCrit); 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); @@ -215,7 +215,6 @@ u16 GetUsedHeldItem(u32 battler); bool32 IsBattlerWeatherAffected(u32 battler, u32 weatherFlags); u32 GetBattlerMoveTargetType(u32 battler, u32 move); bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, u16 move); -bool32 IsMoveAffectedByParentalBond(u16 move, u32 battler); void CopyMonLevelAndBaseStatsToBattleMon(u32 battler, struct Pokemon *mon); void CopyMonAbilityAndTypesToBattleMon(u32 battler, struct Pokemon *mon); void RecalcBattlerStats(u32 battler, struct Pokemon *mon); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 810e2ffff..3e811e334 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -39,7 +39,7 @@ enum static u8 ChooseMoveOrAction_Singles(void); static u8 ChooseMoveOrAction_Doubles(void); -static void BattleAI_DoAIProcessing(void); +static void BattleAI_DoAIProcessing(struct AI_ThinkingStruct *aiThink, u32 battler); static bool32 IsPinchBerryItemEffect(u16 holdEffect); // ewram @@ -47,20 +47,20 @@ EWRAM_DATA const u8 *gAIScriptPtr = NULL; // Still used in contests EWRAM_DATA u8 sBattler_AI = 0; // const rom data -static s16 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); -static s16 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); -static s16 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); -static s16 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); -static s16 AI_Risky(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); -static s16 AI_PreferStrongestMove(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); -static s16 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); -static s16 AI_HPAware(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); -static s16 AI_Roaming(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); -static s16 AI_Safari(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); -static s16 AI_FirstBattle(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); -static s16 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u16 move, s16 score); +static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); +static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); +static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); +static s32 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); +static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); +static s32 AI_PreferStrongestMove(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); +static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); +static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); +static s32 AI_Roaming(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); +static s32 AI_Safari(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); +static s32 AI_FirstBattle(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); +static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u16 move, s32 score); -static s16 (*const sBattleAiFuncTable[])(u32, u32, u16, s16) = +static s32 (*const sBattleAiFuncTable[])(u32, u32, u16, s32) = { [0] = AI_CheckBadMove, // AI_FLAG_CHECK_BAD_MOVE [1] = AI_TryToFaint, // AI_FLAG_TRY_TO_FAINT @@ -482,7 +482,7 @@ static u8 ChooseMoveOrAction_Singles(void) if (flags & 1) { AI_THINKING_STRUCT->aiState = AIState_SettingUp; - BattleAI_DoAIProcessing(); + BattleAI_DoAIProcessing(AI_THINKING_STRUCT, sBattler_AI); } flags >>= 1; AI_THINKING_STRUCT->aiLogicId++; @@ -566,7 +566,7 @@ static u8 ChooseMoveOrAction_Doubles(void) if (flags & 1) { AI_THINKING_STRUCT->aiState = AIState_SettingUp; - BattleAI_DoAIProcessing(); + BattleAI_DoAIProcessing(AI_THINKING_STRUCT, sBattler_AI); } flags >>= 1; AI_THINKING_STRUCT->aiLogicId++; @@ -651,50 +651,50 @@ static u8 ChooseMoveOrAction_Doubles(void) return actionOrMoveIndex[gBattlerTarget]; } -static void BattleAI_DoAIProcessing(void) +static void BattleAI_DoAIProcessing(struct AI_ThinkingStruct *aiThink, u32 battler) { - while (AI_THINKING_STRUCT->aiState != AIState_FinishedProcessing) + while (aiThink->aiState != AIState_FinishedProcessing) { - switch (AI_THINKING_STRUCT->aiState) + switch (aiThink->aiState) { case AIState_DoNotProcess: // Needed to match. break; case AIState_SettingUp: - if (gBattleMons[sBattler_AI].pp[AI_THINKING_STRUCT->movesetIndex] == 0) + if (gBattleMons[battler].pp[aiThink->movesetIndex] == 0) { - AI_THINKING_STRUCT->moveConsidered = 0; + aiThink->moveConsidered = 0; } else { - AI_THINKING_STRUCT->moveConsidered = gBattleMons[sBattler_AI].moves[AI_THINKING_STRUCT->movesetIndex]; + aiThink->moveConsidered = gBattleMons[battler].moves[aiThink->movesetIndex]; } - AI_THINKING_STRUCT->aiState++; + aiThink->aiState++; break; case AIState_Processing: - if (AI_THINKING_STRUCT->moveConsidered != MOVE_NONE - && AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] > 0) + if (aiThink->moveConsidered != MOVE_NONE + && aiThink->score[aiThink->movesetIndex] > 0) { - if (AI_THINKING_STRUCT->aiLogicId < ARRAY_COUNT(sBattleAiFuncTable) - && sBattleAiFuncTable[AI_THINKING_STRUCT->aiLogicId] != NULL) + if (aiThink->aiLogicId < ARRAY_COUNT(sBattleAiFuncTable) + && sBattleAiFuncTable[aiThink->aiLogicId] != NULL) { // Call AI function - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = - sBattleAiFuncTable[AI_THINKING_STRUCT->aiLogicId](sBattler_AI, + aiThink->score[aiThink->movesetIndex] = + sBattleAiFuncTable[aiThink->aiLogicId](battler, gBattlerTarget, - AI_THINKING_STRUCT->moveConsidered, - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex]); + aiThink->moveConsidered, + aiThink->score[aiThink->movesetIndex]); } } else { - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; + aiThink->score[aiThink->movesetIndex] = 0; } - AI_THINKING_STRUCT->movesetIndex++; - if (AI_THINKING_STRUCT->movesetIndex < MAX_MON_MOVES && !(AI_THINKING_STRUCT->aiAction & AI_ACTION_DO_NOT_ATTACK)) - AI_THINKING_STRUCT->aiState = AIState_SettingUp; + aiThink->movesetIndex++; + if (aiThink->movesetIndex < MAX_MON_MOVES && !(aiThink->aiAction & AI_ACTION_DO_NOT_ATTACK)) + aiThink->aiState = AIState_SettingUp; else - AI_THINKING_STRUCT->aiState++; + aiThink->aiState++; break; } } @@ -702,7 +702,7 @@ static void BattleAI_DoAIProcessing(void) // AI Score Functions // AI_FLAG_CHECK_BAD_MOVE - decreases move scores -static s16 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { // move data u8 atkPriority = GetMovePriority(battlerAtk, move); @@ -2686,7 +2686,7 @@ static s16 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) return score; } -static s16 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { if (IsTargetingPartner(battlerAtk, battlerDef)) return score; @@ -2741,7 +2741,7 @@ static s16 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) } // double battle logic -static s16 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { // move data u8 moveType = gBattleMoves[move].type; @@ -3154,7 +3154,7 @@ static u32 GetAIMostDamagingMoveId(u32 battlerAtk, u32 battlerDef) } // AI_FLAG_CHECK_VIABILITY - a weird mix of increasing and decreasing scores -static s16 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { // move data u16 moveEffect = gBattleMoves[move].effect; @@ -4956,7 +4956,7 @@ static s16 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u16 move, s16 score } // Effects that are encouraged on the first turn of battle -static s16 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { if (IsTargetingPartner(battlerAtk, battlerDef) || gBattleResults.battleTurnCounter != 0) @@ -5067,7 +5067,7 @@ static s16 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u16 move, s16 score } // Adds score bonus to 'riskier' move effects and high crit moves -static s16 AI_Risky(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { if (IsTargetingPartner(battlerAtk, battlerDef)) return score; @@ -5106,7 +5106,7 @@ static s16 AI_Risky(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) } // Adds score bonus to best powered move -static s16 AI_PreferStrongestMove(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_PreferStrongestMove(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { if (IsTargetingPartner(battlerAtk, battlerDef)) return score; @@ -5118,7 +5118,7 @@ static s16 AI_PreferStrongestMove(u32 battlerAtk, u32 battlerDef, u16 move, s16 } // Prefers moves that are good for baton pass -static s16 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { u32 i; @@ -5173,7 +5173,7 @@ static s16 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u16 move, s16 scor return score; } -static s16 AI_HPAware(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { u16 effect = gBattleMoves[move].effect; u8 moveType = gBattleMoves[move].type; @@ -5376,7 +5376,7 @@ static void AI_Watch(void) } // Roaming pokemon logic -static s16 AI_Roaming(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_Roaming(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { if (IsBattlerTrapped(battlerAtk, FALSE)) return score; @@ -5386,7 +5386,7 @@ static s16 AI_Roaming(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) } // Safari pokemon logic -static s16 AI_Safari(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_Safari(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { u8 safariFleeRate = gBattleStruct->safariEscapeFactor * 5; // Safari flee rate, from 0-20. @@ -5399,7 +5399,7 @@ static s16 AI_Safari(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) } // First battle logic -static s16 AI_FirstBattle(u32 battlerAtk, u32 battlerDef, u16 move, s16 score) +static s32 AI_FirstBattle(u32 battlerAtk, u32 battlerDef, u16 move, s32 score) { if (AI_DATA->hpPercents[battlerDef] <= 20) AI_Flee(); diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 19eba9051..6e85112c2 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -803,6 +803,7 @@ s32 AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectivenes SetTypeBeforeUsingMove(move, battlerAtk); GET_MOVE_TYPE(move, moveType); + effectivenessMultiplier = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, FALSE); if (gBattleMoves[move].power) { ProteanTryChangeType(battlerAtk, AI_DATA->abilities[battlerAtk], move, moveType); @@ -821,8 +822,8 @@ s32 AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectivenes fixedBasePower = 0; break; } - normalDmg = CalculateMoveDamageAndEffectiveness(move, battlerAtk, battlerDef, moveType, fixedBasePower, &effectivenessMultiplier); - critDmg = CalculateMoveDamage(move, battlerAtk, battlerDef, moveType, fixedBasePower, TRUE, FALSE, FALSE); + normalDmg = CalculateMoveDamageWithEffectiveness(move, battlerAtk, battlerDef, moveType, fixedBasePower, effectivenessMultiplier, FALSE); + critDmg = CalculateMoveDamageWithEffectiveness(move, battlerAtk, battlerDef, moveType, fixedBasePower, effectivenessMultiplier, TRUE); if (critChance == -1) dmg = normalDmg; @@ -887,7 +888,6 @@ s32 AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectivenes } else { - effectivenessMultiplier = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, FALSE); dmg = 0; } @@ -1679,7 +1679,7 @@ bool32 ShouldSetSnow(u8 battler, u16 ability, u16 holdEffect) return FALSE; } -void ProtectChecks(u32 battlerAtk, u32 battlerDef, u16 move, u16 predictedMove, s16 *score) +void ProtectChecks(u32 battlerAtk, u32 battlerDef, u16 move, u16 predictedMove, s32 *score) { // TODO more sophisticated logic u16 predictedEffect = gBattleMoves[predictedMove].effect; @@ -3602,7 +3602,7 @@ bool32 IsRecycleEncouragedItem(u16 item) // score increases #define STAT_UP_2_STAGE 8 #define STAT_UP_STAGE 10 -void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u8 statId, s16 *score) +void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u8 statId, s32 *score) { if (AI_DATA->abilities[battlerAtk] == ABILITY_CONTRARY) return; @@ -3682,7 +3682,7 @@ void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u8 statId, s16 *score) } } -void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score) +void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score) { if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PSN || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) @@ -3706,7 +3706,7 @@ void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score) } } -void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score) +void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score) { if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_BRN || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) @@ -3726,7 +3726,7 @@ void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score) } } -void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score) +void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score) { if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PAR || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) @@ -3748,7 +3748,7 @@ void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score) } } -void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score) +void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score) { if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_SLP || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) @@ -3767,7 +3767,7 @@ void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score) (*score)++; } -void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score) +void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score) { if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_CONFUSION || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) @@ -3786,7 +3786,7 @@ void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score } } -void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u16 move, s16 *score) +void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u16 move, s32 *score) { if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index b93586d84..e5ed23bb2 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -15839,7 +15839,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 diff --git a/src/battle_util.c b/src/battle_util.c index 1e3c43e7b..9e489e9e3 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -9818,11 +9818,10 @@ s32 CalculateMoveDamage(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, updateFlags, CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, updateFlags)); } -// for AI - get move damage and effectiveness with one function call -s32 CalculateMoveDamageAndEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, uq4_12_t *typeEffectivenessModifier) +// 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) { - *typeEffectivenessModifier = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, FALSE); - return DoMoveDamageCalc(move, battlerAtk, battlerDef, moveType, fixedBasePower, FALSE, FALSE, FALSE, *typeEffectivenessModifier); + return DoMoveDamageCalc(move, battlerAtk, battlerDef, moveType, fixedBasePower, isCrit, FALSE, FALSE, typeEffectivenessModifier); } static inline void MulByTypeEffectiveness(uq4_12_t *modifier, u32 move, u32 moveType, u32 battlerDef, u32 defType, u32 battlerAtk, bool32 recordAbilities)