mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
More AI function code rewrites themed around stat changes
This commit is contained in:
@@ -118,10 +118,11 @@ class Battle::Move::HealUserByTargetAttackLowerTargetAttack1 < Battle::Move
|
|||||||
# has Contrary and is at +6" check too for symmetry. This move still
|
# has Contrary and is at +6" check too for symmetry. This move still
|
||||||
# works even if the stat stage cannot be changed due to an ability or
|
# works even if the stat stage cannot be changed due to an ability or
|
||||||
# other effect.
|
# other effect.
|
||||||
if !@battle.moldBreaker && target.hasActiveAbility?(:CONTRARY) &&
|
if !@battle.moldBreaker && target.hasActiveAbility?(:CONTRARY)
|
||||||
target.statStageAtMax?(:ATTACK)
|
if target.statStageAtMax?(:ATTACK)
|
||||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||||
return true
|
return true
|
||||||
|
end
|
||||||
elsif target.statStageAtMin?(:ATTACK)
|
elsif target.statStageAtMin?(:ATTACK)
|
||||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -176,16 +176,18 @@ class Battle::AI
|
|||||||
score += t_score
|
score += t_score
|
||||||
affected_targets += 1
|
affected_targets += 1
|
||||||
end
|
end
|
||||||
# Check if any targets were affected
|
# Set the default score if no targets were affected
|
||||||
|
if affected_targets == 0
|
||||||
|
score = (@trainer.has_skill_flag?("PredictMoveFailure")) ? MOVE_USELESS_SCORE : MOVE_BASE_SCORE
|
||||||
|
end
|
||||||
|
# Score based on how many targets were affected
|
||||||
if affected_targets == 0 && @trainer.has_skill_flag?("PredictMoveFailure")
|
if affected_targets == 0 && @trainer.has_skill_flag?("PredictMoveFailure")
|
||||||
return MOVE_FAIL_SCORE if !@move.move.worksWithNoTargets?
|
return MOVE_FAIL_SCORE if !@move.move.worksWithNoTargets?
|
||||||
score = MOVE_USELESS_SCORE
|
|
||||||
else
|
else
|
||||||
affected_targets = 1 if affected_targets == 0 # To avoid dividing by 0
|
|
||||||
# TODO: Can this accounting for multiple targets be improved somehow?
|
# TODO: Can this accounting for multiple targets be improved somehow?
|
||||||
score /= affected_targets # Average the score against multiple targets
|
score /= affected_targets if affected_targets > 1 # Average the score against multiple targets
|
||||||
# Bonus for affecting multiple targets
|
# Bonus for affecting multiple targets
|
||||||
if @trainer.has_skill_flag?("PreferMultiTargetMoves")
|
if @trainer.has_skill_flag?("PreferMultiTargetMoves") && affected_targets > 1
|
||||||
score += (affected_targets - 1) * 10
|
score += (affected_targets - 1) * 10
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -623,7 +623,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseTargetAttack2Confus
|
|||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if !target.battler.pbCanConfuse?(user.battler, false, move.move)
|
next Battle::AI::MOVE_USELESS_SCORE if !target.battler.pbCanConfuse?(user.battler, false, move.move)
|
||||||
# Score for stat raise
|
# Score for stat raise
|
||||||
stat_score = ai.get_score_for_target_stat_raise(score, target, [:ATTACK, 2], false)
|
score = ai.get_score_for_target_stat_raise(score, target, [:ATTACK, 2], false)
|
||||||
# Score for confusing the target
|
# Score for confusing the target
|
||||||
next Battle::AI::Handlers.apply_move_effect_against_target_score(
|
next Battle::AI::Handlers.apply_move_effect_against_target_score(
|
||||||
"ConfuseTarget", score, move, user, target, ai, battle)
|
"ConfuseTarget", score, move, user, target, ai, battle)
|
||||||
@@ -643,7 +643,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseTargetSpAtk1Confuse
|
|||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if !target.battler.pbCanConfuse?(user.battler, false, move.move)
|
next Battle::AI::MOVE_USELESS_SCORE if !target.battler.pbCanConfuse?(user.battler, false, move.move)
|
||||||
# Score for stat raise
|
# Score for stat raise
|
||||||
stat_score = ai.get_score_for_target_stat_raise(score, target, [:SPECIAL_ATTACK, 1], false)
|
score = ai.get_score_for_target_stat_raise(score, target, [:SPECIAL_ATTACK, 1], false)
|
||||||
# Score for confusing the target
|
# Score for confusing the target
|
||||||
next Battle::AI::Handlers.apply_move_effect_against_target_score(
|
next Battle::AI::Handlers.apply_move_effect_against_target_score(
|
||||||
"ConfuseTarget", score, move, user, target, ai, battle)
|
"ConfuseTarget", score, move, user, target, ai, battle)
|
||||||
@@ -1020,7 +1020,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAtkDef1",
|
|||||||
"LowerTargetAtkSpAtk1")
|
"LowerTargetAtkSpAtk1")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerPoisonedTargetAtkSpAtkSpd1",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerPoisonedTargetAtkSpAtkSpd1",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -1033,164 +1033,124 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("LowerTargetAtkSpAtk1",
|
|||||||
"LowerPoisonedTargetAtkSpAtkSpd1")
|
"LowerPoisonedTargetAtkSpAtkSpd1")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
# TODO: This code should be for a single battler (each is checked in turn).
|
|
||||||
# target should probably be treated as an enemy when deciding the score,
|
|
||||||
# since the score will be inverted elsewhere due to the target being an
|
|
||||||
# ally.
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaiseAlliesAtkDef1",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaiseAlliesAtkDef1",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
will_fail = true
|
next !target.battler.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) &&
|
||||||
battle.allSameSideBattlers(user.battler).each do |b|
|
!target.battler.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move)
|
||||||
next if b.index == user.index
|
|
||||||
next if !b.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) &&
|
|
||||||
!b.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move)
|
|
||||||
will_fail = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
next will_fail
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseAlliesAtkDef1",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseAlliesAtkDef1",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
user.battler.allAllies.each do |b|
|
next ai.get_score_for_target_stat_raise(score, target, [:ATTACK, 1, :DEFENSE, 1])
|
||||||
score = ai.get_score_for_target_stat_raise(score, b, [:ATTACK, 1, :DEFENSE, 1])
|
|
||||||
end
|
|
||||||
next score
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
# TODO: This code should be for a single battler (each is checked in turn).
|
|
||||||
# target should probably be treated as an enemy when deciding the score,
|
|
||||||
# since the score will be inverted elsewhere due to the target being an
|
|
||||||
# ally.
|
|
||||||
# TODO: Since this also affects the user, this will need a MoveEffectScore and a
|
|
||||||
# MoveFailureCheck.
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaisePlusMinusUserAndAlliesAtkSpAtk1",
|
Battle::AI::Handlers::MoveFailureCheck.add("RaisePlusMinusUserAndAlliesAtkSpAtk1",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, ai, battle|
|
||||||
will_fail = true
|
will_fail = true
|
||||||
battle.allSameSideBattlers(user.battler).each do |b|
|
ai.each_same_side_battler(user.side) do |b, i|
|
||||||
next if !b.hasActiveAbility?([:MINUS, :PLUS])
|
next if !b.has_active_ability?([:MINUS, :PLUS])
|
||||||
next if !b.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) &&
|
next if !b.battler.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) &&
|
||||||
!b.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user.battler, move.move)
|
!b.battler.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user.battler, move.move)
|
||||||
will_fail = false
|
will_fail = false
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
next will_fail
|
next will_fail
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaisePlusMinusUserAndAlliesAtkSpAtk1",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaisePlusMinusUserAndAlliesAtkSpAtk1",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
# score = ai.get_score_for_target_stat_raise(score, user, [:ATTACK, 1, :SPECIAL_ATTACK, 1], false)
|
next true if !target.hasActiveAbility?([:MINUS, :PLUS])
|
||||||
user.battler.allAllies.each do |b|
|
next !target.battler.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) &&
|
||||||
|
!target.battler.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user.battler, move.move)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Battle::AI::Handlers::MoveEffectScore.add("RaisePlusMinusUserAndAlliesAtkSpAtk1",
|
||||||
|
proc { |score, move, user, ai, battle|
|
||||||
|
next score if move.pbTarget(user.battler) != :UserSide
|
||||||
|
ai.each_same_side_battler(user.side) do |b, i|
|
||||||
score = ai.get_score_for_target_stat_raise(score, b, [:ATTACK, 1, :SPECIAL_ATTACK, 1], false)
|
score = ai.get_score_for_target_stat_raise(score, b, [:ATTACK, 1, :SPECIAL_ATTACK, 1], false)
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaisePlusMinusUserAndAlliesAtkSpAtk1",
|
||||||
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
next ai.get_score_for_target_stat_raise(score, target, [:ATTACK, 1, :SPECIAL_ATTACK, 1])
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
# TODO: This code should be for a single battler (each is checked in turn).
|
|
||||||
# target should probably be treated as an enemy when deciding the score,
|
|
||||||
# since the score will be inverted elsewhere due to the target being an
|
|
||||||
# ally.
|
|
||||||
# TODO: Since this also affects the user, this will need a MoveEffectScore and a
|
|
||||||
# MoveFailureCheck.
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaisePlusMinusUserAndAlliesAtkSpAtk1",
|
Battle::AI::Handlers::MoveFailureCheck.add("RaisePlusMinusUserAndAlliesDefSpDef1",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, ai, battle|
|
||||||
will_fail = true
|
will_fail = true
|
||||||
battle.allSameSideBattlers(user.battler).each do |b|
|
ai.each_same_side_battler(user.side) do |b, i|
|
||||||
next if !b.hasActiveAbility?([:MINUS, :PLUS])
|
next if !b.has_active_ability?([:MINUS, :PLUS])
|
||||||
next if !b.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move) &&
|
next if !b.battler.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move) &&
|
||||||
!b.pbCanRaiseStatStage?(:SPECIAL_DEFENSE, user.battler, move.move)
|
!b.battler.pbCanRaiseStatStage?(:SPECIAL_DEFENSE, user.battler, move.move)
|
||||||
will_fail = false
|
will_fail = false
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
next will_fail
|
next will_fail
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaisePlusMinusUserAndAlliesDefSpDef1",
|
||||||
|
proc { |move, user, target, ai, battle|
|
||||||
|
next true if !target.hasActiveAbility?([:MINUS, :PLUS])
|
||||||
|
next !target.battler.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move) &&
|
||||||
|
!target.battler.pbCanRaiseStatStage?(:SPECIAL_DEFENSE, user.battler, move.move)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Battle::AI::Handlers::MoveEffectScore.add("RaisePlusMinusUserAndAlliesDefSpDef1",
|
||||||
|
proc { |score, move, user, ai, battle|
|
||||||
|
next score if move.pbTarget(user.battler) != :UserSide
|
||||||
|
ai.each_same_side_battler(user.side) do |b, i|
|
||||||
|
score = ai.get_score_for_target_stat_raise(score, b, [:DEFENSE, 1, :SPECIAL_DEFENSE, 1], false)
|
||||||
|
end
|
||||||
|
next score
|
||||||
|
}
|
||||||
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaisePlusMinusUserAndAlliesDefSpDef1",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaisePlusMinusUserAndAlliesDefSpDef1",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
user.battler.allAllies.each do |b|
|
next ai.get_score_for_target_stat_raise(score, target, [:DEFENSE, 1, :SPECIAL_DEFENSE, 1])
|
||||||
next if b.statStageAtMax?(:DEFENSE) && b.statStageAtMax?(:SPECIAL_DEFENSE)
|
|
||||||
score -= b.stages[:DEFENSE] * 10
|
|
||||||
score -= b.stages[:SPECIAL_DEFENSE] * 10
|
|
||||||
end
|
|
||||||
score -= user.stages[:DEFENSE] * 10
|
|
||||||
score -= user.stages[:SPECIAL_DEFENSE] * 10
|
|
||||||
next score
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
# TODO: This code should be for a single battler (each is checked in turn).
|
|
||||||
# target should probably be treated as an enemy when deciding the score,
|
|
||||||
# since the score will be inverted elsewhere due to the target being an
|
|
||||||
# ally.
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaiseGroundedGrassBattlersAtkSpAtk1",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaiseGroundedGrassBattlersAtkSpAtk1",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
will_fail = true
|
next true if !b.pbHasType?(:GRASS) || b.airborne? || b.semiInvulnerable?
|
||||||
battle.allBattlers.each do |b|
|
next !target.battler.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) &&
|
||||||
next if !b.pbHasType?(:GRASS) || b.airborne? || b.semiInvulnerable?
|
!target.battler.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user.battler, move.move)
|
||||||
next if !b.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) &&
|
|
||||||
!b.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user.battler, move.move)
|
|
||||||
will_fail = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
next will_fail
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseGroundedGrassBattlersAtkSpAtk1",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseGroundedGrassBattlersAtkSpAtk1",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
battle.allBattlers.each do |b|
|
next ai.get_score_for_target_stat_raise(score, target, [:ATTACK, 1, :SPECIAL_ATTACK, 1])
|
||||||
if user.battler.opposes?(b)
|
|
||||||
score -= 20
|
|
||||||
else
|
|
||||||
score -= b.stages[:ATTACK] * 10
|
|
||||||
score -= b.stages[:SPECIAL_ATTACK] * 10
|
|
||||||
end
|
|
||||||
end
|
|
||||||
next score
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
# TODO: This code should be for a single battler (each is checked in turn).
|
|
||||||
# target should probably be treated as an enemy when deciding the score,
|
|
||||||
# since the score will be inverted elsewhere due to the target being an
|
|
||||||
# ally.
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaiseGrassBattlersDef1",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("RaiseGrassBattlersDef1",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
will_fail = true
|
next true if !b.pbHasType?(:GRASS) || b.semiInvulnerable?
|
||||||
battle.allBattlers.each do |b|
|
next !target.battler.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move)
|
||||||
next if !b.pbHasType?(:GRASS) || b.semiInvulnerable?
|
|
||||||
next if !b.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move)
|
|
||||||
will_fail = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
next will_fail
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseGrassBattlersDef1",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RaiseGrassBattlersDef1",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
battle.allBattlers.each do |b|
|
next ai.get_score_for_target_stat_raise(score, target, [:DEFENSE, 1])
|
||||||
if user.battler.opposes?(b)
|
|
||||||
score -= 20
|
|
||||||
else
|
|
||||||
score -= user.stages[:DEFENSE] * 10
|
|
||||||
end
|
|
||||||
end
|
|
||||||
next score
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -501,7 +501,7 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartWeakenFireMoves",
|
|||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("StartWeakenElectricMoves",
|
Battle::AI::Handlers::MoveEffectScore.add("StartWeakenFireMoves",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
# Don't prefer the lower the user's HP is
|
# Don't prefer the lower the user's HP is
|
||||||
if user.hp < user.totalhp / 2
|
if user.hp < user.totalhp / 2
|
||||||
@@ -782,7 +782,8 @@ Battle::AI::Handlers::MoveFailureCheck.add("HoopaRemoveProtectionsBypassSubstitu
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HoopaRemoveProtectionsBypassSubstituteLowerUserDef1",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HoopaRemoveProtectionsBypassSubstituteLowerUserDef1",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next score + 20 if target.stages[:DEFENSE] > 0
|
score = ai.get_score_for_target_stat_drop(score, user, move.move.statDown, false)
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("HitTwoToFiveTimes",
|
|||||||
"HitTwoToFiveTimesOrThreeForAshGreninja")
|
"HitTwoToFiveTimesOrThreeForAshGreninja")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveBasePower.copy("HitTwoToFiveTimes",
|
Battle::AI::Handlers::MoveBasePower.copy("HitTwoToFiveTimes",
|
||||||
"HitTwoToFiveTimesRaiseUserSpd1LowerUserDef1")
|
"HitTwoToFiveTimesRaiseUserSpd1LowerUserDef1")
|
||||||
@@ -137,13 +137,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HitTwoToFiveTimesRaiseUs
|
|||||||
# Score for being a multi-hit attack
|
# Score for being a multi-hit attack
|
||||||
score = Battle::AI::Handlers.apply_move_effect_against_target_score("HitTwoToFiveTimes",
|
score = Battle::AI::Handlers.apply_move_effect_against_target_score("HitTwoToFiveTimes",
|
||||||
score, move, user, target, ai, battle)
|
score, move, user, target, ai, battle)
|
||||||
# User's stat changes
|
# Score for user's stat changes
|
||||||
aspeed = user.rough_stat(:SPEED)
|
score = ai.get_score_for_target_stat_raise(score, user, [:SPEED, 1], false)
|
||||||
ospeed = target.rough_stat(:SPEED)
|
score = ai.get_score_for_target_stat_drop(score, user, [:DEFENSE, 1], false)
|
||||||
if aspeed < ospeed && aspeed * 1.5 > ospeed
|
|
||||||
score += 15 # Will become faster than the target
|
|
||||||
end
|
|
||||||
score += user.stages[:DEFENSE] * 10
|
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -158,10 +158,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealUserByTargetAttackLo
|
|||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
# Check whether lowering the target's Attack will have any impact
|
# Check whether lowering the target's Attack will have any impact
|
||||||
if ai.trainer.medium_skill?
|
if ai.trainer.medium_skill?
|
||||||
if target.battler.pbCanLowerStatStage?(:ATTACK, user.battler, move.move) &&
|
score = ai.get_score_for_target_stat_drop(score, target, [:ATTACK, 1])
|
||||||
target.check_for_move { |m| m.physicalMove?(m.type) }
|
|
||||||
score += target.stages[:ATTACK] * 10
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
# Consider how much HP will be restored
|
# Consider how much HP will be restored
|
||||||
heal_amt = target.rough_stat(:ATTACK)
|
heal_amt = target.rough_stat(:ATTACK)
|
||||||
@@ -521,15 +518,11 @@ Battle::AI::Handlers::MoveEffectScore.copy("UserFaintsExplosive",
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserFaintsLowerTargetAtkSpAtk2",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserFaintsLowerTargetAtkSpAtk2",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if !target.battler.pbCanLowerStatStage?(:ATTACK, user.battler) &&
|
|
||||||
!target.battler.pbCanLowerStatStage?(:SPECIAL_ATTACK, user.battler)
|
|
||||||
score -= 25 # User will faint, don't prefer this move
|
score -= 25 # User will faint, don't prefer this move
|
||||||
# Check the impact of lowering the target's stats
|
# Check the impact of lowering the target's stats
|
||||||
if target.stages[:ATTACK] < 0 && target.stages[:SPECIAL_ATTACK] < 0
|
score = ai.get_score_for_target_stat_drop(score, target, move.move.statDown)
|
||||||
score -= 20
|
next score if score == Battle::AI::MOVE_USELESS_SCORE
|
||||||
elsif target.stages[:ATTACK] > 0 || target.stages[:SPECIAL_ATTACK] > 0
|
# Score for the user fainting
|
||||||
score += 10
|
|
||||||
end
|
|
||||||
if ai.trainer.medium_skill?
|
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.5 # User at 50% HP or more
|
||||||
score += 10 if user.hp <= user.totalhp * 0.25 # User at 25% HP or less
|
score += 10 if user.hp <= user.totalhp * 0.25 # User at 25% HP or less
|
||||||
|
|||||||
@@ -85,41 +85,38 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealAllyOrDamageFoe",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
Battle::AI::Handlers::MoveFailureCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
||||||
proc { |move, user, ai, battle|
|
proc { |move, user, ai, battle|
|
||||||
if !user.has_type?(:GHOST)
|
next false if user.has_type?(:GHOST)
|
||||||
will_fail = true
|
will_fail = true
|
||||||
(move.move.statUp.length / 2).times do |i|
|
(move.move.statUp.length / 2).times do |i|
|
||||||
next if !user.battler.pbCanRaiseStatStage?(move.move.statUp[i * 2], user.battler, move.move)
|
next if !user.battler.pbCanRaiseStatStage?(move.move.statUp[i * 2], user.battler, move.move)
|
||||||
will_fail = false
|
will_fail = false
|
||||||
break
|
break
|
||||||
end
|
|
||||||
(move.move.statDown.length / 2).times do |i|
|
|
||||||
next if !user.battler.pbCanLowerStatStage?(move.move.statDown[i * 2], user.battler, move.move)
|
|
||||||
will_fail = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
next will_fail
|
|
||||||
end
|
end
|
||||||
|
(move.move.statDown.length / 2).times do |i|
|
||||||
|
next if !user.battler.pbCanLowerStatStage?(move.move.statDown[i * 2], user.battler, move.move)
|
||||||
|
will_fail = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
next will_fail
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
if user.has_type?(:GHOST)
|
next false if !user.has_type?(:GHOST)
|
||||||
next true if target.effects[PBEffects::Curse] || !target.battler.takesIndirectDamage?
|
next true if target.effects[PBEffects::Curse] || !target.battler.takesIndirectDamage?
|
||||||
end
|
next false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
Battle::AI::Handlers::MoveEffectScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
next score if user.has_type?(:GHOST)
|
next score if user.has_type?(:GHOST)
|
||||||
avg = user.stages[:SPEED] * 10
|
score = ai.get_score_for_target_stat_raise(score, user, move.move.statUp)
|
||||||
avg -= user.stages[:ATTACK] * 10
|
next score if score == Battle::AI::MOVE_USELESS_SCORE
|
||||||
avg -= user.stages[:DEFENSE] * 10
|
next ai.get_score_for_target_stat_drop(score, user, move.move.statDown, false)
|
||||||
score += avg / 3
|
|
||||||
next score
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
||||||
@@ -138,7 +135,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CurseTargetOrLowerUserSp
|
|||||||
if ai.trainer.high_skill?
|
if ai.trainer.high_skill?
|
||||||
# Prefer if user can stall while damage is dealt
|
# Prefer if user can stall while damage is dealt
|
||||||
if user.check_for_move { |m| m.is_a?(Battle::Move::ProtectMove) }
|
if user.check_for_move { |m| m.is_a?(Battle::Move::ProtectMove) }
|
||||||
score += 15
|
score += 8
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
@@ -293,14 +290,10 @@ Battle::AI::Handlers::MoveFailureCheck.add("UserAddStockpileRaiseDefSpDef1",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("UserAddStockpileRaiseDefSpDef1",
|
Battle::AI::Handlers::MoveEffectScore.add("UserAddStockpileRaiseDefSpDef1",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
avg = 0
|
score = ai.get_score_for_target_stat_raise(score, user, [:DEFENSE, 1, :SPECIAL_DEFENSE, 1], false)
|
||||||
avg -= user.stages[:DEFENSE] * 10
|
# More preferable if user also has Spit Up/Swallow
|
||||||
avg -= user.stages[:SPECIAL_DEFENSE] * 10
|
score += 20 if user.battler.pbHasMoveFunction?("PowerDependsOnUserStockpile",
|
||||||
score += avg / 2
|
"HealUserDependingOnUserStockpile")
|
||||||
if user.battler.pbHasMoveFunction?("PowerDependsOnUserStockpile",
|
|
||||||
"HealUserDependingOnUserStockpile") # Spit Up, Swallow
|
|
||||||
score += 20 # More preferable if user also has Spit Up/Swallow
|
|
||||||
end
|
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -73,9 +73,7 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetAtkSpAtk1Swi
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAtkSpAtk1SwitchOutUser",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAtkSpAtk1SwitchOutUser",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
avg = target.stages[:ATTACK] * 10
|
score = ai.get_score_for_target_stat_drop(score, target, move.move.statDown, false)
|
||||||
avg += target.stages[:SPECIAL_ATTACK] * 10
|
|
||||||
score += avg / 2
|
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -429,6 +429,9 @@ class Battle::AI::AIMove
|
|||||||
target_battler = target.battler
|
target_battler = target.battler
|
||||||
# OHKO special calculation
|
# OHKO special calculation
|
||||||
if @ai.trainer.medium_skill?
|
if @ai.trainer.medium_skill?
|
||||||
|
# TODO: This is insufficient for OHKO moves, as they should also ignore
|
||||||
|
# effects like Telekinesis and Minimize but def rough_accuracy
|
||||||
|
# treats them as applying to OHKO moves.
|
||||||
case function
|
case function
|
||||||
when "OHKO", "OHKOHitsUndergroundTarget"
|
when "OHKO", "OHKOHitsUndergroundTarget"
|
||||||
modifiers[:base_accuracy] = self.accuracy + user.level - target.level
|
modifiers[:base_accuracy] = self.accuracy + user.level - target.level
|
||||||
|
|||||||
Reference in New Issue
Block a user