From 906ea4a5b086e8c04d30e8187e2e262a4ae558fc Mon Sep 17 00:00:00 2001 From: Pawkkie <61265402+Pawkkie@users.noreply.github.com> Date: Mon, 28 Aug 2023 07:39:27 -0400 Subject: [PATCH] Add missing absorbing abilities to FindMonThatAbsorbsOpponentsMove (#3218) * Add missing absorbing abilities to FindMonThatAbsorbsOpponentsMove * Use array to match ability to absorbing type Previous implementation involving piggybacking on a conditional in a bit of a messy fashion to check for each ability type, this should be more readable and more easily modified by a novice. This is almost exactly BuffelSaft's inclement emerald implementation. * Minor syntax fixes --- src/battle_ai_switch_items.c | 55 +++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index d815d3f8b..0045608b0 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -142,11 +142,12 @@ static bool8 ShouldSwitchIfWonderGuard(void) static bool8 FindMonThatAbsorbsOpponentsMove(void) { u8 battlerIn1, battlerIn2; - u16 absorbingTypeAbility; + u8 numAbsorbingAbilities = 0; + u16 absorbingTypeAbilities[3]; // Array size is maximum number of absorbing abilities for a single type s32 firstId; s32 lastId; // + 1 struct Pokemon *party; - s32 i; + s32 i, j; if (HasSuperEffectiveMoveAgainstOpponents(TRUE) && Random() % 3 != 0) return FALSE; @@ -171,17 +172,42 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void) battlerIn2 = gActiveBattler; } + // Create an array of possible absorb abilities so the AI considers all of them if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_FIRE) - absorbingTypeAbility = ABILITY_FLASH_FIRE; + { + absorbingTypeAbilities[0] = ABILITY_FLASH_FIRE; + numAbsorbingAbilities = 1; + } else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_WATER) - absorbingTypeAbility = ABILITY_WATER_ABSORB; + { + absorbingTypeAbilities[0] = ABILITY_WATER_ABSORB; + absorbingTypeAbilities[1] = ABILITY_STORM_DRAIN; + absorbingTypeAbilities[2] = ABILITY_DRY_SKIN; + numAbsorbingAbilities = 3; + } else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_ELECTRIC) - absorbingTypeAbility = ABILITY_VOLT_ABSORB; + { + absorbingTypeAbilities[0] = ABILITY_VOLT_ABSORB; + absorbingTypeAbilities[1] = ABILITY_MOTOR_DRIVE; + absorbingTypeAbilities[2] = ABILITY_LIGHTNING_ROD; + numAbsorbingAbilities = 3; + } + else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_GRASS) + { + absorbingTypeAbilities[0] = ABILITY_SAP_SIPPER; + numAbsorbingAbilities = 1; + } else + { return FALSE; + } - if (AI_DATA->abilities[gActiveBattler] == absorbingTypeAbility) - return FALSE; + // Check current mon for all absorbing abilities + for (i = 0; i < numAbsorbingAbilities; i++) + { + if (AI_DATA->abilities[gActiveBattler] == absorbingTypeAbilities[i]) + return FALSE; + } GetAIPartyIndexes(gActiveBattler, &firstId, &lastId); @@ -208,15 +234,18 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void) continue; monAbility = GetMonAbility(&party[i]); - if (absorbingTypeAbility == monAbility && Random() & 1) + + for (j = 0; j < numAbsorbingAbilities; j++) { - // we found a mon. - *(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = i; - BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SWITCH, 0); - return TRUE; + if (absorbingTypeAbilities[j] == monAbility && Random() & 1) + { + // we found a mon. + *(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = i; + BtlController_EmitTwoReturnValues(1, B_ACTION_SWITCH, 0); + return TRUE; + } } } - return FALSE; }