First shot at rewriting AI for moves that lower the target's stat(s)

This commit is contained in:
Maruno17
2022-11-06 16:53:24 +00:00
parent 55563463d8
commit b31400b9ae
4 changed files with 352 additions and 388 deletions

View File

@@ -1355,6 +1355,8 @@ end
# stage each. (Venom Drench) # stage each. (Venom Drench)
#=============================================================================== #===============================================================================
class Battle::Move::LowerPoisonedTargetAtkSpAtkSpd1 < Battle::Move class Battle::Move::LowerPoisonedTargetAtkSpAtkSpd1 < Battle::Move
attr_reader :statDown
def canMagicCoat?; return true; end def canMagicCoat?; return true; end
def initialize(battle, move) def initialize(battle, move)
@@ -1367,10 +1369,13 @@ class Battle::Move::LowerPoisonedTargetAtkSpAtkSpd1 < Battle::Move
targets.each do |b| targets.each do |b|
next if !b || b.fainted? next if !b || b.fainted?
next if !b.poisoned? next if !b.poisoned?
next if !b.pbCanLowerStatStage?(:ATTACK, user, self) && failed = true
!b.pbCanLowerStatStage?(:SPECIAL_ATTACK, user, self) && (@statDown.length / 2).times do |i|
!b.pbCanLowerStatStage?(:SPEED, user, self) next if !target.pbCanLowerStatStage?(@statDown[i * 2], user, self)
@validTargets.push(b.index) failed = false
break
end
@validTargets.push(b.index) if !failed
end end
if @validTargets.length == 0 if @validTargets.length == 0
@battle.pbDisplay(_INTL("But it failed!")) @battle.pbDisplay(_INTL("But it failed!"))

View File

@@ -59,7 +59,7 @@ class Battle::AI
# CategoryDependsOnHigherDamageIgnoreTargetAbility. # CategoryDependsOnHigherDamageIgnoreTargetAbility.
#============================================================================= #=============================================================================
def stat_raise_worthwhile?(stat) def stat_raise_worthwhile?(stat)
return false if !@user.battler.pbCanRaiseStatStage?(stat, @user.battler, @move) return false if !@user.battler.pbCanRaiseStatStage?(stat, @user.battler, @move.move)
# Check if user won't benefit from the stat being raised # Check if user won't benefit from the stat being raised
# TODO: Exception if user knows Baton Pass/Stored Power? # TODO: Exception if user knows Baton Pass/Stored Power?
case stat case stat
@@ -69,18 +69,16 @@ class Battle::AI
m.function != "UseTargetAttackInsteadOfUserAttack" } m.function != "UseTargetAttackInsteadOfUserAttack" }
when :DEFENSE when :DEFENSE
each_foe_battler(@user.side) do |b, i| each_foe_battler(@user.side) do |b, i|
next if !b.check_for_move { |m| m.physicalMove?(m.type) || return true if b.check_for_move { |m| m.physicalMove?(m.type) ||
m.function == "UseTargetDefenseInsteadOfTargetSpDef" } m.function == "UseTargetDefenseInsteadOfTargetSpDef" }
return true
end end
return false return false
when :SPECIAL_ATTACK when :SPECIAL_ATTACK
return false if !@user.check_for_move { |m| m.specialMove?(m.type) } return false if !@user.check_for_move { |m| m.specialMove?(m.type) }
when :SPECIAL_DEFENSE when :SPECIAL_DEFENSE
each_foe_battler(@user.side) do |b, i| each_foe_battler(@user.side) do |b, i|
next if !b.check_for_move { |m| m.specialMove?(m.type) && return true if b.check_for_move { |m| m.specialMove?(m.type) &&
m.function != "UseTargetDefenseInsteadOfTargetSpDef" } m.function != "UseTargetDefenseInsteadOfTargetSpDef" }
return true
end end
return false return false
when :SPEED when :SPEED
@@ -103,12 +101,6 @@ class Battle::AI
#============================================================================= #=============================================================================
# Make score changes based on the general concept of raising stats at all. # Make score changes based on the general concept of raising stats at all.
#============================================================================= #=============================================================================
# TODO: These function codes need to have an attr_reader :statUp and for them
# to be set when the move is initialised.
# LowerUserDefSpDef1RaiseUserAtkSpAtkSpd2 Shell Smash
# RaiseTargetRandomStat2 Acupressure
# RaisePlusMinusUserAndAlliesDefSpDef1 Magnetic Flux
# RaisePlusMinusUserAndAlliesAtkSpAtk1 Gear Up
def get_user_stat_raise_score_generic(score, stat_changes) def get_user_stat_raise_score_generic(score, stat_changes)
total_increment = stat_changes.sum { |change| change[1] } total_increment = stat_changes.sum { |change| change[1] }
# TODO: Just return if foe is predicted to use a phazing move (one that # TODO: Just return if foe is predicted to use a phazing move (one that
@@ -154,17 +146,11 @@ class Battle::AI
break break
end end
# Prefer if user has most of its HP
if @user.hp >= @user.totalhp * 3 / 4
mini_score *= (sweeping_stat) ? 1.2 : 1.1
end
# TODO: Prefer if user's moves won't do much damage. # TODO: Prefer if user's moves won't do much damage.
# Prefer if user has something that will limit damage taken # Prefer if user has something that will limit damage taken
mini_score *= 1.3 if @user.effects[PBEffects::Substitute] > 0 || mini_score *= 1.3 if @user.effects[PBEffects::Substitute] > 0 ||
(@user.form == 0 && @user.ability_id == :DISGUISE) (@user.form == 0 && @user.ability_id == :DISGUISE)
# Don't prefer if user doesn't have much HP left
mini_score *= 0.3 if @user.hp < @user.totalhp / 3
# Don't prefer if user is badly poisoned # Don't prefer if user is badly poisoned
mini_score *= 0.2 if @user.effects[PBEffects::Toxic] > 0 && !offensive_stat mini_score *= 0.2 if @user.effects[PBEffects::Toxic] > 0 && !offensive_stat
# Don't prefer if user is confused # Don't prefer if user is confused
@@ -296,6 +282,8 @@ class Battle::AI
when :SPEED when :SPEED
# Prefer if user is slower than a foe # Prefer if user is slower than a foe
# TODO: Don't prefer if the user is too much slower than any foe that it
# can't catch up.
each_foe_battler(@user.side) do |b, i| each_foe_battler(@user.side) do |b, i|
next if @user.faster_than?(b) next if @user.faster_than?(b)
score += 15 * inc_mult score += 15 * inc_mult
@@ -319,7 +307,7 @@ class Battle::AI
next if m.accuracy == 0 || m.is_a?(Battle::Move::OHKO) next if m.accuracy == 0 || m.is_a?(Battle::Move::OHKO)
min_accuracy = m.accuracy if m.accuracy < min_accuracy min_accuracy = m.accuracy if m.accuracy < min_accuracy
end end
min_accuracy *= stage_mul[old_stage] / stage_div[old_stage] min_accuracy = min_accuracy * stage_mul[old_stage] / stage_div[old_stage]
if min_accuracy < 90 if min_accuracy < 90
score += 5 * (3 - old_stage) * inc_mult score += 5 * (3 - old_stage) * inc_mult
score += 5 * inc_mult if @user.hp == @user.totalhp score += 5 * inc_mult if @user.hp == @user.totalhp
@@ -345,18 +333,14 @@ class Battle::AI
end end
# Check impact on moves of gaining stat stages # Prefer if user has Stored Power
pos_change = [old_stage + increment, increment].min if @user.check_for_move { |m| m.function == "PowerHigherWithUserPositiveStatStages" }
if pos_change > 0 score += 5 * pos_change
# Prefer if user has Stored Power end
if @user.check_for_move { |m| m.function == "PowerHigherWithUserPositiveStatStages" } # Don't prefer if any foe has Punishment
score += 5 * pos_change each_foe_battler(@user.side) do |b, i|
end next if !b.check_for_move { |m| m.function == "PowerHigherWithTargetPositiveStatStages" }
# Don't prefer if any foe has Punishment score -= 5 * pos_change
each_foe_battler(@user.side) do |b, i|
next if !b.check_for_move { |m| m.function == "PowerHigherWithTargetPositiveStatStages" }
score -= 5 * pos_change
end
end end
return score return score
@@ -569,6 +553,247 @@ class Battle::AI
=end =end
end end
#=============================================================================
# Main method for calculating the score for moves that lower the target's
# stat(s).
# TODO: Revisit this method as parts may need rewriting.
#=============================================================================
def get_score_for_target_stat_drop(score)
# Discard status move/don't prefer damaging move if target has Contrary
if !@battle.moldBreaker && @target.has_active_ability?(:CONTRARY)
return (@move.statusMove?) ? MOVE_USELESS_SCORE : score - 20
end
# Don't make score changes if foes have Unaware and user can't make use of
# extra stat stages
ally_is_aware = false
each_foe_battler(@target.side) do |b, i|
ally_is_aware = true if !b.has_active_ability?(:UNAWARE)
end
return score if !ally_is_aware
# Figure out which stat raises can happen
stat_changes = []
@move.move.statDown.each_with_index do |stat, idx|
next if idx.odd?
next if !stat_drop_worthwhile?(stat)
# Calculate amount that stat will be raised by
decrement = @move.move.statDown[idx + 1]
decrement *= 2 if !@battle.moldBreaker && @user.has_active_ability?(:SIMPLE)
decrement = [decrement, 6 + @target.stages[stat]].min # The actual stages lost
# Count this as a valid stat drop
stat_changes.push([stat, decrement]) if decrement > 0
end
# Discard move if it can't lower any stats
if stat_changes.length == 0
# TODO: Have a parameter that decides whether to reduce the score here
# (for moves where this is just part of the effect).
return (@move.statusMove?) ? MOVE_USELESS_SCORE : score
end
# Make score changes based on the general concept of lowering stats at all
score = get_target_stat_drop_score_generic(score, stat_changes)
# Make score changes based on the specific changes to each stat that will be
# lowered
stat_changes.each do |change|
score = get_target_stat_drop_score_one(score, change[0], change[1])
end
return score
end
#=============================================================================
# Returns whether the target lowering the given stat will have any impact.
# TODO: Make sure the move's actual damage category is taken into account,
# i.e. CategoryDependsOnHigherDamagePoisonTarget and
# CategoryDependsOnHigherDamageIgnoreTargetAbility.
# TODO: Revisit this method as parts may need rewriting.
#=============================================================================
def stat_drop_worthwhile?(stat)
return false if !@target.battler.pbCanLowerStatStage?(stat, @user.battler, @move.move)
# Check if target won't benefit from the stat being lowered
case stat
when :ATTACK
return false if !@target.check_for_move { |m| m.physicalMove?(m.type) &&
m.function != "UseUserDefenseInsteadOfUserAttack" &&
m.function != "UseTargetAttackInsteadOfUserAttack" }
when :DEFENSE
each_foe_battler(@target.side) do |b, i|
return true if b.check_for_move { |m| m.physicalMove?(m.type) ||
m.function == "UseTargetDefenseInsteadOfTargetSpDef" }
end
return false
when :SPECIAL_ATTACK
return false if !@target.check_for_move { |m| m.specialMove?(m.type) }
when :SPECIAL_DEFENSE
each_foe_battler(@target.side) do |b, i|
return true if b.check_for_move { |m| m.specialMove?(m.type) &&
m.function != "UseTargetDefenseInsteadOfTargetSpDef" }
end
return false
when :SPEED
moves_that_prefer_high_speed = [
"PowerHigherWithUserFasterThanTarget",
"PowerHigherWithUserPositiveStatStages"
]
if !@target.check_for_move { |m| moves_that_prefer_high_speed.include?(m.function) }
each_foe_battler(@target.side) do |b, i|
return true if !b.faster_than?(@target)
end
return false
end
when :ACCURACY
when :EVASION
end
return true
end
#=============================================================================
# Make score changes based on the general concept of lowering stats at all.
# TODO: Revisit this method as parts may need rewriting.
# TODO: All comments in this method may be inaccurate.
#=============================================================================
def get_target_stat_drop_score_generic(score, stat_changes)
total_decrement = stat_changes.sum { |change| change[1] }
# TODO: Just return if target is predicted to switch out (except via Baton Pass).
# TODO: Don't prefer if target is faster than user and is predicted to deal
# lethal damage.
# TODO: Don't prefer if target is slower than user but is predicted to be able
# to 2HKO user.
# TODO: Don't prefer if target is semi-invulnerable and user is faster.
# Prefer if move is a status move and it's the user's first/second turn
# if @user.turnCount < 2 && @move.statusMove?
# score += total_decrement * 4
# end
# Prefer if user is at high HP, don't prefer if user is at low HP
# if @user.hp >= @user.totalhp * 0.7
# score += 4 * total_decrement
# else
# score += total_decrement * ((100 * @user.hp / @user.totalhp) - 50) / 4 # +5 to -12 per stage
# end
# Don't prefer if user is about to faint due to EOR damage
# score -= 30 if @user.rough_end_of_round_damage > @user.hp
# TODO: Look at abilities that trigger upon stat lowering.
return score
end
#=============================================================================
# Make score changes based on the lowering of a specific stat.
# TODO: Revisit this method as parts may need rewriting.
#=============================================================================
def get_target_stat_drop_score_one(score, stat, decrement)
# Figure out how much the stat will actually change by
stage_mul = [2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8]
stage_div = [8, 7, 6, 5, 4, 3, 2, 2, 2, 2, 2, 2, 2]
if [:ACCURACY, :EVASION].include?(stat)
stage_mul = [3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9]
stage_div = [9, 8, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3]
end
old_stage = @target.stages[stat]
new_stage = old_stage - decrement
dec_mult = (stage_mul[old_stage].to_f * stage_div[new_stage]) / (stage_div[old_stage] * stage_mul[new_stage])
dec_mult -= 1
# Stat-based score changes
case stat
when :ATTACK
# Modify score depending on current stat stage
# More strongly prefer if the target has no special moves
if old_stage <= -3
score -= 20
else
has_special_moves = @target.check_for_move { |m| m.specialMove?(m.type) }
dec = (has_special_moves) ? 5 : 10
score += dec * (3 + old_stage) * dec_mult
score += 5 * dec_mult if @target.hp == @target.totalhp
end
when :DEFENSE
# Modify score depending on current stat stage
if old_stage <= -3
score -= 20
else
score += 5 * (3 + old_stage) * dec_mult
score += 5 * dec_mult if @target.hp == @target.totalhp
end
when :SPECIAL_ATTACK
# Modify score depending on current stat stage
# More strongly prefer if the target has no physical moves
if old_stage <= -3
score -= 20
else
has_physical_moves = @target.check_for_move { |m| m.physicalMove?(m.type) &&
m.function != "UseUserDefenseInsteadOfUserAttack" &&
m.function != "UseTargetAttackInsteadOfUserAttack" }
dec = (has_physical_moves) ? 5 : 10
score += dec * (3 + old_stage) * dec_mult
score += 5 * dec_mult if @target.hp == @target.totalhp
end
when :SPECIAL_DEFENSE
# Modify score depending on current stat stage
if old_stage <= -3
score -= 20
else
score += 5 * (3 + old_stage) * dec_mult
score += 5 * dec_mult if @target.hp == @target.totalhp
end
when :SPEED
# Prefer if target is faster than an ally
# TODO: Don't prefer if the target is too much faster than any ally and
# can't be brought slow enough.
each_foe_battler(@target.side) do |b, i|
next if b.faster_than?(@target)
score += 15 * dec_mult
break
end
# Prefer if any ally has Electro Ball
each_foe_battler(@target.side) do |b, i|
next if !b.check_for_move { |m| m.function == "PowerHigherWithUserFasterThanTarget" }
score += 8 * dec_mult
end
# Don't prefer if target has Speed Boost (will be gaining Speed anyway)
score -= 20 if @target.has_active_ability?(:SPEEDBOOST)
when :ACCURACY
# Modify score depending on current stat stage
if old_stage <= -3
score -= 20
else
score += 5 * (3 + old_stage) * dec_mult
score += 5 * dec_mult if @target.hp == @target.totalhp
end
when :EVASION
# Modify score depending on current stat stage
if old_stage <= -3
score -= 20
else
score += 5 * (3 + old_stage) * dec_mult
score += 5 * dec_mult if @target.hp == @target.totalhp
end
end
# Prefer if target has Stored Power
if @target.check_for_move { |m| m.function == "PowerHigherWithUserPositiveStatStages" }
score += 5 * decrement
end
# Don't prefer if any ally has Punishment
each_foe_battler(@target.side) do |b, i|
next if !b.check_for_move { |m| m.function == "PowerHigherWithTargetPositiveStatStages" }
score -= 5 * decrement
end
return score
end
#============================================================================= #=============================================================================
# #
#============================================================================= #=============================================================================

View File

@@ -739,7 +739,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseTargetAtkSpAtk2",
) )
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetAttack1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetAttack1",
proc { |move, user, target, ai, battle| proc { |move, user, target, ai, battle|
@@ -749,104 +749,28 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetAttack1",
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAttack1", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAttack1",
proc { |score, move, user, target, ai, battle| proc { |score, move, user, target, ai, battle|
if move.statusMove? next ai.get_score_for_target_stat_drop(score)
score += target.stages[:ATTACK] * 20
if ai.trainer.medium_skill?
hasPhysicalAttack = false
target.battler.eachMove do |m|
next if !m.physicalMove?(m.type)
hasPhysicalAttack = true
break
end
if hasPhysicalAttack
score += 20
elsif ai.trainer.high_skill?
score -= 90
end
end
else
score += 20 if target.stages[:ATTACK] > 0
if ai.trainer.medium_skill?
hasPhysicalAttack = false
target.battler.eachMove do |m|
next if !m.physicalMove?(m.type)
hasPhysicalAttack = true
break
end
score += 20 if hasPhysicalAttack
end
end
next score
} }
) )
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack1",
"LowerTargetAttack1BypassSubstitute") "LowerTargetAttack1BypassSubstitute")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAttack1BypassSubstitute", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAttack1",
proc { |score, move, user, target, ai, battle| "LowerTargetAttack1BypassSubstitute")
score += target.stages[:ATTACK] * 20
if ai.trainer.medium_skill?
hasPhysicalAttack = false
target.battler.eachMove do |m|
next if !m.physicalMove?(m.type)
hasPhysicalAttack = true
break
end
if hasPhysicalAttack
score += 20
elsif ai.trainer.high_skill?
score -= 90
end
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack1",
"LowerTargetAttack2") "LowerTargetAttack2")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAttack2", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAttack1",
proc { |score, move, user, target, ai, battle| "LowerTargetAttack2")
if move.statusMove?
score += 40 if user.turnCount == 0
score += target.stages[:ATTACK] * 20
if ai.trainer.medium_skill?
hasPhysicalAttack = false
target.battler.eachMove do |m|
next if !m.physicalMove?(m.type)
hasPhysicalAttack = true
break
end
if hasPhysicalAttack
score += 20
elsif ai.trainer.high_skill?
score -= 90
end
end
else
score += 10 if user.turnCount == 0
score += 20 if target.stages[:ATTACK] > 0
if ai.trainer.medium_skill?
hasPhysicalAttack = false
target.battler.eachMove do |m|
next if !m.physicalMove?(m.type)
hasPhysicalAttack = true
break
end
score += 20 if hasPhysicalAttack
end
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack2", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack2",
"LowerTargetAttack3") "LowerTargetAttack3")
@@ -854,62 +778,36 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAttack2",
"LowerTargetAttack3") "LowerTargetAttack3")
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack1",
"LowerTargetDefense1") "LowerTargetDefense1")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetDefense1", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAttack1",
proc { |score, move, user, target, ai, battle| "LowerTargetDefense1")
if move.statusMove?
score += target.stages[:DEFENSE] * 20
elsif target.stages[:DEFENSE] > 0
score += 20
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetDefense1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetDefense1",
"LowerTargetDefense1PowersUpInGravity") "LowerTargetDefense1PowersUpInGravity")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetDefense1",
"LowerTargetDefense1PowersUpInGravity")
Battle::AI::Handlers::MoveBasePower.add("LowerTargetDefense1PowersUpInGravity", Battle::AI::Handlers::MoveBasePower.add("LowerTargetDefense1PowersUpInGravity",
proc { |power, move, user, target, ai, battle| proc { |power, move, user, target, ai, battle|
next move.move.pbBaseDamage(power, user.battler, target.battler) next move.move.pbBaseDamage(power, user.battler, target.battler)
} }
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetDefense1PowersUpInGravity",
proc { |score, move, user, target, ai, battle|
if move.statusMove?
score += target.stages[:DEFENSE] * 20
elsif target.stages[:DEFENSE] > 0
score += 20
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetDefense1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetDefense1",
"LowerTargetDefense2") "LowerTargetDefense2")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetDefense2", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetDefense1",
proc { |score, move, user, target, ai, battle| "LowerTargetDefense2")
if move.statusMove?
score += 40 if user.turnCount == 0
score += target.stages[:DEFENSE] * 20
else
score += 10 if user.turnCount == 0
score += 20 if target.stages[:DEFENSE] > 0
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetDefense2", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetDefense2",
"LowerTargetDefense3") "LowerTargetDefense3")
@@ -917,58 +815,23 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetDefense2",
"LowerTargetDefense3") "LowerTargetDefense3")
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAttack1",
"LowerTargetSpAtk1") "LowerTargetSpAtk1")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetSpAtk1", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAttack1",
proc { |score, move, user, target, ai, battle| "LowerTargetSpAtk1")
if move.statusMove?
score += user.stages[:SPECIAL_ATTACK] * 20
if ai.trainer.medium_skill?
hasSpecicalAttack = false
target.battler.eachMove do |m|
next if !m.specialMove?(m.type)
hasSpecicalAttack = true
break
end
if hasSpecicalAttack
score += 20
elsif ai.trainer.high_skill?
score -= 90
end
end
else
score += 20 if user.stages[:SPECIAL_ATTACK] > 0
if ai.trainer.medium_skill?
hasSpecicalAttack = false
target.battler.eachMove do |m|
next if !m.specialMove?(m.type)
hasSpecicalAttack = true
break
end
score += 20 if hasSpecicalAttack
end
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. # TODO: Review score modifiers.
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpAtk1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpAtk1",
"LowerTargetSpAtk2") "LowerTargetSpAtk2")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetSpAtk2", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpAtk1",
proc { |score, move, user, target, ai, battle| "LowerTargetSpAtk2")
score += 40 if user.turnCount == 0
score += target.stages[:SPECIAL_ATTACK] * 20
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetSpAtk2IfCanAttract", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetSpAtk2IfCanAttract",
proc { |move, user, target, ai, battle| proc { |move, user, target, ai, battle|
@@ -978,90 +841,35 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetSpAtk2IfCanA
next true if !battle.moldBreaker && target.has_active_ability?(:OBLIVIOUS) next true if !battle.moldBreaker && target.has_active_ability?(:OBLIVIOUS)
} }
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetSpAtk2IfCanAttract", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpAtk2",
proc { |score, move, user, target, ai, battle| "LowerTargetSpAtk2IfCanAttract")
if move.statusMove?
score += 40 if user.turnCount == 0
score += target.stages[:SPECIAL_ATTACK] * 20
if ai.trainer.medium_skill?
hasSpecicalAttack = false
target.battler.eachMove do |m|
next if !m.specialMove?(m.type)
hasSpecicalAttack = true
break
end
if hasSpecicalAttack
score += 20
elsif ai.trainer.high_skill?
score -= 90
end
end
else
score += 10 if user.turnCount == 0
score += 20 if target.stages[:SPECIAL_ATTACK] > 0
if ai.trainer.medium_skill?
hasSpecicalAttack = false
target.battler.eachMove do |m|
next if !m.specialMove?(m.type)
hasSpecicalAttack = true
break
end
score += 30 if hasSpecicalAttack
end
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpAtk1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpAtk2",
"LowerTargetSpAtk3") "LowerTargetSpAtk3")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetSpAtk3", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpAtk2",
proc { |score, move, user, target, ai, battle| "LowerTargetSpAtk3")
score += 40 if user.turnCount == 0
score += target.stages[:SPECIAL_ATTACK] * 20
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetDefense1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetDefense1",
"LowerTargetSpDef1") "LowerTargetSpDef1")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetSpDef1", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetDefense1",
proc { |score, move, user, target, ai, battle| "LowerTargetSpDef1")
if move.statusMove?
score += target.stages[:SPECIAL_DEFENSE] * 20
elsif target.stages[:SPECIAL_DEFENSE] > 0
score += 20
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpDef1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpDef1",
"LowerTargetSpDef2") "LowerTargetSpDef2")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetSpDef2", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpDef1",
proc { |score, move, user, target, ai, battle| "LowerTargetSpDef2")
if move.statusMove?
score += 40 if user.turnCount == 0
score += target.stages[:SPECIAL_DEFENSE] * 20
else
score += 10 if user.turnCount == 0
score += 20 if target.stages[:SPECIAL_DEFENSE] > 0
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpDef2", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpDef2",
"LowerTargetSpDef3") "LowerTargetSpDef3")
@@ -1069,87 +877,59 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpDef2",
"LowerTargetSpDef3") "LowerTargetSpDef3")
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpDef1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpDef1",
"LowerTargetSpeed1") "LowerTargetSpeed1")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetSpeed1", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpDef1",
proc { |score, move, user, target, ai, battle| "LowerTargetSpeed1")
if move.statusMove?
score += target.stages[:SPEED] * 10
if ai.trainer.high_skill?
aspeed = user.rough_stat(:SPEED)
ospeed = target.rough_stat(:SPEED)
score += 30 if aspeed < ospeed && aspeed * 2 > ospeed
end
elsif user.stages[:SPEED] > 0
score += 20
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpeed1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpeed1",
"LowerTargetSpeed1WeakerInGrassyTerrain") "LowerTargetSpeed1WeakerInGrassyTerrain")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpeed1",
"LowerTargetSpeed1WeakerInGrassyTerrain")
Battle::AI::Handlers::MoveBasePower.add("LowerTargetSpeed1WeakerInGrassyTerrain", Battle::AI::Handlers::MoveBasePower.add("LowerTargetSpeed1WeakerInGrassyTerrain",
proc { |power, move, user, target, ai, battle| proc { |power, move, user, target, ai, battle|
next move.move.pbBaseDamage(power, user.battler, target.battler) next move.move.pbBaseDamage(power, user.battler, target.battler)
} }
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpeed1",
"LowerTargetSpeed1WeakerInGrassyTerrain")
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. # TODO: Review score modifiers.
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetSpeed1MakeTargetWeakerToFire", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetSpeed1MakeTargetWeakerToFire",
proc { |move, user, target, ai, battle| proc { |move, user, target, ai, battle|
next false if !target.effects[PBEffects::TarShot] if !target.effects[PBEffects::TarShot]
next true if move.statusMove? && next true if move.statusMove? &&
!target.battler.pbCanLowerStatStage?(move.move.statDown[0], user.battler, move.move) !target.battler.pbCanLowerStatStage?(move.move.statDown[0], user.battler, move.move)
end
} }
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetSpeed1MakeTargetWeakerToFire", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetSpeed1MakeTargetWeakerToFire",
proc { |score, move, user, target, ai, battle| proc { |score, move, user, target, ai, battle|
score += target.stages[:SPEED] * 10 # Score for stat drop
if ai.trainer.high_skill? score = ai.get_score_for_target_stat_drop(score)
aspeed = user.rough_stat(:SPEED) # Score for adding weakness to Fire
ospeed = target.rough_stat(:SPEED) if !target.effects[PBEffects::TarShot]
score += 50 if aspeed < ospeed && aspeed * 2 > ospeed score += 20 if user.battler.moves.any? { |m| m.damagingMove? && m.pbCalcType(user.battler) == :FIRE }
end end
score += 20 if user.battler.moves.any? { |m| m.damagingMove? && m.pbCalcType(user.battler) == :FIRE }
next score next score
} }
) )
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpeed1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpeed1",
"LowerTargetSpeed2") "LowerTargetSpeed2")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetSpeed2", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpeed1",
proc { |score, move, user, target, ai, battle| "LowerTargetSpeed2")
if move.statusMove?
score += 20 if user.turnCount == 0
score += target.stages[:SPEED] * 20
if ai.trainer.high_skill?
aspeed = user.rough_stat(:SPEED)
ospeed = target.rough_stat(:SPEED)
score += 30 if aspeed < ospeed && aspeed * 2 > ospeed
end
else
score += 10 if user.turnCount == 0
score += 30 if target.stages[:SPEED] > 0
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpeed2", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpeed2",
"LowerTargetSpeed3") "LowerTargetSpeed3")
@@ -1157,23 +937,15 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpeed2",
"LowerTargetSpeed3") "LowerTargetSpeed3")
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpeed1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetSpeed1",
"LowerTargetAccuracy1") "LowerTargetAccuracy1")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAccuracy1", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetSpeed1",
proc { |score, move, user, target, ai, battle| "LowerTargetAccuracy1")
if move.statusMove?
score += target.stages[:ACCURACY] * 10
elsif target.stages[:ACCURACY] > 0
score += 20
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAccuracy1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAccuracy1",
"LowerTargetAccuracy2") "LowerTargetAccuracy2")
@@ -1181,28 +953,20 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAccuracy1",
"LowerTargetAccuracy2") "LowerTargetAccuracy2")
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAccuracy1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAccuracy2",
"LowerTargetAccuracy3") "LowerTargetAccuracy3")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAccuracy1", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAccuracy2",
"LowerTargetAccuracy3") "LowerTargetAccuracy3")
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAccuracy1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAccuracy1",
"LowerTargetEvasion1") "LowerTargetEvasion1")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetEvasion1", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAccuracy1",
proc { |score, move, user, target, ai, battle| "LowerTargetEvasion1")
if move.statusMove?
score += target.stages[:EVASION] * 10
elsif target.stages[:EVASION] > 0
score += 20
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. # TODO: Review score modifiers.
@@ -1232,11 +996,9 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetEvasion1Remo
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetEvasion1RemoveSideEffects", Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetEvasion1RemoveSideEffects",
proc { |score, move, user, target, ai, battle| proc { |score, move, user, target, ai, battle|
if move.statusMove? # Score for stat drop
score += target.stages[:EVASION] * 10 score = ai.get_score_for_target_stat_drop(score)
elsif target.stages[:EVASION] > 0 # Score for removing side effects/terrain
score += 20
end
score += 30 if target.pbOwnSide.effects[PBEffects::AuroraVeil] > 0 || score += 30 if target.pbOwnSide.effects[PBEffects::AuroraVeil] > 0 ||
target.pbOwnSide.effects[PBEffects::Reflect] > 0 || target.pbOwnSide.effects[PBEffects::Reflect] > 0 ||
target.pbOwnSide.effects[PBEffects::LightScreen] > 0 || target.pbOwnSide.effects[PBEffects::LightScreen] > 0 ||
@@ -1250,23 +1012,15 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetEvasion1Remov
) )
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetEvasion1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetEvasion1",
"LowerTargetEvasion2") "LowerTargetEvasion2")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetEvasion2", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetEvasion1",
proc { |score, move, user, target, ai, battle| "LowerTargetEvasion2")
if move.statusMove?
score += target.stages[:EVASION] * 10
elsif target.stages[:EVASION] > 0
score += 20
end
next score
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetEvasion2", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetEvasion2",
"LowerTargetEvasion3") "LowerTargetEvasion3")
@@ -1274,10 +1028,11 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetEvasion2",
"LowerTargetEvasion3") "LowerTargetEvasion3")
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetAtkDef1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetAtkDef1",
proc { |move, user, target, ai, battle| proc { |move, user, target, ai, battle|
next false if !move.statusMove?
will_fail = true will_fail = true
(move.move.statDown.length / 2).times do |i| (move.move.statDown.length / 2).times do |i|
next if !target.battler.pbCanLowerStatStage?(move.move.statDown[i * 2], user.battler, move.move) next if !target.battler.pbCanLowerStatStage?(move.move.statDown[i * 2], user.battler, move.move)
@@ -1287,26 +1042,16 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetAtkDef1",
next will_fail next will_fail
} }
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAtkDef1", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAttack1",
proc { |score, move, user, target, ai, battle| "LowerTargetAtkDef1")
avg = target.stages[:ATTACK] * 10
avg += target.stages[:DEFENSE] * 10
next score + avg / 2
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAtkDef1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("LowerTargetAtkDef1",
"LowerTargetAtkSpAtk1") "LowerTargetAtkSpAtk1")
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAtkSpAtk1", Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAtkDef1",
proc { |score, move, user, target, ai, battle| "LowerTargetAtkSpAtk1")
avg = target.stages[:ATTACK] * 10
avg += target.stages[:SPECIAL_ATTACK] * 10
next score + avg / 2
}
)
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. # TODO: Review score modifiers.
@@ -1314,23 +1059,12 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAtkSpAtk1",
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerPoisonedTargetAtkSpAtkSpd1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerPoisonedTargetAtkSpAtkSpd1",
proc { |move, user, target, ai, battle| proc { |move, user, target, ai, battle|
next true if !target.battler.poisoned? next true if !target.battler.poisoned?
next true if !target.battler.pbCanLowerStatStage?(:ATTACK, user.battler, move.move) && next Battle::AI::Handlers.move_will_fail_against_target?("LowerTargetAtkSpAtk1",
!target.battler.pbCanLowerStatStage?(:SPECIAL_ATTACK, user.battler, move.move) && move, user, target, ai, battle)
!target.battler.pbCanLowerStatStage?(:SPEED, user.battler, move.move)
}
)
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerPoisonedTargetAtkSpAtkSpd1",
proc { |score, move, user, target, ai, battle|
if target.opposes?(user)
score += target.stages[:ATTACK] * 10
score += target.stages[:SPECIAL_ATTACK] * 10
score += target.stages[:SPEED] * 10
else
score -= 20
end
next score
} }
) )
Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAtkSpAtk1",
"LowerPoisonedTargetAtkSpAtkSpd1")
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. # TODO: Review score modifiers.

View File

@@ -150,7 +150,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("PoisonTarget",
) )
#=============================================================================== #===============================================================================
# TODO: Review score modifiers. #
#=============================================================================== #===============================================================================
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("PoisonTargetLowerTargetSpeed1", Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("PoisonTargetLowerTargetSpeed1",
proc { |move, user, target, ai, battle| proc { |move, user, target, ai, battle|