mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-09 06:04:59 +00:00
Tweaked AI threshold score, added "HPAware" skill flag, changed lots of AI scores
This commit is contained in:
@@ -117,11 +117,11 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FailsIfUserDamagedThisTu
|
||||
end
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if user_faster_count == 0
|
||||
score += 10 if foe_faster_count == 0
|
||||
score += 15 if foe_faster_count == 0
|
||||
# Effects that make the target unlikely to act before the user
|
||||
if ai.trainer.high_skill?
|
||||
if !target.can_attack?
|
||||
score += 20
|
||||
score += 15
|
||||
elsif target.effects[PBEffects::Confusion] > 1 ||
|
||||
target.effects[PBEffects::Attract] == user.index
|
||||
score += 10
|
||||
@@ -130,8 +130,10 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FailsIfUserDamagedThisTu
|
||||
end
|
||||
end
|
||||
# Don't risk using this move if target is weak
|
||||
score -= 10 if target.hp <= target.totalhp / 2
|
||||
score -= 10 if target.hp <= target.totalhp / 4
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if target.hp <= target.totalhp / 2
|
||||
score -= 10 if target.hp <= target.totalhp / 4
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -143,12 +145,13 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FailsIfTargetActed",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Check whether user is faster than its foe(s) and could use this move
|
||||
next Battle::AI::MOVE_USELESS_SCORE if target.faster_than?(user)
|
||||
score += 10
|
||||
# TODO: Predict the target switching/using an item.
|
||||
# TODO: Predict the target using a damaging move or Me First.
|
||||
# Don't risk using this move if target is weak
|
||||
score -= 10 if target.hp <= target.totalhp / 2
|
||||
score -= 10 if target.hp <= target.totalhp / 4
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if target.hp <= target.totalhp / 2
|
||||
score -= 10 if target.hp <= target.totalhp / 4
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -158,7 +161,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FailsIfTargetActed",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CrashDamageIfFailsUnusableInGravity",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score -= (100 - move.rough_accuracy) if user.battler.takesIndirectDamage?
|
||||
if user.battler.takesIndirectDamage?
|
||||
score -= (0.4 * (100 - move.rough_accuracy)).to_i # -0 (100%) to -40 (1%)
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -175,7 +180,10 @@ Battle::AI::Handlers::MoveEffectScore.add("StartSunWeather",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
||||
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||
# Not worth it at lower HP
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp < user.totalhp / 2
|
||||
end
|
||||
if ai.trainer.high_skill? && battle.field.weather != :None
|
||||
score -= ai.get_score_for_weather(battle.field.weather, user)
|
||||
end
|
||||
@@ -193,7 +201,10 @@ Battle::AI::Handlers::MoveEffectScore.add("StartRainWeather",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
||||
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||
# Not worth it at lower HP
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp < user.totalhp / 2
|
||||
end
|
||||
if ai.trainer.high_skill? && battle.field.weather != :None
|
||||
score -= ai.get_score_for_weather(battle.field.weather, user)
|
||||
end
|
||||
@@ -211,7 +222,10 @@ Battle::AI::Handlers::MoveEffectScore.add("StartSandstormWeather",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
||||
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||
# Not worth it at lower HP
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp < user.totalhp / 2
|
||||
end
|
||||
if ai.trainer.high_skill? && battle.field.weather != :None
|
||||
score -= ai.get_score_for_weather(battle.field.weather, user)
|
||||
end
|
||||
@@ -229,7 +243,10 @@ Battle::AI::Handlers::MoveEffectScore.add("StartHailWeather",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
||||
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||
# Not worth it at lower HP
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp < user.totalhp / 2
|
||||
end
|
||||
if ai.trainer.high_skill? && battle.field.weather != :None
|
||||
score -= ai.get_score_for_weather(battle.field.weather, user)
|
||||
end
|
||||
@@ -248,7 +265,10 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartElectricTerrain",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartElectricTerrain",
|
||||
proc { |score, move, user, ai, battle|
|
||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||
# Not worth it at lower HP
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp < user.totalhp / 2
|
||||
end
|
||||
if ai.trainer.high_skill? && battle.field.terrain != :None
|
||||
score -= ai.get_score_for_terrain(battle.field.terrain, user)
|
||||
end
|
||||
@@ -267,7 +287,10 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartGrassyTerrain",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartGrassyTerrain",
|
||||
proc { |score, move, user, ai, battle|
|
||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||
# Not worth it at lower HP
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp < user.totalhp / 2
|
||||
end
|
||||
if ai.trainer.high_skill? && battle.field.terrain != :None
|
||||
score -= ai.get_score_for_terrain(battle.field.terrain, user)
|
||||
end
|
||||
@@ -286,7 +309,10 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartMistyTerrain",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartMistyTerrain",
|
||||
proc { |score, move, user, ai, battle|
|
||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||
# Not worth it at lower HP
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp < user.totalhp / 2
|
||||
end
|
||||
if ai.trainer.high_skill? && battle.field.terrain != :None
|
||||
score -= ai.get_score_for_terrain(battle.field.terrain, user)
|
||||
end
|
||||
@@ -305,7 +331,10 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartPsychicTerrain",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartPsychicTerrain",
|
||||
proc { |score, move, user, ai, battle|
|
||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||
# Not worth it at lower HP
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp < user.totalhp / 2
|
||||
end
|
||||
if ai.trainer.high_skill? && battle.field.terrain != :None
|
||||
score -= ai.get_score_for_terrain(battle.field.terrain, user)
|
||||
end
|
||||
@@ -358,8 +387,8 @@ Battle::AI::Handlers::MoveEffectScore.add("AddSpikesToFoeSide",
|
||||
foe_reserves.push(pkmn) # pkmn will be affected by Spikes
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if foe_reserves.empty?
|
||||
multiplier = [8, 5, 3][user.pbOpposingSide.effects[PBEffects::Spikes]]
|
||||
score += multiplier * foe_reserves.length
|
||||
multiplier = [10, 7, 5][user.pbOpposingSide.effects[PBEffects::Spikes]]
|
||||
score += [multiplier * foe_reserves.length, 30].min
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -402,8 +431,8 @@ Battle::AI::Handlers::MoveEffectScore.add("AddToxicSpikesToFoeSide",
|
||||
foe_reserves.push(pkmn) # pkmn will be affected by Toxic Spikes
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if foe_reserves.empty?
|
||||
multiplier = [6, 4][user.pbOpposingSide.effects[PBEffects::ToxicSpikes]]
|
||||
score += multiplier * foe_reserves.length
|
||||
multiplier = [8, 5][user.pbOpposingSide.effects[PBEffects::ToxicSpikes]]
|
||||
score += [multiplier * foe_reserves.length, 30].min
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -431,7 +460,8 @@ Battle::AI::Handlers::MoveEffectScore.add("AddStealthRocksToFoeSide",
|
||||
foe_reserves.push(pkmn) # pkmn will be affected by Stealth Rock
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if foe_reserves.empty?
|
||||
next score + 8 * foe_reserves.length
|
||||
score += [10 * foe_reserves.length, 30].min
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
@@ -463,7 +493,8 @@ Battle::AI::Handlers::MoveEffectScore.add("AddStickyWebToFoeSide",
|
||||
foe_reserves.push(pkmn) # pkmn will be affected by Sticky Web
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if foe_reserves.empty?
|
||||
next score + 7 * foe_reserves.length
|
||||
score += [8 * foe_reserves.length, 30].min
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
@@ -524,10 +555,12 @@ Battle::AI::Handlers::MoveFailureCheck.add("UserMakeSubstitute",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("UserMakeSubstitute",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Prefer more the higher the user's HP
|
||||
score += (8 * user.hp.to_f / user.totalhp).round
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score += (10 * user.hp.to_f / user.totalhp).round
|
||||
end
|
||||
# Prefer if foes don't know any moves that can bypass a substitute
|
||||
ai.each_battler do |b, i|
|
||||
score += 4 if !b.check_for_move { |m| m.ignoresSubstitute?(b.battler) }
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
score += 5 if !b.check_for_move { |m| m.ignoresSubstitute?(b.battler) }
|
||||
end
|
||||
# TODO: Predict incoming damage, and prefer if it's greater than
|
||||
# user.totalhp / 4?
|
||||
@@ -625,8 +658,8 @@ Battle::AI::Handlers::MoveEffectScore.add("AllBattlersLoseHalfHPUserSkipsNextTur
|
||||
ally_hp_lost += b.hp / 2
|
||||
end
|
||||
end
|
||||
score += 15 * foe_hp_lost / ally_hp_lost
|
||||
score -= 15 * ally_hp_lost / foe_hp_lost
|
||||
score += 20 * foe_hp_lost / ally_hp_lost
|
||||
score -= 20 * ally_hp_lost / foe_hp_lost
|
||||
# Recharging
|
||||
score = Battle::AI::Handlers.apply_move_effect_score("AttackAndSkipNextTurn",
|
||||
score, move, user, ai, battle)
|
||||
@@ -654,7 +687,10 @@ Battle::AI::Handlers::MoveEffectScore.add("StartShadowSkyWeather",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
||||
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
||||
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||
# Not worth it at lower HP
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 15 if user.hp < user.totalhp / 2
|
||||
end
|
||||
if ai.trainer.high_skill? && battle.field.weather != :None
|
||||
score -= ai.get_score_for_weather(battle.field.weather, user)
|
||||
end
|
||||
|
||||
@@ -60,7 +60,9 @@ Battle::AI::Handlers::MoveEffectScore.add("MaxUserAttackLoseHalfOfTotalHP",
|
||||
proc { |score, move, user, ai, battle|
|
||||
score = ai.get_score_for_target_stat_raise(score, user, move.move.statUp)
|
||||
# Don't prefer the lower the user's HP is
|
||||
score -= 80 * (1 - (user.hp.to_f / user.totalhp)) # 0 to -40
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 60 * (1 - (user.hp.to_f / user.totalhp)) # -0 to -30
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -202,7 +204,7 @@ Battle::AI::Handlers::MoveEffectScore.add("RaiseUserSpeed2LowerUserWeight",
|
||||
# User will become susceptible to Sky Drop
|
||||
if b.has_move_with_function?("TwoTurnAttackInvulnerableInSkyTargetCannotAct") &&
|
||||
Settings::MECHANICS_GENERATION >= 6
|
||||
score -= 7 if current_weight >= 2000 && current_weight < 3000
|
||||
score -= 10 if current_weight >= 2000 && current_weight < 3000
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -464,8 +466,8 @@ Battle::AI::Handlers::MoveEffectScore.add("RaiseUserMainStats1LoseThirdOfTotalHP
|
||||
score = ai.get_score_for_target_stat_raise(score, user, move.move.statUp)
|
||||
next score if score == Battle::AI::MOVE_USELESS_SCORE
|
||||
# Score for losing HP
|
||||
if user.hp <= user.totalhp * 0.75
|
||||
score -= 30 * (user.totalhp - user.hp) / user.totalhp
|
||||
if ai.trainer.has_skill_flag?("HPAware") && user.hp <= user.totalhp * 0.75
|
||||
score -= 45 * (user.totalhp - user.hp) / user.totalhp # -0 to -30
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -499,7 +501,7 @@ Battle::AI::Handlers::MoveEffectScore.add("RaiseUserMainStats1TrapUserInBattle",
|
||||
if user.effects[PBEffects::PerishSong] > 0 ||
|
||||
user.effects[PBEffects::Attract] >= 0 ||
|
||||
eor_damage > 0
|
||||
score -= 12
|
||||
score -= 15
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -513,12 +515,14 @@ Battle::AI::Handlers::MoveEffectScore.add("StartRaiseUserAtk1WhenDamaged",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Ignore the stat-raising effect if user is at a low HP and likely won't
|
||||
# benefit from it
|
||||
next score if user.hp < user.totalhp / 3
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
next score if user.hp <= user.totalhp / 3
|
||||
end
|
||||
# TODO: Check whether any foe has damaging moves that will trigger the stat
|
||||
# raise?
|
||||
# Prefer if user benefits from a raised Attack stat
|
||||
score += 8 if ai.stat_raise_worthwhile?(user, :ATTACK)
|
||||
score += 4 if user.has_move_with_function?("PowerHigherWithUserPositiveStatStages")
|
||||
score += 10 if ai.stat_raise_worthwhile?(user, :ATTACK)
|
||||
score += 7 if user.has_move_with_function?("PowerHigherWithUserPositiveStatStages")
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -694,22 +698,24 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseTargetRandomStat2",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !battle.moldBreaker && target.has_active_ability?(:CONTRARY)
|
||||
next Battle::AI::MOVE_USELESS_SCORE if target.rough_end_of_round_damage >= target.hp
|
||||
score -= 5 if target.index != user.index # Less likely to use on ally
|
||||
score += 5 if target.has_active_ability?(:SIMPLE)
|
||||
score -= 7 if target.index != user.index # Less likely to use on ally
|
||||
score += 10 if target.has_active_ability?(:SIMPLE)
|
||||
# Prefer if target is at high HP, don't prefer if target is at low HP
|
||||
if target.hp >= target.totalhp * 0.7
|
||||
score += 8
|
||||
else
|
||||
score += ((100 * target.hp / target.totalhp) - 50) / 4 # +5 to -12
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if target.hp >= target.totalhp * 0.7
|
||||
score += 10
|
||||
else
|
||||
score += (50 * ((target.hp.to_f / target.totalhp) - 0.6)).to_i # +5 to -30
|
||||
end
|
||||
end
|
||||
# Prefer if target has Stored Power
|
||||
if target.has_move_with_function?("PowerHigherWithUserPositiveStatStages")
|
||||
score += 8
|
||||
score += 10
|
||||
end
|
||||
# Don't prefer if any foe has Punishment
|
||||
ai.each_foe_battler(target.side) do |b, i|
|
||||
next if !b.has_move_with_function?("PowerHigherWithTargetPositiveStatStages")
|
||||
score -= 5
|
||||
score -= 8
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -909,7 +915,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetSpeed1MakeTar
|
||||
if !target.effects[PBEffects::TarShot]
|
||||
eff = target.effectiveness_of_type_against_battler(:FIRE)
|
||||
if !Effectiveness.ineffective?(eff)
|
||||
score += 8 * eff if user.has_damaging_move_of_type?(:FIRE)
|
||||
score += 10 * eff if user.has_damaging_move_of_type?(:FIRE)
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -992,22 +998,23 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetEvasion1Remo
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetEvasion1RemoveSideEffects",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !target.opposes?(user)
|
||||
# Score for stat drop
|
||||
score = ai.get_score_for_target_stat_drop(score, target, move.move.statDown)
|
||||
# Score for removing side effects/terrain
|
||||
score += 8 if target.pbOwnSide.effects[PBEffects::AuroraVeil] > 1 ||
|
||||
target.pbOwnSide.effects[PBEffects::Reflect] > 1 ||
|
||||
target.pbOwnSide.effects[PBEffects::LightScreen] > 1 ||
|
||||
target.pbOwnSide.effects[PBEffects::Mist] > 1 ||
|
||||
target.pbOwnSide.effects[PBEffects::Safeguard] > 1
|
||||
score += 10 if target.pbOwnSide.effects[PBEffects::AuroraVeil] > 1 ||
|
||||
target.pbOwnSide.effects[PBEffects::Reflect] > 1 ||
|
||||
target.pbOwnSide.effects[PBEffects::LightScreen] > 1 ||
|
||||
target.pbOwnSide.effects[PBEffects::Mist] > 1 ||
|
||||
target.pbOwnSide.effects[PBEffects::Safeguard] > 1
|
||||
if target.can_switch_lax?
|
||||
score -= 10 if target.pbOwnSide.effects[PBEffects::Spikes] > 0 ||
|
||||
score -= 15 if target.pbOwnSide.effects[PBEffects::Spikes] > 0 ||
|
||||
target.pbOwnSide.effects[PBEffects::ToxicSpikes] > 0 ||
|
||||
target.pbOwnSide.effects[PBEffects::StealthRock] ||
|
||||
target.pbOwnSide.effects[PBEffects::StickyWeb]
|
||||
end
|
||||
if user.opposes?(target) && user.can_switch_lax? && Settings::MECHANICS_GENERATION >= 6
|
||||
score += 10 if target.pbOpposingSide.effects[PBEffects::Spikes] > 0 ||
|
||||
if user.can_switch_lax? && Settings::MECHANICS_GENERATION >= 6
|
||||
score += 15 if target.pbOpposingSide.effects[PBEffects::Spikes] > 0 ||
|
||||
target.pbOpposingSide.effects[PBEffects::ToxicSpikes] > 0 ||
|
||||
target.pbOpposingSide.effects[PBEffects::StealthRock] ||
|
||||
target.pbOpposingSide.effects[PBEffects::StickyWeb]
|
||||
@@ -1296,14 +1303,14 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserCopyTargetStatStages
|
||||
score = ai.get_score_for_target_stat_drop(score, user, drops, false, true) if drops.length > 0
|
||||
if Settings::NEW_CRITICAL_HIT_RATE_MECHANICS
|
||||
if user.effects[PBEffects::FocusEnergy] > 0 && target.effects[PBEffects::FocusEnergy] == 0
|
||||
score -= 4
|
||||
score -= 5
|
||||
elsif user.effects[PBEffects::FocusEnergy] == 0 && target.effects[PBEffects::FocusEnergy] > 0
|
||||
score += 4
|
||||
score += 5
|
||||
end
|
||||
if user.effects[PBEffects::LaserFocus] > 0 && target.effects[PBEffects::LaserFocus] == 0
|
||||
score -= 3
|
||||
score -= 5
|
||||
elsif user.effects[PBEffects::LaserFocus] == 0 && target.effects[PBEffects::LaserFocus] > 0
|
||||
score += 3
|
||||
score += 5
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -1428,7 +1435,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartUserSideImmunityToStatStageLower
|
||||
["LowerPoisonedTargetAtkSpAtkSpd1",
|
||||
"PoisonTargetLowerTargetSpeed1",
|
||||
"HealUserByTargetAttackLowerTargetAttack1"].include?(m.function) }
|
||||
score += 10
|
||||
score += 15
|
||||
has_move = true
|
||||
end
|
||||
end
|
||||
@@ -1498,49 +1505,33 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserTargetAverageBaseAtk
|
||||
change_matters = false
|
||||
# Score based on changes to Attack
|
||||
if target_atk > user_atk
|
||||
# User's Attack will be raised
|
||||
if ai.stat_raise_worthwhile?(user, :ATTACK, true)
|
||||
score += (20 * ((target_atk.to_f / user_atk) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
# Target's Attack will be lowered
|
||||
if ai.stat_drop_worthwhile?(target, :ATTACK, true)
|
||||
score += (20 * ((target_atk.to_f / user_atk) - 1)).to_i
|
||||
# User's Attack will be raised, target's Attack will be lowered
|
||||
if ai.stat_raise_worthwhile?(user, :ATTACK, true) ||
|
||||
ai.stat_drop_worthwhile?(target, :ATTACK, true)
|
||||
score += (40 * ((target_atk.to_f / user_atk) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
elsif target_atk < user_atk
|
||||
# User's Attack will be lowered
|
||||
if ai.stat_drop_worthwhile?(user, :ATTACK, true)
|
||||
score -= (20 * ((user_atk.to_f / target_atk) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
# Target's Attack will be raised
|
||||
if ai.stat_raise_worthwhile?(target, :ATTACK, true)
|
||||
score -= (20 * ((user_atk.to_f / target_atk) - 1)).to_i
|
||||
# User's Attack will be lowered, target's Attack will be raised
|
||||
if ai.stat_drop_worthwhile?(user, :ATTACK, true) ||
|
||||
ai.stat_raise_worthwhile?(target, :ATTACK, true)
|
||||
score -= (40 * ((user_atk.to_f / target_atk) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
end
|
||||
# Score based on changes to Special Attack
|
||||
if target_spatk > user_spatk
|
||||
# User's Special Attack will be raised
|
||||
if ai.stat_raise_worthwhile?(user, :SPECIAL_ATTACK, true)
|
||||
score += (20 * ((target_spatk.to_f / user_spatk) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
# Target's Special Attack will be lowered
|
||||
if ai.stat_drop_worthwhile?(target, :SPECIAL_ATTACK, true)
|
||||
score += (20 * ((target_spatk.to_f / user_spatk) - 1)).to_i
|
||||
# User's Special Attack will be raised, target's Special Attack will be lowered
|
||||
if ai.stat_raise_worthwhile?(user, :SPECIAL_ATTACK, true) ||
|
||||
ai.stat_drop_worthwhile?(target, :SPECIAL_ATTACK, true)
|
||||
score += (40 * ((target_spatk.to_f / user_spatk) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
elsif target_spatk < user_spatk
|
||||
# User's Special Attack will be lowered
|
||||
if ai.stat_drop_worthwhile?(user, :SPECIAL_ATTACK, true)
|
||||
score -= (20 * ((user_spatk.to_f / target_spatk) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
# Target's Special Attack will be raised
|
||||
if ai.stat_raise_worthwhile?(target, :SPECIAL_ATTACK, true)
|
||||
score -= (20 * ((user_spatk.to_f / target_spatk) - 1)).to_i
|
||||
# User's Special Attack will be lowered, target's Special Attack will be raised
|
||||
if ai.stat_drop_worthwhile?(user, :SPECIAL_ATTACK, true) ||
|
||||
ai.stat_raise_worthwhile?(target, :SPECIAL_ATTACK, true)
|
||||
score -= (40 * ((user_spatk.to_f / target_spatk) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
end
|
||||
@@ -1562,49 +1553,33 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserTargetAverageBaseDef
|
||||
change_matters = false
|
||||
# Score based on changes to Defense
|
||||
if target_def > user_def
|
||||
# User's Defense will be raised
|
||||
if ai.stat_raise_worthwhile?(user, :DEFENSE, true)
|
||||
score += (20 * ((target_def.to_f / user_def) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
# Target's Defense will be lowered
|
||||
if ai.stat_drop_worthwhile?(target, :DEFENSE, true)
|
||||
score += (20 * ((target_def.to_f / user_def) - 1)).to_i
|
||||
# User's Defense will be raised, target's Defense will be lowered
|
||||
if ai.stat_raise_worthwhile?(user, :DEFENSE, true) ||
|
||||
ai.stat_drop_worthwhile?(target, :DEFENSE, true)
|
||||
score += (40 * ((target_def.to_f / user_def) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
elsif target_def < user_def
|
||||
# User's Defense will be lowered
|
||||
if ai.stat_drop_worthwhile?(user, :DEFENSE, true)
|
||||
score -= (20 * ((user_def.to_f / target_def) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
# Target's Defense will be raised
|
||||
if ai.stat_raise_worthwhile?(target, :DEFENSE, true)
|
||||
score -= (20 * ((user_def.to_f / target_def) - 1)).to_i
|
||||
# User's Defense will be lowered, target's Defense will be raised
|
||||
if ai.stat_drop_worthwhile?(user, :DEFENSE, true) ||
|
||||
ai.stat_raise_worthwhile?(target, :DEFENSE, true)
|
||||
score -= (40 * ((user_def.to_f / target_def) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
end
|
||||
# Score based on changes to Special Defense
|
||||
if target_spdef > user_spdef
|
||||
# User's Special Defense will be raised
|
||||
if ai.stat_raise_worthwhile?(user, :SPECIAL_DEFENSE, true)
|
||||
score += (20 * ((target_spdef.to_f / user_spdef) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
# Target's Special Defense will be lowered
|
||||
if ai.stat_drop_worthwhile?(target, :SPECIAL_DEFENSE, true)
|
||||
score += (20 * ((target_spdef.to_f / user_spdef) - 1)).to_i
|
||||
# User's Special Defense will be raised, target's Special Defense will be lowered
|
||||
if ai.stat_raise_worthwhile?(user, :SPECIAL_DEFENSE, true) ||
|
||||
ai.stat_drop_worthwhile?(target, :SPECIAL_DEFENSE, true)
|
||||
score += (40 * ((target_spdef.to_f / user_spdef) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
elsif target_spdef < user_spdef
|
||||
# User's Special Defense will be lowered
|
||||
if ai.stat_drop_worthwhile?(user, :SPECIAL_DEFENSE, true)
|
||||
score -= (20 * ((user_spdef.to_f / target_spdef) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
# Target's Special Defense will be raised
|
||||
if ai.stat_raise_worthwhile?(target, :SPECIAL_DEFENSE, true)
|
||||
score -= (20 * ((user_spdef.to_f / target_spdef) - 1)).to_i
|
||||
# User's Special Defense will be lowered, target's Special Defense will be raised
|
||||
if ai.stat_drop_worthwhile?(user, :SPECIAL_DEFENSE, true) ||
|
||||
ai.stat_raise_worthwhile?(target, :SPECIAL_DEFENSE, true)
|
||||
score -= (40 * ((user_spdef.to_f / target_spdef) - 1)).to_i
|
||||
change_matters = true
|
||||
end
|
||||
end
|
||||
@@ -1636,7 +1611,9 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartUserSideDoubleSpeed",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartUserSideDoubleSpeed",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Don't want to make allies faster if Trick Room will make them act later
|
||||
next Battle::AI::MOVE_USELESS_SCORE if battle.field.effects[PBEffects::TrickRoom] > 1
|
||||
if ai.trainer.medium_skill?
|
||||
next Battle::AI::MOVE_USELESS_SCORE if battle.field.effects[PBEffects::TrickRoom] > 1
|
||||
end
|
||||
# Get the speeds of all battlers
|
||||
ally_speeds = []
|
||||
foe_speeds = []
|
||||
@@ -1654,7 +1631,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartUserSideDoubleSpeed",
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if outspeeds == 0
|
||||
# This move will achieve something
|
||||
next score + 10 * outspeeds + 5
|
||||
next score + 8 + (10 * outspeeds)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1663,38 +1640,38 @@ Battle::AI::Handlers::MoveEffectScore.add("StartUserSideDoubleSpeed",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartSwapAllBattlersBaseDefensiveStats",
|
||||
proc { |score, move, user, ai, battle|
|
||||
any_change_matters = false
|
||||
change_matters = false
|
||||
ai.each_battler do |b, i|
|
||||
b_def = b.base_stat(:DEFENSE)
|
||||
b_spdef = b.base_stat(:SPECIAL_DEFENSE)
|
||||
next if b_def == b_spdef
|
||||
score_change = 0
|
||||
if b_def > b_spdef
|
||||
# Battler's Defense will be lowered
|
||||
# Battler's Defense will be lowered, battler's Special Defense will be raised
|
||||
if ai.stat_drop_worthwhile?(b, :DEFENSE, true)
|
||||
score_change -= (20 * ((b_def.to_f / b_spdef) - 1)).to_i
|
||||
any_change_matters = true
|
||||
change_matters = true
|
||||
end
|
||||
# Battler's Special Defense will be raised
|
||||
if ai.stat_raise_worthwhile?(b, :SPECIAL_DEFENSE, true)
|
||||
score_change += (20 * ((b_def.to_f / b_spdef) - 1)).to_i
|
||||
any_change_matters = true
|
||||
change_matters = true
|
||||
end
|
||||
else
|
||||
# Battler's Special Defense will be lowered
|
||||
if ai.stat_drop_worthwhile?(b, :SPECIAL_DEFENSE, true)
|
||||
score_change -= (20 * ((b_spdef.to_f / b_def) - 1)).to_i
|
||||
any_change_matters = true
|
||||
change_matters = true
|
||||
end
|
||||
# Battler's Defense will be raised
|
||||
if ai.stat_raise_worthwhile?(b, :DEFENSE, true)
|
||||
score_change += (20 * ((b_spdef.to_f / b_def) - 1)).to_i
|
||||
any_change_matters = true
|
||||
change_matters = true
|
||||
end
|
||||
end
|
||||
score += (b.opposes?(user)) ? -score_change : score_change
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !any_change_matters
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !change_matters
|
||||
next Battle::AI::MOVE_USELESS_SCORE if score <= Battle::AI::MOVE_BASE_SCORE
|
||||
next score
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#===============================================================================
|
||||
#
|
||||
# TODO: Should there be all the "next score" for status moves? Remember that
|
||||
# other function codes can call this code as part of their scoring.
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SleepTarget",
|
||||
proc { |move, user, target, ai, battle|
|
||||
@@ -33,18 +34,18 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SleepTarget",
|
||||
# asleep, but the target won't (usually) be able to make use of
|
||||
# them, so they're not worth considering.
|
||||
score -= 10 if target.has_active_ability?(:EARLYBIRD)
|
||||
score -= 5 if target.has_active_ability?(:MARVELSCALE)
|
||||
score -= 8 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
|
||||
score -= 8
|
||||
elsif target.has_active_ability?(:HYDRATION) &&
|
||||
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||
score -= 10
|
||||
score -= 15
|
||||
end
|
||||
ai.each_same_side_battler(target.side) do |b, i|
|
||||
score -= 5 if i != target.index && b.has_active_ability?(:HEALER)
|
||||
score -= 8 if i != target.index && b.has_active_ability?(:HEALER)
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -87,7 +88,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("SleepTarget",
|
||||
"SleepTargetNextTurn")
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
# TODO: Should there be all the "next score" for status moves? Remember that
|
||||
# other function codes can call this code as part of their scoring.
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("PoisonTarget",
|
||||
proc { |move, user, target, ai, battle|
|
||||
@@ -108,9 +110,11 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("PoisonTarget",
|
||||
next score if add_effect == -999 # Additional effect will be negated
|
||||
score += add_effect
|
||||
# Inherent preference
|
||||
score += 10
|
||||
score += 15
|
||||
# Prefer if the target is at high HP
|
||||
score += 10 * target.hp / target.totalhp
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score += 15 * target.hp / target.totalhp
|
||||
end
|
||||
# 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, i|
|
||||
score += 5 if b.has_move_with_function?("DoublePowerIfTargetPoisoned",
|
||||
@@ -120,24 +124,24 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("PoisonTarget",
|
||||
# Don't prefer if target benefits from having the poison status problem
|
||||
score -= 8 if target.has_active_ability?([:GUTS, :MARVELSCALE, :QUICKFEET, :TOXICBOOST])
|
||||
score -= 25 if target.has_active_ability?(:POISONHEAL)
|
||||
score -= 15 if target.has_active_ability?(:SYNCHRONIZE) &&
|
||||
score -= 20 if target.has_active_ability?(:SYNCHRONIZE) &&
|
||||
user.battler.pbCanPoisonSynchronize?(target.battler)
|
||||
score -= 5 if target.has_move_with_function?("DoublePowerIfUserPoisonedBurnedParalyzed",
|
||||
"CureUserBurnPoisonParalysis")
|
||||
score -= 10 if target.check_for_move { |m|
|
||||
score -= 15 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?
|
||||
score -= 20 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
|
||||
score -= 8
|
||||
elsif target.has_active_ability?(:HYDRATION) &&
|
||||
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||
score -= 10
|
||||
score -= 15
|
||||
end
|
||||
ai.each_same_side_battler(target.side) do |b, i|
|
||||
score -= 5 if i != target.index && b.has_active_ability?(:HEALER)
|
||||
score -= 8 if i != target.index && b.has_active_ability?(:HEALER)
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -172,7 +176,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("PoisonTarget",
|
||||
"BadPoisonTarget")
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
# TODO: Should there be all the "next score" for status moves? Remember that
|
||||
# other function codes can call this code as part of their scoring.
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("ParalyzeTarget",
|
||||
proc { |move, user, target, ai, battle|
|
||||
@@ -198,11 +203,11 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ParalyzeTarget",
|
||||
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)
|
||||
score += 15 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
|
||||
score += 7 if target.effects[PBEffects::Confusion] > 1
|
||||
score += 7 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, i|
|
||||
score += 5 if b.has_move_with_function?("DoublePowerIfTargetParalyzedCureTarget",
|
||||
@@ -210,22 +215,22 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ParalyzeTarget",
|
||||
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) &&
|
||||
score -= 20 if target.has_active_ability?(:SYNCHRONIZE) &&
|
||||
user.battler.pbCanParalyzeSynchronize?(target.battler)
|
||||
score -= 5 if target.has_move_with_function?("DoublePowerIfUserPoisonedBurnedParalyzed",
|
||||
"CureUserBurnPoisonParalysis")
|
||||
score -= 10 if target.check_for_move { |m|
|
||||
score -= 15 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
|
||||
score -= 8
|
||||
elsif target.has_active_ability?(:HYDRATION) &&
|
||||
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||
score -= 10
|
||||
score -= 15
|
||||
end
|
||||
ai.each_same_side_battler(target.side) do |b, i|
|
||||
score -= 5 if i != target.index && b.has_active_ability?(:HEALER)
|
||||
score -= 8 if i != target.index && b.has_active_ability?(:HEALER)
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -266,7 +271,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ParalyzeFlinchTarget",
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
# TODO: Should there be all the "next score" for status moves? Remember that
|
||||
# other function codes can call this code as part of their scoring.
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("BurnTarget",
|
||||
proc { |move, user, target, ai, battle|
|
||||
@@ -286,10 +292,10 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("BurnTarget",
|
||||
next score if add_effect == -999 # Additional effect will be negated
|
||||
score += add_effect
|
||||
# Inherent preference
|
||||
score += 10
|
||||
score += 15
|
||||
# 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
|
||||
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
|
||||
@@ -299,24 +305,24 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("BurnTarget",
|
||||
# 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) &&
|
||||
score -= 20 if target.has_active_ability?(:SYNCHRONIZE) &&
|
||||
user.battler.pbCanBurnSynchronize?(target.battler)
|
||||
score -= 5 if target.has_move_with_function?("DoublePowerIfUserPoisonedBurnedParalyzed",
|
||||
"CureUserBurnPoisonParalysis")
|
||||
score -= 10 if target.check_for_move { |m|
|
||||
score -= 15 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?
|
||||
score -= 20 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
|
||||
score -= 8
|
||||
elsif target.has_active_ability?(:HYDRATION) &&
|
||||
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||
score -= 10
|
||||
score -= 15
|
||||
end
|
||||
ai.each_same_side_battler(target.side) do |b, i|
|
||||
score -= 5 if i != target.index && b.has_active_ability?(:HEALER)
|
||||
score -= 8 if i != target.index && b.has_active_ability?(:HEALER)
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -342,7 +348,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("BurnFlinchTarget",
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
# TODO: Should there be all the "next score" for status moves? Remember that
|
||||
# other function codes can call this code as part of their scoring.
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("FreezeTarget",
|
||||
proc { |move, user, target, ai, battle|
|
||||
@@ -371,18 +378,18 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FreezeTarget",
|
||||
# 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)
|
||||
score -= 8 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
|
||||
score -= 8
|
||||
elsif target.has_active_ability?(:HYDRATION) &&
|
||||
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||
score -= 10
|
||||
score -= 15
|
||||
end
|
||||
ai.each_same_side_battler(target.side) do |b, i|
|
||||
score -= 5 if i != target.index && b.has_active_ability?(:HEALER)
|
||||
score -= 8 if i != target.index && b.has_active_ability?(:HEALER)
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -451,7 +458,9 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("GiveUserStatusToTarget"
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("GiveUserStatusToTarget",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score += 10 # For getting rid of the user's status problem
|
||||
# Curing the user's status problem
|
||||
score += 15 if !user.wants_status_problem?(user.status)
|
||||
# Giving the target a status problem
|
||||
case user.status
|
||||
when :SLEEP
|
||||
next Battle::AI::Handlers.apply_move_effect_against_target_score("SleepTarget",
|
||||
@@ -483,7 +492,8 @@ Battle::AI::Handlers::MoveFailureCheck.add("CureUserBurnPoisonParalysis",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("CureUserBurnPoisonParalysis",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next score + 15
|
||||
next Battle::AI::MOVE_USELESS_SCORE if user.wants_status_problem?(user.status)
|
||||
next score + 20
|
||||
}
|
||||
)
|
||||
|
||||
@@ -499,7 +509,7 @@ Battle::AI::Handlers::MoveEffectScore.add("CureUserPartyStatus",
|
||||
proc { |score, move, user, ai, battle|
|
||||
score = Battle::AI::MOVE_BASE_SCORE # Ignore the scores for each targeted battler calculated earlier
|
||||
battle.pbParty(user.index).each do |pkmn|
|
||||
score += 10 if pkmn && pkmn.status != :NONE
|
||||
score += 12 if pkmn && pkmn.status != :NONE
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -514,8 +524,11 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CureTargetBurn",
|
||||
next score if add_effect == -999 # Additional effect will be negated
|
||||
if target.status == :BURN
|
||||
score -= add_effect
|
||||
score -= 10
|
||||
score += 15 if target.wants_status_problem?(:BURN)
|
||||
if target.wants_status_problem?(:BURN)
|
||||
score += 15
|
||||
else
|
||||
score -= 10
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -543,7 +556,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartUserSideImmunityToInflictedStatu
|
||||
# Tends to be wasteful if the foe just has one Pokémon left
|
||||
next score - 20 if battle.pbAbleNonActiveCount(user.idxOpposingSide) == 0
|
||||
# Prefer for each user side battler
|
||||
ai.each_same_side_battler(user.side) { |b, i| score += 10 }
|
||||
ai.each_same_side_battler(user.side) { |b, i| score += 15 }
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -559,10 +572,10 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("FlinchTarget",
|
||||
next score if add_effect == -999 # Additional effect will be negated
|
||||
score += add_effect
|
||||
# Inherent preference
|
||||
score += 10
|
||||
score += 15
|
||||
# Prefer if the target is paralysed, confused or infatuated, to compound the
|
||||
# turn skipping
|
||||
score += 5 if target.status == :PARALYSIS ||
|
||||
score += 8 if target.status == :PARALYSIS ||
|
||||
target.effects[PBEffects::Confusion] > 1 ||
|
||||
target.effects[PBEffects::Attract] >= 0
|
||||
next score
|
||||
@@ -614,14 +627,16 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ConfuseTarget",
|
||||
next score if add_effect == -999 # Additional effect will be negated
|
||||
score += add_effect
|
||||
# Inherent preference
|
||||
score += 5
|
||||
score += 10
|
||||
# Prefer if the target is at high HP
|
||||
score += 10 * target.hp / target.totalhp
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score += 20 * target.hp / target.totalhp
|
||||
end
|
||||
# Prefer if the target is paralysed or infatuated, to compound the turn skipping
|
||||
# TODO: Also prefer if the target is trapped in battle or can't switch out?
|
||||
score += 5 if target.status == :PARALYSIS || target.effects[PBEffects::Attract] >= 0
|
||||
score += 8 if target.status == :PARALYSIS || target.effects[PBEffects::Attract] >= 0
|
||||
# Don't prefer if target benefits from being confused
|
||||
score -= 10 if target.has_active_ability?(:TANGLEDFEET)
|
||||
score -= 15 if target.has_active_ability?(:TANGLEDFEET)
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -648,15 +663,15 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AttractTarget",
|
||||
next score if add_effect == -999 # Additional effect will be negated
|
||||
score += add_effect
|
||||
# Inherent preference
|
||||
score += 10
|
||||
score += 15
|
||||
# Prefer if the target is paralysed or confused, to compound the turn skipping
|
||||
# TODO: Also prefer if the target is trapped in battle or can't switch out?
|
||||
score += 5 if target.status == :PARALYSIS || target.effects[PBEffects::Confusion] > 1
|
||||
score += 8 if target.status == :PARALYSIS || target.effects[PBEffects::Confusion] > 1
|
||||
# Don't prefer if the target can infatuate the user because of this move
|
||||
score -= 10 if target.has_active_item?(:DESTINYKNOT) &&
|
||||
score -= 15 if target.has_active_item?(:DESTINYKNOT) &&
|
||||
user.battler.pbCanAttract?(target.battler, false)
|
||||
# Don't prefer if the user has another way to infatuate the target
|
||||
score -= 8 if move.statusMove? && user.has_active_ability?(:CUTECHARM)
|
||||
score -= 15 if move.statusMove? && user.has_active_ability?(:CUTECHARM)
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -695,11 +710,11 @@ Battle::AI::Handlers::MoveEffectScore.add("SetUserTypesBasedOnEnvironment",
|
||||
new_type = :NORMAL if !GameData::Type.exists?(new_type)
|
||||
end
|
||||
# Check if any user's moves will get STAB because of the type change
|
||||
score += 8 if user.has_damaging_move_of_type?(new_type)
|
||||
score += 14 if user.has_damaging_move_of_type?(new_type)
|
||||
# Check if any user's moves will lose STAB because of the type change
|
||||
user.pbTypes(true).each do |type|
|
||||
next if type == new_type
|
||||
score -= 8 if user.has_damaging_move_of_type?(type)
|
||||
score -= 14 if user.has_damaging_move_of_type?(type)
|
||||
end
|
||||
# NOTE: Other things could be considered, like the foes' moves'
|
||||
# effectivenesses against the current and new user's type(s), and
|
||||
@@ -734,11 +749,11 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetUserTypesToResistLast
|
||||
if Effectiveness.ineffective?(effectiveness)
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
elsif Effectiveness.super_effective?(effectiveness)
|
||||
score += 12
|
||||
score += 15
|
||||
elsif Effectiveness.normal?(effectiveness)
|
||||
score += 8
|
||||
score += 10
|
||||
else # Not very effective
|
||||
score += 4
|
||||
score += 5
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -786,7 +801,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetUserTypesToUserMoveTy
|
||||
# Check if any user's moves will get STAB because of the type change
|
||||
possible_types.each do |type|
|
||||
next if !user.has_damaging_move_of_type?(type)
|
||||
score += 10
|
||||
score += 14
|
||||
break
|
||||
end
|
||||
# NOTE: Other things could be considered, like the foes' moves'
|
||||
@@ -817,7 +832,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetTypesToPsychic"
|
||||
next if !m.damagingMove?
|
||||
effectiveness = Effectiveness.calculate(m.pbCalcType(b.battler), :PSYCHIC)
|
||||
if Effectiveness.super_effective?(effectiveness)
|
||||
score += 8
|
||||
score += 10
|
||||
elsif Effectiveness.ineffective?(effectiveness)
|
||||
score -= 10
|
||||
end
|
||||
@@ -842,7 +857,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetTypesToWater",
|
||||
next if !m.damagingMove?
|
||||
effectiveness = Effectiveness.calculate(m.pbCalcType(b.battler), :WATER)
|
||||
if Effectiveness.super_effective?(effectiveness)
|
||||
score += 8
|
||||
score += 10
|
||||
elsif Effectiveness.ineffective?(effectiveness)
|
||||
score -= 10
|
||||
end
|
||||
@@ -866,7 +881,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AddGhostTypeToTarget",
|
||||
next if !m.damagingMove?
|
||||
effectiveness = Effectiveness.calculate(m.pbCalcType(b.battler), :GHOST)
|
||||
if Effectiveness.super_effective?(effectiveness)
|
||||
score += 8
|
||||
score += 10
|
||||
elsif Effectiveness.not_very_effective?(effectiveness)
|
||||
score -= 5
|
||||
elsif Effectiveness.ineffective?(effectiveness)
|
||||
@@ -892,7 +907,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AddGrassTypeToTarget",
|
||||
next if !m.damagingMove?
|
||||
effectiveness = Effectiveness.calculate(m.pbCalcType(b.battler), :GRASS)
|
||||
if Effectiveness.super_effective?(effectiveness)
|
||||
score += 8
|
||||
score += 10
|
||||
elsif Effectiveness.not_very_effective?(effectiveness)
|
||||
score -= 5
|
||||
elsif Effectiveness.ineffective?(effectiveness)
|
||||
@@ -929,9 +944,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetAbilityToSimple
|
||||
new_ability_rating = target.wants_ability?(:SIMPLE)
|
||||
side_mult = (target.opposes?(user)) ? 1 : -1
|
||||
if old_ability_rating > new_ability_rating
|
||||
score += 4 * side_mult * [old_ability_rating - new_ability_rating, 3].max
|
||||
score += 5 * side_mult * [old_ability_rating - new_ability_rating, 3].max
|
||||
elsif old_ability_rating < new_ability_rating
|
||||
score -= 4 * side_mult * [new_ability_rating - old_ability_rating, 3].max
|
||||
score -= 5 * side_mult * [new_ability_rating - old_ability_rating, 3].max
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -953,9 +968,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetAbilityToInsomn
|
||||
new_ability_rating = target.wants_ability?(:INSOMNIA)
|
||||
side_mult = (target.opposes?(user)) ? 1 : -1
|
||||
if old_ability_rating > new_ability_rating
|
||||
score += 4 * side_mult * [old_ability_rating - new_ability_rating, 3].max
|
||||
score += 5 * side_mult * [old_ability_rating - new_ability_rating, 3].max
|
||||
elsif old_ability_rating < new_ability_rating
|
||||
score -= 4 * side_mult * [new_ability_rating - old_ability_rating, 3].max
|
||||
score -= 5 * side_mult * [new_ability_rating - old_ability_rating, 3].max
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -976,9 +991,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetUserAbilityToTargetAb
|
||||
old_ability_rating = user.wants_ability?(user.ability_id)
|
||||
new_ability_rating = user.wants_ability?(target.ability_id)
|
||||
if old_ability_rating > new_ability_rating
|
||||
score += 4 * [old_ability_rating - new_ability_rating, 3].max
|
||||
score += 5 * [old_ability_rating - new_ability_rating, 3].max
|
||||
elsif old_ability_rating < new_ability_rating
|
||||
score -= 4 * [new_ability_rating - old_ability_rating, 3].max
|
||||
score -= 5 * [new_ability_rating - old_ability_rating, 3].max
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -1002,9 +1017,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SetTargetAbilityToUserAb
|
||||
new_ability_rating = target.wants_ability?(user.ability_id)
|
||||
side_mult = (target.opposes?(user)) ? 1 : -1
|
||||
if old_ability_rating > new_ability_rating
|
||||
score += 4 * side_mult * [old_ability_rating - new_ability_rating, 3].max
|
||||
score += 5 * side_mult * [old_ability_rating - new_ability_rating, 3].max
|
||||
elsif old_ability_rating < new_ability_rating
|
||||
score -= 4 * side_mult * [new_ability_rating - old_ability_rating, 3].max
|
||||
score -= 5 * side_mult * [new_ability_rating - old_ability_rating, 3].max
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -1033,9 +1048,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserTargetSwapAbilities"
|
||||
target_diff = 0 if !target.ability_active?
|
||||
side_mult = (target.opposes?(user)) ? 1 : -1
|
||||
if user_diff > target_diff
|
||||
score += 4 * side_mult * [user_diff - target_diff, 3].max
|
||||
score += 5 * side_mult * [user_diff - target_diff, 3].max
|
||||
elsif target_diff < user_diff
|
||||
score -= 4 * side_mult * [target_diff - user_diff, 3].max
|
||||
score -= 5 * side_mult * [target_diff - user_diff, 3].max
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -1054,9 +1069,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("NegateTargetAbility",
|
||||
target_ability_rating = target.wants_ability?(target.ability_id)
|
||||
side_mult = (target.opposes?(user)) ? 1 : -1
|
||||
if target_ability_rating > 0
|
||||
score += 4 * side_mult * [target_ability_rating, 3].max
|
||||
score += 5 * side_mult * [target_ability_rating, 3].max
|
||||
elsif target_ability_rating < 0
|
||||
score -= 4 * side_mult * [target_ability_rating.abs, 3].max
|
||||
score -= 5 * side_mult * [target_ability_rating.abs, 3].max
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -1073,9 +1088,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("NegateTargetAbilityIfTar
|
||||
target_ability_rating = target.wants_ability?(target.ability_id)
|
||||
side_mult = (target.opposes?(user)) ? 1 : -1
|
||||
if target_ability_rating > 0
|
||||
score += 4 * side_mult * [target_ability_rating, 3].max
|
||||
score += 5 * side_mult * [target_ability_rating, 3].max
|
||||
elsif target_ability_rating < 0
|
||||
score -= 4 * side_mult * [target_ability_rating.abs, 3].max
|
||||
score -= 5 * side_mult * [target_ability_rating.abs, 3].max
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -1112,7 +1127,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartUserAirborne",
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.has_damaging_move_of_type?(:GROUND)
|
||||
next if Effectiveness.resistant?(user.effectiveness_of_type_against_battler(:GROUND, b))
|
||||
score += 5
|
||||
score += 10
|
||||
end
|
||||
# Don't prefer if terrain exists (which the user will no longer be affected by)
|
||||
if ai.trainer.medium_skill?
|
||||
@@ -1131,7 +1146,7 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartTargetAirborneAndA
|
||||
next move.move.pbFailsAgainstTarget?(user.battler, target.battler, false)
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartUserAirborne",
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartTargetAirborneAndAlwaysHitByMoves",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Move is useless if the target is already airborne
|
||||
if target.has_type?(:FLYING) ||
|
||||
@@ -1146,12 +1161,12 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartUserAirborne",
|
||||
b.battler.eachMove do |m|
|
||||
acc = m.accuracy
|
||||
acc = m.pbBaseAccuracy(b.battler, target.battler) if ai.trainer.medium_skill?
|
||||
score += 4 if acc < 90 && acc != 0
|
||||
score += 4 if acc <= 50 && acc != 0
|
||||
score += 5 if acc < 90 && acc != 0
|
||||
score += 5 if acc <= 50 && acc != 0
|
||||
end
|
||||
next if !b.has_damaging_move_of_type?(:GROUND)
|
||||
next if Effectiveness.resistant?(target.effectiveness_of_type_against_battler(:GROUND, b))
|
||||
score -= 5
|
||||
score -= 7
|
||||
end
|
||||
# Prefer if terrain exists (which the target will no longer be affected by)
|
||||
if ai.trainer.medium_skill?
|
||||
@@ -1181,7 +1196,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HitsTargetInSkyGroundsTa
|
||||
score += 10
|
||||
# Prefer if any allies have damaging Ground-type moves
|
||||
ai.each_foe_battler(target.side) do |b, i|
|
||||
score += 5 if b.has_damaging_move_of_type?(:GROUND)
|
||||
score += 8 if b.has_damaging_move_of_type?(:GROUND)
|
||||
end
|
||||
# Don't prefer if terrain exists (which the target will become affected by)
|
||||
if ai.trainer.medium_skill?
|
||||
@@ -1207,25 +1222,26 @@ Battle::AI::Handlers::MoveEffectScore.add("StartGravity",
|
||||
# affected by terrain
|
||||
if b.battler.airborne?
|
||||
score_change = 10
|
||||
score_change -= 8 if battle.field.terrain != :None
|
||||
if ai.trainer.medium_skill?
|
||||
score_change -= 8 if battle.field.terrain != :None
|
||||
end
|
||||
score += (user.opposes?(b)) ? score_change : -score_change
|
||||
# Prefer if allies have any damaging Ground moves they'll be able to use
|
||||
# on a grounded foe, and vice versa
|
||||
ai.each_foe_battler(b.side) do |b2, j|
|
||||
if b2.has_damaging_move_of_type?(:GROUND)
|
||||
score += (user.opposes?(b2)) ? -5 : 5
|
||||
end
|
||||
next if !b2.has_damaging_move_of_type?(:GROUND)
|
||||
score += (user.opposes?(b2)) ? -8 : 8
|
||||
end
|
||||
end
|
||||
# Prefer ending Sky Drop being used on allies, don't prefer ending Sky
|
||||
# Drop being used on foes
|
||||
if b.effects[PBEffects::SkyDrop] >= 0
|
||||
score += (user.opposes?(b)) ? -5 : 5
|
||||
score += (user.opposes?(b)) ? -8 : 8
|
||||
end
|
||||
# Gravity raises accuracy of all moves; prefer if the user/ally has low
|
||||
# accuracy moves, don't prefer if foes have any
|
||||
if b.check_for_move { |m| m.accuracy < 85 }
|
||||
score += (user.opposes?(b)) ? -5 : 5
|
||||
score += (user.opposes?(b)) ? -8 : 8
|
||||
end
|
||||
# Prefer stopping foes' sky-based attacks, don't prefer stopping allies'
|
||||
# sky-based attacks
|
||||
@@ -1233,7 +1249,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartGravity",
|
||||
b.battler.inTwoTurnAttack?("TwoTurnAttackInvulnerableInSky",
|
||||
"TwoTurnAttackInvulnerableInSkyParalyzeTarget",
|
||||
"TwoTurnAttackInvulnerableInSkyTargetCannotAct")
|
||||
score += (user.opposes?(b)) ? 8 : -8
|
||||
score += (user.opposes?(b)) ? 10 : -10
|
||||
end
|
||||
end
|
||||
next score
|
||||
|
||||
@@ -75,9 +75,11 @@ Battle::AI::Handlers::MoveBasePower.add("OHKO",
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("OHKO",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Don't prefer if the target has less HP and user has a non-OHKO damaging move
|
||||
if user.check_for_move { |m| !m.is_a?(Battle::Move::OHKO) && m.damagingMove? }
|
||||
score -= 8 if target.hp <= target.totalhp / 2
|
||||
score -= 8 if target.hp <= target.totalhp / 4
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if user.check_for_move { |m| m.damagingMove? && !m.is_a?(Battle::Move::OHKO) }
|
||||
score -= 12 if target.hp <= target.totalhp / 2
|
||||
score -= 8 if target.hp <= target.totalhp / 4
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -115,7 +117,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DamageTargetAlly",
|
||||
target.battler.allAllies.each do |b|
|
||||
next if !b.near?(target.battler) || !b.battler.takesIndirectDamage?
|
||||
score += 10
|
||||
score += 15 if b.hp <= b.totalhp / 16
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score += 10 if b.hp <= b.totalhp / 16
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -218,7 +222,7 @@ Battle::AI::Handlers::MoveEffectScore.add("PowerHigherWithConsecutiveUse",
|
||||
# Prefer continuing to use this move
|
||||
score += 10 if user.effects[PBEffects::FuryCutter] > 0
|
||||
# Prefer if holding the Metronome
|
||||
score += 5 if user.has_active_item?(:METRONOME)
|
||||
score += 7 if user.has_active_item?(:METRONOME)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -236,7 +240,7 @@ Battle::AI::Handlers::MoveEffectScore.add("PowerHigherWithConsecutiveUse",
|
||||
# Prefer continuing to use this move
|
||||
score += 10 if user.pbOwnSide.effects[PBEffects::EchoedVoiceCounter] > 0
|
||||
# Prefer if holding the Metronome
|
||||
score += 5 if user.has_active_item?(:METRONOME)
|
||||
score += 7 if user.has_active_item?(:METRONOME)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -274,8 +278,11 @@ Battle::AI::Handlers::MoveBasePower.copy("DoublePowerIfTargetHPLessThanHalf",
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DoublePowerIfTargetAsleepCureTarget",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if target.status == :SLEEP && target.statusCount > 1 # Will cure status
|
||||
score -= 10
|
||||
score += 15 if target.wants_status_problem?(:SLEEP)
|
||||
if target.wants_status_problem?(:SLEEP)
|
||||
score += 15
|
||||
else
|
||||
score -= 10
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -298,8 +305,11 @@ Battle::AI::Handlers::MoveBasePower.copy("DoublePowerIfTargetPoisoned",
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DoublePowerIfTargetParalyzedCureTarget",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if target.status == :PARALYSIS # Will cure status
|
||||
score -= 10
|
||||
score += 15 if target.wants_status_problem?(:PARALYSIS)
|
||||
if target.wants_status_problem?(:PARALYSIS)
|
||||
score += 15
|
||||
else
|
||||
score -= 10
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -374,7 +384,7 @@ Battle::AI::Handlers::MoveEffectScore.add("DoublePowerIfUserLostHPThisTurn",
|
||||
# Prefer if user is slower than its foe(s) and the foe(s) can attack
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if user.faster_than?(b) || !b.can_attack?
|
||||
score += 4
|
||||
score += 8
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -389,7 +399,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DoublePowerIfTargetLostH
|
||||
ai.each_foe_battler(target.side) do |b, i|
|
||||
next if i == user.index
|
||||
next if user.faster_than?(b) || !b.can_attack?
|
||||
score += 4
|
||||
score += 8
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -405,7 +415,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DoublePowerIfTargetLostH
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DoublePowerIfTargetActed",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score += 15 if target.faster_than?(user)
|
||||
score += 10 if target.faster_than?(user)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -415,7 +425,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DoublePowerIfTargetActed
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DoublePowerIfTargetNotActed",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score += 15 if user.faster_than?(target)
|
||||
score += 10 if user.faster_than?(target)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -457,7 +467,7 @@ Battle::AI::Handlers::MoveEffectScore.add("EnsureNextCriticalHit",
|
||||
# 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
|
||||
score += 15
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -514,7 +524,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartPreventCriticalHitsAgainstUserSi
|
||||
# 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 += 8 * crit_stage if crit_stage > 0
|
||||
score += 10 if b.effects[PBEffects::LaserFocus] > 0
|
||||
end
|
||||
next score
|
||||
@@ -540,15 +550,17 @@ Battle::AI::Handlers::MoveEffectScore.add("UserEnduresFaintingThisTurn",
|
||||
useless = true
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.can_attack?
|
||||
score += 5
|
||||
useless = false
|
||||
score += 4
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
# Don't prefer if user has high HP, prefer if user has lower HP
|
||||
if user.hp >= user.totalhp / 2
|
||||
score -= 8
|
||||
elsif user.hp >= user.totalhp / 8
|
||||
score += 4
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if user.hp >= user.totalhp / 2
|
||||
score -= 15
|
||||
elsif user.hp <= user.totalhp / 4
|
||||
score += 8
|
||||
end
|
||||
end
|
||||
# Don't prefer if the user used a protection move last turn, making this one
|
||||
# less likely to work
|
||||
@@ -570,20 +582,25 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartWeakenElectricMoves",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartWeakenElectricMoves",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Don't prefer the lower the user's HP is
|
||||
if user.hp < user.totalhp / 2
|
||||
score -= 40 * (0.75 - (user.hp.to_f / user.totalhp)) # -10 to -30
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if user.hp <= user.totalhp / 2
|
||||
score -= (20 * (0.75 - (user.hp.to_f / user.totalhp))).to_i # -5 to -15
|
||||
end
|
||||
end
|
||||
# Prefer if foes have Electric moves
|
||||
any_foe_electric_moves = false
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.has_damaging_move_of_type?(:ELECTRIC)
|
||||
score += 10
|
||||
score += 5 if !b.check_for_move { |m| m.damagingMove? && m.pbCalcType(b.battler) != :ELECTRIC }
|
||||
score += 15
|
||||
score += 7 if !b.check_for_move { |m| m.damagingMove? && m.pbCalcType(b.battler) != :ELECTRIC }
|
||||
any_foe_electric_moves = true
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !any_foe_electric_moves
|
||||
# Don't prefer if any allies have Electric moves
|
||||
ai.each_same_side_battler(user.side) do |b, i|
|
||||
next if !b.has_damaging_move_of_type?(:ELECTRIC)
|
||||
score -= 8
|
||||
score -= 4 if !b.check_for_move { |m| m.damagingMove? && m.pbCalcType(b.battler) != :ELECTRIC }
|
||||
score -= 10
|
||||
score -= 5 if !b.check_for_move { |m| m.damagingMove? && m.pbCalcType(b.battler) != :ELECTRIC }
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -601,20 +618,25 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartWeakenFireMoves",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartWeakenFireMoves",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Don't prefer the lower the user's HP is
|
||||
if user.hp < user.totalhp / 2
|
||||
score -= 40 * (0.75 - (user.hp.to_f / user.totalhp)) # -10 to -30
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if user.hp <= user.totalhp / 2
|
||||
score -= (20 * (0.75 - (user.hp.to_f / user.totalhp))).to_i # -5 to -15
|
||||
end
|
||||
end
|
||||
# Prefer if foes have Fire moves
|
||||
any_foe_fire_moves = false
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.has_damaging_move_of_type?(:FIRE)
|
||||
score += 10
|
||||
score += 5 if !b.check_for_move { |m| m.damagingMove? && m.pbCalcType(b.battler) != :FIRE }
|
||||
score += 15
|
||||
score += 7 if !b.check_for_move { |m| m.damagingMove? && m.pbCalcType(b.battler) != :FIRE }
|
||||
any_foe_fire_moves = true
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !any_foe_fire_moves
|
||||
# Don't prefer if any allies have Fire moves
|
||||
ai.each_same_side_battler(user.side) do |b, i|
|
||||
next if !b.has_damaging_move_of_type?(:FIRE)
|
||||
score -= 8
|
||||
score -= 4 if !b.check_for_move { |m| m.damagingMove? && m.pbCalcType(b.battler) != :FIRE }
|
||||
score -= 10
|
||||
score -= 5 if !b.check_for_move { |m| m.damagingMove? && m.pbCalcType(b.battler) != :FIRE }
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -636,14 +658,16 @@ Battle::AI::Handlers::MoveEffectScore.add("StartWeakenPhysicalDamageAgainstUserS
|
||||
# TODO: Should this HP check exist? The effect can still be set up for
|
||||
# allies. Maybe just don't prefer if there are no replacement mons
|
||||
# left.
|
||||
if user.hp < user.totalhp / 2
|
||||
score -= 40 * (0.75 - (user.hp.to_f / user.totalhp)) # -10 to -30
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if user.hp <= user.totalhp / 2
|
||||
score -= (20 * (0.75 - (user.hp.to_f / user.totalhp))).to_i # -5 to -15
|
||||
end
|
||||
end
|
||||
# Prefer if foes have physical moves (moreso if they don't have special moves)
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.check_for_move { |m| m.physicalMove?(m.type) }
|
||||
score += 8
|
||||
score += 5 if !b.check_for_move { |m| m.specialMove?(m.type) }
|
||||
score += 10
|
||||
score += 8 if !b.check_for_move { |m| m.specialMove?(m.type) }
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -665,14 +689,16 @@ Battle::AI::Handlers::MoveEffectScore.add("StartWeakenSpecialDamageAgainstUserSi
|
||||
# TODO: Should this HP check exist? The effect can still be set up for
|
||||
# allies. Maybe just don't prefer if there are no replacement mons
|
||||
# left.
|
||||
if user.hp < user.totalhp / 2
|
||||
score -= 40 * (0.75 - (user.hp.to_f / user.totalhp)) # -10 to -30
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if user.hp <= user.totalhp / 2
|
||||
score -= (20 * (0.75 - (user.hp.to_f / user.totalhp))).to_i # -5 to -15
|
||||
end
|
||||
end
|
||||
# Prefer if foes have special moves (moreso if they don't have physical moves)
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.check_for_move { |m| m.specialMove?(m.type) }
|
||||
score += 8
|
||||
score += 5 if !b.check_for_move { |m| m.physicalMove?(m.type) }
|
||||
score += 10
|
||||
score += 8 if !b.check_for_move { |m| m.physicalMove?(m.type) }
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -697,8 +723,10 @@ Battle::AI::Handlers::MoveEffectScore.add("StartWeakenDamageAgainstUserSideIfHai
|
||||
# TODO: Should this HP check exist? The effect can still be set up for
|
||||
# allies. Maybe just don't prefer if there are no replacement mons
|
||||
# left.
|
||||
if user.hp < user.totalhp / 2
|
||||
score -= 40 * (0.75 - (user.hp.to_f / user.totalhp)) # -10 to -30
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if user.hp <= user.totalhp / 2
|
||||
score -= (20 * (0.75 - (user.hp.to_f / user.totalhp))).to_i # -5 to -15
|
||||
end
|
||||
end
|
||||
next score + 15
|
||||
}
|
||||
@@ -743,16 +771,16 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUser",
|
||||
# be using, so we don't know if Unseen Fist will apply.
|
||||
useless = false
|
||||
# General preference
|
||||
score += 4
|
||||
score += 7
|
||||
# Prefer if the foe is in the middle of using a two turn attack
|
||||
score += 8 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
score += 15 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
# Prefer if foe takes EOR damage, don't prefer if they have EOR healing
|
||||
b_eor_damage = b.rough_end_of_round_damage
|
||||
if b_eor_damage > 0
|
||||
score += 5
|
||||
score += 8
|
||||
elsif b_eor_damage < 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
end
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
@@ -761,13 +789,13 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUser",
|
||||
if user_eor_damage >= user.hp
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
elsif user_eor_damage > 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
elsif user_eor_damage < 0
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
# Don't prefer if the user used a protection move last turn, making this one
|
||||
# less likely to work
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 12 : 8)
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 15 : 10)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -788,7 +816,7 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserBanefulBunker",
|
||||
# be using, so we don't know if Unseen Fist will apply.
|
||||
useless = false
|
||||
# General preference
|
||||
score += 4
|
||||
score += 7
|
||||
# Prefer if the foe is likely to be poisoned by this move
|
||||
if b.check_for_move { |m| m.contactMove? }
|
||||
poison_score = Battle::AI::Handlers.apply_move_effect_against_target_score("PoisonTarget",
|
||||
@@ -796,14 +824,14 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserBanefulBunker",
|
||||
score += poison_score / 2 # Halved because we don't know what move b will use
|
||||
end
|
||||
# Prefer if the foe is in the middle of using a two turn attack
|
||||
score += 8 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
score += 15 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
# Prefer if foe takes EOR damage, don't prefer if they have EOR healing
|
||||
b_eor_damage = b.rough_end_of_round_damage
|
||||
if b_eor_damage > 0
|
||||
score += 5
|
||||
score += 8
|
||||
elsif b_eor_damage < 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
end
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
@@ -812,13 +840,13 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserBanefulBunker",
|
||||
if user_eor_damage >= user.hp
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
elsif user_eor_damage > 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
elsif user_eor_damage < 0
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
# Don't prefer if the user used a protection move last turn, making this one
|
||||
# less likely to work
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 12 : 8)
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 15 : 10)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -839,7 +867,7 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserFromDamagingMovesKingsShie
|
||||
# be using, so we don't know if Unseen Fist will apply.
|
||||
useless = false
|
||||
# General preference
|
||||
score += 4
|
||||
score += 7
|
||||
# Prefer if the foe's Attack can be lowered by this move
|
||||
if b.battler.affectedByContactEffect? && b.check_for_move { |m| m.contactMove? }
|
||||
drop_score = ai.get_score_for_target_stat_drop(
|
||||
@@ -847,14 +875,14 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserFromDamagingMovesKingsShie
|
||||
score += drop_score / 2 # Halved because we don't know what move b will use
|
||||
end
|
||||
# Prefer if the foe is in the middle of using a two turn attack
|
||||
score += 8 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
score += 15 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
# Prefer if foe takes EOR damage, don't prefer if they have EOR healing
|
||||
b_eor_damage = b.rough_end_of_round_damage
|
||||
if b_eor_damage > 0
|
||||
score += 5
|
||||
score += 8
|
||||
elsif b_eor_damage < 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
end
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
@@ -863,13 +891,13 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserFromDamagingMovesKingsShie
|
||||
if user_eor_damage >= user.hp
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
elsif user_eor_damage > 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
elsif user_eor_damage < 0
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
# Don't prefer if the user used a protection move last turn, making this one
|
||||
# less likely to work
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 12 : 8)
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 15 : 10)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -890,21 +918,21 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserFromDamagingMovesObstruct"
|
||||
# be using, so we don't know if Unseen Fist will apply.
|
||||
useless = false
|
||||
# General preference
|
||||
score += 4
|
||||
score += 7
|
||||
# Prefer if the foe's Attack can be lowered by this move
|
||||
if b.battler.affectedByContactEffect? && b.check_for_move { |m| m.contactMove? }
|
||||
drop_score = ai.get_score_for_target_stat_drop(0, b, [:DEFENSE, 2], false)
|
||||
score += drop_score / 2 # Halved because we don't know what move b will use
|
||||
end
|
||||
# Prefer if the foe is in the middle of using a two turn attack
|
||||
score += 8 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
score += 15 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
# Prefer if foe takes EOR damage, don't prefer if they have EOR healing
|
||||
b_eor_damage = b.rough_end_of_round_damage
|
||||
if b_eor_damage > 0
|
||||
score += 5
|
||||
score += 8
|
||||
elsif b_eor_damage < 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
end
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
@@ -913,13 +941,13 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserFromDamagingMovesObstruct"
|
||||
if user_eor_damage >= user.hp
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
elsif user_eor_damage > 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
elsif user_eor_damage < 0
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
# Don't prefer if the user used a protection move last turn, making this one
|
||||
# less likely to work
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 12 : 8)
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 15 : 10)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -940,20 +968,20 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserFromTargetingMovesSpikyShi
|
||||
# be using, so we don't know if Unseen Fist will apply.
|
||||
useless = false
|
||||
# General preference
|
||||
score += 4
|
||||
score += 7
|
||||
# Prefer if this move will deal damage
|
||||
if b.battler.affectedByContactEffect? && b.check_for_move { |m| m.contactMove? }
|
||||
score += 5
|
||||
end
|
||||
# Prefer if the foe is in the middle of using a two turn attack
|
||||
score += 8 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
score += 15 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
# Prefer if foe takes EOR damage, don't prefer if they have EOR healing
|
||||
b_eor_damage = b.rough_end_of_round_damage
|
||||
if b_eor_damage > 0
|
||||
score += 5
|
||||
score += 8
|
||||
elsif b_eor_damage < 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
end
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
@@ -962,13 +990,13 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserFromTargetingMovesSpikyShi
|
||||
if user_eor_damage >= user.hp
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
elsif user_eor_damage > 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
elsif user_eor_damage < 0
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
# Don't prefer if the user used a protection move last turn, making this one
|
||||
# less likely to work
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 12 : 8)
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 15 : 10)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -992,16 +1020,16 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserSideFromDamagingMovesIfUse
|
||||
# be using, so we don't know if Unseen Fist will apply.
|
||||
useless = false
|
||||
# General preference
|
||||
score += 4
|
||||
score += 7
|
||||
# Prefer if the foe is in the middle of using a two turn attack
|
||||
score += 8 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
score += 15 if b.effects[PBEffects::TwoTurnAttack] &&
|
||||
GameData::Move.get(b.effects[PBEffects::TwoTurnAttack]).flags.any? { |f| f[/^CanProtect$/i] }
|
||||
# Prefer if foe takes EOR damage, don't prefer if they have EOR healing
|
||||
b_eor_damage = b.rough_end_of_round_damage
|
||||
if b_eor_damage > 0
|
||||
score += 5
|
||||
score += 8
|
||||
elsif b_eor_damage < 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
end
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
@@ -1010,12 +1038,12 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserSideFromDamagingMovesIfUse
|
||||
if user_eor_damage >= user.hp
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
elsif user_eor_damage > 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
elsif user_eor_damage < 0
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
# Use it or lose it
|
||||
score += 10
|
||||
score += 25
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -1038,13 +1066,13 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserSideFromStatusMoves",
|
||||
!m.pbTarget(b.battler).targets_all }
|
||||
useless = false
|
||||
# General preference
|
||||
score += 4
|
||||
score += 5
|
||||
# Prefer if foe takes EOR damage, don't prefer if they have EOR healing
|
||||
b_eor_damage = b.rough_end_of_round_damage
|
||||
if b_eor_damage > 0
|
||||
score += 5
|
||||
score += 8
|
||||
elsif b_eor_damage < 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
end
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
@@ -1053,9 +1081,9 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserSideFromStatusMoves",
|
||||
if user_eor_damage >= user.hp
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
elsif user_eor_damage > 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
elsif user_eor_damage < 0
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -1082,13 +1110,13 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserSideFromPriorityMoves",
|
||||
next if !b.check_for_move { |m| m.pbPriority(b.battler) > 0 && m.canProtectAgainst? }
|
||||
useless = false
|
||||
# General preference
|
||||
score += 4
|
||||
score += 7
|
||||
# Prefer if foe takes EOR damage, don't prefer if they have EOR healing
|
||||
b_eor_damage = b.rough_end_of_round_damage
|
||||
if b_eor_damage > 0
|
||||
score += 5
|
||||
score += 8
|
||||
elsif b_eor_damage < 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
end
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
@@ -1097,13 +1125,13 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserSideFromPriorityMoves",
|
||||
if user_eor_damage >= user.hp
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
elsif user_eor_damage > 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
elsif user_eor_damage < 0
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
# Don't prefer if the user used a protection move last turn, making this one
|
||||
# less likely to work
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 12 : 8)
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 15 : 10)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -1128,13 +1156,13 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserSideFromMultiTargetDamagin
|
||||
m.pbTarget(b.battler).num_targets > 1 }
|
||||
useless = false
|
||||
# General preference
|
||||
score += 4
|
||||
score += 7
|
||||
# Prefer if foe takes EOR damage, don't prefer if they have EOR healing
|
||||
b_eor_damage = b.rough_end_of_round_damage
|
||||
if b_eor_damage > 0
|
||||
score += (b.opposes?(user)) ? 5 : -5
|
||||
score += (b.opposes?(user)) ? 8 : -8
|
||||
elsif b_eor_damage < 0
|
||||
score -= (b.opposes?(user)) ? 5 : -5
|
||||
score -= (b.opposes?(user)) ? 8 : -8
|
||||
end
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
@@ -1143,13 +1171,13 @@ Battle::AI::Handlers::MoveEffectScore.add("ProtectUserSideFromMultiTargetDamagin
|
||||
if user_eor_damage >= user.hp
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
elsif user_eor_damage > 0
|
||||
score -= 5
|
||||
score -= 8
|
||||
elsif user_eor_damage < 0
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
# Don't prefer if the user used a protection move last turn, making this one
|
||||
# less likely to work
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 12 : 8)
|
||||
score -= (user.effects[PBEffects::ProtectRate] - 1) * ((Settings::MECHANICS_GENERATION >= 6) ? 15 : 10)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -1163,7 +1191,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RemoveProtections",
|
||||
m.is_a?(Battle::Move::ProtectUserSideFromStatusMoves) ||
|
||||
m.is_a?(Battle::Move::ProtectUserSideFromDamagingMovesIfUserFirstTurn)) &&
|
||||
!m.is_a?(Battle::Move::UserEnduresFaintingThisTurn) }
|
||||
score += 5
|
||||
score += 7
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -1203,7 +1231,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RecoilQuarterOfDamageDea
|
||||
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
||||
next Battle::AI::MOVE_USELESS_SCORE if reserves <= foes
|
||||
end
|
||||
score -= 10 * [dmg, user.hp].min / user.hp
|
||||
score -= 25 * [dmg, user.hp].min / user.hp
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -1221,7 +1249,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RecoilThirdOfDamageDealt
|
||||
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
||||
next Battle::AI::MOVE_USELESS_SCORE if reserves <= foes
|
||||
end
|
||||
score -= 10 * [dmg, user.hp].min / user.hp
|
||||
score -= 25 * [dmg, user.hp].min / user.hp
|
||||
end
|
||||
# Score for paralysing
|
||||
score = Battle::AI::Handlers.apply_move_effect_against_target_score("ParalyzeTarget",
|
||||
@@ -1243,7 +1271,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RecoilThirdOfDamageDealt
|
||||
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
||||
next Battle::AI::MOVE_USELESS_SCORE if reserves <= foes
|
||||
end
|
||||
score -= 10 * [dmg, user.hp].min / user.hp
|
||||
score -= 25 * [dmg, user.hp].min / user.hp
|
||||
end
|
||||
# Score for burning
|
||||
score = Battle::AI::Handlers.apply_move_effect_against_target_score("BurnTarget",
|
||||
@@ -1264,7 +1292,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RecoilHalfOfDamageDealt"
|
||||
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
||||
next Battle::AI::MOVE_USELESS_SCORE if reserves <= foes
|
||||
end
|
||||
score -= 10 * [dmg, user.hp].min / user.hp
|
||||
score -= 25 * [dmg, user.hp].min / user.hp
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -1329,13 +1357,16 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("EnsureNextMoveAlwaysHits
|
||||
# benefit from locking on.
|
||||
acc = m.accuracy
|
||||
acc = m.pbBaseAccuracy(user.battler, target.battler) if ai.trainer.medium_skill?
|
||||
score += 4 if acc < 90 && acc != 0
|
||||
score += 4 if acc <= 50 && acc != 0
|
||||
score += 5 if acc < 90 && acc != 0
|
||||
score += 8 if acc <= 50 && acc != 0
|
||||
# TODO: Prefer more if m is a OHKO move.
|
||||
end
|
||||
# TODO: Prefer if target has increased evasion.
|
||||
# Not worth it if the user or the target is at low HP
|
||||
score -= 10 if user.hp < user.totalhp / 2
|
||||
score -= 8 if target.hp < target.totalhp / 2
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp < user.totalhp / 2
|
||||
score -= 8 if target.hp < target.totalhp / 2
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
@@ -8,7 +8,8 @@ Battle::AI::Handlers::MoveBasePower.add("HitTwoTimes",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HitTwoTimes",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Prefer if the target has a Substitute and the first hit can break it
|
||||
# Prefer if the target has a Substitute and this move can break it before
|
||||
# the last hit
|
||||
if target.effects[PBEffects::Substitute] > 0 && !move.move.ignoresSubstitute?(user.battler)
|
||||
dmg = move.rough_damage
|
||||
num_hits = move.move.pbNumHits(user.battler, [target.battler])
|
||||
@@ -72,7 +73,8 @@ Battle::AI::Handlers::MoveBasePower.add("HitThreeTimesPowersUpWithEachHit",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HitThreeTimesPowersUpWithEachHit",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Prefer if the target has a Substitute and the first or second hit can break it
|
||||
# Prefer if the target has a Substitute and this move can break it before
|
||||
# the last hit
|
||||
if target.effects[PBEffects::Substitute] > 0 && !move.move.ignoresSubstitute?(user.battler)
|
||||
dmg = move.rough_damage
|
||||
score += 10 if target.effects[PBEffects::Substitute] < dmg / 2
|
||||
@@ -101,7 +103,8 @@ Battle::AI::Handlers::MoveBasePower.add("HitTwoToFiveTimes",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HitTwoToFiveTimes",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Prefer if the target has a Substitute and the first hit(s) can break it
|
||||
# Prefer if the target has a Substitute and this move can break it before
|
||||
# the last/third hit
|
||||
if target.effects[PBEffects::Substitute] > 0 && !move.move.ignoresSubstitute?(user.battler)
|
||||
dmg = move.rough_damage
|
||||
num_hits = (user.has_active_ability?(:SKILLLINK)) ? 5 : 3 # 3 is about average
|
||||
@@ -169,7 +172,8 @@ Battle::AI::Handlers::MoveBasePower.add("HitOncePerUserTeamMember",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HitOncePerUserTeamMember",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Prefer if the target has a Substitute and the first hit(s) can break it
|
||||
# Prefer if the target has a Substitute and this move can break it before
|
||||
# the last hit
|
||||
if target.effects[PBEffects::Substitute] > 0 && !move.move.ignoresSubstitute?(user.battler)
|
||||
dmg = move.rough_damage
|
||||
num_hits = 0
|
||||
@@ -188,10 +192,10 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HitOncePerUserTeamMember
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectScore.add("AttackAndSkipNextTurn",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Don't prefer because it uses up two turns
|
||||
score -= 10 if !user.has_active_ability?(:TRUANT)
|
||||
# Don't prefer if user is at a high HP (treat this move as a last resort)
|
||||
score -= 10 if user.hp >= user.totalhp / 2
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp >= user.totalhp / 2
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -210,7 +214,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TwoTurnAttack",
|
||||
# Don't prefer because it uses up two turns
|
||||
score -= 10
|
||||
# Don't prefer if user is at a low HP (time is better spent on quicker moves)
|
||||
score -= 8 if user.hp < user.totalhp / 2
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp < user.totalhp / 2
|
||||
end
|
||||
# Don't prefer if target has a protecting move
|
||||
if ai.trainer.high_skill? && !(user.has_active_ability?(:UNSEENFIST) && move.move.contactMove?)
|
||||
has_protect_move = false
|
||||
@@ -241,7 +247,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TwoTurnAttack",
|
||||
end
|
||||
end
|
||||
end
|
||||
score -= 15 if has_protect_move
|
||||
score -= 20 if has_protect_move
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -367,9 +373,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TwoTurnAttackInvulnerabl
|
||||
# Score for being semi-invulnerable underground
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
if b.check_for_move { |m| m.hitsDiggingTargets? }
|
||||
score -= 8
|
||||
score -= 10
|
||||
else
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -387,9 +393,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TwoTurnAttackInvulnerabl
|
||||
# Score for being semi-invulnerable underwater
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
if b.check_for_move { |m| m.hitsDivingTargets? }
|
||||
score -= 8
|
||||
score -= 10
|
||||
else
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -407,9 +413,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TwoTurnAttackInvulnerabl
|
||||
# Score for being semi-invulnerable in the sky
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
if b.check_for_move { |m| m.hitsFlyingTargets? }
|
||||
score -= 8
|
||||
score -= 10
|
||||
else
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -455,7 +461,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TwoTurnAttackInvulnerabl
|
||||
score = Battle::AI::Handlers.apply_move_effect_against_target_score("TwoTurnAttack",
|
||||
score, move, user, target, ai, battle)
|
||||
# Score for being invulnerable
|
||||
score += 5
|
||||
score += 8
|
||||
# Score for removing protections
|
||||
score = Battle::AI::Handlers.apply_move_effect_against_target_score("RemoveProtections",
|
||||
score, move, user, target, ai, battle)
|
||||
@@ -506,9 +512,11 @@ Battle::AI::Handlers::MoveEffectScore.add("MultiTurnAttackBideThenReturnDoubleDa
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !has_damaging_move
|
||||
# Don't prefer if the user isn't at high HP
|
||||
next Battle::AI::MOVE_USELESS_SCORE if user.hp <= user.totalhp / 4
|
||||
score -= 15 if user.hp <= user.totalhp / 2
|
||||
score -= 8 if user.hp <= user.totalhp * 3 / 4
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
next Battle::AI::MOVE_USELESS_SCORE if user.hp <= user.totalhp / 4
|
||||
score -= 15 if user.hp <= user.totalhp / 2
|
||||
score -= 8 if user.hp <= user.totalhp * 3 / 4
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
@@ -12,20 +12,20 @@ Battle::AI::Handlers::MoveFailureCheck.add("HealUserFullyAndFallAsleep",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserFullyAndFallAsleep",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Consider how much HP will be restored
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
score += 30 * (user.totalhp - user.hp) / user.totalhp # +15 to +30
|
||||
end
|
||||
end
|
||||
# Check whether an existing status problem will be removed
|
||||
score += 10 if user.status != :NONE
|
||||
# Check if user will be able to act while asleep
|
||||
if user.status != :NONE
|
||||
score += (user.wants_status_problem?(user.status)) ? -10 : 8
|
||||
end
|
||||
# Check if user is happy to be asleep, e.g. can use moves while asleep
|
||||
if ai.trainer.medium_skill?
|
||||
if user.check_for_move { |m| m.usableWhenAsleep? }
|
||||
score += 10
|
||||
else
|
||||
score -= 10
|
||||
end
|
||||
score += (user.wants_status_problem?(:SLEEP)) ? 10 : -8
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -42,10 +42,9 @@ Battle::AI::Handlers::MoveFailureCheck.add("HealUserHalfOfTotalHP",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserHalfOfTotalHP",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Consider how much HP will be restored
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
next score - 10 if user.hp >= user.totalhp * 0.5
|
||||
score += 30 * (user.totalhp - user.hp) / user.totalhp # +15 to +30
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -59,17 +58,14 @@ Battle::AI::Handlers::MoveFailureCheck.copy("HealUserHalfOfTotalHP",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserDependingOnWeather",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Consider how much HP will be restored
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
score = Battle::AI::Handlers.apply_move_effect_score("HealUserHalfOfTotalHP",
|
||||
score, move, user, ai, battle)
|
||||
case user.battler.effectiveWeather
|
||||
when :Sun, :HarshSun
|
||||
score += 5
|
||||
when :None, :StrongWinds
|
||||
else
|
||||
case user.battler.effectiveWeather
|
||||
when :Sun, :HarshSun
|
||||
score += 5
|
||||
when :None, :StrongWinds
|
||||
else
|
||||
score -= 10
|
||||
end
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||
score -= 10
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -83,12 +79,9 @@ Battle::AI::Handlers::MoveFailureCheck.copy("HealUserHalfOfTotalHP",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserDependingOnSandstorm",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Consider how much HP will be restored
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
score += 5 if user.battler.effectiveWeather == :Sandstorm
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||
end
|
||||
score = Battle::AI::Handlers.apply_move_effect_score("HealUserHalfOfTotalHP",
|
||||
score, move, user, ai, battle)
|
||||
score += 5 if user.battler.effectiveWeather == :Sandstorm
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -101,15 +94,13 @@ Battle::AI::Handlers::MoveFailureCheck.copy("HealUserHalfOfTotalHP",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserHalfOfTotalHPLoseFlyingTypeThisTurn",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Consider how much HP will be restored
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||
end
|
||||
score = Battle::AI::Handlers.apply_move_effect_score("HealUserHalfOfTotalHP",
|
||||
score, move, user, ai, battle)
|
||||
# User loses the Flying type this round
|
||||
if user.has_type?(:FLYING)
|
||||
# TODO: Decide whether losing the Flying type is good or bad. Look at
|
||||
# type effectiveness changes against the user, and for foes' Ground
|
||||
# moves. Anything else?
|
||||
# moves (foe foes slower than the user). Anything else?
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -125,15 +116,11 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("CureTargetStatusHealUse
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CureTargetStatusHealUserHalfOfTotalHP",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Will cure status
|
||||
score -= 10
|
||||
score += 15 if target.wants_status_problem?(target.status)
|
||||
# Consider how much HP will be restored
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||
end
|
||||
score = Battle::AI::Handlers.apply_move_effect_score("HealUserHalfOfTotalHP",
|
||||
score, move, user, ai, battle)
|
||||
# Will cure target's status
|
||||
score += (target.wants_status_problem?(target.status)) ? 10 : -8
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -155,23 +142,23 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealUserByTargetAttackLo
|
||||
if ai.trainer.medium_skill?
|
||||
score = ai.get_score_for_target_stat_drop(score, target, move.move.statDown)
|
||||
end
|
||||
# Consider how much HP will be restored
|
||||
heal_amt = target.rough_stat(:ATTACK)
|
||||
if heal_amt > user.totalhp * 0.3 # Only modify the score if it'll heal a decent amount
|
||||
# Things that affect healing caused by draining
|
||||
if target.has_active_ability?(:LIQUIDOOZE)
|
||||
score -= 20
|
||||
elsif user.battler.canHeal?
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
heal_amt *= 1.3 if user.has_active_item?(:BIGROOT)
|
||||
heal_fraction = [user.totalhp - user.hp, heal_amt].min.to_f / user.totalhp
|
||||
score += 40 * heal_fraction * (user.totalhp - user.hp) / user.totalhp
|
||||
# Healing the user
|
||||
if target.has_active_ability?(:LIQUIDOOZE)
|
||||
score -= 20
|
||||
elsif user.battler.canHeal?
|
||||
score += 5 if user.has_active_item?(:BIGROOT)
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
# Consider how much HP will be restored
|
||||
heal_amt = target.rough_stat(:ATTACK)
|
||||
heal_amt *= 1.3 if user.has_active_item?(:BIGROOT)
|
||||
heal_amt = [heal_amt, user.totalhp - user.hp].min
|
||||
if heal_amt > user.totalhp * 0.3 # Only modify the score if it'll heal a decent amount
|
||||
if user.hp < user.totalhp * 0.5
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp # +10 to +20
|
||||
end
|
||||
score += 20 * heal_amt / user.totalhp # +6 to +20
|
||||
end
|
||||
end
|
||||
else
|
||||
score -= 10 if target.has_active_ability?(:LIQUIDOOZE)
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -182,19 +169,23 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealUserByTargetAttackLo
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealUserByHalfOfDamageDone",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Consider how much HP will be restored
|
||||
heal_amt = move.rough_damage / 2
|
||||
if heal_amt > user.totalhp * 0.3 # Only modify the score if it'll heal a decent amount
|
||||
# Things that affect healing caused by draining
|
||||
if target.has_active_ability?(:LIQUIDOOZE)
|
||||
score -= 20
|
||||
elsif user.battler.canHeal?
|
||||
rough_dmg = move.rough_damage
|
||||
if target.has_active_ability?(:LIQUIDOOZE)
|
||||
score -= 20 if rough_dmg < target.hp
|
||||
elsif user.battler.canHeal?
|
||||
score += 5 if user.has_active_item?(:BIGROOT)
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
# Consider how much HP will be restored
|
||||
heal_amt = rough_dmg / 2
|
||||
heal_amt *= 1.3 if user.has_active_item?(:BIGROOT)
|
||||
heal_fraction = [user.totalhp - user.hp, heal_amt].min.to_f / user.totalhp
|
||||
score += 40 * heal_fraction * (user.totalhp - user.hp) / user.totalhp
|
||||
heal_amt = [heal_amt, user.totalhp - user.hp].min
|
||||
if heal_amt > user.totalhp * 0.3 # Only modify the score if it'll heal a decent amount
|
||||
if user.hp < user.totalhp * 0.5
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp # +10 to +20
|
||||
end
|
||||
score += 20 * heal_amt / user.totalhp # +6 to +20
|
||||
end
|
||||
end
|
||||
else
|
||||
score -= 10 if target.has_active_ability?(:LIQUIDOOZE)
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -216,19 +207,23 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("HealUserByHalfOfDamageD
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealUserByThreeQuartersOfDamageDone",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Consider how much HP will be restored
|
||||
heal_amt = move.rough_damage * 0.75
|
||||
if heal_amt > user.totalhp * 0.3 # Only modify the score if it'll heal a decent amount
|
||||
# Things that affect healing caused by draining
|
||||
if target.has_active_ability?(:LIQUIDOOZE)
|
||||
score -= 20
|
||||
elsif user.battler.canHeal?
|
||||
rough_dmg = move.rough_damage
|
||||
if target.has_active_ability?(:LIQUIDOOZE)
|
||||
score -= 20 if rough_dmg < target.hp
|
||||
elsif user.battler.canHeal?
|
||||
score += 5 if user.has_active_item?(:BIGROOT)
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
# Consider how much HP will be restored
|
||||
heal_amt = rough_dmg * 0.75
|
||||
heal_amt *= 1.3 if user.has_active_item?(:BIGROOT)
|
||||
heal_fraction = [user.totalhp - user.hp, heal_amt].min.to_f / user.totalhp
|
||||
score += 40 * heal_fraction * (user.totalhp - user.hp) / user.totalhp
|
||||
heal_amt = [heal_amt, user.totalhp - user.hp].min
|
||||
if heal_amt > user.totalhp * 0.3 # Only modify the score if it'll heal a decent amount
|
||||
if user.hp < user.totalhp * 0.5
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp # +10 to +20
|
||||
end
|
||||
score += 20 * heal_amt / user.totalhp # +6 to +20
|
||||
end
|
||||
end
|
||||
else
|
||||
score -= 10 if target.has_active_ability?(:LIQUIDOOZE)
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -244,11 +239,14 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("HealUserAndAlliesQuarte
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealUserAndAlliesQuarterOfTotalHP",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next score if !target.battler.canHeal?
|
||||
# Consider how much HP will be restored
|
||||
if target.hp >= target.totalhp * 0.75
|
||||
score -= 5
|
||||
else
|
||||
score += 15 * (target.totalhp - target.hp) / target.totalhp
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if target.hp >= target.totalhp * 0.75
|
||||
score -= 5
|
||||
else
|
||||
score += 15 * (target.totalhp - target.hp) / target.totalhp # +3 to +15
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -265,13 +263,12 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("HealUserAndAlliesQuarte
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealUserAndAlliesQuarterOfTotalHPCureStatus",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Consider how much HP will be restored
|
||||
if target.hp >= target.totalhp * 0.75
|
||||
score -= 5
|
||||
else
|
||||
score += 15 * (target.totalhp - target.hp) / target.totalhp
|
||||
end
|
||||
score = Battle::AI::Handlers.apply_move_effect_score("HealUserAndAlliesQuarterOfTotalHP",
|
||||
score, move, user, ai, battle)
|
||||
# Check whether an existing status problem will be removed
|
||||
score += 10 if target.status != :NONE
|
||||
if target.status != :NONE
|
||||
score += (target.wants_status_problem?(target.status)) ? -10 : 10
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -288,14 +285,17 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealTargetHalfOfTotalHP"
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if target.opposes?(user)
|
||||
# Consider how much HP will be restored
|
||||
heal_amt = target.totalhp / 2
|
||||
heal_amt = target.totalhp * 0.75 if move.move.pulseMove? &&
|
||||
user.has_active_ability?(:MEGALAUNCHER)
|
||||
if target.hp >= target.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
heal_fraction = [target.totalhp - target.hp, heal_amt].min.to_f / target.totalhp
|
||||
score += 40 * heal_fraction * (target.totalhp - target.hp) / target.totalhp
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if target.hp >= target.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
heal_amt = target.totalhp * 0.5
|
||||
heal_amt = target.totalhp * 0.75 if move.move.pulseMove? &&
|
||||
user.has_active_ability?(:MEGALAUNCHER)
|
||||
heal_amt = [heal_amt, target.totalhp - target.hp].min
|
||||
score += 20 * (target.totalhp - target.hp) / target.totalhp # +10 to +20
|
||||
score += 20 * heal_amt / target.totalhp # +10 or +15
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -310,13 +310,16 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealTargetDependingOnGra
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if user.opposes?(target)
|
||||
# Consider how much HP will be restored
|
||||
heal_amt = target.totalhp / 2
|
||||
heal_amt = (target.totalhp * 2 / 3.0).round if battle.field.terrain == :Grassy
|
||||
if target.hp >= target.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
heal_fraction = [target.totalhp - target.hp, heal_amt].min.to_f / target.totalhp
|
||||
score += 40 * heal_fraction * (target.totalhp - target.hp) / target.totalhp
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if target.hp >= target.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
heal_amt = target.totalhp * 0.5
|
||||
heal_amt = (target.totalhp * 2 / 3.0).round if battle.field.terrain == :Grassy
|
||||
heal_amt = [heal_amt, target.totalhp - target.hp].min
|
||||
score += 20 * (target.totalhp - target.hp) / target.totalhp # +10 to +20
|
||||
score += 20 * heal_amt / target.totalhp # +10 or +13
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -333,10 +336,12 @@ Battle::AI::Handlers::MoveFailureCheck.add("HealUserPositionNextTurn",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserPositionNextTurn",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Consider how much HP will be restored
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
score += 15 * (user.totalhp - user.hp) / user.totalhp
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp # +10 to +20
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -352,8 +357,8 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartHealUserEachTurn",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartHealUserEachTurn",
|
||||
proc { |score, move, user, ai, battle|
|
||||
score += 10
|
||||
score += 10 if user.has_active_item?(:BIGROOT)
|
||||
score += 15
|
||||
score += 5 if user.has_active_item?(:BIGROOT)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -368,9 +373,9 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartHealUserEachTurnTrapUserInBattl
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartHealUserEachTurnTrapUserInBattle",
|
||||
proc { |score, move, user, ai, battle|
|
||||
score += 5
|
||||
score += 10 if user.turnCount < 2
|
||||
score += 10 if user.has_active_item?(:BIGROOT)
|
||||
score += 8
|
||||
score += 15 if user.turnCount < 2
|
||||
score += 5 if user.has_active_item?(:BIGROOT)
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -386,7 +391,7 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartDamageTargetEachTu
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartDamageTargetEachTurnIfTargetAsleep",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if target.statusCount <= 1
|
||||
next score + 10 * target.statusCount
|
||||
next score + 8 * target.statusCount
|
||||
}
|
||||
)
|
||||
|
||||
@@ -402,20 +407,21 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartLeechSeedTarget",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartLeechSeedTarget",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score += 15
|
||||
# Prefer early on
|
||||
score += 10 if user.turnCount < 2
|
||||
if ai.trainer.medium_skill?
|
||||
# Prefer if the user has no damaging moves
|
||||
score += 20 if !user.check_for_move { |m| m.damagingMove? }
|
||||
score += 10 if !user.check_for_move { |m| m.damagingMove? }
|
||||
# Prefer if the target can't switch out to remove its seeding
|
||||
score += 10 if !battle.pbCanChooseNonActive?(target.index)
|
||||
score += 8 if !battle.pbCanChooseNonActive?(target.index)
|
||||
# Don't prefer if the leeched HP will hurt the user
|
||||
score -= 20 if target.has_active_ability?([:LIQUIDOOZE])
|
||||
end
|
||||
if ai.trainer.high_skill?
|
||||
# Prefer if user can stall while damage is dealt
|
||||
if user.check_for_move { |m| m.is_a?(Battle::Move::ProtectMove) }
|
||||
score += 15
|
||||
score += 10
|
||||
end
|
||||
# Don't prefer if target can remove the seed
|
||||
if target.has_move_with_function?("RemoveUserBindingAndEntryHazards")
|
||||
@@ -432,9 +438,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartLeechSeedTarget",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("UserLosesHalfOfTotalHP",
|
||||
proc { |score, move, user, ai, battle|
|
||||
score -= 15 # User will lose 50% HP, don't prefer this move
|
||||
if ai.trainer.medium_skill?
|
||||
score += 10 if user.hp >= user.totalhp * 0.75 # User at 75% HP or more
|
||||
score += 10 if user.hp <= user.totalhp * 0.25 # User at 25% HP or less
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score += 15 if user.hp >= user.totalhp * 0.75 # User has HP to spare
|
||||
score += 15 if user.hp <= user.totalhp * 0.25 # User is near fainting anyway; suicide
|
||||
end
|
||||
if ai.trainer.high_skill?
|
||||
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
||||
@@ -467,10 +473,10 @@ Battle::AI::Handlers::MoveFailureCheck.copy("UserLosesHalfOfTotalHPExplosive",
|
||||
"UserFaintsExplosive")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("UserFaintsExplosive",
|
||||
proc { |score, move, user, ai, battle|
|
||||
score -= 25 # User will faint, don't prefer this move
|
||||
if ai.trainer.medium_skill?
|
||||
score -= 10 if user.hp >= user.totalhp * 0.5 # User at 50% HP or more
|
||||
score += 10 if user.hp <= user.totalhp * 0.25 # User at 25% HP or less
|
||||
score -= 20 # User will faint, don't prefer this move
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp >= user.totalhp * 0.5
|
||||
score += 20 if user.hp <= user.totalhp * 0.25 # User is near fainting anyway; suicide
|
||||
end
|
||||
if ai.trainer.high_skill?
|
||||
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
||||
@@ -515,14 +521,14 @@ Battle::AI::Handlers::MoveEffectScore.copy("UserFaintsExplosive",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserFaintsLowerTargetAtkSpAtk2",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score -= 25 # User will faint, don't prefer this move
|
||||
score -= 20 # User will faint, don't prefer this move
|
||||
# Check the impact of lowering the target's stats
|
||||
score = ai.get_score_for_target_stat_drop(score, target, move.move.statDown)
|
||||
next score if score == Battle::AI::MOVE_USELESS_SCORE
|
||||
# Score for the user fainting
|
||||
if ai.trainer.medium_skill?
|
||||
score -= 10 if user.hp >= user.totalhp * 0.5 # User at 50% HP or more
|
||||
score += 10 if user.hp <= user.totalhp * 0.25 # User at 25% HP or less
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp >= user.totalhp * 0.5
|
||||
score += 20 if user.hp <= user.totalhp * 0.25 # User is near fainting anyway; suicide
|
||||
end
|
||||
if ai.trainer.high_skill?
|
||||
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
||||
@@ -545,7 +551,7 @@ Battle::AI::Handlers::MoveFailureCheck.add("UserFaintsHealAndCureReplacement",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("UserFaintsHealAndCureReplacement",
|
||||
proc { |score, move, user, ai, battle|
|
||||
score -= 25 # User will faint, don't prefer this move
|
||||
score -= 20 # User will faint, don't prefer this move
|
||||
# Check whether the replacement user needs healing, and don't make the below
|
||||
# calculations if not
|
||||
if ai.trainer.medium_skill?
|
||||
@@ -556,10 +562,11 @@ Battle::AI::Handlers::MoveEffectScore.add("UserFaintsHealAndCureReplacement",
|
||||
break
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !need_healing
|
||||
score += 10
|
||||
end
|
||||
if ai.trainer.medium_skill?
|
||||
score -= 10 if user.hp >= user.totalhp * 0.5 # User at 50% HP or more
|
||||
score += 10 if user.hp <= user.totalhp * 0.25 # User at 25% HP or less
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score -= 10 if user.hp >= user.totalhp * 0.5
|
||||
score += 20 if user.hp <= user.totalhp * 0.25 # User is near fainting anyway; suicide
|
||||
end
|
||||
if ai.trainer.high_skill?
|
||||
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
||||
@@ -611,16 +618,17 @@ Battle::AI::Handlers::MoveEffectScore.add("StartPerishCountsForAllBattlers",
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if foes_affected == 0
|
||||
score += 15 if allies_affected == 0 # No downside for user; cancel out inherent negative score
|
||||
score += 15 * (foes_affected - allies_affected)
|
||||
score += 5 * foes_with_high_hp
|
||||
score -= 15 * allies_affected
|
||||
score += 20 * foes_affected
|
||||
score += 10 * foes_with_high_hp if ai.trainer.has_skill_flag?("HPAware")
|
||||
end
|
||||
if ai.trainer.high_skill?
|
||||
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
||||
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
||||
if foes == 0 # Foe is down to their last Pokémon, can't lose Perish count
|
||||
score += 30 # => Want to auto-win in 3 turns
|
||||
score += 25 # => Want to auto-win in 3 turns
|
||||
elsif reserves == 0 # AI is down to its last Pokémon, can't lose Perish count
|
||||
score -= 20 # => Don't want to auto-lose in 3 turns
|
||||
score -= 15 # => Don't want to auto-lose in 3 turns
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -644,9 +652,9 @@ Battle::AI::Handlers::MoveEffectScore.add("AttackerFaintsIfUserFaints",
|
||||
user_faster_count += 1 if user.faster_than?(b)
|
||||
end
|
||||
next score if user_faster_count == 0 # Move will almost certainly have no effect
|
||||
score += 5 * user_faster_count
|
||||
score += 7 * user_faster_count
|
||||
# Prefer this move at lower user HP
|
||||
if ai.trainer.medium_skill?
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score += 20 if user.hp <= user.totalhp * 0.4
|
||||
score += 10 if user.hp <= user.totalhp * 0.25
|
||||
score += 15 if user.hp <= user.totalhp * 0.1
|
||||
@@ -667,12 +675,12 @@ Battle::AI::Handlers::MoveEffectScore.add("SetAttackerMovePPTo0IfUserFaints",
|
||||
user_faster_count += 1 if user.faster_than?(b)
|
||||
end
|
||||
next score if user_faster_count == 0 # Move will almost certainly have no effect
|
||||
score += 5 * user_faster_count
|
||||
score += 7 * user_faster_count
|
||||
# Prefer this move at lower user HP (not as preferred as Destiny Bond, though)
|
||||
if ai.trainer.medium_skill?
|
||||
score += 15 if user.hp <= user.totalhp * 0.4
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
score += 20 if user.hp <= user.totalhp * 0.4
|
||||
score += 10 if user.hp <= user.totalhp * 0.25
|
||||
score += 10 if user.hp <= user.totalhp * 0.1
|
||||
score += 15 if user.hp <= user.totalhp * 0.1
|
||||
end
|
||||
next score
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserTakesTargetItem",
|
||||
user_no_item_preference = user.wants_item?(:NONE)
|
||||
target_item_preference = target.wants_item?(target.item_id)
|
||||
target_no_item_preference = target.wants_item?(:NONE)
|
||||
score += (user_item_preference - user_no_item_preference) * 3
|
||||
score += (target_item_preference - target_no_item_preference) * 3
|
||||
score += user_item_preference - user_no_item_preference
|
||||
score += target_item_preference - target_no_item_preference
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -35,8 +35,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TargetTakesUserItem",
|
||||
user_no_item_preference = user.wants_item?(:NONE)
|
||||
target_item_preference = target.wants_item?(user.item_id)
|
||||
target_no_item_preference = target.wants_item?(:NONE)
|
||||
score -= (user_item_preference - user_no_item_preference) * 3
|
||||
score -= (target_item_preference - target_no_item_preference) * 3
|
||||
score += user_no_item_preference - user_item_preference
|
||||
score += target_no_item_preference - target_item_preference
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -60,11 +60,11 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserTargetSwapItems",
|
||||
user_old_item_preference = user.wants_item?(user.item_id)
|
||||
target_new_item_preference = target.wants_item?(user.item_id)
|
||||
target_old_item_preference = target.wants_item?(target.item_id)
|
||||
score += (user_new_item_preference - user_old_item_preference) * 3
|
||||
score -= (target_new_item_preference - target_old_item_preference) * 3
|
||||
score += user_new_item_preference - user_old_item_preference
|
||||
score += target_old_item_preference - target_new_item_preference
|
||||
# Don't prefer if user used this move in the last round
|
||||
score -= 15 if user.battler.lastMoveUsed &&
|
||||
GameData::Move.get(user.battler.lastMoveUsed).function_code == "UserTargetSwapItems"
|
||||
GameData::Move.get(user.battler.lastMoveUsed).function_code == move.function
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -80,8 +80,8 @@ Battle::AI::Handlers::MoveFailureCheck.add("RestoreUserConsumedItem",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RestoreUserConsumedItem",
|
||||
proc { |score, move, user, ai, battle|
|
||||
user_new_item_preference = user.wants_item?(user.battler.recycleItem)
|
||||
user_old_item_preference = user.wants_item?(user.item_id)
|
||||
score += (user_new_item_preference - user_old_item_preference) * 4
|
||||
user_old_item_preference = user.wants_item?(:NONE)
|
||||
score += (user_new_item_preference - user_old_item_preference) * 2
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -103,7 +103,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RemoveTargetItem",
|
||||
# User can knock off the target's item; score it
|
||||
target_item_preference = target.wants_item?(target.item_id)
|
||||
target_no_item_preference = target.wants_item?(:NONE)
|
||||
score += (target_item_preference - target_no_item_preference) * 4
|
||||
score += (target_item_preference - target_no_item_preference) * 2
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -121,7 +121,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DestroyTargetBerryOrGem"
|
||||
# User can incinerate the target's item; score it
|
||||
target_item_preference = target.wants_item?(target.item_id)
|
||||
target_no_item_preference = target.wants_item?(:NONE)
|
||||
score += (target_item_preference - target_no_item_preference) * 4
|
||||
score += (target_item_preference - target_no_item_preference) * 2
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -142,7 +142,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CorrodeTargetItem",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
target_item_preference = target.wants_item?(target.item_id)
|
||||
target_no_item_preference = target.wants_item?(:NONE)
|
||||
score += (target_item_preference - target_no_item_preference) * 4
|
||||
score += (target_item_preference - target_no_item_preference) * 2
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -158,8 +158,9 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartTargetCannotUseIte
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartTargetCannotUseItem",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !target.item || !target.item_active?
|
||||
# TODO: Useless if target's item cannot be negated or it has no effect.
|
||||
item_score = target.wants_item?(target.item_id)
|
||||
score += item_score * 3
|
||||
score += item_score * 2
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -176,6 +177,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartNegateHeldItems",
|
||||
next if !b.item
|
||||
# Skip b if its item is disabled
|
||||
if ai.trainer.medium_skill?
|
||||
# TODO: Skip b if its item cannot be negated or it has no effect.
|
||||
if battle.field.effects[PBEffects::MagicRoom] > 0
|
||||
# NOTE: Same as b.item_active? but ignoring the Magic Room part.
|
||||
next if b.effects[PBEffects::Embargo] > 0
|
||||
@@ -194,10 +196,10 @@ Battle::AI::Handlers::MoveEffectScore.add("StartNegateHeldItems",
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !any_held_items
|
||||
if battle.field.effects[PBEffects::MagicRoom] > 0
|
||||
next Battle::AI::MOVE_USELESS_SCORE if total_want >= 0
|
||||
score -= [total_want, -5].max * 5 # Will enable items, prefer if allies affected more
|
||||
score -= [total_want, -5].max * 4 # Will enable items, prefer if allies affected more
|
||||
else
|
||||
next Battle::AI::MOVE_USELESS_SCORE if total_want <= 0
|
||||
score += [total_want, 5].min * 5 # Will disable items, prefer if foes affected more
|
||||
score += [total_want, 5].min * 4 # Will disable items, prefer if foes affected more
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -218,19 +220,19 @@ Battle::AI::Handlers::MoveEffectScore.add("UserConsumeBerryRaiseDefense2",
|
||||
score = Battle::AI::Handlers.apply_move_effect_score("RaiseUserDefense2",
|
||||
score, move, user, ai, battle)
|
||||
# Score for the consumed berry's effect
|
||||
score += ai.get_score_change_for_consuming_item(user, user.item_id)
|
||||
score += user.get_score_change_for_consuming_item(user.item_id, true)
|
||||
# Score for other results of consuming the berry
|
||||
if ai.trainer.medium_skill?
|
||||
# Prefer if user will heal itself with Cheek Pouch
|
||||
score += 5 if user.battler.canHeal? && user.hp < user.totalhp / 2 &&
|
||||
score += 8 if user.battler.canHeal? && user.hp < user.totalhp / 2 &&
|
||||
user.has_active_ability?(:CHEEKPOUCH)
|
||||
# Prefer if target can recover the consumed berry
|
||||
score += 8 if user.has_active_ability?(:HARVEST) ||
|
||||
user.has_move_with_function?("RestoreUserConsumedItem")
|
||||
# Prefer if user couldn't normally consume the berry
|
||||
score += 4 if !user.battler.canConsumeBerry?
|
||||
score += 5 if !user.battler.canConsumeBerry?
|
||||
# Prefer if user will become able to use Belch
|
||||
score += 4 if !user.battler.belched? && user.has_move_with_function?("FailsIfUserNotConsumedBerry")
|
||||
score += 5 if !user.battler.belched? && user.has_move_with_function?("FailsIfUserNotConsumedBerry")
|
||||
# Prefer if user will benefit from not having an item
|
||||
score += 5 if user.has_active_ability?(:UNBURDEN)
|
||||
end
|
||||
@@ -249,21 +251,21 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("AllBattlersConsumeBerry
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AllBattlersConsumeBerry",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Score for the consumed berry's effect
|
||||
score_change = ai.get_score_change_for_consuming_item(target, target.item_id)
|
||||
score_change = target.get_score_change_for_consuming_item(target.item_id, !target.opposes?(user))
|
||||
# Score for other results of consuming the berry
|
||||
if ai.trainer.medium_skill?
|
||||
# Prefer if target will heal itself with Cheek Pouch
|
||||
score_change += 5 if target.battler.canHeal? && target.hp < target.totalhp / 2 &&
|
||||
score_change += 8 if target.battler.canHeal? && target.hp < target.totalhp / 2 &&
|
||||
target.has_active_ability?(:CHEEKPOUCH)
|
||||
# Prefer if target can recover the consumed berry
|
||||
score_change += 8 if target.has_active_ability?(:HARVEST) ||
|
||||
target.has_move_with_function?("RestoreUserConsumedItem")
|
||||
# Prefer if target couldn't normally consume the berry
|
||||
score_change += 4 if !target.battler.canConsumeBerry?
|
||||
score_change += 5 if !target.battler.canConsumeBerry?
|
||||
# Prefer if target will become able to use Belch
|
||||
score += 4 if !target.battler.belched? && target.has_move_with_function?("FailsIfUserNotConsumedBerry")
|
||||
score_change += 5 if !target.battler.belched? && target.has_move_with_function?("FailsIfUserNotConsumedBerry")
|
||||
# Prefer if target will benefit from not having an item
|
||||
score += 5 if target.has_active_ability?(:UNBURDEN)
|
||||
score_change += 5 if target.has_active_ability?(:UNBURDEN)
|
||||
end
|
||||
score += (target.opposes?(user)) ? -score_change : score_change
|
||||
next score
|
||||
@@ -280,21 +282,21 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserConsumeTargetBerry",
|
||||
next score if target.effects[PBEffects::Substitute] > 0
|
||||
next score if target.has_active_ability?(:STICKYHOLD) && !battle.moldBreaker
|
||||
# Score the user gaining the item's effect
|
||||
score += ai.get_score_change_for_consuming_item(user, target.item_id)
|
||||
score += user.get_score_change_for_consuming_item(target.item_id)
|
||||
# Score for other results of consuming the berry
|
||||
if ai.trainer.medium_skill?
|
||||
# Prefer if user will heal itself with Cheek Pouch
|
||||
score += 5 if user.battler.canHeal? && user.hp < user.totalhp / 2 &&
|
||||
score += 8 if user.battler.canHeal? && user.hp < user.totalhp / 2 &&
|
||||
user.has_active_ability?(:CHEEKPOUCH)
|
||||
# Prefer if user will become able to use Belch
|
||||
score += 4 if !user.battler.belched? && user.has_move_with_function?("FailsIfUserNotConsumedBerry")
|
||||
score += 5 if !user.battler.belched? && user.has_move_with_function?("FailsIfUserNotConsumedBerry")
|
||||
# Don't prefer if target will benefit from not having an item
|
||||
score -= 5 if target.has_active_ability?(:UNBURDEN)
|
||||
end
|
||||
# Score the target no longer having the item
|
||||
target_item_preference = target.wants_item?(target.item_id)
|
||||
target_no_item_preference = target.wants_item?(:NONE)
|
||||
score += (target_item_preference - target_no_item_preference) * 4
|
||||
score += (target_item_preference - target_no_item_preference) * 2
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -332,12 +334,12 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ThrowUserItemAtTarget",
|
||||
score = Battle::AI::Handlers.apply_move_effect_against_target_score("FlinchTarget",
|
||||
score, move, user, target, ai, battle)
|
||||
else
|
||||
score -= ai.get_score_change_for_consuming_item(target, user.item_id)
|
||||
score -= target.get_score_change_for_consuming_item(user.item_id)
|
||||
end
|
||||
# Score for other results of consuming the berry
|
||||
if ai.trainer.medium_skill?
|
||||
# Don't prefer if target will become able to use Belch
|
||||
score -= 4 if user.item.is_berry? && !target.battler.belched? &&
|
||||
score -= 5 if user.item.is_berry? && !target.battler.belched? &&
|
||||
target.has_move_with_function?("FailsIfUserNotConsumedBerry")
|
||||
# Prefer if user will benefit from not having an item
|
||||
score += 5 if user.has_active_ability?(:UNBURDEN)
|
||||
@@ -346,7 +348,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ThrowUserItemAtTarget",
|
||||
# keep its held item
|
||||
user_item_preference = user.wants_item?(user.item_id)
|
||||
user_no_item_preference = user.wants_item?(:NONE)
|
||||
score += (user_item_preference - user_no_item_preference) * 4
|
||||
score += (user_item_preference - user_no_item_preference) * 2
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ Battle::AI::Handlers::MoveEffectScore.add("RedirectAllMovesToUser",
|
||||
# Useless if there is no ally to redirect attacks from
|
||||
next Battle::AI::MOVE_USELESS_SCORE if user.battler.allAllies.length == 0
|
||||
# Prefer if ally is at low HP and user is at high HP
|
||||
if user.hp > user.totalhp * 2 / 3
|
||||
if ai.trainer.has_skill_flag?("HPAware") && user.hp > user.totalhp * 2 / 3
|
||||
ai.each_ally(user.index) do |b, i|
|
||||
score += 10 if b.hp <= b.totalhp / 3
|
||||
end
|
||||
@@ -27,7 +27,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RedirectAllMovesToTarget
|
||||
next Battle::AI::MOVE_USELESS_SCORE if user.battler.allAllies.length == 0
|
||||
end
|
||||
# Generaly don't prefer this move, as it's a waste of the user's turn
|
||||
next score - 15
|
||||
next score - 20
|
||||
}
|
||||
)
|
||||
|
||||
@@ -47,7 +47,7 @@ Battle::AI::Handlers::MoveBasePower.add("RandomlyDamageOrHealTarget",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RandomlyDamageOrHealTarget",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Generaly don't prefer this move, as it may heal the target instead
|
||||
next score - 8
|
||||
next score - 10
|
||||
}
|
||||
)
|
||||
|
||||
@@ -56,17 +56,18 @@ Battle::AI::Handlers::MoveEffectScore.add("RandomlyDamageOrHealTarget",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("HealAllyOrDamageFoe",
|
||||
proc { |move, user, target, ai, battle|
|
||||
next !target.opposes?(user) && target.battler.canHeal?
|
||||
next !target.opposes?(user) && !target.battler.canHeal?
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealAllyOrDamageFoe",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if !target.opposes?(user)
|
||||
# Consider how much HP will be restored
|
||||
next score if target.opposes?(user)
|
||||
# Consider how much HP will be restored
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
if target.hp >= target.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
score += 20 * (target.totalhp - target.hp) / target.totalhp
|
||||
score += 20 * (target.totalhp - target.hp) / target.totalhp # +10 to +20
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -116,19 +117,21 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CurseTargetOrLowerUserSp
|
||||
next score if !user.has_type?(:GHOST) &&
|
||||
!(move.rough_type == :GHOST && user.has_active_ability?([:LIBERO, :PROTEAN]))
|
||||
# Don't prefer if user will faint because of using this move
|
||||
next Battle::AI::MOVE_USELESS_SCORE if user.hp <= user.totalhp / 2
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
next Battle::AI::MOVE_USELESS_SCORE if user.hp <= user.totalhp / 2
|
||||
end
|
||||
# Prefer early on
|
||||
score += 10 if user.turnCount < 2
|
||||
if ai.trainer.medium_skill?
|
||||
# Prefer if the user has no damaging moves
|
||||
score += 20 if !user.check_for_move { |m| m.damagingMove? }
|
||||
score += 15 if !user.check_for_move { |m| m.damagingMove? }
|
||||
# Prefer if the target can't switch out to remove its curse
|
||||
score += 10 if !battle.pbCanChooseNonActive?(target.index)
|
||||
end
|
||||
if ai.trainer.high_skill?
|
||||
# Prefer if user can stall while damage is dealt
|
||||
if user.check_for_move { |m| m.is_a?(Battle::Move::ProtectMove) }
|
||||
score += 8
|
||||
score += 5
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -192,13 +195,10 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("TargetNextFireMoveDamag
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TargetNextFireMoveDamagesTarget",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Effect wears off at the end of the round
|
||||
next Battle::AI::MOVE_USELESS_SCORE if target.faster_than?(user)
|
||||
# Prefer if target knows any Fire moves (moreso if that's the only type they know)
|
||||
if target.check_for_move { |m| m.pbCalcType(b.battler) == :FIRE }
|
||||
score += 10
|
||||
score += 10 if !target.check_for_move { |m| m.pbCalcType(b.battler) != :FIRE }
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !target.check_for_move { |m| m.pbCalcType(target.battler) == :FIRE }
|
||||
score += 10
|
||||
score += 10 if !target.check_for_move { |m| m.pbCalcType(target.battler) != :FIRE }
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -240,7 +240,7 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("PowerUpAllyMove",
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("PowerUpAllyMove",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !target.check_for_move { |m| m.damagingMove? }
|
||||
next score + 4
|
||||
next score + 5
|
||||
}
|
||||
)
|
||||
|
||||
@@ -265,10 +265,10 @@ Battle::AI::Handlers::MoveEffectScore.add("CounterPhysicalDamage",
|
||||
score += 5 if b.rough_stat(:ATTACK) > b.rough_stat(:SPECIAL_ATTACK)
|
||||
# Prefer if the last move the foe used was physical
|
||||
if ai.trainer.medium_skill? && b.battler.lastMoveUsed
|
||||
score += 5 if GameData::Move.get(b.battler.lastMoveUsed).physical?
|
||||
score += 8 if GameData::Move.get(b.battler.lastMoveUsed).physical?
|
||||
end
|
||||
# Prefer if the foe is taunted into using a damaging move
|
||||
score += 4 if b.effects[PBEffects::Taunt] > 0
|
||||
score += 5 if b.effects[PBEffects::Taunt] > 0
|
||||
end
|
||||
# Useless if no foes have a physical move to counter
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !has_physical_move
|
||||
@@ -297,10 +297,10 @@ Battle::AI::Handlers::MoveEffectScore.add("CounterSpecialDamage",
|
||||
score += 5 if b.rough_stat(:SPECIAL_ATTACK) > b.rough_stat(:ATTACK)
|
||||
# Prefer if the last move the foe used was special
|
||||
if ai.trainer.medium_skill? && b.battler.lastMoveUsed
|
||||
score += 5 if GameData::Move.get(b.battler.lastMoveUsed).special?
|
||||
score += 8 if GameData::Move.get(b.battler.lastMoveUsed).special?
|
||||
end
|
||||
# Prefer if the foe is taunted into using a damaging move
|
||||
score += 4 if b.effects[PBEffects::Taunt] > 0
|
||||
score += 5 if b.effects[PBEffects::Taunt] > 0
|
||||
end
|
||||
# Useless if no foes have a special move to counter
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !has_special_move
|
||||
@@ -327,10 +327,10 @@ Battle::AI::Handlers::MoveEffectScore.add("CounterDamagePlusHalf",
|
||||
has_damaging_move = true
|
||||
# Prefer if the last move the foe used was damaging
|
||||
if ai.trainer.medium_skill? && b.battler.lastMoveUsed
|
||||
score += 5 if GameData::Move.get(b.battler.lastMoveUsed).damaging?
|
||||
score += 8 if GameData::Move.get(b.battler.lastMoveUsed).damaging?
|
||||
end
|
||||
# Prefer if the foe is taunted into using a damaging move
|
||||
score += 6 if b.effects[PBEffects::Taunt] > 0
|
||||
score += 5 if b.effects[PBEffects::Taunt] > 0
|
||||
end
|
||||
# Useless if no foes have a damaging move to counter
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !has_damaging_move
|
||||
@@ -352,7 +352,7 @@ Battle::AI::Handlers::MoveEffectScore.add("UserAddStockpileRaiseDefSpDef1",
|
||||
# More preferable if user also has Spit Up/Swallow
|
||||
if user.battler.pbHasMoveFunction?("PowerDependsOnUserStockpile",
|
||||
"HealUserDependingOnUserStockpile")
|
||||
score += [10, 8, 5, 3][user.effects[PBEffects::Stockpile]]
|
||||
score += [10, 10, 8, 5][user.effects[PBEffects::Stockpile]]
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -397,13 +397,12 @@ Battle::AI::Handlers::MoveEffectScore.add("HealUserDependingOnUserStockpile",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !user.battler.canHeal?
|
||||
# Consider how much HP will be restored
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
else
|
||||
# Slightly prefer to hold out for another Stockpile to make this move stronger
|
||||
score -= 5 if user.effects[PBEffects::Stockpile] < 2
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||
if ai.trainer.has_skill_flag?("HPAware")
|
||||
next score - 10 if user.hp >= user.totalhp * 0.5
|
||||
score += 20 * (user.totalhp - user.hp) / user.totalhp # +10 to +20
|
||||
end
|
||||
# Slightly prefer to hold out for another Stockpile to make this move stronger
|
||||
score -= 5 if user.effects[PBEffects::Stockpile] < 2
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -550,13 +549,13 @@ Battle::AI::Handlers::MoveEffectScore.add("BounceBackProblemCausingStatusMoves",
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.can_attack?
|
||||
next if !b.check_for_move { |m| m.statusMove? && m.canMagicCoat? }
|
||||
score += 4
|
||||
score += 5
|
||||
useless = false
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
# Don't prefer the lower the user's HP is (better to try something else)
|
||||
if user.hp < user.totalhp / 2
|
||||
score -= 20 * (0.75 - (user.hp.to_f / user.totalhp)) # -5 to -15
|
||||
if ai.trainer.has_skill_flag?("HPAware") && user.hp < user.totalhp / 2
|
||||
score -= (20 * (1.0 - (user.hp.to_f / user.totalhp))).to_i # -10 to -20
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -571,13 +570,13 @@ Battle::AI::Handlers::MoveEffectScore.add("StealAndUseBeneficialStatusMove",
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.can_attack?
|
||||
next if !b.check_for_move { |m| m.statusMove? && m.canSnatch? }
|
||||
score += 4
|
||||
score += 5
|
||||
useless = false
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
# Don't prefer the lower the user's HP is (better to try something else)
|
||||
if user.hp < user.totalhp / 2
|
||||
score -= 20 * (0.75 - (user.hp.to_f / user.totalhp)) # -5 to -15
|
||||
if ai.trainer.has_skill_flag?("HPAware") && user.hp < user.totalhp / 2
|
||||
score -= (20 * (1.0 - (user.hp.to_f / user.totalhp))).to_i # -10 to -20
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -606,7 +605,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ReplaceMoveThisBattleWit
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Generally don't prefer, as this wastes the user's turn just to gain a move
|
||||
# of unknown utility
|
||||
score -= 8
|
||||
score -= 10
|
||||
# Slightly prefer if this move will definitely succeed, just for the sake of
|
||||
# getting rid of this move
|
||||
score += 5 if user.faster_than?(target)
|
||||
|
||||
@@ -139,9 +139,9 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("SwitchOutTargetStatusMo
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SwitchOutTargetStatusMove",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score += 20 if target.pbOwnSide.effects[PBEffects::Spikes] > 0
|
||||
score += 20 if target.pbOwnSide.effects[PBEffects::ToxicSpikes] > 0
|
||||
score += 20 if target.pbOwnSide.effects[PBEffects::StealthRock]
|
||||
score += 15 if target.pbOwnSide.effects[PBEffects::Spikes] > 0
|
||||
score += 15 if target.pbOwnSide.effects[PBEffects::ToxicSpikes] > 0
|
||||
score += 15 if target.pbOwnSide.effects[PBEffects::StealthRock]
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -153,9 +153,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SwitchOutTargetDamagingM
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if (battle.moldBreaker || !target.has_active_ability?(:SUCTIONCUPS)) &&
|
||||
!target.effects[PBEffects::Ingrain]
|
||||
score += 20 if target.pbOwnSide.effects[PBEffects::Spikes] > 0
|
||||
score += 20 if target.pbOwnSide.effects[PBEffects::ToxicSpikes] > 0
|
||||
score += 20 if target.pbOwnSide.effects[PBEffects::StealthRock]
|
||||
score += 15 if target.pbOwnSide.effects[PBEffects::Spikes] > 0
|
||||
score += 15 if target.pbOwnSide.effects[PBEffects::ToxicSpikes] > 0
|
||||
score += 15 if target.pbOwnSide.effects[PBEffects::StealthRock]
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -172,7 +172,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("BindTarget",
|
||||
# you don't want to use it?)
|
||||
score += 5 if user.has_active_item?([:BINDINGBAND, :GRIPCLAW])
|
||||
# Target will take damage at the end of each round from the binding
|
||||
score += 8 if target.battler.takesIndirectDamage?
|
||||
score += 10 if target.battler.takesIndirectDamage?
|
||||
# Check whether the target will be trapped in battle by the binding
|
||||
if target.can_become_trapped?
|
||||
score += 8 # Prefer if the target will become trapped by this move
|
||||
@@ -180,20 +180,20 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("BindTarget",
|
||||
if eor_damage > 0
|
||||
# Prefer if the target will take damage at the end of each round on top
|
||||
# of binding damage
|
||||
score += 8
|
||||
score += 10
|
||||
elsif eor_damage < 0
|
||||
# Don't prefer if the target will heal itself at the end of each round
|
||||
score -= 8
|
||||
score -= 10
|
||||
end
|
||||
# Prefer if the target has been Perish Songed
|
||||
score += 10 if target.effects[PBEffects::PerishSong] > 0
|
||||
score += 15 if target.effects[PBEffects::PerishSong] > 0
|
||||
end
|
||||
# Don't prefer if the target can remove the binding (and the binding has an
|
||||
# effect)
|
||||
if target.can_become_trapped? || target.battler.takesIndirectDamage?
|
||||
if ai.trainer.medium_skill? &&
|
||||
target.has_move_with_function?("RemoveUserBindingAndEntryHazards")
|
||||
score -= 8
|
||||
score -= 10
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -232,13 +232,6 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TrapTargetInBattle",
|
||||
if eor_damage >= target.hp
|
||||
next (move.damagingMove?) ? score : Battle::AI::MOVE_USELESS_SCORE
|
||||
end
|
||||
# Score for EOR damage (intentionally before Rapid Spin check)
|
||||
hp_fraction = (Settings::MECHANICS_GENERATION >= 6) ? 8 : 16
|
||||
if user.has_active_item?(:BINDINGBAND)
|
||||
hp_fraction = (Settings::MECHANICS_GENERATION >= 6) ? 6 : 8
|
||||
end
|
||||
rounds_to_deplete_hp = (hp_fraction.to_f * target.hp / target.totalhp).ceil
|
||||
score += 30 / rounds_to_deplete_hp
|
||||
# Not worth trapping if target can remove the binding
|
||||
if ai.trainer.medium_skill? &&
|
||||
target.has_move_with_function?("RemoveUserBindingAndEntryHazards")
|
||||
@@ -256,7 +249,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TrapTargetInBattle",
|
||||
if target.effects[PBEffects::PerishSong] > 0 ||
|
||||
target.effects[PBEffects::Attract] >= 0 ||
|
||||
eor_damage > 0
|
||||
score += 12
|
||||
score += 15
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -284,7 +277,7 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("TrapTargetInBattleLower
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TrapTargetInBattleLowerTargetDefSpDef1EachTurn",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Score for stat drop
|
||||
score = ai.get_score_for_target_stat_drop(score, target, [:DEFENSE, 1, :SPECIAL_DEFENSE], false)
|
||||
score = ai.get_score_for_target_stat_drop(score, target, [:DEFENSE, 1, :SPECIAL_DEFENSE, 1], false)
|
||||
# Score for target becoming trapped in battle
|
||||
if target.can_become_trapped? && battle.pbCanChooseNonActive?(target.index)
|
||||
# Not worth trapping if target will faint this round anyway
|
||||
@@ -304,7 +297,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TrapTargetInBattleLowerT
|
||||
if target.effects[PBEffects::PerishSong] > 0 ||
|
||||
target.effects[PBEffects::Attract] >= 0 ||
|
||||
eor_damage > 0
|
||||
score += 12
|
||||
score += 15
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -338,7 +331,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TrapUserAndTargetInBattl
|
||||
if target.effects[PBEffects::PerishSong] > 0 ||
|
||||
target.effects[PBEffects::Attract] >= 0 ||
|
||||
eor_damage > 0
|
||||
score += 12
|
||||
score += 15
|
||||
end
|
||||
end
|
||||
next score
|
||||
@@ -403,7 +396,7 @@ Battle::AI::Handlers::MoveEffectScore.add("UsedAfterAllyRoundWithDoublePower",
|
||||
end
|
||||
next score if !ally_has_move
|
||||
# Prefer for the sake of doubling in power
|
||||
score += 5
|
||||
score += 10
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -502,7 +495,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TargetUsesItsLastUsedMov
|
||||
# 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.
|
||||
score += 20
|
||||
score += 10
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -601,19 +594,19 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("DisableTargetLastMoveUs
|
||||
next !target.check_for_move { |m| m.id == target.battler.lastRegularMoveUsed }
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DisableTargetUsingSameMoveConsecutively",
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DisableTargetLastMoveUsed",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if target.has_active_item?(:MENTALHERB)
|
||||
# Inherent preference
|
||||
score += 5
|
||||
# Prefer if the target is locked into using a single move, or will be
|
||||
if target.effects[PBEffects::ChoiceBand] ||
|
||||
target.has_active_item?([:CHOICEBAND, :CHOICESPECS, :CHOICESCARF]) ||
|
||||
target.has_active_ability?(:GORILLATACTICS)
|
||||
score += 8
|
||||
score += 10
|
||||
end
|
||||
# PRefer disabling a damaging move
|
||||
score += 5 if GameData::Move.try_get(target.battler.lastRegularMoveUsed)&.damaging?
|
||||
# Inherent preference
|
||||
score += 8
|
||||
# Prefer disabling a damaging move
|
||||
score += 8 if GameData::Move.try_get(target.battler.lastRegularMoveUsed)&.damaging?
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -631,14 +624,14 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("DisableTargetUsingSameM
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DisableTargetUsingSameMoveConsecutively",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if target.has_active_item?(:MENTALHERB)
|
||||
# Inherent preference
|
||||
score += 10
|
||||
# Prefer if the target is locked into using a single move, or will be
|
||||
if target.effects[PBEffects::ChoiceBand] ||
|
||||
target.has_active_item?([:CHOICEBAND, :CHOICESPECS, :CHOICESCARF]) ||
|
||||
target.has_active_ability?(:GORILLATACTICS)
|
||||
score += 8
|
||||
score += 10
|
||||
end
|
||||
# Inherent preference
|
||||
score += 8
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -672,24 +665,24 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DisableTargetUsingDiffer
|
||||
else
|
||||
score += 8
|
||||
end
|
||||
elsif move_data.damaging? && move_data.target == :NearOther
|
||||
elsif move_data.damaging? && [:NearOther, :Other].include?(move_data.target)
|
||||
# Prefer encoring damaging moves depending on their type effectiveness
|
||||
# against the user
|
||||
eff = user.effectiveness_of_type_against_battler(move_data.type, target)
|
||||
if Effectiveness.ineffective?(eff)
|
||||
score += 15
|
||||
score += 20
|
||||
elsif Effectiveness.not_very_effective?(eff)
|
||||
score += 10
|
||||
score += 15
|
||||
elsif Effectiveness.super_effective?(eff)
|
||||
score -= 5
|
||||
score -= 8
|
||||
else
|
||||
score += 5
|
||||
score += 8
|
||||
end
|
||||
end
|
||||
else
|
||||
# We don't know which move is going to be encored; just prefer limiting
|
||||
# the target's options
|
||||
score += 8
|
||||
score += 10
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -717,13 +710,17 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DisableTargetStatusMoves
|
||||
end
|
||||
end
|
||||
# Move is likely useless if the target will lock themselves into a move,
|
||||
# because they'll likely lock themselves into a damaging move anyway
|
||||
# because they'll likely lock themselves into a damaging move
|
||||
if !target.effects[PBEffects::ChoiceBand]
|
||||
if target.has_active_item?([:CHOICEBAND, :CHOICESPECS, :CHOICESCARF]) ||
|
||||
target.has_active_ability?(:GORILLATACTICS)
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
end
|
||||
end
|
||||
# Prefer based on how many status moves the target knows
|
||||
target.battler.eachMove do |m|
|
||||
score += 5 if m.statusMove? && (m.pp > 0 || m.total_pp == 0)
|
||||
end
|
||||
# Prefer if the target has a protection move
|
||||
protection_moves = [
|
||||
"ProtectUser", # Detect, Protect
|
||||
@@ -738,10 +735,8 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DisableTargetStatusMoves
|
||||
"ProtectUserBanefulBunker" # Baneful Bunker
|
||||
]
|
||||
if target.check_for_move { |m| m.statusMove? && protection_moves.include?(m.function) }
|
||||
score += 6
|
||||
score += 10
|
||||
end
|
||||
# Inherent preference
|
||||
score += 8
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -766,7 +761,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DisableTargetHealingMove
|
||||
end
|
||||
end
|
||||
# Inherent preference
|
||||
score += 8
|
||||
score += 10
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -799,16 +794,16 @@ Battle::AI::Handlers::MoveFailureCheck.add("DisableTargetMovesKnownByUser",
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DisableTargetMovesKnownByUser",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Useless if the foes have no moves that the user also knows
|
||||
shared_move = false
|
||||
affected_foe_count = 0
|
||||
user_moves = user.battler.moves.map { |m| m.id }
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.check_for_move { |m| user_moves.include?(m.id) }
|
||||
shared_move = true
|
||||
affected_foe_count += 1
|
||||
break
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !shared_move
|
||||
next Battle::AI::MOVE_USELESS_SCORE if affected_foe_count == 0
|
||||
# Inherent preference
|
||||
score += 6
|
||||
score += 8 * affected_foe_count
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user