From e9a44377cee5d18ed24c079f7f0404f88ff00409 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sat, 11 Mar 2023 20:13:02 +0000 Subject: [PATCH] AI: Added checks for additional effect chance, Snatch/Magic Coat, more item ratings --- .../012_MoveEffects_ChangeMoveEffect.rb | 7 +- .../005_AI/020_AI_Move_EffectScoresGeneric.rb | 12 ++ .../070_AI_MoveHandlers_GeneralModifiers.rb | 78 ++++--- .../011_Battle/005_AI/102_AIBattler.rb | 190 +++++++++++++++--- Data/Scripts/011_Battle/005_AI/103_AIMove.rb | 27 ++- .../051_AI_MoveHandlers_Misc.rb | 3 + .../052_AI_MoveHandlers_BattlerStats.rb | 36 ++-- .../053_AI_MoveHandlers_BattlerOther.rb | 76 +++---- .../057_AI_MoveHandlers_Items.rb | 2 +- .../059_AI_MoveHandlers_SwitchingActing.rb | 8 + 10 files changed, 308 insertions(+), 131 deletions(-) diff --git a/Data/Scripts/011_Battle/003_Move/012_MoveEffects_ChangeMoveEffect.rb b/Data/Scripts/011_Battle/003_Move/012_MoveEffects_ChangeMoveEffect.rb index fc37fd333..7f3a39053 100644 --- a/Data/Scripts/011_Battle/003_Move/012_MoveEffects_ChangeMoveEffect.rb +++ b/Data/Scripts/011_Battle/003_Move/012_MoveEffects_ChangeMoveEffect.rb @@ -273,6 +273,7 @@ class Battle::Move::EffectDependsOnEnvironment < Battle::Move def pbEffectAfterAllHits(user, target) return if target.fainted? return if target.damageState.unaffected || target.damageState.substitute + return if user.hasActiveAbility?(:SHEERFORCE) chance = pbAdditionalEffectChance(user, target) return if @battle.pbRandom(100) >= chance case @secretPower @@ -1194,8 +1195,8 @@ class Battle::Move::UseRandomUserMoveIfAsleep < Battle::Move end #=============================================================================== -# This round, reflects all moves with the "C" flag targeting the user back at -# their origin. (Magic Coat) +# This round, reflects all moves that can be Magic Coated which target the user +# or which have no target back at their origin. (Magic Coat) #=============================================================================== class Battle::Move::BounceBackProblemCausingStatusMoves < Battle::Move def pbEffectGeneral(user) @@ -1205,7 +1206,7 @@ class Battle::Move::BounceBackProblemCausingStatusMoves < Battle::Move end #=============================================================================== -# This round, snatches all used moves with the "D" flag. (Snatch) +# This round, snatches all used moves that can be Snatched. (Snatch) #=============================================================================== class Battle::Move::StealAndUseBeneficialStatusMove < Battle::Move def pbEffectGeneral(user) diff --git a/Data/Scripts/011_Battle/005_AI/020_AI_Move_EffectScoresGeneric.rb b/Data/Scripts/011_Battle/005_AI/020_AI_Move_EffectScoresGeneric.rb index 6722e08fb..54bd0ea36 100644 --- a/Data/Scripts/011_Battle/005_AI/020_AI_Move_EffectScoresGeneric.rb +++ b/Data/Scripts/011_Battle/005_AI/020_AI_Move_EffectScoresGeneric.rb @@ -24,6 +24,10 @@ class Battle::AI end return get_score_for_target_stat_drop(score, target, stat_changes, whole_effect, fixed_change, true) end + # Don't make score changes if the move is a damaging move and its additional + # effect (the stat raise(s)) will be negated + add_effect = @move.get_score_change_for_additional_effect(@user, target) + return score if add_effect == -999 # Additional effect will be negated # Don't make score changes if target will faint from EOR damage if target.rough_end_of_round_damage >= target.hp ret = (whole_effect) ? MOVE_USELESS_SCORE : score @@ -66,6 +70,8 @@ class Battle::AI if real_stat_changes.length == 0 return (whole_effect) ? MOVE_USELESS_SCORE : score end + # Make score change based on the additional effect chance + score += add_effect # Make score changes based on the general concept of raising stats at all score = get_target_stat_raise_score_generic(score, target, real_stat_changes, desire_mult) # Make score changes based on the specific changes to each stat that will be @@ -314,6 +320,10 @@ class Battle::AI end return get_score_for_target_stat_raise(score, target, stat_changes, whole_effect, fixed_change, true) end + # Don't make score changes if the move is a damaging move and its additional + # effect (the stat drop(s)) will be negated + add_effect = @move.get_score_change_for_additional_effect(@user, target) + return score if add_effect == -999 # Additional effect will be negated # Don't make score changes if target will faint from EOR damage if target.rough_end_of_round_damage >= target.hp ret = (whole_effect) ? MOVE_USELESS_SCORE : score @@ -354,6 +364,8 @@ class Battle::AI if real_stat_changes.length == 0 return (whole_effect) ? MOVE_USELESS_SCORE : score end + # Make score change based on the additional effect chance + score += add_effect # Make score changes based on the general concept of lowering stats at all score = get_target_stat_drop_score_generic(score, target, real_stat_changes, desire_mult) # Make score changes based on the specific changes to each stat that will be diff --git a/Data/Scripts/011_Battle/005_AI/070_AI_MoveHandlers_GeneralModifiers.rb b/Data/Scripts/011_Battle/005_AI/070_AI_MoveHandlers_GeneralModifiers.rb index 0723ad4d7..bcf4deba2 100644 --- a/Data/Scripts/011_Battle/005_AI/070_AI_MoveHandlers_GeneralModifiers.rb +++ b/Data/Scripts/011_Battle/005_AI/070_AI_MoveHandlers_GeneralModifiers.rb @@ -148,15 +148,13 @@ Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:thawing_move_against_fr # flinching are dealt with in the function code part of score calculation). # TODO: Review score modifier. #=============================================================================== -Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:flinching_effects, +Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:external_flinching_effects, proc { |score, move, user, target, ai, battle| - if ai.trainer.medium_skill? + if ai.trainer.medium_skill? && move.damagingMove? && !move.move.flinchingMove? if (battle.moldBreaker || !target.has_active_ability?([:INNERFOCUS, :SHIELDDUST])) && target.effects[PBEffects::Substitute] == 0 - if move.move.flinchingMove? || - (move.damagingMove? && - (user.has_active_item?([:KINGSROCK, :RAZORFANG]) || - user.has_active_ability?(:STENCH))) + if user.has_active_item?([:KINGSROCK, :RAZORFANG]) || + user.has_active_ability?(:STENCH) old_score = score score += 8 PBDebug.log_score_change(score - old_score, "flinching") @@ -195,7 +193,7 @@ Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:flinching_effects, # repeatedly until the target retaliates). Doesn't do a score change if the user # will be immune to Bide's damage. #=============================================================================== -Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:avoid_damaging_a_biding_target, +Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:damaging_a_biding_target, proc { |score, move, user, target, ai, battle| if ai.trainer.medium_skill? && target.effects[PBEffects::Bide] > 0 && move.damagingMove? eff = user.effectiveness_of_type_against_battler(:NORMAL, target) # Bide is Normal type @@ -216,7 +214,6 @@ Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:avoid_damaging_a_biding } ) - #=============================================================================== # Don't prefer damaging moves that will knock out the target if they are using # Destiny Bond. @@ -224,7 +221,7 @@ Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:avoid_damaging_a_biding # => Also don't prefer damaging moves if user is slower than the target, move # is likely to be lethal, and target has previously used Destiny Bond #=============================================================================== -Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:avoid_knocking_out_destiny_bonder, +Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:knocking_out_a_destiny_bonder, proc { |score, move, user, target, ai, battle| if ai.trainer.medium_skill? && move.damagingMove? && target.effects[PBEffects::DestinyBond] dmg = move.rough_damage @@ -254,34 +251,65 @@ Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:avoid_knocking_out_dest #=============================================================================== # Don't prefer a move that can be Magic Coated if the target (or any foe if the -# move doesn't have a target) has Magic Bounce. +# move doesn't have a target) knows Magic Coat/has Magic Bounce. #=============================================================================== -Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:avoid_targeting_bouncable_move_against_Magic_Bouncer, +Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:target_can_Magic_Coat_or_Bounce_move, proc { |score, move, user, target, ai, battle| + # TODO: Modify the semiInvulnerable? check to only apply if the target will + # still be invulnerable when the user acts, i.e. compare speeds? if move.statusMove? && move.move.canMagicCoat? && - !battle.moldBreaker && target.has_active_ability?(:MAGICBOUNCE) + target.opposes?(user) && !target.battler.semiInvulnerable? old_score = score - score = Battle::AI::MOVE_USELESS_SCORE - PBDebug.log_score_change(score - old_score, "useless because target will Magic Bounce it") + if !battle.moldBreaker && target.has_active_ability?(:MAGICBOUNCE) + score = Battle::AI::MOVE_USELESS_SCORE + PBDebug.log_score_change(score - old_score, "useless because target will Magic Bounce it") + elsif target.has_move_with_function?("BounceBackProblemCausingStatusMoves") + score -= 8 + PBDebug.log_score_change(score - old_score, "target knows Magic Coat and could bounce it") + end end next score } ) -Battle::AI::Handlers::GeneralMoveScore.add(:avoid_bouncable_move_with_foe_Magic_Bouncer, +Battle::AI::Handlers::GeneralMoveScore.add(:any_foe_can_Magic_Coat_or_Bounce_move, proc { |score, move, user, ai, battle| - if move.statusMove? && move.move.canMagicCoat? && - move.pbTarget(user.battler).num_targets == 0 && !battle.moldBreaker - has_magic_bounce = false + if move.statusMove? && move.move.canMagicCoat? && move.pbTarget(user.battler).num_targets == 0 + old_score = score ai.each_foe_battler(user.side) do |b, i| - next if !b.has_active_ability?(:MAGICBOUNCE) - has_magic_bounce = true - break + # TODO: Modify the semiInvulnerable? check to only apply if the target + # will still be invulnerable when the user acts, i.e. compare + # speeds? + next if b.battler.semiInvulnerable? + if b.has_active_ability?(:MAGICBOUNCE) && !battle.moldBreaker + score = Battle::AI::MOVE_USELESS_SCORE + PBDebug.log_score_change(score - old_score, "useless because a foe will Magic Bounce it") + break + elsif b.has_move_with_function?("BounceBackProblemCausingStatusMoves") + score -= 8 + PBDebug.log_score_change(score - old_score, "a foe knows Magic Coat and could bounce it") + break + end end - if has_magic_bounce + end + next score + } +) + +#=============================================================================== +# Don't prefer a move that can be Snatched if any other battler knows Snatch. +#=============================================================================== +Battle::AI::Handlers::GeneralMoveScore.add(:any_battler_can_Snatch_move, + proc { |score, move, user, ai, battle| + if move.statusMove? && move.move.canSnatch? + ai.each_battler do |b, i| + next if b.index == user.index + next if b.effects[PBEffects::SkyDrop] >= 0 + next if !b.has_move_with_function?("StealAndUseBeneficialStatusMove") old_score = score - score = Battle::AI::MOVE_USELESS_SCORE - PBDebug.log_score_change(score - old_score, "useless because a foe will Magic Bounce it") + score -= 8 + PBDebug.log_score_change(score - old_score, "another battler could Snatch it") + break end end next score @@ -372,7 +400,7 @@ Battle::AI::Handlers::GeneralMoveScore.add(:good_move_for_choice_item, # more (desperate). # TODO: Review score modifier. #=============================================================================== -Battle::AI::Handlers::GeneralMoveScore.add(:prefer_damaging_moves_if_last_pokemon, +Battle::AI::Handlers::GeneralMoveScore.add(:either_side_down_to_last_pokemon, proc { |score, move, user, ai, battle| if ai.trainer.medium_skill? && move.damagingMove? reserves = battle.pbAbleNonActiveCount(user.idxOwnSide) diff --git a/Data/Scripts/011_Battle/005_AI/102_AIBattler.rb b/Data/Scripts/011_Battle/005_AI/102_AIBattler.rb index d9ed711d6..78ef2b77b 100644 --- a/Data/Scripts/011_Battle/005_AI/102_AIBattler.rb +++ b/Data/Scripts/011_Battle/005_AI/102_AIBattler.rb @@ -301,34 +301,174 @@ class Battle::AI::AIBattler #============================================================================= + # TODO: Add more items. + BASE_ITEM_RATINGS = { + :ADAMANTORB => 3, + :BLACKBELT => 2, + :BLACKGLASSES => 2, + :BLACKSLUDGE => -4, + :CHARCOAL => 2, + :CHOICEBAND => 4, + :CHOICESCARF => 4, + :CHOICESPECS => 4, + :DEEPSEATOOTH => 4, + :DRACOPLATE => 2, + :DRAGONFANG => 2, + :DREADPLATE => 2, + :EARTHPLATE => 2, + :FISTPLATE => 2, + :FLAMEORB => -4, + :FLAMEPLATE => 2, + :GRISEOUSORB => 3, + :HARDSTONE => 2, + :ICICLEPLATE => 2, + :INSECTPLATE => 2, + :IRONBALL => -4, + :IRONPLATE => 2, + :LAGGINGTAIL => -2, + :LEFTOVERS => 4, + :LIFEORB => 3, + :LIGHTBALL => 4, + :LUSTROUSORB => 3, + :MAGNET => 2, + :MEADOWPLATE => 2, + :METALCOAT => 2, + :METRONOME => 1, + :MINDPLATE => 2, + :MIRACLESEED => 2, + :MUSCLEBAND => 2, + :MYSTICWATER => 2, + :NEVERMELTICE => 2, + :ODDINCENSE => 2, + :PIXIEPLATE => 2, + :POISONBARB => 2, + :ROCKINCENSE => 2, + :ROSEINCENSE => 2, + :SEAINCENSE => 2, + :SHARPBEAK => 2, + :SILKSCARF => 2, + :SILVERPOWDER => 2, + :SKYPLATE => 2, + :SOFTSAND => 2, + :SOULDEW => 3, + :SPELLTAG => 2, + :SPLASHPLATE => 2, + :SPOOKYPLATE => 2, + :STICKYBARB => -2, + :STONEPLATE => 2, + :THICKCLUB => 4, + :TOXICORB => -4, + :TOXICPLATE => 2, + :TWISTEDSPOON => 2, + :WAVEINCENSE => 2, + :WISEGLASSES => 2, + :ZAPPLATE => 2 + } + # Returns a value indicating how beneficial the given item will be to this # battler if it is holding it. - # Return values are typically -2, -1, 0, 1 or 2. 0 is indifferent, positive + # Return values are typically between -10 and +10. 0 is indifferent, positive # values mean this battler benefits, negative values mean this battler suffers. - def wants_item?(item = :NONE) - item == :NONE if item.nil? - # TODO: Add more items. - preferred_items = [ - :CHOICESCARF, - :LEFTOVERS - ] - preferred_items.push(:BLACKSLUDGE) if has_type?(:POISON) - preferred_items.push(:IRONBALL) if has_move_with_function?("ThrowUserItemAtTarget") - preferred_items.push(:CHOICEBAND) if check_for_move { |m| m.physicalMove?(m.type) } - preferred_items.push(:CHOICESPECS) if check_for_move { |m| m.specialMove?(m.type) } - unpreferred_items = [ - :BLACKSLUDGE, - :FLAMEORB, - :IRONBALL, - :LAGGINGTAIL, - :STICKYBARB, - :TOXICORB - ] - ret = 0 - if preferred_items.include?(item) - ret = 2 - elsif unpreferred_items.include?(item) - ret = -2 + def wants_item?(item) + item = item.id if !item.is_a?(Symbol) && item.respond_to?("id") + return 0 if has_active_ability?(:KLUTZ) + # TODO: Unnerve, other item-negating effects. + ret = BASE_ITEM_RATINGS[item] || 0 + case item + when :ADAMANTORB + ret = 0 if !@battler.isSpecies?(:DIALGA) || !has_damaging_move_of_type?(:DRAGON, :STEEL) + when :BLACKBELT, :BLACKGLASSES, :CHARCOAL, :DRAGONFANG, :HARDSTONE, :MAGNET, + :METALCOAT, :MIRACLESEED, :MYSTICWATER, :NEVERMELTICE, :POISONBARB, + :SHARPBEAK, :SILKSCARF, :SILVERPOWDER, :SOFTSAND, :SPELLTAG, + :TWISTEDSPOON, + :DRACOPLATE, :DREADPLATE, :EARTHPLATE, :FISTPLATE, :FLAMEPLATE, + :ICICLEPLATE, :INSECTPLATE, :IRONPLATE, :MEADOWPLATE, :MINDPLATE, + :PIXIEPLATE, :SKYPLATE, :SPLASHPLATE, :SPOOKYPLATE, :STONEPLATE, + :TOXICPLATE, :ZAPPLATE, + :ODDINCENSE, :ROCKINCENSE, :ROSEINCENSE, :SEAINCENSE, :WAVEINCENSE + boosted_type = { + :BLACKBELT => :FIGHTING, + :BLACKGLASSES => :DARK, + :CHARCOAL => :FIRE, + :DRAGONFANG => :DRAGON, + :HARDSTONE => :ROCK, + :MAGNET => :ELECTRIC, + :METALCOAT => :STEEL, + :MIRACLESEED => :GRASS, + :MYSTICWATER => :WATER, + :NEVERMELTICE => :ICE, + :POISONBARB => :POISON, + :SHARPBEAK => :FLYING, + :SILKSCARF => :NORMAL, + :SILVERPOWDER => :BUG, + :SOFTSAND => :GROUND, + :SPELLTAG => :GHOST, + :TWISTEDSPOON => :PSYCHIC, + :DRACOPLATE => :DRAGON, + :DREADPLATE => :DARK, + :EARTHPLATE => :GROUND, + :FISTPLATE => :FIGHTING, + :FLAMEPLATE => :FIRE, + :ICICLEPLATE => :ICE, + :INSECTPLATE => :BUG, + :IRONPLATE => :STEEL, + :MEADOWPLATE => :GRASS, + :MINDPLATE => :PSYCHIC, + :PIXIEPLATE => :FAIRY, + :SKYPLATE => :FLYING, + :SPLASHPLATE => :WATER, + :SPOOKYPLATE => :GHOST, + :STONEPLATE => :ROCK, + :TOXICPLATE => :POISON, + :ZAPPLATE => :ELECTRIC, + :ODDINCENSE => :PSYCHIC, + :ROCKINCENSE => :ROCK, + :ROSEINCENSE => :GRASS, + :SEAINCENSE => :WATER, + :WAVEINCENSE => :WATER + }[item] + ret = 0 if !has_damaging_move_of_type?(boosted_type) + when :BLACKSLUDGE + ret = 4 if has_type?(:POISON) + when :CHOICEBAND, :MUSCLEBAND + ret = 0 if !check_for_move { |m| m.physicalMove?(m.type) } + when :CHOICESPECS, :WISEGLASSES + ret = 0 if !check_for_move { |m| m.specialMove?(m.type) } + when :DEEPSEATOOTH + ret = 0 if !@battler.isSpecies?(:CLAMPERL) || !check_for_move { |m| m.specialMove?(m.type) } + when :GRISEOUSORB + ret = 0 if !@battler.isSpecies?(:GIRATINA) || !has_damaging_move_of_type?(:DRAGON, :GHOST) + when :IRONBALL + ret = 0 if has_move_with_function?("ThrowUserItemAtTarget") + when :LIGHTBALL + ret = 0 if !@battler.isSpecies?(:PIKACHU) || !check_for_move { |m| m.damagingMove? } + when :LUSTROUSORB + ret = 0 if !@battler.isSpecies?(:PALKIA) || !has_damaging_move_of_type?(:DRAGON, :WATER) + when :SOULDEW + if !@battler.isSpecies?(:LATIAS) && !@battler.isSpecies?(:LATIOS) + ret = 0 + elsif Settings::SOUL_DEW_POWERS_UP_TYPES + ret = 0 if !has_damaging_move_of_type?(:PSYCHIC, :DRAGON) + else + ret -= 2 if !check_for_move { |m| m.specialMove?(m.type) } # Also boosts SpDef + end + when :THICKCLUB + ret = 0 if (!@battler.isSpecies?(:CUBONE) && !@battler.isSpecies?(:MAROWAK)) || + !check_for_move { |m| m.physicalMove?(m.type) } + end + # Prefer if this battler knows Fling and it will do a lot of damage/have an + # additional (negative) effect when flung + if has_move_with_function?("ThrowUserItemAtTarget") + GameData::Item.get(item).flags.each do |flag| + next if !flag[/^Fling_(\d+)$/i] + amt = $~[1].to_i + ret += 1 if amt >= 80 + ret += 1 if amt >= 100 + break + end + if [:FLAMEORB, :KINGSROCK, :LIGHTBALL, :POISONBARB, :RAZORFANG, :TOXICORB].include?(item) + ret += 1 + end end # Don't prefer if this battler knows Acrobatics if has_move_with_function?("DoublePowerIfUserHasNoItem") diff --git a/Data/Scripts/011_Battle/005_AI/103_AIMove.rb b/Data/Scripts/011_Battle/005_AI/103_AIMove.rb index 5a12f7845..e4062af31 100644 --- a/Data/Scripts/011_Battle/005_AI/103_AIMove.rb +++ b/Data/Scripts/011_Battle/005_AI/103_AIMove.rb @@ -546,17 +546,22 @@ class Battle::AI::AIMove #============================================================================= - # Returns: - # 0 = move doesn't have an additional effect - # 1 = additional effect will be negated - # 2 = additional effect will work - # 3 = additional effect has an increased chance to work - def additional_effect_usability(user, target) - return 3 if self.function == "ThrowUserItemAtTarget" - return 0 if @move.addlEffect == 0 # Doesn't have an additional effect - return 1 if target.has_active_ability?(:SHIELDDUST) && !@ai.battle.moldBreaker - return 3 if (Settings::MECHANICS_GENERATION >= 6 || self.function != "EffectDependsOnEnvironment") && + # Return values: + # 0: Regular additional effect chance or isn't an additional effect + # -999: Additional effect will be negated + # Other: Amount to add to a move's score + def get_score_change_for_additional_effect(user, target) + # Doesn't have an additional effect + return 0 if @move.addlEffect == 0 + # Additional effect will be negated + return -999 if user.has_active_ability?(:SHEERFORCE) + return -999 if user.index != target.index && + target.has_active_ability?(:SHIELDDUST) && !@ai.battle.moldBreaker + # Prefer if the additional effect will have an increased chance of working + return 5 if @move.addlEffect < 100 && + (Settings::MECHANICS_GENERATION >= 6 || self.function != "EffectDependsOnEnvironment") && (user.has_active_ability?(:SERENEGRACE) || user.pbOwnSide.effects[PBEffects::Rainbow] > 0) - return 2 + # No change to score + return 0 end end diff --git a/Data/Scripts/011_Battle/005b_AI move function codes/051_AI_MoveHandlers_Misc.rb b/Data/Scripts/011_Battle/005b_AI move function codes/051_AI_MoveHandlers_Misc.rb index 21f51852f..5a69ef0d0 100644 --- a/Data/Scripts/011_Battle/005b_AI move function codes/051_AI_MoveHandlers_Misc.rb +++ b/Data/Scripts/011_Battle/005b_AI move function codes/051_AI_MoveHandlers_Misc.rb @@ -540,6 +540,9 @@ Battle::AI::Handlers::MoveEffectScore.add("UserMakeSubstitute", #=============================================================================== Battle::AI::Handlers::MoveEffectScore.add("RemoveUserBindingAndEntryHazards", proc { |score, move, user, ai, battle| + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated + score += add_effect score += 10 if user.effects[PBEffects::Trapping] > 0 score += 15 if user.effects[PBEffects::LeechSeed] >= 0 if battle.pbAbleNonActiveCount(user.idxOwnSide) > 0 diff --git a/Data/Scripts/011_Battle/005b_AI move function codes/052_AI_MoveHandlers_BattlerStats.rb b/Data/Scripts/011_Battle/005b_AI move function codes/052_AI_MoveHandlers_BattlerStats.rb index 3629dc517..ff90635a8 100644 --- a/Data/Scripts/011_Battle/005b_AI move function codes/052_AI_MoveHandlers_BattlerStats.rb +++ b/Data/Scripts/011_Battle/005b_AI move function codes/052_AI_MoveHandlers_BattlerStats.rb @@ -36,9 +36,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseUserAttack2IfTarget #=============================================================================== # #=============================================================================== -Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAttack2", +Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAttack1", "RaiseUserAttack3") -Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAttack2", +Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAttack1", "RaiseUserAttack3") #=============================================================================== @@ -282,9 +282,9 @@ Battle::AI::Handlers::MoveEffectScore.add("RaiseUserEvasion2MinimizeUser", #=============================================================================== # #=============================================================================== -Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserEvasion2", +Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserEvasion1", "RaiseUserEvasion3") -Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserEvasion2", +Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserEvasion1", "RaiseUserEvasion3") #=============================================================================== @@ -763,9 +763,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAttack1", #=============================================================================== # #=============================================================================== -Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack2", +Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack1", "LowerTargetAttack3") -Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAttack2", +Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAttack1", "LowerTargetAttack3") #=============================================================================== @@ -800,9 +800,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetDefense1", #=============================================================================== # #=============================================================================== -Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetDefense2", +Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetDefense1", "LowerTargetDefense3") -Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetDefense2", +Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetDefense1", "LowerTargetDefense3") #=============================================================================== @@ -839,9 +839,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpAtk2", #=============================================================================== # #=============================================================================== -Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpAtk2", +Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpAtk1", "LowerTargetSpAtk3") -Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpAtk2", +Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpAtk1", "LowerTargetSpAtk3") #=============================================================================== @@ -863,9 +863,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpDef1", #=============================================================================== # #=============================================================================== -Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpDef2", +Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpDef1", "LowerTargetSpDef3") -Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpDef2", +Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpDef1", "LowerTargetSpDef3") #=============================================================================== @@ -925,9 +925,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpeed1", #=============================================================================== # #=============================================================================== -Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpeed2", +Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpeed1", "LowerTargetSpeed3") -Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpeed2", +Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpeed1", "LowerTargetSpeed3") #=============================================================================== @@ -949,9 +949,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAccuracy1", #=============================================================================== # #=============================================================================== -Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAccuracy2", +Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAccuracy1", "LowerTargetAccuracy3") -Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAccuracy2", +Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAccuracy1", "LowerTargetAccuracy3") #=============================================================================== @@ -1028,9 +1028,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetEvasion1", #=============================================================================== # #=============================================================================== -Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetEvasion2", +Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetEvasion1", "LowerTargetEvasion3") -Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetEvasion2", +Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetEvasion1", "LowerTargetEvasion3") #=============================================================================== diff --git a/Data/Scripts/011_Battle/005b_AI move function codes/053_AI_MoveHandlers_BattlerOther.rb b/Data/Scripts/011_Battle/005b_AI move function codes/053_AI_MoveHandlers_BattlerOther.rb index 1928b130b..772a948f8 100644 --- a/Data/Scripts/011_Battle/005b_AI move function codes/053_AI_MoveHandlers_BattlerOther.rb +++ b/Data/Scripts/011_Battle/005b_AI move function codes/053_AI_MoveHandlers_BattlerOther.rb @@ -15,12 +15,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SleepTarget", target.has_active_ability?(:HYDRATION) && [:Rain, :HeavyRain].include?(target.battler.effectiveWeather) if target.battler.pbCanSleep?(user.battler, false, move.move) - case move.additional_effect_usability(user, target) - when 1 # Additional effect will be negated - next score - when 3 # Additional effect has an increased chance to work - score += 5 - end + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated + score += add_effect # Inherent preference score += 15 # Prefer if the user or an ally has a move/ability that is better if the target is asleep @@ -107,12 +104,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("PoisonTarget", target.has_active_ability?(:HYDRATION) && [:Rain, :HeavyRain].include?(target.battler.effectiveWeather) if target.battler.pbCanPoison?(user.battler, false, move.move) - case move.additional_effect_usability(user, target) - when 1 # Additional effect will be negated - next score - when 3 # Additional effect has an increased chance to work - score += 5 - end + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated + score += add_effect # Inherent preference score += 10 # Prefer if the target is at high HP @@ -194,12 +188,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ParalyzeTarget", target.has_active_ability?(:HYDRATION) && [:Rain, :HeavyRain].include?(target.battler.effectiveWeather) if target.battler.pbCanParalyze?(user.battler, false, move.move) - case move.additional_effect_usability(user, target) - when 1 # Additional effect will be negated - next score - when 3 # Additional effect has an increased chance to work - score += 5 - end + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated + score += add_effect # Inherent preference (because of the chance of full paralysis) score += 10 # Prefer if the target is faster than the user but will become slower if @@ -291,12 +282,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("BurnTarget", target.has_active_ability?(:HYDRATION) && [:Rain, :HeavyRain].include?(target.battler.effectiveWeather) if target.battler.pbCanBurn?(user.battler, false, move.move) - case move.additional_effect_usability(user, target) - when 1 # Additional effect will be negated - next score - when 3 # Additional effect has an increased chance to work - score += 5 - end + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated + score += add_effect # Inherent preference score += 10 # Prefer if the target knows any physical moves that will be weaked by a burn @@ -370,12 +358,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FreezeTarget", target.has_active_ability?(:HYDRATION) && [:Rain, :HeavyRain].include?(target.battler.effectiveWeather) if target.battler.pbCanFreeze?(user.battler, false, move.move) - case move.additional_effect_usability(user, target) - when 1 # Additional effect will be negated - next score - when 3 # Additional effect has an increased chance to work - score += 5 - end + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated + score += add_effect # Inherent preference score += 15 # Prefer if the user or an ally has a move/ability that is better if the target is frozen @@ -528,10 +513,14 @@ Battle::AI::Handlers::MoveEffectScore.add("CureUserPartyStatus", #=============================================================================== Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CureTargetBurn", proc { |score, move, user, target, ai, battle| + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated if target.status == :BURN if target.opposes?(user) + score -= add_effect score -= 10 else + score += add_effect score += 10 end end @@ -573,12 +562,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FlinchTarget", proc { |score, move, user, target, ai, battle| next score if target.faster_than?(user) || target.effects[PBEffects::Substitute] > 0 next score if target.has_active_ability?(:INNERFOCUS) && !battle.moldBreaker - case move.additional_effect_usability(user, target) - when 1 # Additional effect will be negated - next score - when 3 # Additional effect has an increased chance to work - score += 5 - end + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated + score += add_effect # Inherent preference score += 10 # Prefer if the target is paralysed, confused or infatuated, to compound the @@ -631,12 +617,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ConfuseTarget", # No score modifier if the status problem will be removed immediately next score if target.has_active_item?(:PERSIMBERRY) if target.battler.pbCanConfuse?(user.battler, false, move.move) - case move.additional_effect_usability(user, target) - when 1 # Additional effect will be negated - next score - when 3 # Additional effect has an increased chance to work - score += 5 - end + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated + score += add_effect # Inherent preference score += 5 # Prefer if the target is at high HP @@ -668,12 +651,9 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("AttractTarget", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AttractTarget", proc { |score, move, user, target, ai, battle| if target.battler.pbCanAttract?(user.battler, false) - case move.additional_effect_usability(user, target) - when 1 # Additional effect will be negated - next score - when 3 # Additional effect has an increased chance to work - score += 5 - end + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated + score += add_effect # Inherent preference score += 10 # Prefer if the target is paralysed or confused, to compound the turn skipping diff --git a/Data/Scripts/011_Battle/005b_AI move function codes/057_AI_MoveHandlers_Items.rb b/Data/Scripts/011_Battle/005b_AI move function codes/057_AI_MoveHandlers_Items.rb index ff3db8ba2..09fad1164 100644 --- a/Data/Scripts/011_Battle/005b_AI move function codes/057_AI_MoveHandlers_Items.rb +++ b/Data/Scripts/011_Battle/005b_AI move function codes/057_AI_MoveHandlers_Items.rb @@ -159,7 +159,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartTargetCannotUseItem proc { |score, move, user, target, ai, battle| next Battle::AI::MOVE_USELESS_SCORE if !target.item || !target.item_active? item_score = target.wants_item?(target.item_id) - score += item_score * 5 + score += item_score * 3 next score } ) diff --git a/Data/Scripts/011_Battle/005b_AI move function codes/059_AI_MoveHandlers_SwitchingActing.rb b/Data/Scripts/011_Battle/005b_AI move function codes/059_AI_MoveHandlers_SwitchingActing.rb index b6d4e5874..63b74e369 100644 --- a/Data/Scripts/011_Battle/005b_AI move function codes/059_AI_MoveHandlers_SwitchingActing.rb +++ b/Data/Scripts/011_Battle/005b_AI move function codes/059_AI_MoveHandlers_SwitchingActing.rb @@ -207,6 +207,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("BindTarget", #=============================================================================== # TODO: Review score modifiers. +# TODO: Include get_score_change_for_additional_effect usage. #=============================================================================== Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("TrapTargetInBattle", proc { |move, user, target, ai, battle| @@ -466,9 +467,12 @@ Battle::AI::Handlers::MoveEffectScore.add("StartSlowerBattlersActFirst", #=============================================================================== Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerPPOfTargetLastMoveBy3", proc { |score, move, user, target, ai, battle| + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated if user.faster_than?(target) last_move = target.battler.pbGetMoveWithID(target.battler.lastRegularMoveUsed) if last_move && last_move.total_pp > 0 + score += add_effect next score + 20 if last_move.pp <= 3 # Will fully deplete the move's PP next score + 10 if last_move.pp <= 5 next score - 10 if last_move.pp > 9 # Too much PP left to make a difference @@ -685,6 +689,10 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DisableTargetSoundMoves" proc { |score, move, user, target, ai, battle| next score if target.effects[PBEffects::ThroatChop] > 1 next score if !target.check_for_move { |m| m.soundMove? } + # Check additional effect chance + add_effect = move.get_score_change_for_additional_effect(user, target) + next score if add_effect == -999 # Additional effect will be negated + score += add_effect # Inherent preference score += 8 next score