mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-08 13:44:59 +00:00
Rewrote AI calculations for moves that inflict a status problem
This commit is contained in:
@@ -49,14 +49,14 @@ class Battle::AI
|
|||||||
def each_foe_battler(side)
|
def each_foe_battler(side)
|
||||||
@battlers.each_with_index do |battler, i|
|
@battlers.each_with_index do |battler, i|
|
||||||
next if !battler || battler.fainted?
|
next if !battler || battler.fainted?
|
||||||
yield battler, i if i.even? != side.even?
|
yield battler, i if i.even? != side.even?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def each_same_side_battler(side)
|
def each_same_side_battler(side)
|
||||||
@battlers.each_with_index do |battler, i|
|
@battlers.each_with_index do |battler, i|
|
||||||
next if !battler || battler.fainted?
|
next if !battler || battler.fainted?
|
||||||
yield battler, i if i.even? == side.even?
|
yield battler, i if i.even? == side.even?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ class Battle::AI
|
|||||||
end
|
end
|
||||||
# Discard move if it can't raise any stats
|
# Discard move if it can't raise any stats
|
||||||
if stat_changes.length == 0
|
if stat_changes.length == 0
|
||||||
|
# TODO: Have a parameter that decides whether to reduce the score here
|
||||||
|
# (for moves where this is just part of the effect).
|
||||||
return (@move.statusMove?) ? score - 40 : score
|
return (@move.statusMove?) ? score - 40 : score
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("SleepTarget",
|
Battle::AI::Handlers::MoveFailureCheck.add("SleepTarget",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -8,17 +8,40 @@ Battle::AI::Handlers::MoveFailureCheck.add("SleepTarget",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("SleepTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("SleepTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if target.battler.pbCanSleep?(user.battler, false, move.move)
|
next score if target.effects[PBEffects::Yawn] > 0 # Target is going to fall asleep anyway
|
||||||
score += 30
|
# No score modifier if the sleep will be removed immediately
|
||||||
if ai.trainer.medium_skill?
|
next score if target.has_active_item?([:CHESTOBERRY, :LUMBERRY])
|
||||||
score -= 30 if target.effects[PBEffects::Yawn] > 0
|
next score if target.faster_than?(user) &&
|
||||||
|
target.has_active_ability?(:HYDRATION) &&
|
||||||
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
|
if move.statusMove? || target.battler.pbCanSleep?(user.battler, false, move.move)
|
||||||
|
# Inherent preference
|
||||||
|
score += 15
|
||||||
|
# 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|
|
||||||
|
score += 5 if b.check_for_move { |m| ["DoublePowerIfTargetAsleepCureTarget",
|
||||||
|
"DoublePowerIfTargetStatusProblem",
|
||||||
|
"HealUserByHalfOfDamageDoneIfTargetAsleep",
|
||||||
|
"StartDamageTargetEachTurnIfTargetAsleep"].include?(m.function) }
|
||||||
|
score += 10 if b.has_active_ability?(:BADDREAMS)
|
||||||
end
|
end
|
||||||
score -= 30 if target.has_active_ability?(:MARVELSCALE)
|
# Don't prefer if target benefits from having the sleep status problem
|
||||||
if ai.trainer.best_skill?
|
# NOTE: The target's Guts/Quick Feet will benefit from the target being
|
||||||
if target.battler.pbHasMoveFunction?("FlinchTargetFailsIfUserNotAsleep",
|
# asleep, but the target won't (usually) be able to make use of
|
||||||
"UseRandomUserMoveIfAsleep") # Snore, Sleep Talk
|
# them, so they're not worth considering.
|
||||||
score -= 50
|
score -= 10 if target.has_active_ability?(:EARLYBIRD)
|
||||||
end
|
score -= 5 if target.has_active_ability?(:MARVELSCALE)
|
||||||
|
# Don't prefer if target has a move it can use while asleep
|
||||||
|
score -= 8 if target.check_for_move { |m| m.usableWhenAsleep? }
|
||||||
|
# Don't prefer if the target can heal itself (or be healed by an ally)
|
||||||
|
if target.has_active_ability?(:SHEDSKIN)
|
||||||
|
score -= 5
|
||||||
|
elsif target.has_active_ability?(:HYDRATION) &&
|
||||||
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
ai.each_same_side_battler(target.side) do |b|
|
||||||
|
score -= 5 if b.index != target.index && b.has_active_ability?(:HEALER)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
@@ -26,7 +49,7 @@ Battle::AI::Handlers::MoveEffectScore.add("SleepTarget",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("SleepTargetIfUserDarkrai",
|
Battle::AI::Handlers::MoveFailureCheck.add("SleepTargetIfUserDarkrai",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -38,13 +61,13 @@ Battle::AI::Handlers::MoveEffectScore.copy("SleepTarget",
|
|||||||
"SleepTargetIfUserDarkrai")
|
"SleepTargetIfUserDarkrai")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.copy("SleepTarget",
|
Battle::AI::Handlers::MoveEffectScore.copy("SleepTarget",
|
||||||
"SleepTargetChangeUserMeloettaForm")
|
"SleepTargetChangeUserMeloettaForm")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("SleepTargetNextTurn",
|
Battle::AI::Handlers::MoveFailureCheck.add("SleepTargetNextTurn",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -52,24 +75,11 @@ Battle::AI::Handlers::MoveFailureCheck.add("SleepTargetNextTurn",
|
|||||||
next true if !target.battler.pbCanSleep?(user.battler, false, move.move)
|
next true if !target.battler.pbCanSleep?(user.battler, false, move.move)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("SleepTargetNextTurn",
|
Battle::AI::Handlers::MoveEffectScore.copy("SleepTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
"SleepTargetNextTurn")
|
||||||
if target.battler.pbCanSleep?(user.battler, false, move.move)
|
|
||||||
score += 30
|
|
||||||
score -= 30 if target.has_active_ability?(:MARVELSCALE)
|
|
||||||
if ai.trainer.best_skill?
|
|
||||||
if target.battler.pbHasMoveFunction?("FlinchTargetFailsIfUserNotAsleep",
|
|
||||||
"UseRandomUserMoveIfAsleep") # Snore, Sleep Talk
|
|
||||||
score -= 50
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
next score
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("PoisonTarget",
|
Battle::AI::Handlers::MoveFailureCheck.add("PoisonTarget",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -78,18 +88,46 @@ Battle::AI::Handlers::MoveFailureCheck.add("PoisonTarget",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("PoisonTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("PoisonTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if target.battler.pbCanPoison?(user.battler, false, move.move)
|
next score if target.effects[PBEffects::Yawn] > 0 # Target is going to fall asleep
|
||||||
score += 30
|
next score - 40 if move.statusMove? && target.has_active_ability?(:POISONHEAL)
|
||||||
if ai.trainer.medium_skill?
|
# No score modifier if the poisoning will be removed immediately
|
||||||
score += 30 if target.hp <= target.totalhp / 4
|
next score if target.has_active_item?([:PECHABERRY, :LUMBERRY])
|
||||||
score += 50 if target.hp <= target.totalhp / 8
|
next score if target.faster_than?(user) &&
|
||||||
score -= 40 if target.effects[PBEffects::Yawn] > 0
|
target.has_active_ability?(:HYDRATION) &&
|
||||||
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
|
if move.statusMove? || target.battler.pbCanPoison?(user.battler, false, move.move)
|
||||||
|
# Inherent preference
|
||||||
|
score += 10
|
||||||
|
# Prefer if the target is at high HP
|
||||||
|
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
|
||||||
|
ai.each_same_side_battler(user.side) do |b|
|
||||||
|
score += 5 if b.check_for_move { |m| ["DoublePowerIfTargetPoisoned",
|
||||||
|
"DoublePowerIfTargetStatusProblem"].include?(m.function) }
|
||||||
|
score += 10 if b.has_active_ability?(:MERCILESS)
|
||||||
end
|
end
|
||||||
if ai.trainer.high_skill?
|
# Don't prefer if target benefits from having the poison status problem
|
||||||
score += 10 if target.rough_stat(:DEFENSE) > 100
|
score -= 8 if target.has_active_ability?([:GUTS, :MARVELSCALE, :QUICKFEET, :TOXICBOOST])
|
||||||
score += 10 if target.rough_stat(:SPECIAL_DEFENSE) > 100
|
score -= 25 if target.has_active_ability?(:POISONHEAL)
|
||||||
|
score -= 15 if target.has_active_ability?(:SYNCHRONIZE) &&
|
||||||
|
user.battler.pbCanPoisonSynchronize?(target.battler)
|
||||||
|
score -= 5 if target.check_for_move { |m| ["DoublePowerIfUserPoisonedBurnedParalyzed",
|
||||||
|
"CureUserBurnPoisonParalysis"].include?(m.function) }
|
||||||
|
score -= 10 if target.check_for_move { |m|
|
||||||
|
m.function == "GiveUserStatusToTarget" && user.battler.pbCanPoison?(target.battler, false, m)
|
||||||
|
}
|
||||||
|
# Don't prefer if the target won't take damage from the poison
|
||||||
|
score -= 15 if !target.battler.takesIndirectDamage?
|
||||||
|
# Don't prefer if the target can heal itself (or be healed by an ally)
|
||||||
|
if target.has_active_ability?(:SHEDSKIN)
|
||||||
|
score -= 5
|
||||||
|
elsif target.has_active_ability?(:HYDRATION) &&
|
||||||
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
ai.each_same_side_battler(target.side) do |b|
|
||||||
|
score -= 5 if b.index != target.index && b.has_active_ability?(:HEALER)
|
||||||
end
|
end
|
||||||
score -= 40 if target.has_active_ability?([:GUTS, :MARVELSCALE, :TOXICBOOST])
|
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
@@ -106,57 +144,24 @@ Battle::AI::Handlers::MoveFailureCheck.add("PoisonTargetLowerTargetSpeed1",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("PoisonTargetLowerTargetSpeed1",
|
Battle::AI::Handlers::MoveEffectScore.add("PoisonTargetLowerTargetSpeed1",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if target.battler.pbCanPoison?(user.battler, false)
|
score = Battle::AI::Handlers.apply_move_effect_score("PoisonTarget",
|
||||||
score += 30
|
score, move, user, target, ai, battle)
|
||||||
if ai.trainer.medium_skill?
|
score = Battle::AI::Handlers.apply_move_effect_score("LowerTargetSpeed1",
|
||||||
score += 30 if target.hp <= target.totalhp / 4
|
score, move, user, target, ai, battle)
|
||||||
score += 50 if target.hp <= target.totalhp / 8
|
|
||||||
score -= 40 if target.effects[PBEffects::Yawn] > 0
|
|
||||||
end
|
|
||||||
if ai.trainer.high_skill?
|
|
||||||
score += 10 if target.rough_stat(:DEFENSE) > 100
|
|
||||||
score += 10 if target.rough_stat(:SPECIAL_DEFENSE) > 100
|
|
||||||
end
|
|
||||||
score -= 40 if target.has_active_ability?([:GUTS, :MARVELSCALE, :TOXICBOOST])
|
|
||||||
end
|
|
||||||
if target.battler.pbCanLowerStatStage?(:SPEED, user.battler)
|
|
||||||
score += target.stages[:SPEED] * 10
|
|
||||||
if ai.trainer.high_skill?
|
|
||||||
aspeed = user.rough_stat(:SPEED)
|
|
||||||
ospeed = target.rough_stat(:SPEED)
|
|
||||||
score += 30 if aspeed < ospeed && aspeed * 2 > ospeed
|
|
||||||
end
|
|
||||||
end
|
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.copy("PoisonTarget",
|
Battle::AI::Handlers::MoveFailureCheck.copy("PoisonTarget",
|
||||||
"BadPoisonTarget")
|
"BadPoisonTarget")
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("BadPoisonTarget",
|
Battle::AI::Handlers::MoveEffectScore.copy("PoisonTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
"BadPoisonTarget")
|
||||||
if target.battler.pbCanPoison?(user.battler, false)
|
|
||||||
score += 30
|
|
||||||
if ai.trainer.medium_skill?
|
|
||||||
score += 30 if target.hp <= target.totalhp / 4
|
|
||||||
score += 50 if target.hp <= target.totalhp / 8
|
|
||||||
score -= 40 if target.effects[PBEffects::Yawn] > 0
|
|
||||||
end
|
|
||||||
if ai.trainer.high_skill?
|
|
||||||
score += 10 if target.rough_stat(:DEFENSE) > 100
|
|
||||||
score += 10 if target.rough_stat(:SPECIAL_DEFENSE) > 100
|
|
||||||
end
|
|
||||||
score -= 40 if target.has_active_ability?([:GUTS, :MARVELSCALE, :TOXICBOOST])
|
|
||||||
end
|
|
||||||
next score
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("ParalyzeTarget",
|
Battle::AI::Handlers::MoveFailureCheck.add("ParalyzeTarget",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -165,25 +170,56 @@ Battle::AI::Handlers::MoveFailureCheck.add("ParalyzeTarget",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("ParalyzeTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("ParalyzeTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if target.battler.pbCanParalyze?(user.battler, false, move.move)
|
next score if target.effects[PBEffects::Yawn] > 0 # Target is going to fall asleep
|
||||||
score += 30
|
# No score modifier if the paralysis will be removed immediately
|
||||||
if ai.trainer.medium_skill?
|
next score if target.has_active_item?([:CHERIBERRY, :LUMBERRY])
|
||||||
aspeed = user.rough_stat(:SPEED)
|
next score if target.faster_than?(user) &&
|
||||||
ospeed = target.rough_stat(:SPEED)
|
target.has_active_ability?(:HYDRATION) &&
|
||||||
if aspeed < ospeed
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
score += 30
|
if move.statusMove? || target.battler.pbCanParalyze?(user.battler, false, move.move)
|
||||||
elsif aspeed > ospeed
|
# Inherent preference (because of the chance of full paralysis)
|
||||||
score -= 40
|
score += 10
|
||||||
end
|
# Prefer if the target is faster than the user but will become slower if
|
||||||
|
# paralysed
|
||||||
|
if target.faster_than?(user)
|
||||||
|
user_speed = user.rough_stat(:SPEED)
|
||||||
|
target_speed = target.rough_stat(:SPEED)
|
||||||
|
score += 10 if target_speed < user_speed * ((Settings::MECHANICS_GENERATION >= 7) ? 2 : 4)
|
||||||
|
end
|
||||||
|
# Prefer if the target is confused or infatuated, to compound the turn skipping
|
||||||
|
score += 5 if target.effects[PBEffects::Confusion] > 1
|
||||||
|
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
|
||||||
|
ai.each_same_side_battler(user.side) do |b|
|
||||||
|
score += 5 if b.check_for_move { |m| ["DoublePowerIfTargetParalyzedCureTarget",
|
||||||
|
"DoublePowerIfTargetStatusProblem"].include?(m.function) }
|
||||||
|
end
|
||||||
|
# Don't prefer if target benefits from having the paralysis status problem
|
||||||
|
score -= 8 if target.has_active_ability?([:GUTS, :MARVELSCALE, :QUICKFEET])
|
||||||
|
score -= 15 if target.has_active_ability?(:SYNCHRONIZE) &&
|
||||||
|
user.battler.pbCanParalyzeSynchronize?(target.battler)
|
||||||
|
score -= 5 if target.check_for_move { |m| ["DoublePowerIfUserPoisonedBurnedParalyzed",
|
||||||
|
"CureUserBurnPoisonParalysis"].include?(m.function) }
|
||||||
|
score -= 10 if target.check_for_move { |m|
|
||||||
|
m.function == "GiveUserStatusToTarget" && user.battler.pbCanParalyze?(target.battler, false, m)
|
||||||
|
}
|
||||||
|
# Don't prefer if the target can heal itself (or be healed by an ally)
|
||||||
|
if target.has_active_ability?(:SHEDSKIN)
|
||||||
|
score -= 5
|
||||||
|
elsif target.has_active_ability?(:HYDRATION) &&
|
||||||
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
ai.each_same_side_battler(target.side) do |b|
|
||||||
|
score -= 5 if b.index != target.index && b.has_active_ability?(:HEALER)
|
||||||
end
|
end
|
||||||
score -= 40 if target.has_active_ability?([:GUTS, :MARVELSCALE, :QUICKFEET])
|
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("ParalyzeTargetIfNotTypeImmune",
|
Battle::AI::Handlers::MoveFailureCheck.add("ParalyzeTargetIfNotTypeImmune",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -196,15 +232,20 @@ Battle::AI::Handlers::MoveEffectScore.copy("ParalyzeTarget",
|
|||||||
"ParalyzeTargetIfNotTypeImmune")
|
"ParalyzeTargetIfNotTypeImmune")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.copy("ParalyzeTarget",
|
Battle::AI::Handlers::MoveEffectScore.copy("ParalyzeTarget",
|
||||||
"ParalyzeTargetAlwaysHitsInRainHitsTargetInSky",
|
"ParalyzeTargetAlwaysHitsInRainHitsTargetInSky")
|
||||||
"ParalyzeFlinchTarget")
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
# TODO: Review score modifiers.
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
|
Battle::AI::Handlers::MoveEffectScore.copy("ParalyzeTarget",
|
||||||
|
"ParalyzeFlinchTarget")
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
#
|
||||||
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("BurnTarget",
|
Battle::AI::Handlers::MoveFailureCheck.add("BurnTarget",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if move.statusMove? && !target.battler.pbCanBurn?(user.battler, false, move.move)
|
next true if move.statusMove? && !target.battler.pbCanBurn?(user.battler, false, move.move)
|
||||||
@@ -212,19 +253,55 @@ Battle::AI::Handlers::MoveFailureCheck.add("BurnTarget",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("BurnTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("BurnTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if target.battler.pbCanBurn?(user.battler, false, move.move)
|
next score if target.effects[PBEffects::Yawn] > 0 # Target is going to fall asleep
|
||||||
score += 30
|
# No score modifier if the burn will be removed immediately
|
||||||
score -= 40 if target.has_active_ability?([:GUTS, :MARVELSCALE, :QUICKFEET, :FLAREBOOST])
|
next score if target.has_active_item?([:RAWSTBERRY, :LUMBERRY])
|
||||||
|
next score if target.faster_than?(user) &&
|
||||||
|
target.has_active_ability?(:HYDRATION) &&
|
||||||
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
|
if move.statusMove? || target.battler.pbCanBurn?(user.battler, false, move.move)
|
||||||
|
# Inherent preference
|
||||||
|
score += 10
|
||||||
|
# Prefer if the target knows any physical moves that will be weaked by a burn
|
||||||
|
if !target.has_active_ability?(:GUTS) && target.check_for_move { |m| m.physicalMove? }
|
||||||
|
score += 5
|
||||||
|
score += 8 if !target.check_for_move { |m| m.specialMove? }
|
||||||
|
end
|
||||||
|
# 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|
|
||||||
|
score += 5 if b.check_for_move { |m| m.function == "DoublePowerIfTargetStatusProblem" }
|
||||||
|
end
|
||||||
|
# Don't prefer if target benefits from having the burn status problem
|
||||||
|
score -= 8 if target.has_active_ability?([:FLAREBOOST, :GUTS, :MARVELSCALE, :QUICKFEET])
|
||||||
|
score -= 5 if target.has_active_ability?(:HEATPROOF)
|
||||||
|
score -= 15 if target.has_active_ability?(:SYNCHRONIZE) &&
|
||||||
|
user.battler.pbCanBurnSynchronize?(target.battler)
|
||||||
|
score -= 5 if target.check_for_move { |m| ["DoublePowerIfUserPoisonedBurnedParalyzed",
|
||||||
|
"CureUserBurnPoisonParalysis"].include?(m.function) }
|
||||||
|
score -= 10 if target.check_for_move { |m|
|
||||||
|
m.function == "GiveUserStatusToTarget" && user.battler.pbCanBurn?(target.battler, false, m)
|
||||||
|
}
|
||||||
|
# Don't prefer if the target won't take damage from the burn
|
||||||
|
score -= 15 if !target.battler.takesIndirectDamage?
|
||||||
|
# Don't prefer if the target can heal itself (or be healed by an ally)
|
||||||
|
if target.has_active_ability?(:SHEDSKIN)
|
||||||
|
score -= 5
|
||||||
|
elsif target.has_active_ability?(:HYDRATION) &&
|
||||||
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
ai.each_same_side_battler(target.side) do |b|
|
||||||
|
score -= 5 if b.index != target.index && b.has_active_ability?(:HEALER)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.copy("BurnTarget",
|
# BurnTargetIfTargetStatsRaisedThisTurn
|
||||||
"BurnTargetIfTargetStatsRaisedThisTurn")
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
# TODO: Review score modifiers.
|
||||||
@@ -233,7 +310,7 @@ Battle::AI::Handlers::MoveEffectScore.copy("BurnTarget",
|
|||||||
"BurnFlinchTarget")
|
"BurnFlinchTarget")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("FreezeTarget",
|
Battle::AI::Handlers::MoveFailureCheck.add("FreezeTarget",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -242,22 +319,49 @@ Battle::AI::Handlers::MoveFailureCheck.add("FreezeTarget",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("FreezeTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("FreezeTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if target.battler.pbCanFreeze?(user.battler, false, move.move)
|
next score if target.effects[PBEffects::Yawn] > 0 # Target is going to fall asleep
|
||||||
score += 30
|
# No score modifier if the freeze will be removed immediately
|
||||||
score -= 20 if target.has_active_ability?(:MARVELSCALE)
|
next score if target.has_active_item?([:ASPEARBERRY, :LUMBERRY])
|
||||||
|
next score if target.faster_than?(user) &&
|
||||||
|
target.has_active_ability?(:HYDRATION) &&
|
||||||
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
|
if move.statusMove? || target.battler.pbCanFreeze?(user.battler, false, move.move)
|
||||||
|
# Inherent preference
|
||||||
|
score += 15
|
||||||
|
# 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|
|
||||||
|
score += 5 if b.check_for_move { |m| m.function == "DoublePowerIfTargetStatusProblem" }
|
||||||
|
end
|
||||||
|
# Don't prefer if target benefits from having the frozen status problem
|
||||||
|
# NOTE: The target's Guts/Quick Feet will benefit from the target being
|
||||||
|
# frozen, but the target won't be able to make use of them, so
|
||||||
|
# they're not worth considering.
|
||||||
|
score -= 5 if target.has_active_ability?(:MARVELSCALE)
|
||||||
|
# Don't prefer if the target knows a move that can thaw it
|
||||||
|
score -= 15 if target.check_for_move { |m| m.thawsUser? }
|
||||||
|
# Don't prefer if the target can heal itself (or be healed by an ally)
|
||||||
|
if target.has_active_ability?(:SHEDSKIN)
|
||||||
|
score -= 5
|
||||||
|
elsif target.has_active_ability?(:HYDRATION) &&
|
||||||
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
ai.each_same_side_battler(target.side) do |b|
|
||||||
|
score -= 5 if b.index != target.index && b.has_active_ability?(:HEALER)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.copy("FreezeTarget",
|
Battle::AI::Handlers::MoveEffectScore.copy("FreezeTarget",
|
||||||
"FreezeTargetSuperEffectiveAgainstWater")
|
"FreezeTargetSuperEffectiveAgainstWater")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.copy("FreezeTarget",
|
Battle::AI::Handlers::MoveEffectScore.copy("FreezeTarget",
|
||||||
"FreezeTargetAlwaysHitsInHail")
|
"FreezeTargetAlwaysHitsInHail")
|
||||||
@@ -269,11 +373,24 @@ Battle::AI::Handlers::MoveEffectScore.copy("FreezeTarget",
|
|||||||
"FreezeFlinchTarget")
|
"FreezeFlinchTarget")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("ParalyzeBurnOrFreezeTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("ParalyzeBurnOrFreezeTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next score + 30 if target.status == :NONE
|
next score if target.effects[PBEffects::Yawn] > 0 # Target is going to fall asleep
|
||||||
|
# No score modifier if the status problem will be removed immediately
|
||||||
|
next score if target.has_active_item?(:LUMBERRY)
|
||||||
|
next score if target.faster_than?(user) &&
|
||||||
|
target.has_active_ability?(:HYDRATION) &&
|
||||||
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
|
# Scores for the possible effects
|
||||||
|
score += (Battle::AI::Handlers.apply_move_effect_score("ParalyzeTarget",
|
||||||
|
100, move, user, target, ai, battle) - 100) / 3
|
||||||
|
score += (Battle::AI::Handlers.apply_move_effect_score("BurnTarget",
|
||||||
|
100, move, user, target, ai, battle) - 100) / 3
|
||||||
|
score += (Battle::AI::Handlers.apply_move_effect_score("FreezeTarget",
|
||||||
|
100, move, user, target, ai, battle) - 100) / 3
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -529,17 +529,14 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUser",
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("ProtectUserBanefulBunker",
|
Battle::AI::Handlers::MoveEffectScore.add("ProtectUserBanefulBunker",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if user.effects[PBEffects::ProtectRate] > 1 ||
|
next score - 40 if user.effects[PBEffects::ProtectRate] > 1 ||
|
||||||
target.effects[PBEffects::HyperBeam] > 0
|
target.effects[PBEffects::HyperBeam] > 0
|
||||||
score -= 50
|
if ai.trainer.medium_skill?
|
||||||
else
|
score -= user.effects[PBEffects::ProtectRate] * 40
|
||||||
if ai.trainer.medium_skill?
|
|
||||||
score -= user.effects[PBEffects::ProtectRate] * 40
|
|
||||||
end
|
|
||||||
score += 50 if user.turnCount == 0
|
|
||||||
score += 30 if target.effects[PBEffects::TwoTurnAttack]
|
|
||||||
score += 20 # Because of possible poisoning
|
|
||||||
end
|
end
|
||||||
|
score += 10 if user.turnCount == 0
|
||||||
|
score += 15 if target.effects[PBEffects::TwoTurnAttack]
|
||||||
|
score += 15 # Because of possible poisoning
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -668,7 +665,7 @@ Battle::AI::Handlers::MoveEffectScore.add("HoopaRemoveProtectionsBypassSubstitut
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("RecoilQuarterOfDamageDealt",
|
Battle::AI::Handlers::MoveEffectScore.add("RecoilQuarterOfDamageDealt",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next score - 25
|
next score - 8
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -677,20 +674,11 @@ Battle::AI::Handlers::MoveEffectScore.add("RecoilQuarterOfDamageDealt",
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("RecoilThirdOfDamageDealtParalyzeTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("RecoilThirdOfDamageDealtParalyzeTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
score -= 30
|
# Score for being a recoil move
|
||||||
if target.battler.pbCanParalyze?(user.battler, false)
|
score -= 10
|
||||||
score += 30
|
# Score for paralysing
|
||||||
if ai.trainer.medium_skill?
|
score = Battle::AI::Handlers.apply_move_effect_score("ParalyzeTarget",
|
||||||
aspeed = user.rough_stat(:SPEED)
|
score, move, user, target, ai, battle)
|
||||||
ospeed = target.rough_stat(:SPEED)
|
|
||||||
if aspeed < ospeed
|
|
||||||
score += 30
|
|
||||||
elsif aspeed > ospeed
|
|
||||||
score -= 40
|
|
||||||
end
|
|
||||||
end
|
|
||||||
score -= 40 if target.has_active_ability?([:GUTS, :MARVELSCALE, :QUICKFEET])
|
|
||||||
end
|
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -700,11 +688,11 @@ Battle::AI::Handlers::MoveEffectScore.add("RecoilThirdOfDamageDealtParalyzeTarge
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("RecoilThirdOfDamageDealtBurnTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("RecoilThirdOfDamageDealtBurnTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
score -= 30
|
# Score for being a recoil move
|
||||||
if target.battler.pbCanBurn?(user.battler, false)
|
score -= 10
|
||||||
score += 30
|
# Score for burning
|
||||||
score -= 40 if target.has_active_ability?([:GUTS, :MARVELSCALE, :QUICKFEET, :FLAREBOOST])
|
score = Battle::AI::Handlers.apply_move_effect_score("BurnTarget",
|
||||||
end
|
score, move, user, target, ai, battle)
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -714,7 +702,7 @@ Battle::AI::Handlers::MoveEffectScore.add("RecoilThirdOfDamageDealtBurnTarget",
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("RecoilHalfOfDamageDealt",
|
Battle::AI::Handlers::MoveEffectScore.add("RecoilHalfOfDamageDealt",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next score - 40
|
next score - 15
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Battle::AI::Handlers::MoveEffectScore.add("HitTwoTimes",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveBasePower.copy("HitTwoTimes",
|
Battle::AI::Handlers::MoveBasePower.copy("HitTwoTimes",
|
||||||
"HitTwoTimesPoisonTarget")
|
"HitTwoTimesPoisonTarget")
|
||||||
@@ -29,19 +29,9 @@ Battle::AI::Handlers::MoveEffectScore.add("HitTwoTimesPoisonTarget",
|
|||||||
# Score for hitting multiple times
|
# Score for hitting multiple times
|
||||||
score = Battle::AI::Handlers.apply_move_effect_score("HitTwoTimes",
|
score = Battle::AI::Handlers.apply_move_effect_score("HitTwoTimes",
|
||||||
score, move, user, target, ai, battle)
|
score, move, user, target, ai, battle)
|
||||||
next score if !target.battler.pbCanPoison?(user.battler, false)
|
# Score for poisoning
|
||||||
# Poisoning
|
score = Battle::AI::Handlers.apply_move_effect_score("PoisonTarget",
|
||||||
score += 30
|
score, move, user, target, ai, battle)
|
||||||
if ai.trainer.medium_skill?
|
|
||||||
score += 30 if target.hp <= target.totalhp / 4
|
|
||||||
score += 50 if target.hp <= target.totalhp / 8
|
|
||||||
score -= 40 if target.effects[PBEffects::Yawn] > 0
|
|
||||||
end
|
|
||||||
if ai.trainer.high_skill?
|
|
||||||
score += 10 if target.rough_stat(:DEFENSE) > 100
|
|
||||||
score += 10 if target.rough_stat(:SPECIAL_DEFENSE) > 100
|
|
||||||
end
|
|
||||||
score -= 40 if target.has_active_ability?([:GUTS, :MARVELSCALE, :TOXICBOOST])
|
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -285,42 +275,31 @@ Battle::AI::Handlers::MoveEffectScore.add("TwoTurnAttackOneTurnInSun",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("TwoTurnAttackParalyzeTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("TwoTurnAttackParalyzeTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
# Score for being a two turn attack
|
# Score for being a two turn attack
|
||||||
score = Battle::AI::Handlers.apply_move_effect_score("TwoTurnAttack",
|
score = Battle::AI::Handlers.apply_move_effect_score("TwoTurnAttack",
|
||||||
score, move, user, target, ai, battle)
|
score, move, user, target, ai, battle)
|
||||||
# Paralyze the target
|
# Score for paralysing
|
||||||
if !target.battler.pbCanParalyze?(user.battler, false)
|
score = Battle::AI::Handlers.apply_move_effect_score("ParalyzeTarget",
|
||||||
score += 10
|
score, move, user, target, ai, battle)
|
||||||
if ai.trainer.medium_skill?
|
|
||||||
score += 10 if !user.faster_than?(target)
|
|
||||||
end
|
|
||||||
score -= 15 if target.has_active_ability?([:GUTS, :MARVELSCALE, :QUICKFEET])
|
|
||||||
else
|
|
||||||
next 25 if move.statusMove?
|
|
||||||
end
|
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("TwoTurnAttackBurnTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("TwoTurnAttackBurnTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
# Score for being a two turn attack
|
# Score for being a two turn attack
|
||||||
score = Battle::AI::Handlers.apply_move_effect_score("TwoTurnAttack",
|
score = Battle::AI::Handlers.apply_move_effect_score("TwoTurnAttack",
|
||||||
score, move, user, target, ai, battle)
|
score, move, user, target, ai, battle)
|
||||||
# Burn the target
|
# Score for burning
|
||||||
if target.battler.pbCanBurn?(user.battler, false)
|
score = Battle::AI::Handlers.apply_move_effect_score("BurnTarget",
|
||||||
score += 10
|
score, move, user, target, ai, battle)
|
||||||
score -= 15 if target.has_active_ability?([:GUTS, :MARVELSCALE, :QUICKFEET, :FLAREBOOST])
|
|
||||||
else
|
|
||||||
next 25 if move.statusMove?
|
|
||||||
end
|
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ class Battle::AI::AIBattler
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
@battler.pbTypes(true).each_with_index do |defend_type, i|
|
@battler.pbTypes(true).each_with_index do |defend_type, i|
|
||||||
|
# TODO: Need to check the move's pbCalcTypeModSingle.
|
||||||
type_mults[i] = effectiveness_of_type_against_single_battler_type(type, defend_type, user)
|
type_mults[i] = effectiveness_of_type_against_single_battler_type(type, defend_type, user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -545,6 +545,7 @@ class Battle::AI::AIMove
|
|||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
|
|
||||||
|
# TODO:
|
||||||
# pbBaseAccuracy(@ai.user.battler, @ai.target.battler) if @ai.trainer.medium_skill?
|
# pbBaseAccuracy(@ai.user.battler, @ai.target.battler) if @ai.trainer.medium_skill?
|
||||||
# pbCriticalOverride(@ai.user.battler, @ai.target.battler)
|
# pbCriticalOverride(@ai.user.battler, @ai.target.battler)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user