Rewrites of AI for airborne-related moves

This commit is contained in:
Maruno17
2022-11-09 22:21:32 +00:00
parent 8f014135e5
commit 6f2e72eed6
3 changed files with 182 additions and 107 deletions

View File

@@ -203,7 +203,7 @@ Battle::AI::Handlers::MoveEffectScore.add("RaiseUserSpeed2LowerUserWeight",
if user.check_for_move { |m| m.function == "PowerHigherWithUserHeavierThanTarget" } if user.check_for_move { |m| m.function == "PowerHigherWithUserHeavierThanTarget" }
score -= 10 score -= 10
end end
ai.each_foe_battler(user.side) do |b| ai.each_foe_battler(user.side) do |b, i|
if b.check_for_move { |m| m.function == "PowerHigherWithUserHeavierThanTarget" } if b.check_for_move { |m| m.function == "PowerHigherWithUserHeavierThanTarget" }
score -= 10 score -= 10
end end
@@ -276,7 +276,7 @@ Battle::AI::Handlers::MoveEffectScore.add("RaiseUserEvasion2MinimizeUser",
proc { |score, move, user, ai, battle| proc { |score, move, user, ai, battle|
score = ai.get_score_for_user_stat_raise(score) score = ai.get_score_for_user_stat_raise(score)
if ai.trainer.medium_skill? && !user.effects[PBEffects::Minimize] if ai.trainer.medium_skill? && !user.effects[PBEffects::Minimize]
ai.each_foe_battler(user.side) do |b| ai.each_foe_battler(user.side) do |b, i|
# Moves that do double damage and (in Gen 6+) have perfect accuracy # Moves that do double damage and (in Gen 6+) have perfect accuracy
if b.check_for_move { |m| m.tramplesMinimize? } if b.check_for_move { |m| m.tramplesMinimize? }
score -= (Settings::MECHANICS_GENERATION >= 6) ? 15 : 10 score -= (Settings::MECHANICS_GENERATION >= 6) ? 15 : 10

View File

@@ -24,7 +24,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SleepTarget",
# Inherent preference # Inherent preference
score += 15 score += 15
# Prefer if the user or an ally has a move/ability that is better if the target is asleep # Prefer if the user or an ally has a move/ability that is better if the target is asleep
ai.each_same_side_battler(user.side) do |b| ai.each_same_side_battler(user.side) do |b, i|
score += 5 if b.check_for_move { |m| ["DoublePowerIfTargetAsleepCureTarget", score += 5 if b.check_for_move { |m| ["DoublePowerIfTargetAsleepCureTarget",
"DoublePowerIfTargetStatusProblem", "DoublePowerIfTargetStatusProblem",
"HealUserByHalfOfDamageDoneIfTargetAsleep", "HealUserByHalfOfDamageDoneIfTargetAsleep",
@@ -46,8 +46,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SleepTarget",
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather) [:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
score -= 10 score -= 10
end end
ai.each_same_side_battler(target.side) do |b| ai.each_same_side_battler(target.side) do |b, i|
score -= 5 if b.index != target.index && b.has_active_ability?(:HEALER) score -= 5 if i != target.index && b.has_active_ability?(:HEALER)
end end
end end
next score next score
@@ -117,7 +117,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("PoisonTarget",
# Prefer if the target is at high HP # Prefer if the target is at high HP
score += 10 * target.hp / target.totalhp score += 10 * target.hp / target.totalhp
# Prefer if the user or an ally has a move/ability that is better if the target is poisoned # Prefer if the user or an ally has a move/ability that is better if the target is poisoned
ai.each_same_side_battler(user.side) do |b| ai.each_same_side_battler(user.side) do |b, i|
score += 5 if b.check_for_move { |m| ["DoublePowerIfTargetPoisoned", score += 5 if b.check_for_move { |m| ["DoublePowerIfTargetPoisoned",
"DoublePowerIfTargetStatusProblem"].include?(m.function) } "DoublePowerIfTargetStatusProblem"].include?(m.function) }
score += 10 if b.has_active_ability?(:MERCILESS) score += 10 if b.has_active_ability?(:MERCILESS)
@@ -141,8 +141,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("PoisonTarget",
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather) [:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
score -= 10 score -= 10
end end
ai.each_same_side_battler(target.side) do |b| ai.each_same_side_battler(target.side) do |b, i|
score -= 5 if b.index != target.index && b.has_active_ability?(:HEALER) score -= 5 if i != target.index && b.has_active_ability?(:HEALER)
end end
end end
next score next score
@@ -212,7 +212,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ParalyzeTarget",
score += 5 if target.effects[PBEffects::Confusion] > 1 score += 5 if target.effects[PBEffects::Confusion] > 1
score += 5 if target.effects[PBEffects::Attract] >= 0 score += 5 if target.effects[PBEffects::Attract] >= 0
# Prefer if the user or an ally has a move/ability that is better if the target is paralysed # Prefer if the user or an ally has a move/ability that is better if the target is paralysed
ai.each_same_side_battler(user.side) do |b| ai.each_same_side_battler(user.side) do |b, i|
score += 5 if b.check_for_move { |m| ["DoublePowerIfTargetParalyzedCureTarget", score += 5 if b.check_for_move { |m| ["DoublePowerIfTargetParalyzedCureTarget",
"DoublePowerIfTargetStatusProblem"].include?(m.function) } "DoublePowerIfTargetStatusProblem"].include?(m.function) }
end end
@@ -232,8 +232,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ParalyzeTarget",
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather) [:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
score -= 10 score -= 10
end end
ai.each_same_side_battler(target.side) do |b| ai.each_same_side_battler(target.side) do |b, i|
score -= 5 if b.index != target.index && b.has_active_ability?(:HEALER) score -= 5 if i != target.index && b.has_active_ability?(:HEALER)
end end
end end
next score next score
@@ -303,7 +303,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("BurnTarget",
score += 8 if !target.check_for_move { |m| m.specialMove? } score += 8 if !target.check_for_move { |m| m.specialMove? }
end end
# Prefer if the user or an ally has a move/ability that is better if the target is burned # Prefer if the user or an ally has a move/ability that is better if the target is burned
ai.each_same_side_battler(user.side) do |b| ai.each_same_side_battler(user.side) do |b, i|
score += 5 if b.check_for_move { |m| m.function == "DoublePowerIfTargetStatusProblem" } score += 5 if b.check_for_move { |m| m.function == "DoublePowerIfTargetStatusProblem" }
end end
# Don't prefer if target benefits from having the burn status problem # Don't prefer if target benefits from having the burn status problem
@@ -325,8 +325,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("BurnTarget",
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather) [:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
score -= 10 score -= 10
end end
ai.each_same_side_battler(target.side) do |b| ai.each_same_side_battler(target.side) do |b, i|
score -= 5 if b.index != target.index && b.has_active_ability?(:HEALER) score -= 5 if i != target.index && b.has_active_ability?(:HEALER)
end end
end end
next score next score
@@ -377,7 +377,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FreezeTarget",
# Inherent preference # Inherent preference
score += 15 score += 15
# Prefer if the user or an ally has a move/ability that is better if the target is frozen # Prefer if the user or an ally has a move/ability that is better if the target is frozen
ai.each_same_side_battler(user.side) do |b| ai.each_same_side_battler(user.side) do |b, i|
score += 5 if b.check_for_move { |m| m.function == "DoublePowerIfTargetStatusProblem" } score += 5 if b.check_for_move { |m| m.function == "DoublePowerIfTargetStatusProblem" }
end end
# Don't prefer if target benefits from having the frozen status problem # Don't prefer if target benefits from having the frozen status problem
@@ -394,8 +394,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FreezeTarget",
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather) [:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
score -= 10 score -= 10
end end
ai.each_same_side_battler(target.side) do |b| ai.each_same_side_battler(target.side) do |b, i|
score -= 5 if b.index != target.index && b.has_active_ability?(:HEALER) score -= 5 if i != target.index && b.has_active_ability?(:HEALER)
end end
end end
next score next score
@@ -551,7 +551,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartUserSideImmunityToInflictedStatu
if battle.field.terrain == :Misty && if battle.field.terrain == :Misty &&
(battle.field.terrainDuration > 1 || battle.field.terrainDuration < 0) (battle.field.terrainDuration > 1 || battle.field.terrainDuration < 0)
already_immune = true already_immune = true
ai.each_same_side_battler(user.side) do |b| ai.each_same_side_battler(user.side) do |b, i|
already_immune = false if !b.battler.affectedByTerrain? already_immune = false if !b.battler.affectedByTerrain?
end end
next Battle::AI::MOVE_USELESS_SCORE if already_immune next Battle::AI::MOVE_USELESS_SCORE if already_immune
@@ -559,7 +559,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartUserSideImmunityToInflictedStatu
# Tends to be wasteful if the foe just has one Pokémon left # Tends to be wasteful if the foe just has one Pokémon left
next score - 20 if battle.pbAbleNonActiveCount(user.idxOpposingSide) == 0 next score - 20 if battle.pbAbleNonActiveCount(user.idxOpposingSide) == 0
# Prefer for each user side battler # Prefer for each user side battler
ai.each_same_side_battler(user.side) { |b| score += 10 } ai.each_same_side_battler(user.side) { |b, i| score += 10 }
next score next score
} }
) )
@@ -811,18 +811,19 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SetTargetTypesToPsychic
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetTypesToPsychic", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetTypesToPsychic",
proc { |score, move, user, target, ai, battle| proc { |score, move, user, target, ai, battle|
# Prefer if user knows damaging moves that are super-effective against # Prefer if target's foes know damaging moves that are super-effective
# Psychic, and don't prefer if they know damaging moves that are ineffective # against Psychic, and don't prefer if they know damaging moves that are
# against Psychic # ineffective against Psychic
user.battler.eachMoveWithIndex do |m, i| ai.each_foe_battler(target.side) do |b, b|
next if !m.damagingMove? b.battler.eachMove do |m,|
effectiveness = Effectiveness.calculate(m.pbCalcType(user.battler), :PSYCHIC) next if !m.damagingMove?
if Effectiveness.super_effective?(effectiveness) effectiveness = Effectiveness.calculate(m.pbCalcType(b.battler), :PSYCHIC)
score += 8 if Effectiveness.super_effective?(effectiveness)
elsif Effectiveness.ineffective?(effectiveness) score += 8
score -= 10 elsif Effectiveness.ineffective?(effectiveness)
score -= 10
end
end end
end
next score next score
} }
) )
@@ -834,16 +835,18 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("SetTargetTypesToPsychi
"SetTargetTypesToWater") "SetTargetTypesToWater")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetTypesToWater", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetTypesToWater",
proc { |score, move, user, target, ai, battle| proc { |score, move, user, target, ai, battle|
# Prefer if user knows damaging moves that are super-effective against # Prefer if target's foes know damaging moves that are super-effective
# Water, and don't prefer if they know damaging moves that are ineffective # against Water, and don't prefer if they know damaging moves that are
# against Water # ineffective against Water
user.battler.eachMoveWithIndex do |m, i| ai.each_foe_battler(target.side) do |b, i|
next if !m.damagingMove? b.battler.eachMove do |m|
effectiveness = Effectiveness.calculate(m.pbCalcType(user.battler), :WATER) next if !m.damagingMove?
if Effectiveness.super_effective?(effectiveness) effectiveness = Effectiveness.calculate(m.pbCalcType(b.battler), :WATER)
score += 8 if Effectiveness.super_effective?(effectiveness)
elsif Effectiveness.ineffective?(effectiveness) score += 8
score -= 10 elsif Effectiveness.ineffective?(effectiveness)
score -= 10
end
end end
end end
next score next score
@@ -857,17 +860,19 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("SetTargetTypesToWater"
"AddGhostTypeToTarget") "AddGhostTypeToTarget")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AddGhostTypeToTarget", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AddGhostTypeToTarget",
proc { |score, move, user, target, ai, battle| proc { |score, move, user, target, ai, battle|
# Prefer/don't prefer depending on the effectiveness of the user's damaging # Prefer/don't prefer depending on the effectiveness of the target's foes'
# moves against the added type # damaging moves against the added type
user.battler.eachMoveWithIndex do |m, i| ai.each_foe_battler(target.side) do |b, i|
next if !m.damagingMove? b.battler.eachMove do |m|
effectiveness = Effectiveness.calculate(m.pbCalcType(user.battler), :GHOST) next if !m.damagingMove?
if Effectiveness.super_effective?(effectiveness) effectiveness = Effectiveness.calculate(m.pbCalcType(b.battler), :GHOST)
score += 8 if Effectiveness.super_effective?(effectiveness)
elsif Effectiveness.not_very_effective?(effectiveness) score += 8
score -= 5 elsif Effectiveness.not_very_effective?(effectiveness)
elsif Effectiveness.ineffective?(effectiveness) score -= 5
score -= 10 elsif Effectiveness.ineffective?(effectiveness)
score -= 10
end
end end
end end
next score next score
@@ -881,17 +886,19 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("AddGhostTypeToTarget",
"AddGrassTypeToTarget") "AddGrassTypeToTarget")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AddGrassTypeToTarget", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AddGrassTypeToTarget",
proc { |score, move, user, target, ai, battle| proc { |score, move, user, target, ai, battle|
# Prefer/don't prefer depending on the effectiveness of the user's damaging # Prefer/don't prefer depending on the effectiveness of the target's foes'
# moves against the added type # damaging moves against the added type
user.battler.eachMoveWithIndex do |m, i| ai.each_foe_battler(target.side) do |b, i|
next if !m.damagingMove? b.battler.eachMove do |m|
effectiveness = Effectiveness.calculate(m.pbCalcType(user.battler), :GRASS) next if !m.damagingMove?
if Effectiveness.super_effective?(effectiveness) effectiveness = Effectiveness.calculate(m.pbCalcType(b.battler), :GRASS)
score += 8 if Effectiveness.super_effective?(effectiveness)
elsif Effectiveness.not_very_effective?(effectiveness) score += 8
score -= 5 elsif Effectiveness.not_very_effective?(effectiveness)
elsif Effectiveness.ineffective?(effectiveness) score -= 5
score -= 10 elsif Effectiveness.ineffective?(effectiveness)
score -= 10
end
end end
end end
next score next score
@@ -913,8 +920,7 @@ Battle::AI::Handlers::MoveFailureCheck.add("UserLosesFireType",
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SetTargetAbilityToSimple", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SetTargetAbilityToSimple",
proc { |move, user, target, ai, battle| proc { |move, user, target, ai, battle|
next true if !GameData::Ability.exists?(:SIMPLE) next true if !GameData::Ability.exists?(:SIMPLE)
next true if target.battler.unstoppableAbility? || next move.move.pbFailsAgainstTarget?(user.battler, target.battler, false)
[:TRUANT, :SIMPLE].include?(target.ability_id)
} }
) )
@@ -924,8 +930,7 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SetTargetAbilityToSimpl
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SetTargetAbilityToInsomnia", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SetTargetAbilityToInsomnia",
proc { |move, user, target, ai, battle| proc { |move, user, target, ai, battle|
next true if !GameData::Ability.exists?(:INSOMNIA) next true if !GameData::Ability.exists?(:INSOMNIA)
next true if target.battler.unstoppableAbility? || next move.move.pbFailsAgainstTarget?(user.battler, target.battler, false)
[:TRUANT, :INSOMNIA].include?(target.ability_id)
} }
) )
@@ -935,9 +940,7 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SetTargetAbilityToInsom
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SetUserAbilityToTargetAbility", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SetUserAbilityToTargetAbility",
proc { |move, user, target, ai, battle| proc { |move, user, target, ai, battle|
next true if user.battler.unstoppableAbility? next true if user.battler.unstoppableAbility?
next true if !target.ability || user.ability_id == target.ability_id next move.move.pbFailsAgainstTarget?(user.battler, target.battler, false)
next true if target.battler.ungainableAbility? ||
[:POWEROFALCHEMY, :RECEIVER, :TRACE, :WONDERGUARD].include?(target.ability_id)
} }
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetUserAbilityToTargetAbility", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetUserAbilityToTargetAbility",
@@ -958,7 +961,7 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SetTargetAbilityToUserA
next true if !user.ability || user.ability_id == target.ability_id next true if !user.ability || user.ability_id == target.ability_id
next true if user.battler.ungainableAbility? || next true if user.battler.ungainableAbility? ||
[:POWEROFALCHEMY, :RECEIVER, :TRACE].include?(user.ability_id) [:POWEROFALCHEMY, :RECEIVER, :TRACE].include?(user.ability_id)
next true if target.battler.unstoppableAbility? || target.ability_id == :TRUANT next move.move.pbFailsAgainstTarget?(user.battler, target.battler, false)
} }
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetAbilityToUserAbility", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetAbilityToUserAbility",
@@ -976,12 +979,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetAbilityToUserAb
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("UserTargetSwapAbilities", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("UserTargetSwapAbilities",
proc { |move, user, target, ai, battle| proc { |move, user, target, ai, battle|
next true if !user.ability || !target.ability next true if !user.ability || user.battler.unstoppableAbility? ||
next true if Settings::MECHANICS_GENERATION <= 5 && user.ability_id == target.ability_id
next true if user.battler.unstoppableAbility? || user.battler.ungainableAbility? ||
user.ability_id == :WONDERGUARD user.ability_id == :WONDERGUARD
next true if target.battler.unstoppableAbility? || target.battler.ungainableAbility? || next move.move.pbFailsAgainstTarget?(user.battler, target.battler, false)
target.ability_id == :WONDERGUARD
} }
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserTargetSwapAbilities", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserTargetSwapAbilities",
@@ -1008,8 +1008,10 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("NegateTargetAbility",
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("NegateTargetAbilityIfTargetActed", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("NegateTargetAbilityIfTargetActed",
proc { |score, move, user, target, ai, battle| proc { |score, move, user, target, ai, battle|
score += 15 if target.faster_than?(user) next score if target.effects[PBEffects::Substitute] > 0 || target.effects[PBEffects::GastroAcid]
next score next score if target.battler.unstoppableAbility?
next score if user.faster_than?(target)
next score + 10
} }
) )
@@ -1019,24 +1021,78 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("NegateTargetAbilityIfTar
# IgnoreTargetAbility # IgnoreTargetAbility
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureCheck.add("StartUserAirborne", Battle::AI::Handlers::MoveFailureCheck.add("StartUserAirborne",
proc { |move, user, ai, battle| proc { |move, user, ai, battle|
next true if user.has_active_item?(:IRONBALL)
next true if user.effects[PBEffects::Ingrain] || next true if user.effects[PBEffects::Ingrain] ||
user.effects[PBEffects::SmackDown] || user.effects[PBEffects::SmackDown] ||
user.effects[PBEffects::MagnetRise] > 0 user.effects[PBEffects::MagnetRise] > 0
} }
) )
Battle::AI::Handlers::MoveEffectScore.add("StartUserAirborne",
proc { |score, move, user, ai, battle|
# Move is useless if user is already airborne
if user.has_type?(:FLYING) ||
user.has_active_ability?(:LEVITATE) ||
user.has_active_item?(:AIRBALLOON) ||
user.effects[PBEffects::Telekinesis] > 0
next Battle::AI::MOVE_USELESS_SCORE
end
# Prefer if any foes have damaging Ground-type moves that do 1x or more
# damage to the user
ai.each_foe_battler(user.side) do |b, i|
next if !b.check_for_move { |m| m.damagingMove? && m.pbCalcType(b.battler) == :GROUND }
next if Effectiveness.resistant?(user.effectiveness_of_type_against_battler(:GROUND, b))
score += 5
end
# Don't prefer if terrain exists (which the user will no longer be affected by)
if ai.trainer.medium_skill?
score -= 8 if battle.field.terrain != :None
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartTargetAirborneAndAlwaysHitByMoves", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartTargetAirborneAndAlwaysHitByMoves",
proc { |move, user, target, ai, battle| proc { |move, user, target, ai, battle|
next true if target.has_active_item?(:IRONBALL)
next move.move.pbFailsAgainstTarget?(user.battler, target.battler, false) next move.move.pbFailsAgainstTarget?(user.battler, target.battler, false)
} }
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartUserAirborne",
proc { |score, move, user, target, ai, battle|
# Move is useless if the target is already airborne
if target.has_type?(:FLYING) ||
target.has_active_ability?(:LEVITATE) ||
target.has_active_item?(:AIRBALLOON)
next Battle::AI::MOVE_USELESS_SCORE
end
# Prefer if any allies have moves with accuracy < 90%
# Don't prefer if any allies have damaging Ground-type moves that do 1x or
# more damage to the target
ai.each_foe_battler(target.side) do |b, i|
b.battler.eachMove do |m|
acc = m.accuracy
acc = m.pbBaseAccuracy(b.battler, target.battler) if ai.trainer.medium_skill?
score += 4 if acc < 90 && acc != 0
score += 4 if acc <= 50 && acc != 0
end
next if !b.check_for_move { |m| m.damagingMove? && m.pbCalcType(b.battler) == :GROUND }
next if Effectiveness.resistant?(target.effectiveness_of_type_against_battler(:GROUND, b))
score -= 5
end
# Prefer if terrain exists (which the target will no longer be affected by)
if ai.trainer.medium_skill?
score += 8 if battle.field.terrain != :None
end
next score
}
)
#=============================================================================== #===============================================================================
# #
@@ -1044,26 +1100,31 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartTargetAirborneAndA
# HitsTargetInSky # HitsTargetInSky
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HitsTargetInSkyGroundsTarget", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HitsTargetInSkyGroundsTarget",
proc { |score, move, user, target, ai, battle| proc { |score, move, user, target, ai, battle|
if ai.trainer.medium_skill? next score if target.effects[PBEffects::Substitute] > 0
score += 20 if target.effects[PBEffects::MagnetRise] > 0 || if !target.battler.airborne?
target.effects[PBEffects::Telekinesis] > 0 || next score if target.faster_than?(user) ||
target.has_type?(:FLYING) || !target.battler.inTwoTurnAttack?("TwoTurnAttackInvulnerableInSky",
(!battle.moldBreaker && target.has_active_ability?(:LEVITATE)) ||
target.has_active_item?(:AIRBALLOON) ||
target.battler.inTwoTurnAttack?("TwoTurnAttackInvulnerableInSky",
"TwoTurnAttackInvulnerableInSkyParalyzeTarget") "TwoTurnAttackInvulnerableInSkyParalyzeTarget")
end end
next score # Prefer if the target is airborne
score += 10
# Prefer if any allies have damaging Ground-type moves
ai.each_foe_battler(target.side) do |b, i|
score += 5 if b.check_for_move { |m| m.damagingMove? && m.pbCalcType(b.battler) == :GROUND }
end
# Don't prefer if terrain exists (which the target will become affected by)
if ai.trainer.medium_skill?
score -= 8 if battle.field.terrain != :None
end
} }
) )
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
# TODO: This code shouldn't make use of target.
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureCheck.add("StartGravity", Battle::AI::Handlers::MoveFailureCheck.add("StartGravity",
proc { |move, user, ai, battle| proc { |move, user, ai, battle|
@@ -1072,22 +1133,36 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartGravity",
) )
Battle::AI::Handlers::MoveEffectScore.add("StartGravity", Battle::AI::Handlers::MoveEffectScore.add("StartGravity",
proc { |score, move, user, ai, battle| proc { |score, move, user, ai, battle|
if ai.trainer.medium_skill? # TODO: Gravity increases accuracy of all moves. Should this be considered?
score -= 15 if user.effects[PBEffects::SkyDrop] >= 0 || ai.each_battler do |b, i|
user.effects[PBEffects::MagnetRise] > 0 || # Prefer grounding airborne foes, don't prefer grounding airborne allies
user.effects[PBEffects::Telekinesis] > 0 || # Prefer making allies affected by terrain, don't prefer making foes
user.has_type?(:FLYING) || # affected by terrain
user.has_active_ability?(:LEVITATE) || if b.battler.airborne?
user.has_active_item?(:AIRBALLOON) score_change = 10
# score += 15 if target.effects[PBEffects::SkyDrop] >= 0 || score_change -= 8 if battle.field.terrain != :None
# target.effects[PBEffects::MagnetRise] > 0 || score += (user.opposes?(b)) ? score_change : -score_change
# target.effects[PBEffects::Telekinesis] > 0 || # Prefer if allies have any damaging Ground moves they'll be able to use
# target.has_type?(:FLYING) || # on a grounded foe, and vice versa
# target.has_active_ability?(:LEVITATE) || ai.each_foe_battler(b.side) do |b2|
# target.has_active_item?(:AIRBALLOON) if b2.check_for_move { |m| m.damagingMove? && m.pbCalcType(b2.battler) == :GROUND }
# score += 5 if target.battler.inTwoTurnAttack?("TwoTurnAttackInvulnerableInSky", score += (user.opposes?(b2)) ? -5 : 5
# "TwoTurnAttackInvulnerableInSkyParalyzeTarget", end
# "TwoTurnAttackInvulnerableInSkyTargetCannotAct") end
end
# Prefer ending Sky Drop being used on allies, don't prefer ending Sky
# Drop being used on foes
if b.effects[PBEffects::SkyDrop] >= 0
score += (user.opposes?(b)) ? -5 : 5
end
# Prefer stopping foes' sky-based attacks, don't prefer stopping allies'
# sky-based attacks
if user.faster_than?(b) &&
b.battler.inTwoTurnAttack?("TwoTurnAttackInvulnerableInSky",
"TwoTurnAttackInvulnerableInSkyParalyzeTarget",
"TwoTurnAttackInvulnerableInSkyTargetCannotAct")
score += (user.opposes?(b)) ? 8 : -8
end
end end
next score next score
} }

View File

@@ -792,7 +792,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("EnsureNextMoveAlwaysHits
acc = m.accuracy acc = m.accuracy
acc = m.pbBaseAccuracy(user.battler, target.battler) if ai.trainer.medium_skill? acc = m.pbBaseAccuracy(user.battler, target.battler) if ai.trainer.medium_skill?
score += 4 if acc < 90 && acc != 0 score += 4 if acc < 90 && acc != 0
score += 8 if acc < 50 && acc != 0 score += 4 if acc <= 50 && acc != 0
end end
# Not worth it if the user or the target is at low HP # Not worth it if the user or the target is at low HP
score -= 10 if user.hp < user.totalhp / 2 score -= 10 if user.hp < user.totalhp / 2