Rewrote AI calculations for moves that inflict a status problem

This commit is contained in:
Maruno17
2022-10-04 21:25:58 +01:00
parent 63ec037481
commit 2897476d1b
7 changed files with 264 additions and 176 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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
} }
) )

View File

@@ -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
} }
) )

View File

@@ -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
} }
) )

View File

@@ -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

View File

@@ -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