mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-07 13:15:01 +00:00
AI function code rewrites, added Shadow Sky's missing effects, fixed Shadow End's recoil damage
This commit is contained in:
@@ -750,7 +750,7 @@ module GameData
|
|||||||
when "12F" then new_code = "TrapTargetInBattle"
|
when "12F" then new_code = "TrapTargetInBattle"
|
||||||
when "130" then new_code = "UserLosesHalfHP"
|
when "130" then new_code = "UserLosesHalfHP"
|
||||||
when "131" then new_code = "StartShadowSkyWeather"
|
when "131" then new_code = "StartShadowSkyWeather"
|
||||||
when "132" then new_code = "RemoveAllScreens"
|
when "132" then new_code = "RemoveAllScreensAndSafeguard"
|
||||||
when "133" then new_code = "DoesNothingFailsIfNoAlly"
|
when "133" then new_code = "DoesNothingFailsIfNoAlly"
|
||||||
when "134" then new_code = "DoesNothingCongratulations"
|
when "134" then new_code = "DoesNothingCongratulations"
|
||||||
when "135" then new_code = "FreezeTargetSuperEffectiveAgainstWater"
|
when "135" then new_code = "FreezeTargetSuperEffectiveAgainstWater"
|
||||||
|
|||||||
@@ -423,6 +423,8 @@ class Battle::Move
|
|||||||
if target.pbHasType?(:ROCK) && specialMove? && @function != "UseTargetDefenseInsteadOfTargetSpDef"
|
if target.pbHasType?(:ROCK) && specialMove? && @function != "UseTargetDefenseInsteadOfTargetSpDef"
|
||||||
multipliers[:defense_multiplier] *= 1.5
|
multipliers[:defense_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
|
when :ShadowSky
|
||||||
|
multipliers[:final_damage_multiplier] *= 1.5 if type == :SHADOW
|
||||||
end
|
end
|
||||||
# Critical hits
|
# Critical hits
|
||||||
if target.damageState.critical
|
if target.damageState.critical
|
||||||
|
|||||||
@@ -839,9 +839,9 @@ class Battle::Move::RemoveScreens < Battle::Move
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true)
|
def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true)
|
||||||
if user.pbOpposingSide.effects[PBEffects::LightScreen] > 0 ||
|
if user.pbOpposingSide.effects[PBEffects::AuroraVeil] > 0 ||
|
||||||
user.pbOpposingSide.effects[PBEffects::Reflect] > 0 ||
|
user.pbOpposingSide.effects[PBEffects::LightScreen] > 0 ||
|
||||||
user.pbOpposingSide.effects[PBEffects::AuroraVeil] > 0
|
user.pbOpposingSide.effects[PBEffects::Reflect] > 0
|
||||||
hitNum = 1 # Wall-breaking anim
|
hitNum = 1 # Wall-breaking anim
|
||||||
end
|
end
|
||||||
super
|
super
|
||||||
@@ -1540,6 +1540,8 @@ class Battle::Move::TypeAndPowerDependOnWeather < Battle::Move
|
|||||||
ret = :ROCK if GameData::Type.exists?(:ROCK)
|
ret = :ROCK if GameData::Type.exists?(:ROCK)
|
||||||
when :Hail
|
when :Hail
|
||||||
ret = :ICE if GameData::Type.exists?(:ICE)
|
ret = :ICE if GameData::Type.exists?(:ICE)
|
||||||
|
when :ShadowSky
|
||||||
|
ret = :NONE
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -109,8 +109,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FailsIfUserDamagedThisTu
|
|||||||
# Check whether user is faster than its foe(s) and could use this move
|
# Check whether user is faster than its foe(s) and could use this move
|
||||||
user_faster_count = 0
|
user_faster_count = 0
|
||||||
foe_faster_count = 0
|
foe_faster_count = 0
|
||||||
ai.battlers.each_with_index do |b, i|
|
ai.each_foe_battler(user.side) do |b, i|
|
||||||
next if !user.opposes?(b) || b.battler.fainted?
|
|
||||||
if user.faster_than?(b)
|
if user.faster_than?(b)
|
||||||
user_faster_count += 1
|
user_faster_count += 1
|
||||||
else
|
else
|
||||||
@@ -121,10 +120,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FailsIfUserDamagedThisTu
|
|||||||
score += 10 if foe_faster_count == 0
|
score += 10 if foe_faster_count == 0
|
||||||
# Effects that make the target unlikely to act before the user
|
# Effects that make the target unlikely to act before the user
|
||||||
if ai.trainer.high_skill?
|
if ai.trainer.high_skill?
|
||||||
if target.effects[PBEffects::HyperBeam] > 0 ||
|
if !target.can_attack?
|
||||||
target.effects[PBEffects::Truant] ||
|
|
||||||
(target.battler.asleep? && target.statusCount > 1) ||
|
|
||||||
target.battler.frozen?
|
|
||||||
score += 20
|
score += 20
|
||||||
elsif target.effects[PBEffects::Confusion] > 1 ||
|
elsif target.effects[PBEffects::Confusion] > 1 ||
|
||||||
target.effects[PBEffects::Attract] == user.index
|
target.effects[PBEffects::Attract] == user.index
|
||||||
@@ -183,8 +179,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartSunWeather",
|
|||||||
score += 15 if user.has_active_item?(:HEATROCK)
|
score += 15 if user.has_active_item?(:HEATROCK)
|
||||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||||
# Check for Fire/Water moves
|
# Check for Fire/Water moves
|
||||||
ai.battlers.each do |b|
|
ai.each_battler do |b, i|
|
||||||
next if !b || b.battler.fainted?
|
|
||||||
if b.has_damaging_move_of_type?(:FIRE)
|
if b.has_damaging_move_of_type?(:FIRE)
|
||||||
score += (b.opposes?(user)) ? -15 : 15
|
score += (b.opposes?(user)) ? -15 : 15
|
||||||
end
|
end
|
||||||
@@ -229,8 +224,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartRainWeather",
|
|||||||
score += 15 if user.has_active_item?(:DAMPROCK)
|
score += 15 if user.has_active_item?(:DAMPROCK)
|
||||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||||
# Check for Fire/Water moves
|
# Check for Fire/Water moves
|
||||||
ai.battlers.each do |b|
|
ai.each_battler do |b, i|
|
||||||
next if !b || b.battler.fainted?
|
|
||||||
if b.has_damaging_move_of_type?(:WATER)
|
if b.has_damaging_move_of_type?(:WATER)
|
||||||
score += (b.opposes?(user)) ? -15 : 15
|
score += (b.opposes?(user)) ? -15 : 15
|
||||||
end
|
end
|
||||||
@@ -271,8 +265,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartSandstormWeather",
|
|||||||
score += 15 if user.has_active_item?(:SMOOTHROCK)
|
score += 15 if user.has_active_item?(:SMOOTHROCK)
|
||||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||||
# Check for battlers affected by sandstorm's effects
|
# Check for battlers affected by sandstorm's effects
|
||||||
ai.battlers.each do |b|
|
ai.each_battler do |b, i|
|
||||||
next if !b || b.battler.fainted?
|
|
||||||
if b.battler.takesSandstormDamage? # End of round damage
|
if b.battler.takesSandstormDamage? # End of round damage
|
||||||
score += (b.opposes?(user)) ? 15 : -15
|
score += (b.opposes?(user)) ? 15 : -15
|
||||||
end
|
end
|
||||||
@@ -312,8 +305,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartHailWeather",
|
|||||||
score += 15 if user.has_active_item?(:ICYROCK)
|
score += 15 if user.has_active_item?(:ICYROCK)
|
||||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||||
# Check for battlers affected by hail's effects
|
# Check for battlers affected by hail's effects
|
||||||
ai.battlers.each do |b|
|
ai.each_battler do |b, i|
|
||||||
next if !b || b.battler.fainted?
|
|
||||||
if b.battler.takesHailDamage? # End of round damage
|
if b.battler.takesHailDamage? # End of round damage
|
||||||
score += (b.opposes?(user)) ? 15 : -15
|
score += (b.opposes?(user)) ? 15 : -15
|
||||||
end
|
end
|
||||||
@@ -667,9 +659,9 @@ Battle::AI::Handlers::MoveFailureCheck.add("UserSwapsPositionsWithAlly",
|
|||||||
proc { |move, user, ai, battle|
|
proc { |move, user, ai, battle|
|
||||||
num_targets = 0
|
num_targets = 0
|
||||||
idxUserOwner = battle.pbGetOwnerIndexFromBattlerIndex(user.index)
|
idxUserOwner = battle.pbGetOwnerIndexFromBattlerIndex(user.index)
|
||||||
user.battler.allAllies.each do |b|
|
ai.each_ally(user.side) do |b, i|
|
||||||
next if battle.pbGetOwnerIndexFromBattlerIndex(b.index) != idxUserOwner
|
next if battle.pbGetOwnerIndexFromBattlerIndex(b.index) != idxUserOwner
|
||||||
next if !b.near?(user)
|
next if !b.battler.near?(user.battler)
|
||||||
num_targets += 1
|
num_targets += 1
|
||||||
end
|
end
|
||||||
next num_targets != 1
|
next num_targets != 1
|
||||||
@@ -686,8 +678,7 @@ Battle::AI::Handlers::MoveEffectScore.add("UserSwapsPositionsWithAlly",
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("BurnAttackerBeforeUserActs",
|
Battle::AI::Handlers::MoveEffectScore.add("BurnAttackerBeforeUserActs",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
ai.battlers.each do |b|
|
ai.each_foe_battler(user.side) do |b|
|
||||||
next if !b || !b.opposes?(user)
|
|
||||||
next if !b.battler.affectedByContactEffect?
|
next if !b.battler.affectedByContactEffect?
|
||||||
next if !b.battler.pbCanBurn?(user.battler, false, move.move)
|
next if !b.battler.pbCanBurn?(user.battler, false, move.move)
|
||||||
if ai.trainer.high_skill?
|
if ai.trainer.high_skill?
|
||||||
@@ -700,31 +691,43 @@ Battle::AI::Handlers::MoveEffectScore.add("BurnAttackerBeforeUserActs",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("AllBattlersLoseHalfHPUserSkipsNextTurn",
|
Battle::AI::Handlers::MoveEffectScore.add("AllBattlersLoseHalfHPUserSkipsNextTurn",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
next target.hp <= 1
|
# HP halving
|
||||||
}
|
foe_hp_lost = 0
|
||||||
)
|
ally_hp_lost = 0
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AllBattlersLoseHalfHPUserSkipsNextTurn",
|
ai.each_battler do |b, i|
|
||||||
proc { |score, move, user, target, ai, battle|
|
next if b.hp == 1
|
||||||
score += 20 if target.hp >= target.totalhp / 2
|
if b.battler.opposes?(user.battler)
|
||||||
|
foe_hp_lost += b.hp / 2
|
||||||
|
else
|
||||||
|
ally_hp_lost += b.hp / 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
score += 15 * foe_hp_lost / ally_hp_lost
|
||||||
|
score -= 15 * ally_hp_lost / foe_hp_lost
|
||||||
|
# Recharging
|
||||||
|
score = Battle::AI::Handlers.apply_move_effect_score("AttackAndSkipNextTurn",
|
||||||
|
score, move, user, ai, battle)
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("UserLosesHalfHP",
|
Battle::AI::Handlers::MoveEffectScore.add("UserLosesHalfHP",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
next score - 40
|
score = Battle::AI::Handlers.apply_move_effect_score("UserLosesHalfOfTotalHP",
|
||||||
|
score, move, user, ai, battle)
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.copy("StartSunWeather",
|
Battle::AI::Handlers::MoveFailureCheck.copy("StartSunWeather",
|
||||||
"StartShadowSkyWeather")
|
"StartShadowSkyWeather")
|
||||||
@@ -734,39 +737,64 @@ Battle::AI::Handlers::MoveEffectScore.add("StartShadowSkyWeather",
|
|||||||
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
||||||
score += 10 if battle.field.weather != :None # Prefer replacing another weather
|
score += 10 if battle.field.weather != :None # Prefer replacing another weather
|
||||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||||
|
# Check for battlers affected by Shadow Sky's effects
|
||||||
|
ai.each_battler do |b, i|
|
||||||
|
if b.has_damaging_move_of_type?(:SHADOW)
|
||||||
|
score += (b.opposes?(user)) ? 15 : -15
|
||||||
|
end
|
||||||
|
if b.battler.takesShadowSkyDamage? # End of round damage
|
||||||
|
score += (b.opposes?(user)) ? 15 : -15
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Check for moves affected by Shadow Sky
|
||||||
|
# TODO: Check other battlers for these as well?
|
||||||
|
if ai.trainer.medium_skill? && !user.has_active_item?(:UTILITYUMBRELLA)
|
||||||
|
if user.has_move_with_function?("TypeAndPowerDependOnWeather")
|
||||||
|
score += 10
|
||||||
|
end
|
||||||
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("RemoveAllScreens",
|
Battle::AI::Handlers::MoveFailureCheck.add("RemoveAllScreensAndSafeguard",
|
||||||
proc { |move, user, ai, battle|
|
proc { |move, user, ai, battle|
|
||||||
will_fail = true
|
will_fail = true
|
||||||
battle.sides.each do |side|
|
battle.sides.each do |side|
|
||||||
will_fail = false if side.effects[PBEffects::AuroraVeil] > 0 ||
|
will_fail = false if side.effects[PBEffects::AuroraVeil] > 0 ||
|
||||||
side.effects[PBEffects::Reflect] > 0 ||
|
|
||||||
side.effects[PBEffects::LightScreen] > 0 ||
|
side.effects[PBEffects::LightScreen] > 0 ||
|
||||||
|
side.effects[PBEffects::Reflect] > 0 ||
|
||||||
side.effects[PBEffects::Safeguard] > 0
|
side.effects[PBEffects::Safeguard] > 0
|
||||||
end
|
end
|
||||||
next will_fail
|
next will_fail
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("RemoveAllScreens",
|
Battle::AI::Handlers::MoveEffectScore.add("RemoveAllScreensAndSafeguard",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
if user.pbOpposingSide.effects[PBEffects::AuroraVeil] > 0 ||
|
foe_side = user.pbOpposingSide
|
||||||
user.pbOpposingSide.effects[PBEffects::Reflect] > 0 ||
|
# Useless if the foe's side has no screens/Safeguard to remove, or if
|
||||||
user.pbOpposingSide.effects[PBEffects::LightScreen] > 0 ||
|
# they'll end this round anyway
|
||||||
user.pbOpposingSide.effects[PBEffects::Safeguard] > 0
|
if foe_side.effects[PBEffects::AuroraVeil] <= 1 &&
|
||||||
score += 30
|
foe_side.effects[PBEffects::LightScreen] <= 1 &&
|
||||||
|
foe_side.effects[PBEffects::Reflect] <= 1 &&
|
||||||
|
foe_side.effects[PBEffects::Safeguard] <= 1
|
||||||
|
next Battle::AI::MOVE_USELESS_SCORE
|
||||||
end
|
end
|
||||||
if user.pbOwnSide.effects[PBEffects::AuroraVeil] > 0 ||
|
# Prefer removing opposing screens
|
||||||
user.pbOwnSide.effects[PBEffects::Reflect] > 0 ||
|
score = Battle::AI::Handlers.apply_move_effect_score("RemoveScreens",
|
||||||
user.pbOwnSide.effects[PBEffects::LightScreen] > 0 ||
|
score, move, user, ai, battle)
|
||||||
user.pbOwnSide.effects[PBEffects::Safeguard] > 0
|
# Don't prefer removing same side screens
|
||||||
score -= 70
|
ai.each_foe_battler(user.side) do |b, i|
|
||||||
|
score -= Battle::AI::Handlers.apply_move_effect_score("RemoveScreens",
|
||||||
|
0, move, b, ai, battle)
|
||||||
|
break
|
||||||
end
|
end
|
||||||
|
# Safeguard
|
||||||
|
score += 10 if foe_side.effects[PBEffects::Safeguard] > 0
|
||||||
|
score -= 10 if user.pbOwnSide.effects[PBEffects::Safeguard] > 0
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -371,9 +371,7 @@ Battle::AI::Handlers::MoveEffectScore.add("DoublePowerIfUserLostHPThisTurn",
|
|||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
# Prefer if user is slower than its foe(s) and the foe(s) can attack
|
# Prefer if user is slower than its foe(s) and the foe(s) can attack
|
||||||
ai.each_foe_battler(user.side) do |b, i|
|
ai.each_foe_battler(user.side) do |b, i|
|
||||||
next if user.faster_than?(b) || (b.status == :SLEEP && b.statusCount > 1) ||
|
next if user.faster_than?(b) || !b.can_attack?
|
||||||
b.status == :FROZEN || b.effects[PBEffects::HyperBeam] > 0 ||
|
|
||||||
b.effects[PBEffects::Truant] || b.effects[PBEffects::SkyDrop] >= 0
|
|
||||||
score += 4
|
score += 4
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
@@ -388,9 +386,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DoublePowerIfTargetLostH
|
|||||||
# Prefer if a user's ally is faster than the user and that ally can attack
|
# Prefer if a user's ally is faster than the user and that ally can attack
|
||||||
ai.each_foe_battler(target.side) do |b, i|
|
ai.each_foe_battler(target.side) do |b, i|
|
||||||
next if i == user.index
|
next if i == user.index
|
||||||
next if user.faster_than?(b) || (b.status == :SLEEP && b.statusCount > 1) ||
|
next if user.faster_than?(b) || !b.can_attack?
|
||||||
b.status == :FROZEN || b.effects[PBEffects::HyperBeam] > 0 ||
|
|
||||||
b.effects[PBEffects::Truant] || b.effects[PBEffects::SkyDrop] >= 0
|
|
||||||
score += 4
|
score += 4
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
@@ -428,25 +424,85 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DoublePowerIfTargetNotAc
|
|||||||
# AlwaysCriticalHit
|
# AlwaysCriticalHit
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("EnsureNextCriticalHit",
|
Battle::AI::Handlers::MoveEffectScore.add("EnsureNextCriticalHit",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if user.effects[PBEffects::LaserFocus] > 0
|
next Battle::AI::MOVE_USELESS_SCORE if user.effects[PBEffects::LaserFocus] > 0
|
||||||
# TODO: Useless if user will already always critical hit ("AlwaysCriticalHit"
|
# Useless if the user's critical hit stage ensures critical hits already, or
|
||||||
# or Lucky Chant/crit stage is +3/etc.).
|
# critical hits are impossible (e.g. via Lucky Chant)
|
||||||
next score + 10
|
crit_stage = move.rough_critical_hit_stage
|
||||||
|
if crit_stage < 0 ||
|
||||||
|
crit_stage >= Battle::Move::CRITICAL_HIT_RATIOS.length ||
|
||||||
|
Battle::Move::CRITICAL_HIT_RATIOS[crit_stage] == 1
|
||||||
|
next Battle::AI::MOVE_USELESS_SCORE
|
||||||
|
end
|
||||||
|
# Prefer if user knows a damaging move which won't definitely critical hit
|
||||||
|
if user.check_for_move { |m| m.damagingMove? && m.function != "AlwaysCriticalHit"}
|
||||||
|
# TODO: Change the score depending on how much of an effect a critical hit
|
||||||
|
# will have? Critical hits ignore the user's offensive stat drops
|
||||||
|
# and the target's defensive stat raises, and multiply the damage.
|
||||||
|
score += 10
|
||||||
|
end
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("StartPreventCriticalHitsAgainstUserSide",
|
Battle::AI::Handlers::MoveFailureCheck.add("StartPreventCriticalHitsAgainstUserSide",
|
||||||
proc { |move, user, ai, battle|
|
proc { |move, user, ai, battle|
|
||||||
next user.pbOwnSide.effects[PBEffects::LuckyChant] > 0
|
next user.pbOwnSide.effects[PBEffects::LuckyChant] > 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Battle::AI::Handlers::MoveEffectScore.add("StartPreventCriticalHitsAgainstUserSide",
|
||||||
|
proc { |score, move, user, ai, battle|
|
||||||
|
# Useless if Pokémon on the user's side are immune to critical hits
|
||||||
|
user_side_immune = true
|
||||||
|
ai.each_same_side_battler(user.side) do |b, i|
|
||||||
|
crit_stage = 0
|
||||||
|
if b.ability_active?
|
||||||
|
crit_stage = Battle::AbilityEffects.triggerCriticalCalcFromTarget(b.battler.ability,
|
||||||
|
b.battler, b.battler, crit_stage)
|
||||||
|
next if crit_stage < 0
|
||||||
|
end
|
||||||
|
if b.item_active?
|
||||||
|
crit_stage = Battle::ItemEffects.triggerCriticalCalcFromTarget(b.battler.item,
|
||||||
|
b.battler, b.battler, crit_stage)
|
||||||
|
next if crit_stage < 0
|
||||||
|
end
|
||||||
|
user_side_immune = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
next Battle::AI::MOVE_USELESS_SCORE if user_side_immune
|
||||||
|
# Prefer if any foe has an increased critical hit rate or moves/effects that
|
||||||
|
# make critical hits more likely
|
||||||
|
ai.each_foe_battler(user.side) do |b, i|
|
||||||
|
crit_stage = 0
|
||||||
|
if b.ability_active?
|
||||||
|
crit_stage = Battle::AbilityEffects.triggerCriticalCalcFromUser(b.battler.ability,
|
||||||
|
b.battler, user.battler, crit_stage)
|
||||||
|
next if crit_stage < 0
|
||||||
|
end
|
||||||
|
if b.item_active?
|
||||||
|
crit_stage = Battle::ItemEffects.triggerCriticalCalcFromUser(b.battler.item,
|
||||||
|
b.battler, user.battler, crit_stage)
|
||||||
|
next if crit_stage < 0
|
||||||
|
end
|
||||||
|
crit_stage += b.effects[PBEffects::FocusEnergy]
|
||||||
|
crit_stage += 1 if m.check_for_move { |m| m.highCriticalRate? }
|
||||||
|
crit_stage = [crit_stage, Battle::Move::CRITICAL_HIT_RATIOS.length - 1].min
|
||||||
|
crit_stage = 3 if crit_stage < 3 && m.check_for_move { |m| m.pbCritialOverride(b.battler, user.battler) > 0 }
|
||||||
|
# TODO: Change the score depending on how much of an effect a critical hit
|
||||||
|
# will have? Critical hits ignore the user's offensive stat drops
|
||||||
|
# and the target's defensive stat raises, and multiply the damage.
|
||||||
|
score += 5 * crit_stage if crit_stage > 0
|
||||||
|
score += 10 if b.effects[PBEffects::LaserFocus] > 0
|
||||||
|
end
|
||||||
|
next score
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
#
|
#
|
||||||
@@ -466,9 +522,7 @@ Battle::AI::Handlers::MoveEffectScore.add("UserEnduresFaintingThisTurn",
|
|||||||
# Prefer for each foe that can attack
|
# Prefer for each foe that can attack
|
||||||
useless = true
|
useless = true
|
||||||
ai.each_foe_battler(user.side) do |b, i|
|
ai.each_foe_battler(user.side) do |b, i|
|
||||||
next if (b.status == :SLEEP && b.statusCount > 1) ||
|
next if !b.can_attack?
|
||||||
b.status == :FROZEN || b.effects[PBEffects::HyperBeam] > 0 ||
|
|
||||||
b.effects[PBEffects::Truant] || b.effects[PBEffects::SkyDrop] >= 0
|
|
||||||
useless = false
|
useless = false
|
||||||
score += 4
|
score += 4
|
||||||
end
|
end
|
||||||
@@ -639,15 +693,15 @@ Battle::AI::Handlers::MoveEffectScore.add("StartWeakenDamageAgainstUserSideIfHai
|
|||||||
Battle::AI::Handlers::MoveEffectScore.add("RemoveScreens",
|
Battle::AI::Handlers::MoveEffectScore.add("RemoveScreens",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
# Prefer if allies have physical moves that are being weakened
|
# Prefer if allies have physical moves that are being weakened
|
||||||
if user.pbOpposingSide.effects[PBEffects::Reflect] > 0 ||
|
if user.pbOpposingSide.effects[PBEffects::Reflect] > 1 ||
|
||||||
user.pbOpposingSide.effects[PBEffects::AuroraVeil] > 0
|
user.pbOpposingSide.effects[PBEffects::AuroraVeil] > 1
|
||||||
ai.each_same_side_battler(user.side) do |b, i|
|
ai.each_same_side_battler(user.side) do |b, i|
|
||||||
score += 10 if b.check_for_move { |m| m.physicalMove?(m.type) }
|
score += 10 if b.check_for_move { |m| m.physicalMove?(m.type) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Prefer if allies have special moves that are being weakened
|
# Prefer if allies have special moves that are being weakened
|
||||||
if user.pbOpposingSide.effects[PBEffects::LightScreen] > 0 ||
|
if user.pbOpposingSide.effects[PBEffects::LightScreen] > 1 ||
|
||||||
user.pbOpposingSide.effects[PBEffects::AuroraVeil] > 0
|
user.pbOpposingSide.effects[PBEffects::AuroraVeil] > 1
|
||||||
ai.each_same_side_battler(user.side) do |b, i|
|
ai.each_same_side_battler(user.side) do |b, i|
|
||||||
score += 10 if b.check_for_move { |m| m.specialMove?(m.type) }
|
score += 10 if b.check_for_move { |m| m.specialMove?(m.type) }
|
||||||
end
|
end
|
||||||
@@ -666,9 +720,7 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUser",
|
|||||||
# Prefer for each foe that can attack
|
# Prefer for each foe that can attack
|
||||||
useless = true
|
useless = true
|
||||||
ai.each_foe_battler(user.side) do |b, i|
|
ai.each_foe_battler(user.side) do |b, i|
|
||||||
next if (b.status == :SLEEP && b.statusCount > 1) ||
|
next if !b.can_attack?
|
||||||
b.status == :FROZEN || b.effects[PBEffects::HyperBeam] > 0 ||
|
|
||||||
b.effects[PBEffects::Truant] || b.effects[PBEffects::SkyDrop] >= 0
|
|
||||||
useless = false
|
useless = false
|
||||||
score += 4
|
score += 4
|
||||||
score += 4 if b.effects[PBEffects::TwoTurnAttack]
|
score += 4 if b.effects[PBEffects::TwoTurnAttack]
|
||||||
|
|||||||
@@ -646,8 +646,7 @@ Battle::AI::Handlers::MoveEffectScore.add("AttackerFaintsIfUserFaints",
|
|||||||
score -= 25
|
score -= 25
|
||||||
# Check whether user is faster than its foe(s) and could use this move
|
# Check whether user is faster than its foe(s) and could use this move
|
||||||
user_faster_count = 0
|
user_faster_count = 0
|
||||||
ai.battlers.each_with_index do |b, i|
|
ai.each_foe_battler(user.side) do |b, i|
|
||||||
next if !user.opposes?(b) || b.battler.fainted?
|
|
||||||
user_faster_count += 1 if user.faster_than?(b)
|
user_faster_count += 1 if user.faster_than?(b)
|
||||||
end
|
end
|
||||||
next score if user_faster_count == 0 # Move will almost certainly have no effect
|
next score if user_faster_count == 0 # Move will almost certainly have no effect
|
||||||
@@ -670,8 +669,7 @@ Battle::AI::Handlers::MoveEffectScore.add("SetAttackerMovePPTo0IfUserFaints",
|
|||||||
score -= 25
|
score -= 25
|
||||||
# Check whether user is faster than its foe(s) and could use this move
|
# Check whether user is faster than its foe(s) and could use this move
|
||||||
user_faster_count = 0
|
user_faster_count = 0
|
||||||
ai.battlers.each_with_index do |b, i|
|
ai.each_foe_battler(user.side) do |b, i|
|
||||||
next if !user.opposes?(b) || b.battler.fainted?
|
|
||||||
user_faster_count += 1 if user.faster_than?(b)
|
user_faster_count += 1 if user.faster_than?(b)
|
||||||
end
|
end
|
||||||
next score if user_faster_count == 0 # Move will almost certainly have no effect
|
next score if user_faster_count == 0 # Move will almost certainly have no effect
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserTakesTargetItem",
|
|||||||
user_no_item_preference = ai.battler_wants_item?(user, :NONE)
|
user_no_item_preference = ai.battler_wants_item?(user, :NONE)
|
||||||
target_item_preference = ai.battler_wants_item?(target, target.item_id)
|
target_item_preference = ai.battler_wants_item?(target, target.item_id)
|
||||||
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
||||||
score += (user_item_preference - user_no_item_preference) * 5
|
score += (user_item_preference - user_no_item_preference) * 3
|
||||||
score += (target_item_preference - target_no_item_preference) * 5
|
score += (target_item_preference - target_no_item_preference) * 3
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -35,8 +35,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TargetTakesUserItem",
|
|||||||
user_no_item_preference = ai.battler_wants_item?(user, :NONE)
|
user_no_item_preference = ai.battler_wants_item?(user, :NONE)
|
||||||
target_item_preference = ai.battler_wants_item?(target, user.item_id)
|
target_item_preference = ai.battler_wants_item?(target, user.item_id)
|
||||||
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
||||||
score -= (user_item_preference - user_no_item_preference) * 5
|
score -= (user_item_preference - user_no_item_preference) * 3
|
||||||
score -= (target_item_preference - target_no_item_preference) * 5
|
score -= (target_item_preference - target_no_item_preference) * 3
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -60,8 +60,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserTargetSwapItems",
|
|||||||
user_old_item_preference = ai.battler_wants_item?(user, user.item_id)
|
user_old_item_preference = ai.battler_wants_item?(user, user.item_id)
|
||||||
target_new_item_preference = ai.battler_wants_item?(target, user.item_id)
|
target_new_item_preference = ai.battler_wants_item?(target, user.item_id)
|
||||||
target_old_item_preference = ai.battler_wants_item?(target, target.item_id)
|
target_old_item_preference = ai.battler_wants_item?(target, target.item_id)
|
||||||
score += (user_new_item_preference - user_old_item_preference) * 5
|
score += (user_new_item_preference - user_old_item_preference) * 3
|
||||||
score -= (target_new_item_preference - target_old_item_preference) * 5
|
score -= (target_new_item_preference - target_old_item_preference) * 3
|
||||||
# Don't prefer if user used this move in the last round
|
# Don't prefer if user used this move in the last round
|
||||||
score -= 15 if user.battler.lastMoveUsed &&
|
score -= 15 if user.battler.lastMoveUsed &&
|
||||||
GameData::Move.get(user.battler.lastMoveUsed).function_code == "UserTargetSwapItems"
|
GameData::Move.get(user.battler.lastMoveUsed).function_code == "UserTargetSwapItems"
|
||||||
@@ -81,7 +81,7 @@ Battle::AI::Handlers::MoveEffectScore.add("RestoreUserConsumedItem",
|
|||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
user_new_item_preference = ai.battler_wants_item?(user, user.battler.recycleItem)
|
user_new_item_preference = ai.battler_wants_item?(user, user.battler.recycleItem)
|
||||||
user_old_item_preference = ai.battler_wants_item?(user, user.item_id)
|
user_old_item_preference = ai.battler_wants_item?(user, user.item_id)
|
||||||
score += (user_new_item_preference - user_old_item_preference) * 8
|
score += (user_new_item_preference - user_old_item_preference) * 4
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -103,7 +103,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RemoveTargetItem",
|
|||||||
# User can knock off the target's item; score it
|
# User can knock off the target's item; score it
|
||||||
target_item_preference = ai.battler_wants_item?(target, target.item_id)
|
target_item_preference = ai.battler_wants_item?(target, target.item_id)
|
||||||
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
||||||
score += (target_item_preference - target_no_item_preference) * 5
|
score += (target_item_preference - target_no_item_preference) * 4
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -121,7 +121,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DestroyTargetBerryOrGem"
|
|||||||
# User can incinerate the target's item; score it
|
# User can incinerate the target's item; score it
|
||||||
target_item_preference = ai.battler_wants_item?(target, target.item_id)
|
target_item_preference = ai.battler_wants_item?(target, target.item_id)
|
||||||
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
||||||
score += (target_item_preference - target_no_item_preference) * 8
|
score += (target_item_preference - target_no_item_preference) * 4
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -142,7 +142,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CorrodeTargetItem",
|
|||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
target_item_preference = ai.battler_wants_item?(target, target.item_id)
|
target_item_preference = ai.battler_wants_item?(target, target.item_id)
|
||||||
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
||||||
score += (target_item_preference - target_no_item_preference) * 8
|
score += (target_item_preference - target_no_item_preference) * 4
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -258,13 +258,13 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserConsumeTargetBerry",
|
|||||||
# User can consume the target's berry; score it
|
# User can consume the target's berry; score it
|
||||||
target_item_preference = ai.battler_wants_item?(target, target.item_id)
|
target_item_preference = ai.battler_wants_item?(target, target.item_id)
|
||||||
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
||||||
score += (target_item_preference - target_no_item_preference) * 8
|
score += (target_item_preference - target_no_item_preference) * 4
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("ThrowUserItemAtTarget",
|
Battle::AI::Handlers::MoveFailureCheck.add("ThrowUserItemAtTarget",
|
||||||
proc { |move, user, ai, battle|
|
proc { |move, user, ai, battle|
|
||||||
@@ -280,3 +280,40 @@ Battle::AI::Handlers::MoveBasePower.add("ThrowUserItemAtTarget",
|
|||||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ThrowUserItemAtTarget",
|
||||||
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
case user.item_id
|
||||||
|
when :POISONBARB, :TOXICORB
|
||||||
|
score = Battle::AI::Handlers.apply_move_effect_against_target_score("PoisonTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
when :FLAMEORB
|
||||||
|
score = Battle::AI::Handlers.apply_move_effect_against_target_score("BurnTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
when :LIGHTBALL
|
||||||
|
score = Battle::AI::Handlers.apply_move_effect_against_target_score("ParalyzeTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
when :KINGSROCK, :RAZORFANG
|
||||||
|
score = Battle::AI::Handlers.apply_move_effect_against_target_score("FlinchTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
else
|
||||||
|
# TODO: Berries/Berry Juice/Mental Herb/White Herb also have Fling
|
||||||
|
# effects. Should they be accounted for individually, or is it okay
|
||||||
|
# to consider it bad to Fling these in general? Note that they all
|
||||||
|
# do minimal damage so this move probably won't be used anyway.
|
||||||
|
if Battle::ItemEffects::HPHeal[user.item_id] ||
|
||||||
|
Battle::ItemEffects::StatusCure[user.item_id] ||
|
||||||
|
Battle::ItemEffects::OnEndOfUsingMove[user.item_id] ||
|
||||||
|
Battle::ItemEffects::OnEndOfUsingMoveStatRestore[user.item_id]
|
||||||
|
score -= 8
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Prefer if the user doesn't want its held item/don't prefer if it wants to
|
||||||
|
# keep its held item
|
||||||
|
user_item_preference = ai.battler_wants_item?(user, user.item_id)
|
||||||
|
user_no_item_preference = ai.battler_wants_item?(user, :NONE)
|
||||||
|
score += (user_item_preference - user_no_item_preference) * 4
|
||||||
|
# Prefer if user will benefit from not having an item
|
||||||
|
score += 5 if user.has_active_ability?(:UNBURDEN)
|
||||||
|
next score
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -289,14 +289,10 @@ Battle::AI::Handlers::MoveEffectScore.add("UsedAfterAllyRoundWithDoublePower",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers. This could reasonably used on an ally.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("TargetActsNext",
|
Battle::AI::Handlers::MoveEffectScore.add("TargetActsNext",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
# Useless if the user has no ally
|
|
||||||
has_ally = false
|
|
||||||
ai.each_ally(user.index) { |b, i| has_ally = true }
|
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if !has_ally
|
|
||||||
# Useless if the target is a foe
|
# Useless if the target is a foe
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if target.opposes?(user)
|
next Battle::AI::MOVE_USELESS_SCORE if target.opposes?(user)
|
||||||
# Compare the speeds of all battlers
|
# Compare the speeds of all battlers
|
||||||
@@ -313,21 +309,27 @@ Battle::AI::Handlers::MoveEffectScore.add("TargetActsNext",
|
|||||||
next Battle::AI::MOVE_USELESS_SCORE if idx_target < idx_user
|
next Battle::AI::MOVE_USELESS_SCORE if idx_target < idx_user
|
||||||
# Useless if the target will move next anyway
|
# Useless if the target will move next anyway
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if idx_target - idx_user <= 1
|
next Battle::AI::MOVE_USELESS_SCORE if idx_target - idx_user <= 1
|
||||||
next score
|
# Generally not worth using
|
||||||
|
# NOTE: Because this move can be used against a foe but is being used on an
|
||||||
|
# ally (since we're here in this code), this move's score will be
|
||||||
|
# inverted later. A higher score here means this move will be less
|
||||||
|
# preferred, which is the result we want.
|
||||||
|
next score + 10
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("TargetActsLast",
|
Battle::AI::Handlers::MoveEffectScore.add("TargetActsLast",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
# Useless if the user has no ally
|
|
||||||
has_ally = false
|
|
||||||
ai.each_ally(user.index) { |b, i| has_ally = true }
|
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if !has_ally
|
|
||||||
# Useless if the target is an ally
|
# Useless if the target is an ally
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if !target.opposes?(user)
|
next Battle::AI::MOVE_USELESS_SCORE if !target.opposes?(user)
|
||||||
|
# Useless if the user has no ally (the point of this move is to let the ally
|
||||||
|
# get in a hit before the foe)
|
||||||
|
has_ally = false
|
||||||
|
ai.each_ally(user.index) { |b, i| has_ally = true if b.can_attack? }
|
||||||
|
next Battle::AI::MOVE_USELESS_SCORE if !has_ally
|
||||||
# Compare the speeds of all battlers
|
# Compare the speeds of all battlers
|
||||||
speeds = []
|
speeds = []
|
||||||
ai.each_battler { |b, i| speeds.push([i, rough_stat(:SPEED)]) }
|
ai.each_battler { |b, i| speeds.push([i, rough_stat(:SPEED)]) }
|
||||||
@@ -338,11 +340,16 @@ Battle::AI::Handlers::MoveEffectScore.add("TargetActsLast",
|
|||||||
end
|
end
|
||||||
idx_user = speeds.index { |ele| ele[0] == user.index }
|
idx_user = speeds.index { |ele| ele[0] == user.index }
|
||||||
idx_target = speeds.index { |ele| ele[0] == target.index }
|
idx_target = speeds.index { |ele| ele[0] == target.index }
|
||||||
|
idx_slowest_ally = -1
|
||||||
|
speeds.each_with_index { |ele, i| idx_slowest_ally = i if user.index.even? == ele[0].even? }
|
||||||
# Useless if the target is faster than the user
|
# Useless if the target is faster than the user
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if idx_target < idx_user
|
next Battle::AI::MOVE_USELESS_SCORE if idx_target < idx_user
|
||||||
# Useless if the target will move last anyway
|
# Useless if the target will move last anyway
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if idx_target == speeds.length - 1
|
next Battle::AI::MOVE_USELESS_SCORE if idx_target == speeds.length - 1
|
||||||
next score
|
# Useless if the slowest ally is faster than the target
|
||||||
|
next Battle::AI::MOVE_USELESS_SCORE if idx_slowest_ally < idx_target
|
||||||
|
# Generally not worth using
|
||||||
|
next score - 10
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -378,16 +385,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TargetUsesItsLastUsedMov
|
|||||||
# StartSlowerBattlersActFirst
|
# StartSlowerBattlersActFirst
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HigherPriorityInGrassyTerrain",
|
# HigherPriorityInGrassyTerrain
|
||||||
proc { |score, move, user, target, ai, battle|
|
|
||||||
if ai.trainer.medium_skill? && battle.field.terrain == :Grassy
|
|
||||||
score += 15 if target.faster_than?(user)
|
|
||||||
end
|
|
||||||
next score
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ class Battle::AI::AIBattler
|
|||||||
# TODO: Need to check the move's pbCalcTypeModSingle.
|
# TODO: Need to check the move's pbCalcTypeModSingle.
|
||||||
ret *= effectiveness_of_type_against_single_battler_type(type, defend_type, user)
|
ret *= effectiveness_of_type_against_single_battler_type(type, defend_type, user)
|
||||||
end
|
end
|
||||||
ret *= 2 if @battler.effects[PBEffects::TarShot] && type == :FIRE
|
ret *= 2 if self.effects[PBEffects::TarShot] && type == :FIRE
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
@@ -281,6 +281,18 @@ class Battle::AI::AIBattler
|
|||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
|
|
||||||
|
def can_attack?
|
||||||
|
return false if self.effects[PBEffects::SkyDrop] >= 0
|
||||||
|
return false if self.effects[PBEffects::HyperBeam] > 0
|
||||||
|
return false if status == :SLEEP && statusCount > 1
|
||||||
|
return false if status == :FROZEN # Only 20% chance of unthawing; assune it won't
|
||||||
|
return false if self.effects[PBEffects::Truant]
|
||||||
|
return false if self.effects[PBEffects::Flinch]
|
||||||
|
# NOTE: Confusion/infatuation/paralysis have higher chances of allowing the
|
||||||
|
# attack, so the battler is treated as able to attack in those cases.
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
def can_switch_lax?
|
def can_switch_lax?
|
||||||
return false if wild?
|
return false if wild?
|
||||||
@ai.battle.eachInTeamFromBattlerIndex(@index) do |pkmn, i|
|
@ai.battle.eachInTeamFromBattlerIndex(@index) do |pkmn, i|
|
||||||
|
|||||||
@@ -546,6 +546,7 @@ class Battle::AI::AIMove
|
|||||||
# 2 = additional effect will work
|
# 2 = additional effect will work
|
||||||
# 3 = additional effect has an increased chance to work
|
# 3 = additional effect has an increased chance to work
|
||||||
def additional_effect_usability(user, target)
|
def additional_effect_usability(user, target)
|
||||||
|
return 3 if self.function == "ThrowUserItemAtTarget"
|
||||||
return 0 if @move.addlEffect == 0 # Doesn't have an additional effect
|
return 0 if @move.addlEffect == 0 # Doesn't have an additional effect
|
||||||
return 1 if target.has_active_ability?(:SHIELDDUST) && !@ai.battle.moldBreaker
|
return 1 if target.has_active_ability?(:SHIELDDUST) && !@ai.battle.moldBreaker
|
||||||
return 3 if (Settings::MECHANICS_GENERATION >= 6 || self.function != "EffectDependsOnEnvironment") &&
|
return 3 if (Settings::MECHANICS_GENERATION >= 6 || self.function != "EffectDependsOnEnvironment") &&
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ end
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
class Battle::Move::UserLosesHalfHP < Battle::Move::RecoilMove
|
class Battle::Move::UserLosesHalfHP < Battle::Move::RecoilMove
|
||||||
def pbRecoilDamage(user, target)
|
def pbRecoilDamage(user, target)
|
||||||
return (target.damageState.totalHPLost / 2.0).round
|
return (user.hp / 2.0).round
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbEffectAfterAllHits(user, target)
|
def pbEffectAfterAllHits(user, target)
|
||||||
@@ -398,13 +398,13 @@ end
|
|||||||
# Ends the effects of Light Screen, Reflect and Safeguard on both sides.
|
# Ends the effects of Light Screen, Reflect and Safeguard on both sides.
|
||||||
# (Shadow Shed)
|
# (Shadow Shed)
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class Battle::Move::RemoveAllScreens < Battle::Move
|
class Battle::Move::RemoveAllScreensAndSafeguard < Battle::Move
|
||||||
def pbMoveFailed?(user, targets)
|
def pbMoveFailed?(user, targets)
|
||||||
will_fail = true
|
will_fail = true
|
||||||
@battle.sides.each do |side|
|
@battle.sides.each do |side|
|
||||||
will_fail = false if side.effects[PBEffects::AuroraVeil] > 0 ||
|
will_fail = false if side.effects[PBEffects::AuroraVeil] > 0 ||
|
||||||
side.effects[PBEffects::Reflect] > 0 ||
|
|
||||||
side.effects[PBEffects::LightScreen] > 0 ||
|
side.effects[PBEffects::LightScreen] > 0 ||
|
||||||
|
side.effects[PBEffects::Reflect] > 0 ||
|
||||||
side.effects[PBEffects::Safeguard] > 0
|
side.effects[PBEffects::Safeguard] > 0
|
||||||
end
|
end
|
||||||
if will_fail
|
if will_fail
|
||||||
@@ -417,8 +417,8 @@ class Battle::Move::RemoveAllScreens < Battle::Move
|
|||||||
def pbEffectGeneral(user)
|
def pbEffectGeneral(user)
|
||||||
@battle.sides.each do |i|
|
@battle.sides.each do |i|
|
||||||
i.effects[PBEffects::AuroraVeil] = 0
|
i.effects[PBEffects::AuroraVeil] = 0
|
||||||
i.effects[PBEffects::Reflect] = 0
|
|
||||||
i.effects[PBEffects::LightScreen] = 0
|
i.effects[PBEffects::LightScreen] = 0
|
||||||
|
i.effects[PBEffects::Reflect] = 0
|
||||||
i.effects[PBEffects::Safeguard] = 0
|
i.effects[PBEffects::Safeguard] = 0
|
||||||
end
|
end
|
||||||
@battle.pbDisplay(_INTL("It broke all barriers!"))
|
@battle.pbDisplay(_INTL("It broke all barriers!"))
|
||||||
|
|||||||
Reference in New Issue
Block a user