From e055456b7eae91bb22995bf8ba6ea722531af96c Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Tue, 7 Mar 2023 09:34:26 +0100 Subject: [PATCH] Fix Protean / Libero when AI calculates Damage (#2714) * Fix Protean / Libero when AI calculates Damage * fix ai changing types when calculating dmg --- include/battle_script_commands.h | 1 + src/battle_ai_util.c | 10 ++++++---- src/battle_script_commands.c | 19 ++++++++++++++----- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index c3d6831e9..d65728628 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -44,6 +44,7 @@ u16 GetSecretPowerMoveEffect(void); void StealTargetItem(u8 battlerStealer, u8 battlerItem); u8 GetCatchingBattler(void); u32 GetHighestStatId(u32 battlerId); +bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType); bool32 DoSwitchInAbilitiesItems(u32 battlerId); extern void (* const gBattleScriptingCommandsTable[])(void); diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 523d9229f..a9e3ed3e0 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -538,9 +538,10 @@ void SaveBattlerData(u8 battlerId) AI_THINKING_STRUCT->saved[battlerId].species = gBattleMons[battlerId].species; for (i = 0; i < 4; i++) AI_THINKING_STRUCT->saved[battlerId].moves[i] = gBattleMons[battlerId].moves[i]; - AI_THINKING_STRUCT->saved[battlerId].types[0] = gBattleMons[battlerId].type1; - AI_THINKING_STRUCT->saved[battlerId].types[1] = gBattleMons[battlerId].type2; } + // Save and restore types even for AI controlled battlers in case it gets changed during move evaluation process. + AI_THINKING_STRUCT->saved[battlerId].types[0] = gBattleMons[battlerId].type1; + AI_THINKING_STRUCT->saved[battlerId].types[1] = gBattleMons[battlerId].type2; } static bool32 ShouldFailForIllusion(u16 illusionSpecies, u32 battlerId) @@ -631,9 +632,9 @@ void RestoreBattlerData(u8 battlerId) gBattleMons[battlerId].species = AI_THINKING_STRUCT->saved[battlerId].species; for (i = 0; i < 4; i++) gBattleMons[battlerId].moves[i] = AI_THINKING_STRUCT->saved[battlerId].moves[i]; - gBattleMons[battlerId].type1 = AI_THINKING_STRUCT->saved[battlerId].types[0]; - gBattleMons[battlerId].type2 = AI_THINKING_STRUCT->saved[battlerId].types[1]; } + gBattleMons[battlerId].type1 = AI_THINKING_STRUCT->saved[battlerId].types[0]; + gBattleMons[battlerId].type2 = AI_THINKING_STRUCT->saved[battlerId].types[1]; } u32 GetHealthPercentage(u8 battlerId) @@ -801,6 +802,7 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *typeEffectiveness, if (gBattleMoves[move].power) { + ProteanTryChangeType(battlerAtk, AI_DATA->abilities[battlerAtk], move, moveType); critChance = GetInverseCritChance(battlerAtk, battlerDef, move); normalDmg = CalculateMoveDamageAndEffectiveness(move, battlerAtk, battlerDef, moveType, &effectivenessMultiplier); critDmg = CalculateMoveDamage(move, battlerAtk, battlerDef, moveType, 0, TRUE, FALSE, FALSE); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index a5b7656bf..40a7598de 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1443,6 +1443,19 @@ static bool32 TryAegiFormChange(void) return TRUE; } +bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType) +{ + if ((ability == ABILITY_PROTEAN || ability == ABILITY_LIBERO) + && (gBattleMons[battler].type1 != moveType || gBattleMons[battler].type2 != moveType + || (gBattleMons[battler].type3 != moveType && gBattleMons[battler].type3 != TYPE_MYSTERY)) + && move != MOVE_STRUGGLE) + { + SET_BATTLER_TYPE(gBattlerAttacker, moveType); + return TRUE; + } + return FALSE; +} + static void Cmd_attackcanceler(void) { CMD_ARGS(); @@ -1499,13 +1512,9 @@ static void Cmd_attackcanceler(void) } // Check Protean activation. - if ((attackerAbility == ABILITY_PROTEAN || attackerAbility == ABILITY_LIBERO) - && (gBattleMons[gBattlerAttacker].type1 != moveType || gBattleMons[gBattlerAttacker].type2 != moveType || - (gBattleMons[gBattlerAttacker].type3 != moveType && gBattleMons[gBattlerAttacker].type3 != TYPE_MYSTERY)) - && gCurrentMove != MOVE_STRUGGLE) + if (ProteanTryChangeType(gBattlerAttacker, attackerAbility, gCurrentMove, moveType)) { PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType); - SET_BATTLER_TYPE(gBattlerAttacker, moveType); gBattlerAbility = gBattlerAttacker; BattleScriptPushCursor(); PrepareStringBattle(STRINGID_EMPTYSTRING3, gBattlerAttacker);