diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 8ccb05640f..0b60efb6a8 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -516,7 +516,6 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) u8 moveTarget = gBattleMoves[move].target; u16 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect, move); u8 effectiveness = AI_GetMoveEffectiveness(move); - u8 typeEffectiveness = AI_GetTypeEffectiveness(move, battlerAtk, battlerDef); bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk); u32 i; u16 predictedMove = gLastMoves[battlerDef]; // TODO better move prediction @@ -548,7 +547,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) } // check if negates type - if (!IS_MOVE_STATUS(move) && (effectiveness == AI_EFFECTIVENESS_x0 || typeEffectiveness == AI_EFFECTIVENESS_x0)) + if (!IS_MOVE_STATUS(move) && (effectiveness == AI_EFFECTIVENESS_x0 || effectiveness == AI_EFFECTIVENESS_x0)) score -= 10; // target ability checks @@ -756,7 +755,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_WILL_SUICIDE)) score -= 2; - if (typeEffectiveness == AI_EFFECTIVENESS_x0) + if (effectiveness == AI_EFFECTIVENESS_x0) { score -= 10; } @@ -775,7 +774,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) case EFFECT_DREAM_EATER: if (!(gBattleMons[battlerDef].status1 & STATUS1_SLEEP) || AI_DATA->defAbility == ABILITY_COMATOSE) score -= 8; - else if (typeEffectiveness == AI_EFFECTIVENESS_x0) + else if (effectiveness == AI_EFFECTIVENESS_x0) score -= 10; break; // stat raising effects @@ -1112,7 +1111,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) //case EFFECT_ENDEAVOR: case EFFECT_LOW_KICK: // AI_CBM_HighRiskForDamage - if (AI_DATA->defAbility == ABILITY_WONDER_GUARD && typeEffectiveness < AI_EFFECTIVENESS_x2) + if (AI_DATA->defAbility == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2) score -= 10; break; case EFFECT_COUNTER: @@ -1652,7 +1651,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) score -= 6; break; case EFFECT_RECHARGE: - if (AI_DATA->defAbility == ABILITY_WONDER_GUARD && typeEffectiveness < AI_EFFECTIVENESS_x2) + if (AI_DATA->defAbility == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2) score -= 10; else if (AI_DATA->atkAbility != ABILITY_TRUANT && !CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) @@ -2706,7 +2705,6 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) // move data u16 moveEffect = gBattleMoves[move].effect; u8 effectiveness = AI_GetMoveEffectiveness(move); - u8 typeEffectiveness = AI_GetTypeEffectiveness(move, battlerAtk, battlerDef); u8 atkPriority = GetMovePriority(battlerAtk, move); u16 predictedMove = gLastMoves[battlerDef]; //for now bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk); @@ -2808,7 +2806,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) case EFFECT_ABSORB: if (AI_DATA->atkHoldEffect == HOLD_EFFECT_BIG_ROOT) score++; - if (typeEffectiveness <= AI_EFFECTIVENESS_x0_5 && AI_RandLessThan(50)) + if (effectiveness <= AI_EFFECTIVENESS_x0_5 && AI_RandLessThan(50)) score -= 3; break; case EFFECT_EXPLOSION: @@ -3201,6 +3199,14 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (AI_DATA->atkAbility == ABILITY_SERENE_GRACE && AI_DATA->defAbility != ABILITY_CONTRARY) score++; break; + if (ShouldLowerSpeed(battlerAtk, battlerDef, AI_DATA->defAbility)) + { + if (AI_DATA->atkAbility == ABILITY_SERENE_GRACE && AI_DATA->defAbility != ABILITY_CONTRARY) + score += 4; + else + score += 2; + } + break; case EFFECT_SUBSTITUTE: if (gStatuses3[battlerDef] & STATUS3_PERISH_SONG) score += 3; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 4897f93d64..5e7cbadf75 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -873,36 +873,23 @@ u32 GetCurrDamageHpPercent(u8 battlerAtk, u8 battlerDef) u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef) { - u8 damageVar; - u32 effectivenessMultiplier; + u16 typeEffectiveness, moveType; - gMoveResultFlags = 0; - gCurrentMove = AI_THINKING_STRUCT->moveConsidered; - effectivenessMultiplier = AI_GetTypeEffectiveness(gCurrentMove, sBattler_AI, gBattlerTarget); - switch (effectivenessMultiplier) - { - case UQ_4_12(0.0): - default: - damageVar = AI_EFFECTIVENESS_x0; - break; - case UQ_4_12(0.25): - damageVar = AI_EFFECTIVENESS_x0_25; - break; - case UQ_4_12(0.5): - damageVar = AI_EFFECTIVENESS_x0_5; - break; - case UQ_4_12(1.0): - damageVar = AI_EFFECTIVENESS_x1; - break; - case UQ_4_12(2.0): - damageVar = AI_EFFECTIVENESS_x2; - break; - case UQ_4_12(4.0): - damageVar = AI_EFFECTIVENESS_x4; - break; - } + SaveBattlerData(battlerAtk); + SaveBattlerData(battlerDef); - return damageVar; + SetBattlerData(battlerAtk); + SetBattlerData(battlerDef); + + gBattleStruct->dynamicMoveType = 0; + SetTypeBeforeUsingMove(move, battlerAtk); + GET_MOVE_TYPE(move, moveType); + typeEffectiveness = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, FALSE); + + RestoreBattlerData(battlerAtk); + RestoreBattlerData(battlerDef); + + return typeEffectiveness; } u8 AI_GetMoveEffectiveness(u16 move) @@ -3298,17 +3285,17 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score) break; case STAT_ACC: if (HasMoveWithLowAccuracy(battlerAtk, battlerDef, 80, TRUE, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect)) - *score += 3; // has moves with less than 80% accuracy + *score += 2; // has moves with less than 80% accuracy else if (HasMoveWithLowAccuracy(battlerAtk, battlerDef, 90, TRUE, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect)) - *score += 2; + *(score)++; break; case STAT_EVASION: if (!BattlerWillFaintFromWeather(battlerAtk, AI_DATA->atkAbility)) { if (!GetBattlerSecondaryDamage(battlerAtk) && !(gStatuses3[battlerAtk] & STATUS3_ROOTED)) - *score += 3; - else *score += 2; + else + *(score)++; } break; }