From 539a47671df0c48791a231b92dd6e7657cadacce Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 4 Dec 2022 19:09:46 +0000 Subject: [PATCH] Some more AI function code rewrites --- .../012_MoveEffects_ChangeMoveEffect.rb | 41 ++++- .../011_Battle/005_AI/003_AI_Switch.rb | 14 +- .../005_AI/020_AI_MoveEffectScores_Generic.rb | 28 +-- .../005_AI/056_AI_MoveHandlers_Healing.rb | 15 +- .../058_AI_MoveHandlers_ChangeMoveEffect.rb | 172 +++++++++++++----- .../059_AI_MoveHandlers_SwitchingActing.rb | 32 ++-- .../070_AI_MoveHandlers_GeneralModifiers.rb | 2 +- .../011_Battle/005_AI/101_AITrainer.rb | 5 + 8 files changed, 218 insertions(+), 91 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 6463704c1..1abe4eec1 100644 --- a/Data/Scripts/011_Battle/003_Move/012_MoveEffects_ChangeMoveEffect.rb +++ b/Data/Scripts/011_Battle/003_Move/012_MoveEffects_ChangeMoveEffect.rb @@ -138,8 +138,16 @@ end # user's Attack and Defense by 1 stage each. (Curse) #=============================================================================== class Battle::Move::CurseTargetOrLowerUserSpd1RaiseUserAtkDef1 < Battle::Move + attr_reader :statUp, :statDown + def ignoresSubstitute?(user); return true; end + def initialize(battle, move) + super + @statUp = [:ATTACK, 1, :DEFENSE, 1] + @statDown = [:SPEED, 1] + end + def pbTarget(user) if user.pbHasType?(:GHOST) ghost_target = (Settings::MECHANICS_GENERATION >= 8) ? :RandomNearFoe : :NearFoe @@ -150,9 +158,18 @@ class Battle::Move::CurseTargetOrLowerUserSpd1RaiseUserAtkDef1 < Battle::Move def pbMoveFailed?(user, targets) return false if user.pbHasType?(:GHOST) - if !user.pbCanLowerStatStage?(:SPEED, user, self) && - !user.pbCanRaiseStatStage?(:ATTACK, user, self) && - !user.pbCanRaiseStatStage?(:DEFENSE, user, self) + failed = true + (@statUp.length / 2).times do |i| + next if !user.pbCanRaiseStatStage?(@statUp[i * 2], user, self) + failed = false + break + end + (@statDown.length / 2).times do |i| + next if !user.pbCanLowerStatStage?(@statDown[i * 2], user, self) + failed = false + break + end + if failed @battle.pbDisplay(_INTL("But it failed!")) return true end @@ -170,15 +187,19 @@ class Battle::Move::CurseTargetOrLowerUserSpd1RaiseUserAtkDef1 < Battle::Move def pbEffectGeneral(user) return if user.pbHasType?(:GHOST) # Non-Ghost effect - if user.pbCanLowerStatStage?(:SPEED, user, self) - user.pbLowerStatStage(:SPEED, 1, user) + showAnim = true + (@statDown.length / 2).times do |i| + next if !user.pbCanLowerStatStage?(@statDown[i * 2], user, self) + if user.pbLowerStatStage(@statDown[i * 2], @statDown[(i * 2) + 1], user, showAnim) + showAnim = false + end end showAnim = true - if user.pbCanRaiseStatStage?(:ATTACK, user, self) - showAnim = false if user.pbRaiseStatStage(:ATTACK, 1, user, showAnim) - end - if user.pbCanRaiseStatStage?(:DEFENSE, user, self) - user.pbRaiseStatStage(:DEFENSE, 1, user, showAnim) + (@statUp.length / 2).times do |i| + next if !user.pbCanRaiseStatStage?(@statUp[i * 2], user, self) + if user.pbRaiseStatStage(@statUp[i * 2], @statUp[(i * 2) + 1], user, showAnim) + showAnim = false + end end end diff --git a/Data/Scripts/011_Battle/005_AI/003_AI_Switch.rb b/Data/Scripts/011_Battle/005_AI/003_AI_Switch.rb index e02a3d587..b6da6cad1 100644 --- a/Data/Scripts/011_Battle/005_AI/003_AI_Switch.rb +++ b/Data/Scripts/011_Battle/005_AI/003_AI_Switch.rb @@ -36,6 +36,10 @@ class Battle::AI battler.turnCount && battler.turnCount >= 5 shouldSwitch = true end + # Pokémon is about to faint because of Perish Song + if !shouldSwitch && battler.effects[PBEffects::PerishSong] == 1 + shouldSwitch = true + end # Pokémon is Perish Songed and has Baton Pass if @trainer.high_skill? && battler.effects[PBEffects::PerishSong] == 1 battler.eachMoveWithIndex do |m, i| @@ -87,15 +91,11 @@ class Battle::AI shouldSwitch = true end end - # Pokémon is about to faint because of Perish Song - if !shouldSwitch && battler.effects[PBEffects::PerishSong] == 1 - shouldSwitch = true - end if shouldSwitch list = [] idxPartyStart, idxPartyEnd = @battle.pbTeamIndexRangeFromBattlerIndex(battler.index) @battle.pbParty(battler.index).each_with_index do |pkmn, i| - next if i == idxPartyEnd - 1 # Don't choose to switch in ace + next if @trainer.has_skill_flag?("ReserveLastPokemon") && i == idxPartyEnd - 1 # Don't choose to switch in ace next if !@battle.pbCanSwitch?(battler.index, i) # If perish count is 1, it may be worth it to switch # even with Spikes, since Perish Song's effect will end @@ -152,7 +152,9 @@ class Battle::AI enemies = [] idxPartyStart, idxPartyEnd = @battle.pbTeamIndexRangeFromBattlerIndex(idxBattler) party.each_with_index do |_p, i| - next if i == idxPartyEnd - 1 && enemies.length > 0 # Ignore ace if possible + if @trainer.has_skill_flag?("ReserveLastPokemon") + next if i == idxPartyEnd - 1 && enemies.length > 0 # Ignore ace if possible + end enemies.push(i) if @battle.pbCanSwitchLax?(idxBattler, i) end return -1 if enemies.length == 0 diff --git a/Data/Scripts/011_Battle/005_AI/020_AI_MoveEffectScores_Generic.rb b/Data/Scripts/011_Battle/005_AI/020_AI_MoveEffectScores_Generic.rb index 11dc4b3f5..e3e240d0f 100644 --- a/Data/Scripts/011_Battle/005_AI/020_AI_MoveEffectScores_Generic.rb +++ b/Data/Scripts/011_Battle/005_AI/020_AI_MoveEffectScores_Generic.rb @@ -246,9 +246,9 @@ class Battle::AI score -= 20 else has_special_moves = @user.check_for_move { |m| m.specialMove?(m.type) } - inc = (has_special_moves) ? 5 : 10 - score += inc * (2 - old_stage) * inc_mult - score += 4 * inc_mult if @user.hp == @user.totalhp + inc = (has_special_moves) ? 10 : 20 + score += inc * inc_mult + score += 8 * inc_mult if @user.hp == @user.totalhp end when :DEFENSE @@ -256,8 +256,8 @@ class Battle::AI if old_stage >= 2 score -= 20 else - score += 5 * (2 - old_stage) * inc_mult - score += 4 * inc_mult if @user.hp == @user.totalhp + score += 10 * inc_mult + score += 8 * inc_mult if @user.hp == @user.totalhp end when :SPECIAL_ATTACK @@ -269,9 +269,9 @@ class Battle::AI has_physical_moves = @user.check_for_move { |m| m.physicalMove?(m.type) && m.function != "UseUserDefenseInsteadOfUserAttack" && m.function != "UseTargetAttackInsteadOfUserAttack" } - inc = (has_physical_moves) ? 5 : 10 - score += inc * (2 - old_stage) * inc_mult - score += 4 * inc_mult if @user.hp == @user.totalhp + inc = (has_physical_moves) ? 10 : 20 + score += inc * inc_mult + score += 8 * inc_mult if @user.hp == @user.totalhp end when :SPECIAL_DEFENSE @@ -279,8 +279,8 @@ class Battle::AI if old_stage >= 2 score -= 20 else - score += 5 * (2 - old_stage) * inc_mult - score += 4 * inc_mult if @user.hp == @user.totalhp + score += 10 * inc_mult + score += 8 * inc_mult if @user.hp == @user.totalhp end when :SPEED @@ -312,8 +312,8 @@ class Battle::AI end min_accuracy = min_accuracy * stage_mul[old_stage] / stage_div[old_stage] if min_accuracy < 90 - score += 5 * (2 - old_stage) * inc_mult - score += 4 * inc_mult if @user.hp == @user.totalhp + score += 10 * inc_mult + score += 8 * inc_mult if @user.hp == @user.totalhp end end @@ -330,8 +330,8 @@ class Battle::AI if old_stage >= 2 score -= 20 else - score += 5 * (2 - old_stage) * inc_mult - score += 4 * inc_mult if @user.hp == @user.totalhp + score += 10 * (2 - old_stage) * inc_mult + score += 8 * inc_mult if @user.hp == @user.totalhp end end 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 91f66990a..4b492dbb7 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 @@ -404,22 +404,27 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartDamageTargetEachTur Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartLeechSeedTarget", proc { |move, user, target, ai, battle| next true if target.effects[PBEffects::LeechSeed] >= 0 - next true if target.has_type?(:GRASS) + next true if target.has_type?(:GRASS) || !target.battler.takesIndirectDamage? } ) Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartLeechSeedTarget", proc { |score, move, user, target, ai, battle| + # Prefer early on score += 10 if user.turnCount < 2 if ai.trainer.medium_skill? - if !user.check_for_move { |m| m.damagingMove? } - score += 20 - end - score -= 20 if target.has_active_ability?([:LIQUIDOOZE]) || !target.battler.takesIndirectDamage? + # Prefer if the user has no damaging moves + score += 20 if !user.check_for_move { |m| m.damagingMove? } + # Prefer if the target can't switch out to remove its seeding + score += 10 if !battle.pbCanChooseNonActive?(target.index) + # Don't prefer if the leeched HP will hurt the user + score -= 20 if target.has_active_ability?([:LIQUIDOOZE]) end 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 end + # Don't prefer if target can remove the seed if target.check_for_move { |m| m.is_a?(Battle::Move::RemoveUserBindingAndEntryHazards) } score -= 15 end 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 eaa51c68f..3f50589c8 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 @@ -1,18 +1,32 @@ #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== Battle::AI::Handlers::MoveEffectScore.add("RedirectAllMovesToUser", proc { |score, move, user, ai, battle| + # Useless if there is no ally to redirect attacks from next Battle::AI::MOVE_USELESS_SCORE if user.battler.allAllies.length == 0 + # Prefer if ally is at low HP and user is at high HP + if user.hp > user.totalhp * 2 / 3 + ai.each_ally(user.index) do |b, i| + score += 10 if b.hp <= b.totalhp / 3 + end + end } ) #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RedirectAllMovesToTarget", proc { |score, move, user, target, ai, battle| - next Battle::AI::MOVE_USELESS_SCORE if user.battler.allAllies.length == 0 + if target.opposes?(user) + # Useless if target is a foe but there is only one foe + next Battle::AI::MOVE_USELESS_SCORE if target.battler.allAllies.length == 0 + # Useless if there is no ally to attack the spotlighted foe + next Battle::AI::MOVE_USELESS_SCORE if user.battler.allAllies.length == 0 + end + # Generaly don't prefer this move, as it's a waste of the user's turn + next score - 15 } ) @@ -49,7 +63,7 @@ Battle::AI::Handlers::MoveBasePower.add("RandomlyDamageOrHealTarget", ) #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("HealAllyOrDamageFoe", proc { |move, user, target, ai, battle| @@ -59,8 +73,12 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("HealAllyOrDamageFoe", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealAllyOrDamageFoe", proc { |score, move, user, target, ai, battle| if !target.opposes?(user) - score += 50 - score -= target.hp * 100 / target.totalhp + # Consider how much HP will be restored + if target.hp >= target.totalhp * 0.5 + score -= 10 + else + score += 20 * (target.totalhp - target.hp) / target.totalhp + end end next score } @@ -72,15 +90,26 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealAllyOrDamageFoe", Battle::AI::Handlers::MoveFailureCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1", proc { |move, user, ai, battle| if !user.has_type?(:GHOST) - next true if !user.battler.pbCanLowerStatStage?(:SPEED, user.battler, move.move) && - !user.battler.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) && - !user.battler.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move) + 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 end } ) Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1", proc { |move, user, target, ai, battle| - next true if user.has_type?(:GHOST) && target.effects[PBEffects::Curse] + if user.has_type?(:GHOST) + next true if target.effects[PBEffects::Curse] || !target.battler.takesIndirectDamage? + end } ) Battle::AI::Handlers::MoveEffectScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1", @@ -96,12 +125,20 @@ Battle::AI::Handlers::MoveEffectScore.add("CurseTargetOrLowerUserSpd1RaiseUserAt Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1", proc { |score, move, user, target, ai, battle| next score if !user.has_type?(:GHOST) - if user.hp <= user.totalhp / 2 - if battle.pbAbleNonActiveCount(user.idxOwnSide) == 0 - score -= 90 - else - score -= 50 - score -= 30 if battle.switchStyle + # Don't prefer if user will faint because of using this move + next Battle::AI::MOVE_USELESS_SCORE if user.hp <= user.totalhp / 2 + # Prefer early on + score += 10 if user.turnCount < 2 + if ai.trainer.medium_skill? + # Prefer if the user has no damaging moves + score += 20 if !user.check_for_move { |m| m.damagingMove? } + # Prefer if the target can't switch out to remove its curse + score += 10 if !battle.pbCanChooseNonActive?(target.index) + end + 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 end end next score @@ -144,14 +181,30 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TargetNextFireMoveDamage ) #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== -# DoublePowerAfterFusionFlare +Battle::AI::Handlers::MoveEffectScore.add("DoublePowerAfterFusionFlare", + proc { |score, move, user, ai, battle| + # Prefer if an ally knows Fusion Flare + ai.each_ally(user.index) do |b, i| + score += 10 if b.check_for_move { |m| m.function == "DoublePowerAfterFusionBolt" } + end + next score + } +) #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== -# DoublePowerAfterFusionBolt +Battle::AI::Handlers::MoveEffectScore.add("DoublePowerAfterFusionBolt", + proc { |score, move, user, ai, battle| + # Prefer if an ally knows Fusion Bolt + ai.each_ally(user.index) do |b, i| + score += 10 if b.check_for_move { |m| m.function == "DoublePowerAfterFusionFlare" } + end + next score + } +) #=============================================================================== # TODO: Review score modifiers. @@ -287,19 +340,43 @@ Battle::AI::Handlers::MoveEffectScore.add("HealUserDependingOnUserStockpile", ) #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== -# GrassPledge +Battle::AI::Handlers::MoveEffectScore.add("GrassPledge", + proc { |score, move, user, ai, battle| + # Prefer if an ally knows a different Pledge move + ai.each_ally(user.index) do |b, i| + score += 10 if b.check_for_move { |m| ["FirePledge", "WaterPledge"].include?(m.function) } + end + next score + } +) #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== -# FirePledge +Battle::AI::Handlers::MoveEffectScore.add("FirePledge", + proc { |score, move, user, ai, battle| + # Prefer if an ally knows a different Pledge move + ai.each_ally(user.index) do |b, i| + score += 10 if b.check_for_move { |m| ["GrassPledge", "WaterPledge"].include?(m.function) } + end + next score + } +) #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== -# WaterPledge +Battle::AI::Handlers::MoveEffectScore.add("WaterPledge", + proc { |score, move, user, ai, battle| + # Prefer if an ally knows a different Pledge move + ai.each_ally(user.index) do |b, i| + score += 10 if b.check_for_move { |m| ["GrassPledge", "FirePledge"].include?(m.function) } + end + next score + } +) #=============================================================================== # TODO: Review score modifiers. @@ -392,29 +469,36 @@ Battle::AI::Handlers::MoveFailureCheck.add("UseRandomUserMoveIfAsleep", # StealAndUseBeneficialStatusMove #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("ReplaceMoveThisBattleWithTargetLastMoveUsed", proc { |move, user, target, ai, battle| - next true if user.effects[PBEffects::Transform] || user.battler.pbHasMove?(move.id) - last_move_data = GameData::Move.try_get(target.battler.lastRegularMoveUsed) - next true if !last_move_data || - user.battler.pbHasMove?(target.battler.lastRegularMoveUsed) || - move.move.moveBlacklist.include?(last_move_data.function_code) || - last_move_data.type == :SHADOW + next true if user.effects[PBEffects::Transform] || !user.battler.pbHasMove?(move.id) + if user.faster_than?(target) + last_move_data = GameData::Move.try_get(target.battler.lastRegularMoveUsed) + next true if !last_move_data || + user.battler.pbHasMove?(target.battler.lastRegularMoveUsed) || + move.move.moveBlacklist.include?(last_move_data.function_code) || + last_move_data.type == :SHADOW + end + } +) +Battle::AI::Handlers::MoveEffectScore.add("ReplaceMoveThisBattleWithTargetLastMoveUsed", + proc { |score, move, user, ai, battle| + # Generally don't prefer, as this wastes the user's turn just to gain a move + # of unknown utility + score -= 8 + # Slightly prefer if this move will definitely succeed, just for the sake of + # getting rid of this move + score += 5 if user.faster_than?(target) + next score } ) #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== -Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("ReplaceMoveWithTargetLastMoveUsed", - proc { |move, user, target, ai, battle| - next true if user.effects[PBEffects::Transform] || !user.battler.pbHasMove?(move.id) - last_move_data = GameData::Move.try_get(target.battler.lastRegularMoveUsed) - next true if !last_move_data || - user.battler.pbHasMove?(target.battler.lastRegularMoveUsed) || - move.move.moveBlacklist.include?(last_move_data.function_code) || - last_move_data.type == :SHADOW - } -) +Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("ReplaceMoveThisBattleWithTargetLastMoveUsed", + "ReplaceMoveWithTargetLastMoveUsed") +Battle::AI::Handlers::MoveEffectScore.copy("ReplaceMoveThisBattleWithTargetLastMoveUsed", + "ReplaceMoveWithTargetLastMoveUsed") 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 30e8bd331..8ae175be6 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 @@ -22,8 +22,8 @@ Battle::AI::Handlers::MoveFailureCheck.add("SwitchOutUserStatusMove", Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserStatusMove", proc { |score, move, user, ai, battle| next score + 10 if user.wild? - if battle.pbTeamAbleNonActiveCount(user.index) == 1 # Don't switch in ace - score -= 60 + if ai.trainer.has_skill_flag?("ReserveLastPokemon") && battle.pbTeamAbleNonActiveCount(user.index) == 1 + score -= 60 # Don't switch in ace else score += 40 if user.effects[PBEffects::Confusion] > 0 total = 0 @@ -51,8 +51,8 @@ Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserStatusMove", #=============================================================================== Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserDamagingMove", proc { |score, move, user, ai, battle| - next 0 if !battle.pbCanChooseNonActive?(user.index) || - battle.pbTeamAbleNonActiveCount(user.index) == 1 # Don't switch in ace + next 0 if !battle.pbCanChooseNonActive?(user.index) + next 0 if ai.trainer.has_skill_flag?("ReserveLastPokemon") && battle.pbTeamAbleNonActiveCount(user.index) == 1 # Don't switch in ace } ) @@ -326,20 +326,24 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HigherPriorityInGrassyTe ) #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerPPOfTargetLastMoveBy3", proc { |score, move, user, target, ai, battle| - last_move = target.battler.pbGetMoveWithID(target.battler.lastRegularMoveUsed) - if last_move && last_move.total_pp > 0 && last_move.pp <= 3 - score += 50 + if user.faster_than?(target) + last_move = target.battler.pbGetMoveWithID(target.battler.lastRegularMoveUsed) + if last_move && last_move.total_pp > 0 + 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 + end end - next score + next score # Don't know which move it will affect; treat as just a damaging move } ) #=============================================================================== -# TODO: Review score modifiers. +# #=============================================================================== Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerPPOfTargetLastMoveBy4", proc { |move, user, target, ai, battle| @@ -349,7 +353,13 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerPPOfTargetLastMove ) Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerPPOfTargetLastMoveBy4", proc { |score, move, user, target, ai, battle| - next Battle::AI::MOVE_USELESS_SCORE + if user.faster_than?(target) + last_move = target.battler.pbGetMoveWithID(target.battler.lastRegularMoveUsed) + next score + 20 if last_move.pp <= 4 # Will fully deplete the move's PP + next score + 10 if last_move.pp <= 6 + next score - 10 if last_move.pp > 10 # Too much PP left to make a difference + end + next score - 10 # Don't know which move it will affect; don't prefer } ) 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 b2de360e4..98c577df5 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 @@ -2,7 +2,6 @@ # TODO: Review score modifier. #=============================================================================== # TODO: -# => Prefer move if it will KO the target (moreso if user is slower than target) # => Don't prefer damaging move if it won't KO, user has Stance Change and # is in shield form, and user is slower than the target # => Check memory for past damage dealt by a target's non-high priority move, @@ -38,6 +37,7 @@ Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:shiny_target, # => If target has previously used a move that will hurt the user by 30% of # its current HP or more, moreso don't prefer a status move. # => Include EOR damage in this? +# => Prefer move if it will KO the target (moreso if user is slower than target) #=============================================================================== Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:add_predicted_damage, proc { |score, move, user, target, ai, battle| diff --git a/Data/Scripts/011_Battle/005_AI/101_AITrainer.rb b/Data/Scripts/011_Battle/005_AI/101_AITrainer.rb index be691055b..561ba768d 100644 --- a/Data/Scripts/011_Battle/005_AI/101_AITrainer.rb +++ b/Data/Scripts/011_Battle/005_AI/101_AITrainer.rb @@ -13,6 +13,7 @@ # PredictMoveFailure # ScoreMoves # PreferMultiTargetMoves +# ReserveLastPokemon (don't switch it in if possible) #=============================================================================== class Battle::AI::AITrainer attr_reader :side, :trainer_index @@ -36,6 +37,10 @@ class Battle::AI::AITrainer @skill_flags.push("ScoreMoves") @skill_flags.push("PreferMultiTargetMoves") end + if @skill >= 100 + # TODO: Also have flag "DontReserveLastPokemon" which negates this. + @skill_flags.push("ReserveLastPokemon") + end end def has_skill_flag?(flag)