From 1258e4b9c9aae4f7767de0128039662ee1e7d285 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 25 Dec 2022 00:39:25 +0000 Subject: [PATCH] More AI function code rewrites themed around stat changes --- .../003_Move/010_MoveEffects_Healing.rb | 9 +- .../011_Battle/005_AI/004_AI_ChooseMove.rb | 12 +- .../052_AI_MoveHandlers_BattlerStats.rb | 166 +++++++----------- .../054_AI_MoveHandlers_MoveAttributes.rb | 5 +- .../005_AI/055_AI_MoveHandlers_MultiHit.rb | 12 +- .../005_AI/056_AI_MoveHandlers_Healing.rb | 15 +- .../058_AI_MoveHandlers_ChangeMoveEffect.rb | 55 +++--- .../059_AI_MoveHandlers_SwitchingActing.rb | 4 +- Data/Scripts/011_Battle/005_AI/103_AIMove.rb | 3 + 9 files changed, 114 insertions(+), 167 deletions(-) diff --git a/Data/Scripts/011_Battle/003_Move/010_MoveEffects_Healing.rb b/Data/Scripts/011_Battle/003_Move/010_MoveEffects_Healing.rb index 7e796900f..16a9dbed3 100644 --- a/Data/Scripts/011_Battle/003_Move/010_MoveEffects_Healing.rb +++ b/Data/Scripts/011_Battle/003_Move/010_MoveEffects_Healing.rb @@ -118,10 +118,11 @@ class Battle::Move::HealUserByTargetAttackLowerTargetAttack1 < Battle::Move # has Contrary and is at +6" check too for symmetry. This move still # works even if the stat stage cannot be changed due to an ability or # other effect. - if !@battle.moldBreaker && target.hasActiveAbility?(:CONTRARY) && - target.statStageAtMax?(:ATTACK) - @battle.pbDisplay(_INTL("But it failed!")) if show_message - return true + if !@battle.moldBreaker && target.hasActiveAbility?(:CONTRARY) + if target.statStageAtMax?(:ATTACK) + @battle.pbDisplay(_INTL("But it failed!")) if show_message + return true + end elsif target.statStageAtMin?(:ATTACK) @battle.pbDisplay(_INTL("But it failed!")) if show_message return true diff --git a/Data/Scripts/011_Battle/005_AI/004_AI_ChooseMove.rb b/Data/Scripts/011_Battle/005_AI/004_AI_ChooseMove.rb index 9e9dd542c..85b546935 100644 --- a/Data/Scripts/011_Battle/005_AI/004_AI_ChooseMove.rb +++ b/Data/Scripts/011_Battle/005_AI/004_AI_ChooseMove.rb @@ -176,16 +176,18 @@ class Battle::AI score += t_score affected_targets += 1 end - # Check if any targets were affected + # Set the default score if no targets were affected + if affected_targets == 0 + score = (@trainer.has_skill_flag?("PredictMoveFailure")) ? MOVE_USELESS_SCORE : MOVE_BASE_SCORE + end + # Score based on how many targets were affected if affected_targets == 0 && @trainer.has_skill_flag?("PredictMoveFailure") return MOVE_FAIL_SCORE if !@move.move.worksWithNoTargets? - score = MOVE_USELESS_SCORE else - affected_targets = 1 if affected_targets == 0 # To avoid dividing by 0 # TODO: Can this accounting for multiple targets be improved somehow? - score /= affected_targets # Average the score against multiple targets + score /= affected_targets if affected_targets > 1 # Average the score against multiple targets # Bonus for affecting multiple targets - if @trainer.has_skill_flag?("PreferMultiTargetMoves") + if @trainer.has_skill_flag?("PreferMultiTargetMoves") && affected_targets > 1 score += (affected_targets - 1) * 10 end end diff --git a/Data/Scripts/011_Battle/005_AI/052_AI_MoveHandlers_BattlerStats.rb b/Data/Scripts/011_Battle/005_AI/052_AI_MoveHandlers_BattlerStats.rb index d021b4252..289a99bbb 100644 --- a/Data/Scripts/011_Battle/005_AI/052_AI_MoveHandlers_BattlerStats.rb +++ b/Data/Scripts/011_Battle/005_AI/052_AI_MoveHandlers_BattlerStats.rb @@ -623,7 +623,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseTargetAttack2Confus proc { |score, move, user, target, ai, battle| next Battle::AI::MOVE_USELESS_SCORE if !target.battler.pbCanConfuse?(user.battler, false, move.move) # Score for stat raise - stat_score = ai.get_score_for_target_stat_raise(score, target, [:ATTACK, 2], false) + score = ai.get_score_for_target_stat_raise(score, target, [:ATTACK, 2], false) # Score for confusing the target next Battle::AI::Handlers.apply_move_effect_against_target_score( "ConfuseTarget", score, move, user, target, ai, battle) @@ -643,7 +643,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseTargetSpAtk1Confuse proc { |score, move, user, target, ai, battle| next Battle::AI::MOVE_USELESS_SCORE if !target.battler.pbCanConfuse?(user.battler, false, move.move) # Score for stat raise - stat_score = ai.get_score_for_target_stat_raise(score, target, [:SPECIAL_ATTACK, 1], false) + score = ai.get_score_for_target_stat_raise(score, target, [:SPECIAL_ATTACK, 1], false) # Score for confusing the target next Battle::AI::Handlers.apply_move_effect_against_target_score( "ConfuseTarget", score, move, user, target, ai, battle) @@ -1020,7 +1020,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAtkDef1", "LowerTargetAtkSpAtk1") #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerPoisonedTargetAtkSpAtkSpd1", proc { |move, user, target, ai, battle| @@ -1033,164 +1033,124 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAtkSpAtk1", "LowerPoisonedTargetAtkSpAtkSpd1") #=============================================================================== -# TODO: Review score modifiers. -# TODO: This code should be for a single battler (each is checked in turn). -# target should probably be treated as an enemy when deciding the score, -# since the score will be inverted elsewhere due to the target being an -# ally. +# #=============================================================================== Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaiseAlliesAtkDef1", proc { |move, user, target, ai, battle| - will_fail = true - battle.allSameSideBattlers(user.battler).each do |b| - next if b.index == user.index - next if !b.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) && - !b.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move) - will_fail = false - break - end - next will_fail + next !target.battler.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) && + !target.battler.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move) } ) Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseAlliesAtkDef1", proc { |score, move, user, target, ai, battle| - user.battler.allAllies.each do |b| - score = ai.get_score_for_target_stat_raise(score, b, [:ATTACK, 1, :DEFENSE, 1]) - end - next score + next ai.get_score_for_target_stat_raise(score, target, [:ATTACK, 1, :DEFENSE, 1]) } ) #=============================================================================== -# TODO: Review score modifiers. -# TODO: This code should be for a single battler (each is checked in turn). -# target should probably be treated as an enemy when deciding the score, -# since the score will be inverted elsewhere due to the target being an -# ally. -# TODO: Since this also affects the user, this will need a MoveEffectScore and a -# MoveFailureCheck. +# #=============================================================================== -Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaisePlusMinusUserAndAlliesAtkSpAtk1", - proc { |move, user, target, ai, battle| +Battle::AI::Handlers::MoveFailureCheck.add("RaisePlusMinusUserAndAlliesAtkSpAtk1", + proc { |move, user, ai, battle| will_fail = true - battle.allSameSideBattlers(user.battler).each do |b| - next if !b.hasActiveAbility?([:MINUS, :PLUS]) - next if !b.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) && - !b.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user.battler, move.move) + ai.each_same_side_battler(user.side) do |b, i| + next if !b.has_active_ability?([:MINUS, :PLUS]) + next if !b.battler.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) && + !b.battler.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user.battler, move.move) will_fail = false break end next will_fail } ) -Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaisePlusMinusUserAndAlliesAtkSpAtk1", - proc { |score, move, user, target, ai, battle| -# score = ai.get_score_for_target_stat_raise(score, user, [:ATTACK, 1, :SPECIAL_ATTACK, 1], false) - user.battler.allAllies.each do |b| +Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaisePlusMinusUserAndAlliesAtkSpAtk1", + proc { |move, user, target, ai, battle| + next true if !target.hasActiveAbility?([:MINUS, :PLUS]) + next !target.battler.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) && + !target.battler.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user.battler, move.move) + } +) +Battle::AI::Handlers::MoveEffectScore.add("RaisePlusMinusUserAndAlliesAtkSpAtk1", + proc { |score, move, user, ai, battle| + next score if move.pbTarget(user.battler) != :UserSide + ai.each_same_side_battler(user.side) do |b, i| score = ai.get_score_for_target_stat_raise(score, b, [:ATTACK, 1, :SPECIAL_ATTACK, 1], false) end next score } ) +Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaisePlusMinusUserAndAlliesAtkSpAtk1", + proc { |score, move, user, target, ai, battle| + next ai.get_score_for_target_stat_raise(score, target, [:ATTACK, 1, :SPECIAL_ATTACK, 1]) + } +) #=============================================================================== -# TODO: Review score modifiers. -# TODO: This code should be for a single battler (each is checked in turn). -# target should probably be treated as an enemy when deciding the score, -# since the score will be inverted elsewhere due to the target being an -# ally. -# TODO: Since this also affects the user, this will need a MoveEffectScore and a -# MoveFailureCheck. +# #=============================================================================== -Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaisePlusMinusUserAndAlliesAtkSpAtk1", - proc { |move, user, target, ai, battle| +Battle::AI::Handlers::MoveFailureCheck.add("RaisePlusMinusUserAndAlliesDefSpDef1", + proc { |move, user, ai, battle| will_fail = true - battle.allSameSideBattlers(user.battler).each do |b| - next if !b.hasActiveAbility?([:MINUS, :PLUS]) - next if !b.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move) && - !b.pbCanRaiseStatStage?(:SPECIAL_DEFENSE, user.battler, move.move) + ai.each_same_side_battler(user.side) do |b, i| + next if !b.has_active_ability?([:MINUS, :PLUS]) + next if !b.battler.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move) && + !b.battler.pbCanRaiseStatStage?(:SPECIAL_DEFENSE, user.battler, move.move) will_fail = false break end next will_fail } ) +Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaisePlusMinusUserAndAlliesDefSpDef1", + proc { |move, user, target, ai, battle| + next true if !target.hasActiveAbility?([:MINUS, :PLUS]) + next !target.battler.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move) && + !target.battler.pbCanRaiseStatStage?(:SPECIAL_DEFENSE, user.battler, move.move) + } +) +Battle::AI::Handlers::MoveEffectScore.add("RaisePlusMinusUserAndAlliesDefSpDef1", + proc { |score, move, user, ai, battle| + next score if move.pbTarget(user.battler) != :UserSide + ai.each_same_side_battler(user.side) do |b, i| + score = ai.get_score_for_target_stat_raise(score, b, [:DEFENSE, 1, :SPECIAL_DEFENSE, 1], false) + end + next score + } +) Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaisePlusMinusUserAndAlliesDefSpDef1", proc { |score, move, user, target, ai, battle| - user.battler.allAllies.each do |b| - next if b.statStageAtMax?(:DEFENSE) && b.statStageAtMax?(:SPECIAL_DEFENSE) - score -= b.stages[:DEFENSE] * 10 - score -= b.stages[:SPECIAL_DEFENSE] * 10 - end - score -= user.stages[:DEFENSE] * 10 - score -= user.stages[:SPECIAL_DEFENSE] * 10 - next score + next ai.get_score_for_target_stat_raise(score, target, [:DEFENSE, 1, :SPECIAL_DEFENSE, 1]) } ) #=============================================================================== -# TODO: Review score modifiers. -# TODO: This code should be for a single battler (each is checked in turn). -# target should probably be treated as an enemy when deciding the score, -# since the score will be inverted elsewhere due to the target being an -# ally. +# #=============================================================================== Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaiseGroundedGrassBattlersAtkSpAtk1", proc { |move, user, target, ai, battle| - will_fail = true - battle.allBattlers.each do |b| - next if !b.pbHasType?(:GRASS) || b.airborne? || b.semiInvulnerable? - next if !b.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) && - !b.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user.battler, move.move) - will_fail = false - break - end - next will_fail + next true if !b.pbHasType?(:GRASS) || b.airborne? || b.semiInvulnerable? + next !target.battler.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) && + !target.battler.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user.battler, move.move) } ) Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseGroundedGrassBattlersAtkSpAtk1", proc { |score, move, user, target, ai, battle| - battle.allBattlers.each do |b| - if user.battler.opposes?(b) - score -= 20 - else - score -= b.stages[:ATTACK] * 10 - score -= b.stages[:SPECIAL_ATTACK] * 10 - end - end - next score + next ai.get_score_for_target_stat_raise(score, target, [:ATTACK, 1, :SPECIAL_ATTACK, 1]) } ) #=============================================================================== -# TODO: Review score modifiers. -# TODO: This code should be for a single battler (each is checked in turn). -# target should probably be treated as an enemy when deciding the score, -# since the score will be inverted elsewhere due to the target being an -# ally. +# #=============================================================================== Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaiseGrassBattlersDef1", proc { |move, user, target, ai, battle| - will_fail = true - battle.allBattlers.each do |b| - next if !b.pbHasType?(:GRASS) || b.semiInvulnerable? - next if !b.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move) - will_fail = false - break - end - next will_fail + next true if !b.pbHasType?(:GRASS) || b.semiInvulnerable? + next !target.battler.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move) } ) Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseGrassBattlersDef1", proc { |score, move, user, target, ai, battle| - battle.allBattlers.each do |b| - if user.battler.opposes?(b) - score -= 20 - else - score -= user.stages[:DEFENSE] * 10 - end - end - next score + next ai.get_score_for_target_stat_raise(score, target, [:DEFENSE, 1]) } ) diff --git a/Data/Scripts/011_Battle/005_AI/054_AI_MoveHandlers_MoveAttributes.rb b/Data/Scripts/011_Battle/005_AI/054_AI_MoveHandlers_MoveAttributes.rb index 390d7b07b..acef4e172 100644 --- a/Data/Scripts/011_Battle/005_AI/054_AI_MoveHandlers_MoveAttributes.rb +++ b/Data/Scripts/011_Battle/005_AI/054_AI_MoveHandlers_MoveAttributes.rb @@ -501,7 +501,7 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartWeakenFireMoves", end } ) -Battle::AI::Handlers::MoveEffectScore.add("StartWeakenElectricMoves", +Battle::AI::Handlers::MoveEffectScore.add("StartWeakenFireMoves", proc { |score, move, user, ai, battle| # Don't prefer the lower the user's HP is if user.hp < user.totalhp / 2 @@ -782,7 +782,8 @@ Battle::AI::Handlers::MoveFailureCheck.add("HoopaRemoveProtectionsBypassSubstitu ) Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HoopaRemoveProtectionsBypassSubstituteLowerUserDef1", proc { |score, move, user, target, ai, battle| - next score + 20 if target.stages[:DEFENSE] > 0 + score = ai.get_score_for_target_stat_drop(score, user, move.move.statDown, false) + next score } ) diff --git a/Data/Scripts/011_Battle/005_AI/055_AI_MoveHandlers_MultiHit.rb b/Data/Scripts/011_Battle/005_AI/055_AI_MoveHandlers_MultiHit.rb index fb83ac0cb..d689386c3 100644 --- a/Data/Scripts/011_Battle/005_AI/055_AI_MoveHandlers_MultiHit.rb +++ b/Data/Scripts/011_Battle/005_AI/055_AI_MoveHandlers_MultiHit.rb @@ -128,7 +128,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("HitTwoToFiveTimes", "HitTwoToFiveTimesOrThreeForAshGreninja") #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== Battle::AI::Handlers::MoveBasePower.copy("HitTwoToFiveTimes", "HitTwoToFiveTimesRaiseUserSpd1LowerUserDef1") @@ -137,13 +137,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HitTwoToFiveTimesRaiseUs # Score for being a multi-hit attack score = Battle::AI::Handlers.apply_move_effect_against_target_score("HitTwoToFiveTimes", score, move, user, target, ai, battle) - # User's stat changes - aspeed = user.rough_stat(:SPEED) - ospeed = target.rough_stat(:SPEED) - if aspeed < ospeed && aspeed * 1.5 > ospeed - score += 15 # Will become faster than the target - end - score += user.stages[:DEFENSE] * 10 + # Score for user's stat changes + score = ai.get_score_for_target_stat_raise(score, user, [:SPEED, 1], false) + score = ai.get_score_for_target_stat_drop(score, user, [:DEFENSE, 1], false) next score } ) diff --git a/Data/Scripts/011_Battle/005_AI/056_AI_MoveHandlers_Healing.rb b/Data/Scripts/011_Battle/005_AI/056_AI_MoveHandlers_Healing.rb index 4b492dbb7..1e6715bd8 100644 --- a/Data/Scripts/011_Battle/005_AI/056_AI_MoveHandlers_Healing.rb +++ b/Data/Scripts/011_Battle/005_AI/056_AI_MoveHandlers_Healing.rb @@ -158,10 +158,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealUserByTargetAttackLo proc { |score, move, user, target, ai, battle| # Check whether lowering the target's Attack will have any impact if ai.trainer.medium_skill? - if target.battler.pbCanLowerStatStage?(:ATTACK, user.battler, move.move) && - target.check_for_move { |m| m.physicalMove?(m.type) } - score += target.stages[:ATTACK] * 10 - end + score = ai.get_score_for_target_stat_drop(score, target, [:ATTACK, 1]) end # Consider how much HP will be restored heal_amt = target.rough_stat(:ATTACK) @@ -521,15 +518,11 @@ Battle::AI::Handlers::MoveEffectScore.copy("UserFaintsExplosive", #=============================================================================== Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserFaintsLowerTargetAtkSpAtk2", proc { |score, move, user, target, ai, battle| - next Battle::AI::MOVE_USELESS_SCORE if !target.battler.pbCanLowerStatStage?(:ATTACK, user.battler) && - !target.battler.pbCanLowerStatStage?(:SPECIAL_ATTACK, user.battler) score -= 25 # User will faint, don't prefer this move # Check the impact of lowering the target's stats - if target.stages[:ATTACK] < 0 && target.stages[:SPECIAL_ATTACK] < 0 - score -= 20 - elsif target.stages[:ATTACK] > 0 || target.stages[:SPECIAL_ATTACK] > 0 - score += 10 - end + score = ai.get_score_for_target_stat_drop(score, target, move.move.statDown) + next score if score == Battle::AI::MOVE_USELESS_SCORE + # Score for the user fainting if ai.trainer.medium_skill? score -= 10 if user.hp >= user.totalhp * 0.5 # User at 50% HP or more score += 10 if user.hp <= user.totalhp * 0.25 # User at 25% HP or less diff --git a/Data/Scripts/011_Battle/005_AI/058_AI_MoveHandlers_ChangeMoveEffect.rb b/Data/Scripts/011_Battle/005_AI/058_AI_MoveHandlers_ChangeMoveEffect.rb index 88a07541f..4c58c9ea1 100644 --- a/Data/Scripts/011_Battle/005_AI/058_AI_MoveHandlers_ChangeMoveEffect.rb +++ b/Data/Scripts/011_Battle/005_AI/058_AI_MoveHandlers_ChangeMoveEffect.rb @@ -85,41 +85,38 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealAllyOrDamageFoe", ) #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== Battle::AI::Handlers::MoveFailureCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1", proc { |move, user, ai, battle| - if !user.has_type?(:GHOST) - will_fail = true - (move.move.statUp.length / 2).times do |i| - next if !user.battler.pbCanRaiseStatStage?(move.move.statUp[i * 2], user.battler, move.move) - will_fail = false - break - end - (move.move.statDown.length / 2).times do |i| - next if !user.battler.pbCanLowerStatStage?(move.move.statDown[i * 2], user.battler, move.move) - will_fail = false - break - end - next will_fail + next false if user.has_type?(:GHOST) + will_fail = true + (move.move.statUp.length / 2).times do |i| + next if !user.battler.pbCanRaiseStatStage?(move.move.statUp[i * 2], user.battler, move.move) + will_fail = false + break end + (move.move.statDown.length / 2).times do |i| + next if !user.battler.pbCanLowerStatStage?(move.move.statDown[i * 2], user.battler, move.move) + will_fail = false + break + end + next will_fail } ) Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1", proc { |move, user, target, ai, battle| - if user.has_type?(:GHOST) - next true if target.effects[PBEffects::Curse] || !target.battler.takesIndirectDamage? - end + next false if !user.has_type?(:GHOST) + next true if target.effects[PBEffects::Curse] || !target.battler.takesIndirectDamage? + next false } ) Battle::AI::Handlers::MoveEffectScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1", proc { |score, move, user, ai, battle| next score if user.has_type?(:GHOST) - avg = user.stages[:SPEED] * 10 - avg -= user.stages[:ATTACK] * 10 - avg -= user.stages[:DEFENSE] * 10 - score += avg / 3 - next score + score = ai.get_score_for_target_stat_raise(score, user, move.move.statUp) + next score if score == Battle::AI::MOVE_USELESS_SCORE + next ai.get_score_for_target_stat_drop(score, user, move.move.statDown, false) } ) Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1", @@ -138,7 +135,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CurseTargetOrLowerUserSp if ai.trainer.high_skill? # Prefer if user can stall while damage is dealt if user.check_for_move { |m| m.is_a?(Battle::Move::ProtectMove) } - score += 15 + score += 8 end end next score @@ -293,14 +290,10 @@ Battle::AI::Handlers::MoveFailureCheck.add("UserAddStockpileRaiseDefSpDef1", ) Battle::AI::Handlers::MoveEffectScore.add("UserAddStockpileRaiseDefSpDef1", proc { |score, move, user, ai, battle| - avg = 0 - avg -= user.stages[:DEFENSE] * 10 - avg -= user.stages[:SPECIAL_DEFENSE] * 10 - score += avg / 2 - if user.battler.pbHasMoveFunction?("PowerDependsOnUserStockpile", - "HealUserDependingOnUserStockpile") # Spit Up, Swallow - score += 20 # More preferable if user also has Spit Up/Swallow - end + score = ai.get_score_for_target_stat_raise(score, user, [:DEFENSE, 1, :SPECIAL_DEFENSE, 1], false) + # More preferable if user also has Spit Up/Swallow + score += 20 if user.battler.pbHasMoveFunction?("PowerDependsOnUserStockpile", + "HealUserDependingOnUserStockpile") next score } ) diff --git a/Data/Scripts/011_Battle/005_AI/059_AI_MoveHandlers_SwitchingActing.rb b/Data/Scripts/011_Battle/005_AI/059_AI_MoveHandlers_SwitchingActing.rb index fd8eecf7f..7475ebf3a 100644 --- a/Data/Scripts/011_Battle/005_AI/059_AI_MoveHandlers_SwitchingActing.rb +++ b/Data/Scripts/011_Battle/005_AI/059_AI_MoveHandlers_SwitchingActing.rb @@ -73,9 +73,7 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetAtkSpAtk1Swi ) Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAtkSpAtk1SwitchOutUser", proc { |score, move, user, target, ai, battle| - avg = target.stages[:ATTACK] * 10 - avg += target.stages[:SPECIAL_ATTACK] * 10 - score += avg / 2 + score = ai.get_score_for_target_stat_drop(score, target, move.move.statDown, false) next score } ) diff --git a/Data/Scripts/011_Battle/005_AI/103_AIMove.rb b/Data/Scripts/011_Battle/005_AI/103_AIMove.rb index 9cd04ab5d..075bb9f3f 100644 --- a/Data/Scripts/011_Battle/005_AI/103_AIMove.rb +++ b/Data/Scripts/011_Battle/005_AI/103_AIMove.rb @@ -429,6 +429,9 @@ class Battle::AI::AIMove target_battler = target.battler # OHKO special calculation if @ai.trainer.medium_skill? + # TODO: This is insufficient for OHKO moves, as they should also ignore + # effects like Telekinesis and Minimize but def rough_accuracy + # treats them as applying to OHKO moves. case function when "OHKO", "OHKOHitsUndergroundTarget" modifiers[:base_accuracy] = self.accuracy + user.level - target.level