mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
Rewrote AI calculations for move effects that raise the user's stats, fixed Sea of Fire effect lasting forever
This commit is contained in:
@@ -134,6 +134,8 @@ class Battle
|
||||
#=============================================================================
|
||||
def pbEORSeaOfFireDamage(priority)
|
||||
2.times do |side|
|
||||
next if sides[side].effects[PBEffects::SeaOfFire] == 0
|
||||
sides[side].effects[PBEffects::SeaOfFire] -= 1
|
||||
next if sides[side].effects[PBEffects::SeaOfFire] == 0
|
||||
pbCommonAnimation("SeaOfFire") if side == 0
|
||||
pbCommonAnimation("SeaOfFireOpp") if side == 1
|
||||
|
||||
@@ -1199,6 +1199,7 @@ end
|
||||
# user's Attack (and Attack stat stages) to calculate damage. All other effects
|
||||
# are applied normally, applying the user's Attack modifiers and not the user's
|
||||
# Defence modifiers. (Body Press)
|
||||
# TODO: Rename this function code to remove both "Base"s?
|
||||
#===============================================================================
|
||||
class Battle::Move::UseUserBaseDefenseInsteadOfUserBaseAttack < Battle::Move
|
||||
def pbGetAttackStats(user, target)
|
||||
|
||||
@@ -133,7 +133,7 @@ class Battle::AI
|
||||
# after all.
|
||||
return true if @move.move.pbImmunityByAbility(@user.battler, @target.battler, false)
|
||||
# Type immunity
|
||||
calc_type = @move.rough_type(@user.battler)
|
||||
calc_type = @move.rough_type
|
||||
typeMod = @move.move.pbCalcTypeMod(calc_type, @user.battler, @target.battler)
|
||||
return true if @move.move.pbDamagingMove? && Effectiveness.ineffective?(typeMod)
|
||||
# Dark-type immunity to moves made faster by Prankster
|
||||
|
||||
@@ -37,15 +37,33 @@ class Battle::AI
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Check if battler has a move that meets the criteria in the block provided
|
||||
# Yields certain AIBattler objects
|
||||
#=============================================================================
|
||||
def check_for_move(battler)
|
||||
ret = false
|
||||
battler.eachMove do |move|
|
||||
next unless yield move
|
||||
ret = true
|
||||
break
|
||||
def each_battler
|
||||
@battlers.each_with_index do |battler, i|
|
||||
next if !battler || battler.fainted?
|
||||
yield battler, i
|
||||
end
|
||||
end
|
||||
|
||||
def each_foe_battler(side)
|
||||
@battlers.each_with_index do |battler, i|
|
||||
next if !battler || battler.fainted?
|
||||
yield battler, i if i.even? != side.even?
|
||||
end
|
||||
end
|
||||
|
||||
def each_same_side_battler(side)
|
||||
@battlers.each_with_index do |battler, i|
|
||||
next if !battler || battler.fainted?
|
||||
yield battler, i if i.even? == side.even?
|
||||
end
|
||||
end
|
||||
|
||||
def each_ally(index)
|
||||
@battlers.each_with_index do |battler, i|
|
||||
next if !battler || battler.fainted?
|
||||
yield battler, i if i != index && i.even? == index.even?
|
||||
end
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,24 +1,105 @@
|
||||
class Battle::AI
|
||||
#=============================================================================
|
||||
# Apply additional effect chance to a move's score
|
||||
# TODO: Apply all the additional effect chance modifiers.
|
||||
# Main method for calculating the score for moves that raise the user's stat(s).
|
||||
#=============================================================================
|
||||
def apply_effect_chance_to_score(score)
|
||||
if @move.damagingMove?
|
||||
# TODO: Doesn't return the correct value for "ConfuseTarget" (Chatter).
|
||||
effect_chance = @move.addlEffect
|
||||
if effect_chance > 0
|
||||
effect_chance *= 2 if @user.hasActiveAbility?(:SERENEGRACE) ||
|
||||
@user.pbOwnSide.effects[PBEffects::Rainbow] > 0
|
||||
effect_multiplier = [effect_chance.to_f, 100].min / 100
|
||||
score = ((score - 1) * effect_multiplier) + 1
|
||||
end
|
||||
def get_score_for_user_stat_raise(score)
|
||||
# Discard status move/don't prefer damaging move if user has Contrary
|
||||
if !@battle.moldBreaker && @user.has_active_ability?(:CONTRARY)
|
||||
return (@move.statusMove?) ? score - 40 : score - 20
|
||||
end
|
||||
# Don't make score changes if foes have Unaware and user can't make use of
|
||||
# extra stat stages
|
||||
if !@user.check_for_move { |move| move.function == "PowerHigherWithUserPositiveStatStages" }
|
||||
foe_is_aware = false
|
||||
each_foe_battler(@user.side) do |b, i|
|
||||
foe_is_aware = true if !b.has_active_ability?(:UNAWARE)
|
||||
end
|
||||
return score if !foe_is_aware
|
||||
end
|
||||
|
||||
# Figure out which stat raises can happen
|
||||
stat_changes = []
|
||||
@move.move.statUp.each_with_index do |stat, idx|
|
||||
next if idx.odd?
|
||||
next if !stat_raise_worthwhile?(stat)
|
||||
# Calculate amount that stat will be raised by
|
||||
increment = @move.move.statUp[idx + 1]
|
||||
if @move.function == "RaiseUserAtkSpAtk1Or2InSun"
|
||||
increment = 1
|
||||
increment = 2 if [:Sun, :HarshSun].include?(@user.battler.effectiveWeather)
|
||||
end
|
||||
increment *= 2 if !@battle.moldBreaker && @user.has_active_ability?(:SIMPLE)
|
||||
increment = [increment, 6 - @user.stages[stat]].min # The actual stages gained
|
||||
# Count this as a valid stat raise
|
||||
stat_changes.push([stat, increment]) if increment > 0
|
||||
end
|
||||
# Discard move if it can't raise any stats
|
||||
if stat_changes.length == 0
|
||||
return (@move.statusMove?) ? score - 40 : score
|
||||
end
|
||||
|
||||
# Make score changes based on the general concept of raising stats at all
|
||||
score = get_user_stat_raise_score_generic(score, stat_changes)
|
||||
|
||||
# Make score changes based on the specific changes to each stat that will be
|
||||
# raised
|
||||
stat_changes.each do |change|
|
||||
score = get_user_stat_raise_score_one(score, change[0], change[1])
|
||||
end
|
||||
|
||||
return score
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
#
|
||||
# Returns whether the user raising 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.
|
||||
#=============================================================================
|
||||
def stat_raise_worthwhile?(stat)
|
||||
return false if !@user.battler.pbCanRaiseStatStage?(stat, @user.battler, @move)
|
||||
# Check if user won't benefit from the stat being raised
|
||||
# TODO: Exception if user knows Baton Pass/Stored Power?
|
||||
case stat
|
||||
when :ATTACK
|
||||
return false if !@user.check_for_move { |move| move.physicalMove?(move.type) &&
|
||||
move.function != "UseUserBaseDefenseInsteadOfUserBaseAttack" &&
|
||||
move.function != "UseTargetAttackInsteadOfUserAttack" }
|
||||
when :DEFENSE
|
||||
each_foe_battler(@user.side) do |b, i|
|
||||
next if !b.check_for_move { |move| move.physicalMove?(move.type) ||
|
||||
move.function == "UseTargetDefenseInsteadOfTargetSpDef" }
|
||||
return true
|
||||
end
|
||||
return false
|
||||
when :SPECIAL_ATTACK
|
||||
return false if !@user.check_for_move { |move| move.specialMove?(move.rough_type) }
|
||||
when :SPECIAL_DEFENSE
|
||||
each_foe_battler(@user.side) do |b, i|
|
||||
next if !b.check_for_move { |move| move.specialMove?(move.type) &&
|
||||
move.function != "UseTargetDefenseInsteadOfTargetSpDef" }
|
||||
return true
|
||||
end
|
||||
return false
|
||||
when :SPEED
|
||||
moves_that_prefer_high_speed = [
|
||||
"PowerHigherWithUserFasterThanTarget",
|
||||
"PowerHigherWithUserPositiveStatStages"
|
||||
]
|
||||
if !@user.check_for_move { |move| moves_that_prefer_high_speed.include?(move.function) }
|
||||
each_foe_battler(@user.side) do |b, i|
|
||||
return true if b.faster_than?(@user)
|
||||
end
|
||||
return false
|
||||
end
|
||||
when :ACCURACY
|
||||
when :EVASION
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# 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.
|
||||
@@ -26,15 +107,45 @@ class Battle::AI
|
||||
# RaiseTargetRandomStat2 Acupressure
|
||||
# RaisePlusMinusUserAndAlliesDefSpDef1 Magnetic Flux
|
||||
# RaisePlusMinusUserAndAlliesAtkSpAtk1 Gear Up
|
||||
def calc_user_stat_raise_mini_score
|
||||
def get_user_stat_raise_score_generic(score, stat_changes)
|
||||
total_increment = stat_changes.sum { |change| change[1] }
|
||||
# TODO: Just return if foe is predicted to use a phazing move (one that
|
||||
# switches the user out).
|
||||
# TODO: Don't prefer if foe is faster than user and is predicted to deal
|
||||
# lethal damage.
|
||||
# TODO: Don't prefer if foe is slower than user but is predicted to be able
|
||||
# to 2HKO user.
|
||||
# TODO: Prefer if foe is semi-invulnerable and user is faster (can't hit
|
||||
# the foe anyway).
|
||||
|
||||
# Prefer if move is a status move and it's the user's first/second turn
|
||||
if @user.turnCount < 2 && @move.statusMove?
|
||||
score += total_increment * 5
|
||||
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 += 10 * total_increment
|
||||
else
|
||||
score += total_increment * ((100 * @user.hp / @user.totalhp) - 50) / 2 # +10 to -25 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 raise. There are none.
|
||||
|
||||
return score
|
||||
|
||||
|
||||
|
||||
mini_score = 1.0
|
||||
# Determine whether the move boosts Attack, Special Attack or Speed (Bulk Up
|
||||
# is sometimes not considered a sweeping move)
|
||||
sweeping_stat = false
|
||||
offensive_stat = false
|
||||
@move.stat_up.each_with_index do |stat, idx|
|
||||
next if idx.odd?
|
||||
next if ![:ATTACK, :SPATK, :SPEED].include?(stat)
|
||||
stat_changes.each do |change|
|
||||
next if ![:ATTACK, :SPECIAL_ATTACK, :SPEED].include?(change[0])
|
||||
sweeping_stat = true
|
||||
next if @move.function == "RaiseUserAtkDef1" # Bulk Up (+Atk +Def)
|
||||
offensive_stat = true
|
||||
@@ -45,12 +156,6 @@ class Battle::AI
|
||||
if @user.hp >= @user.totalhp * 3 / 4
|
||||
mini_score *= (sweeping_stat) ? 1.2 : 1.1
|
||||
end
|
||||
# Prefer if user hasn't been in battle for long
|
||||
if @user.turnCount < 2
|
||||
mini_score *= (sweeping_stat) ? 1.2 : 1.1
|
||||
end
|
||||
# Prefer if user has the ability Simple
|
||||
mini_score *= 2 if !@battle.moldBreaker && @user.hasActiveAbility?(:SIMPLE)
|
||||
# TODO: Prefer if user's moves won't do much damage.
|
||||
# Prefer if user has something that will limit damage taken
|
||||
mini_score *= 1.3 if @user.effects[PBEffects::Substitute] > 0 ||
|
||||
@@ -116,12 +221,6 @@ class Battle::AI
|
||||
# TODO: Prefer if the maximum damage the target has dealt wouldn't hurt
|
||||
# the user much.
|
||||
end
|
||||
# Don't prefer if foe's side is able to use a boosted Retaliate
|
||||
# TODO: I think this is what Reborn means. Reborn doesn't check for the
|
||||
# existence of the move Retaliate, just whether it can be boosted.
|
||||
if @user.pbOpposingSide.effects[PBEffects::LastRoundFainted] == @battle.turnCount - 1
|
||||
mini_score *= 0.3
|
||||
end
|
||||
|
||||
# Don't prefer if it's not a single battle
|
||||
if !@battle.singleBattle?
|
||||
@@ -132,197 +231,271 @@ class Battle::AI
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
#
|
||||
# Make score changes based on the raising of a specific stat.
|
||||
#=============================================================================
|
||||
# TODO: This method doesn't take the increment into account but should.
|
||||
def calc_user_stat_raise_one(stat, increment)
|
||||
mini_score = 1.0
|
||||
|
||||
# Ignore if user won't benefit from the stat being raised
|
||||
# TODO: Exception if user knows Baton Pass? Exception if user knows Power Trip?
|
||||
def get_user_stat_raise_score_one(score, stat, increment)
|
||||
case stat
|
||||
when :ATTACK
|
||||
has_physical_move = false
|
||||
@user.eachMove do |m|
|
||||
next if !m.physicalMove?(m.type) || m.function == "UseTargetAttackInsteadOfUserAttack" # Foul Play
|
||||
has_physical_move = true
|
||||
break
|
||||
# Modify score depending on current stat stage
|
||||
# More strongly prefer if the user has no special moves
|
||||
if @user.stages[stat] >= 3
|
||||
score -= 20
|
||||
else
|
||||
has_special_moves = @user.check_for_move { |move| move.specialMove?(move.rough_type) }
|
||||
inc = (has_special_moves) ? 5 : 10
|
||||
score += inc * (3 - @user.stages[stat]) * increment # 5 to 45
|
||||
score += 5 * increment if @user.hp == @user.totalhp
|
||||
end
|
||||
return mini_score if !has_physical_move
|
||||
|
||||
when :DEFENSE
|
||||
# Modify score depending on current stat stage
|
||||
if @user.stages[stat] >= 3
|
||||
score -= 20
|
||||
else
|
||||
score += 5 * (3 - @user.stages[stat]) * increment # 5 to 45
|
||||
score += 5 * increment if @user.hp == @user.totalhp
|
||||
end
|
||||
|
||||
when :SPECIAL_ATTACK
|
||||
has_special_move = false
|
||||
@user.eachMove do |m|
|
||||
next if !m.specialMove?(m.type)
|
||||
has_special_move = true
|
||||
# Modify score depending on current stat stage
|
||||
# More strongly prefer if the user has no physical moves
|
||||
if @user.stages[stat] >= 3
|
||||
score -= 20
|
||||
else
|
||||
has_physical_moves = @user.check_for_move { |move| move.physicalMove?(move.type) &&
|
||||
move.function != "UseUserBaseDefenseInsteadOfUserBaseAttack" &&
|
||||
move.function != "UseTargetAttackInsteadOfUserAttack" }
|
||||
inc = (has_physical_moves) ? 5 : 10
|
||||
score += inc * (3 - @user.stages[stat]) * increment # 5 to 45
|
||||
score += 5 * increment if @user.hp == @user.totalhp
|
||||
end
|
||||
|
||||
when :SPECIAL_DEFENSE
|
||||
# Modify score depending on current stat stage
|
||||
if @user.stages[stat] >= 3
|
||||
score -= 20
|
||||
else
|
||||
score += 5 * (3 - @user.stages[stat]) * increment # 5 to 45
|
||||
score += 5 * increment if @user.hp == @user.totalhp
|
||||
end
|
||||
|
||||
when :SPEED
|
||||
# Prefer if user is slower than a foe
|
||||
each_foe_battler(@user.side) do |b, i|
|
||||
next if @user.faster_than?(b)
|
||||
score += 15 * increment
|
||||
break
|
||||
end
|
||||
return mini_score if !has_special_move
|
||||
end
|
||||
# Don't prefer if any foe has Gyro Ball
|
||||
each_foe_battler(@user.side) do |b, i|
|
||||
next if !b.check_for_move { |move| move.function == "PowerHigherWithTargetFasterThanUser" }
|
||||
score -= 10 * increment
|
||||
end
|
||||
# Don't prefer if user has Speed Boost (will be gaining Speed anyway)
|
||||
score -= 20 if @user.has_active_ability?(:SPEEDBOOST)
|
||||
|
||||
case stat
|
||||
when :ATTACK
|
||||
# Prefer if user can definitely survive a hit no matter how powerful, and
|
||||
# it won't be hurt by weather
|
||||
if @user.hp == @user.totalhp &&
|
||||
(@user.hasActiveItem?(:FOCUSSASH) || (!@battle.moldBreaker && @user.hasActiveAbility?(:STURDY)))
|
||||
if !(@battle.pbWeather == :Sandstorm && @user.takesSandstormDamage?) &&
|
||||
!(@battle.pbWeather == :Hail && @user.takesHailDamage?) &&
|
||||
!(@battle.pbWeather == :ShadowSky && @user.takesShadowSkyDamage?)
|
||||
mini_score *= 1.4
|
||||
when :ACCURACY
|
||||
# Modify score depending on current stat stage
|
||||
if @user.stages[stat] >= 3
|
||||
score -= 20
|
||||
else
|
||||
min_accuracy = 100
|
||||
@user.battler.moves.each do |m|
|
||||
next if m.accuracy == 0 || m.is_a?(Battle::Move::OHKO)
|
||||
min_accuracy = m.accuracy if m.accuracy < min_accuracy
|
||||
end
|
||||
stageMul = [3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9]
|
||||
stageDiv = [9, 8, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3]
|
||||
min_accuracy *= stageMul[@user.stages[stat]] / stageDiv[@user.stages[stat]]
|
||||
if min_accuracy < 90
|
||||
score += 5 * (3 - @user.stages[stat]) * increment # 5 to 45
|
||||
score += 5 * increment if @user.hp == @user.totalhp
|
||||
end
|
||||
end
|
||||
# Prefer if user has the Sweeper role
|
||||
# TODO: Is 1.1x for RaiseUserAtkDefAcc1 Coil (+Atk, +Def, +acc).
|
||||
mini_score *= 1.3 if check_battler_role(@user, BattleRole::SWEEPER)
|
||||
# Don't prefer if user is burned or paralysed
|
||||
mini_score *= 0.5 if @user.status == :BURN || @user.status == :PARALYSIS
|
||||
# Don't prefer if user's Speed stat is lowered
|
||||
sum_stages = @user.stages[:SPEED]
|
||||
mini_score *= 1 + sum_stages * 0.05 if sum_stages < 0
|
||||
|
||||
# TODO: Prefer if target has previously used a HP-restoring move.
|
||||
# TODO: Don't prefer if some of foes' stats are raised
|
||||
sum_stages = 0
|
||||
[:ATTACK, :SPECIAL_ATTACK, :SPEED].each do |s|
|
||||
sum_stages += @target.stages[s]
|
||||
when :EVASION
|
||||
# Prefer if a foe will (probably) take damage at the end of the round
|
||||
# TODO: Should this take into account EOR healing, one-off damage and
|
||||
# damage-causing effects that wear off naturally (like Sea of Fire)?
|
||||
# TODO: Emerald AI also prefers if user is rooted via Ingrain.
|
||||
each_foe_battler(@user.side) do |b, i|
|
||||
eor_damage = b.rough_end_of_round_damage
|
||||
score += 60 * eor_damage / b.totalhp if eor_damage > 0
|
||||
end
|
||||
mini_score *= 1 - sum_stages * 0.05 if sum_stages > 0
|
||||
# TODO: Don't prefer if target has Speed Boost (+Spd at end of each round).
|
||||
mini_score *= 0.6 if @target.hasActiveAbility?(:SPEEDBOOST)
|
||||
# Modify score depending on current stat stage
|
||||
if @user.stages[stat] >= 3
|
||||
score -= 20
|
||||
else
|
||||
score += 5 * (3 - @user.stages[stat]) * increment # 5 to 45
|
||||
score += 5 * increment if @user.hp == @user.totalhp
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Check impact on moves of gaining stat stages
|
||||
pos_change = [@user.stages[stat] + increment, increment].min
|
||||
if pos_change > 0
|
||||
# Prefer if user has Stored Power
|
||||
if @user.check_for_move { |move| move.function == "PowerHigherWithUserPositiveStatStages" }
|
||||
score += 10 * pos_change
|
||||
end
|
||||
# Don't prefer if any foe has Punishment
|
||||
each_foe_battler(@user.side) do |b, i|
|
||||
next if !b.check_for_move { |move| move.function == "PowerHigherWithTargetPositiveStatStages" }
|
||||
score -= 10 * pos_change
|
||||
end
|
||||
end
|
||||
|
||||
return score
|
||||
|
||||
|
||||
|
||||
mini_score = 1.0
|
||||
case stat
|
||||
when :ATTACK
|
||||
# TODO: Don't prefer if target has previously used a move that benefits
|
||||
# from user's Attack being boosted.
|
||||
mini_score *= 0.3 if check_for_move(@target) { |move| move.function == "UseTargetAttackInsteadOfUserAttack" } # Foul Play
|
||||
# TODO: Don't prefer if the target has previously used a priority move.
|
||||
# mini_score *= 0.3 if @target.check_for_move { |move| move.function == "UseTargetAttackInsteadOfUserAttack" } # Foul Play
|
||||
# Prefer if user can definitely survive a hit no matter how powerful, and
|
||||
# it won't be hurt by weather
|
||||
# if @user.hp == @user.totalhp &&
|
||||
# (@user.hasActiveItem?(:FOCUSSASH) || (!@battle.moldBreaker && @user.hasActiveAbility?(:STURDY)))
|
||||
# if !(@battle.pbWeather == :Sandstorm && @user.takesSandstormDamage?) &&
|
||||
# !(@battle.pbWeather == :Hail && @user.takesHailDamage?) &&
|
||||
# !(@battle.pbWeather == :ShadowSky && @user.takesShadowSkyDamage?)
|
||||
# mini_score *= 1.4
|
||||
# end
|
||||
# end
|
||||
# Prefer if user has the Sweeper role
|
||||
# TODO: Is 1.1x for RaiseUserAtkDefAcc1 Coil (+Atk, +Def, +acc).
|
||||
# mini_score *= 1.3 if check_battler_role(@user, BattleRole::SWEEPER)
|
||||
|
||||
# # Don't prefer if user is burned or paralysed
|
||||
# mini_score *= 0.5 if @user.status == :BURN || @user.status == :PARALYSIS
|
||||
# # Don't prefer if user's Speed stat is lowered
|
||||
# sum_stages = @user.stages[:SPEED]
|
||||
# mini_score *= 1 + sum_stages * 0.05 if sum_stages < 0
|
||||
# # TODO: Prefer if target has previously used a HP-restoring move.
|
||||
# # TODO: Don't prefer if some of foes' stats are raised.
|
||||
# sum_stages = 0
|
||||
# [:ATTACK, :SPECIAL_ATTACK, :SPEED].each do |s|
|
||||
# sum_stages += @target.stages[s]
|
||||
# end
|
||||
# mini_score *= 1 - sum_stages * 0.05 if sum_stages > 0
|
||||
# # TODO: Don't prefer if target has Speed Boost (+Spd at end of each round).
|
||||
# mini_score *= 0.6 if @target.hasActiveAbility?(:SPEEDBOOST)
|
||||
# # TODO: Don't prefer if the target has previously used a priority move.
|
||||
|
||||
when :DEFENSE
|
||||
# Prefer if user has a healing item
|
||||
# TODO: Is 1.1x for RaiseUserAtkDefAcc1 Coil (+Atk, +Def, +acc).
|
||||
mini_score *= 1.2 if @user.hasActiveItem?(:LEFTOVERS) ||
|
||||
(@user.hasActiveItem?(:BLACKSLUDGE) && @user.pbHasType?(:POISON))
|
||||
# mini_score *= 1.2 if @user.hasActiveItem?(:LEFTOVERS) ||
|
||||
# (@user.hasActiveItem?(:BLACKSLUDGE) && @user.pbHasType?(:POISON))
|
||||
# Prefer if user knows any healing moves
|
||||
# TODO: Is 1.2x for RaiseUserAtkDefAcc1 Coil (+Atk, +Def, +acc).
|
||||
mini_score *= 1.3 if check_for_move(@user) { |move| move.healingMove? }
|
||||
# # TODO: Is 1.2x for RaiseUserAtkDefAcc1 Coil (+Atk, +Def, +acc).
|
||||
# mini_score *= 1.3 if check_for_move(@user) { |move| move.healingMove? }
|
||||
# Prefer if user knows Pain Split or Leech Seed
|
||||
# TODO: Leech Seed is 1.2x for RaiseUserAtkDefAcc1 Coil (+Atk, +Def, +acc).
|
||||
mini_score *= 1.2 if @user.pbHasMoveFunction?("UserTargetAverageHP") # Pain Split
|
||||
mini_score *= 1.3 if @user.pbHasMoveFunction?("StartLeechSeedTarget") # Leech Seed
|
||||
# # TODO: Leech Seed is 1.2x for RaiseUserAtkDefAcc1 Coil (+Atk, +Def, +acc).
|
||||
# mini_score *= 1.2 if @user.pbHasMoveFunction?("UserTargetAverageHP") # Pain Split
|
||||
# mini_score *= 1.3 if @user.pbHasMoveFunction?("StartLeechSeedTarget") # Leech Seed
|
||||
# Prefer if user has certain roles
|
||||
# TODO: Is 1.1x for RaiseUserAtkDefAcc1 Coil (+Atk, +Def, +acc).
|
||||
mini_score *= 1.3 if check_battler_role(@user, BattleRole::PHYSICALWALL, BattleRole::SPECIALWALL)
|
||||
# # TODO: Is 1.1x for RaiseUserAtkDefAcc1 Coil (+Atk, +Def, +acc).
|
||||
# mini_score *= 1.3 if check_battler_role(@user, BattleRole::PHYSICALWALL, BattleRole::SPECIALWALL)
|
||||
# Don't prefer if user is badly poisoned
|
||||
mini_score *= 0.2 if @user.effects[PBEffects::Toxic] > 0
|
||||
# Don't prefer if user's Defense stat is raised
|
||||
sum_stages = @user.stages[:DEFENSE]
|
||||
mini_score *= 1 - sum_stages * 0.15 if sum_stages > 0
|
||||
|
||||
# TODO: Prefer if foes have higher Attack than Special Attack, and user
|
||||
# doesn't have a wall role, user is faster and user has at least 75%
|
||||
# HP. Don't prefer instead if user is slower (ignore HP).
|
||||
|
||||
# # TODO: Prefer if foes have higher Attack than Special Attack, and user
|
||||
# # doesn't have a wall role, user is faster and user has at least 75%
|
||||
# # HP. Don't prefer instead if user is slower (ignore HP).
|
||||
# TODO: Don't prefer if previous damage done by foes wouldn't hurt the
|
||||
# user much.
|
||||
|
||||
when :SPEED
|
||||
# Don't prefer if user has Speed Boost
|
||||
# mini_score *= 0.6 if @user.hasActiveAbility?(:SPEEDBOOST)
|
||||
# Prefer if user can definitely survive a hit no matter how powerful, and
|
||||
# it won't be hurt by weather
|
||||
if @user.hp == @user.totalhp &&
|
||||
(@user.hasActiveItem?(:FOCUSSASH) || (!@battle.moldBreaker && @user.hasActiveAbility?(:STURDY)))
|
||||
if !(@battle.pbWeather == :Sandstorm && @user.takesSandstormDamage?) &&
|
||||
!(@battle.pbWeather == :Hail && @user.takesHailDamage?) &&
|
||||
!(@battle.pbWeather == :ShadowSky && @user.takesShadowSkyDamage?)
|
||||
mini_score *= 1.4
|
||||
end
|
||||
end
|
||||
# Prefer if user's Attack/SpAtk stat (whichever is higher) is lowered
|
||||
# TODO: Why?
|
||||
if @user.attack > @user.spatk
|
||||
sum_stages = @user.stages[:ATTACK]
|
||||
mini_score *= 1 - sum_stages * 0.05 if sum_stages < 0
|
||||
else
|
||||
sum_stages = @user.stages[:SPATK]
|
||||
mini_score *= 1 - sum_stages * 0.05 if sum_stages < 0
|
||||
end
|
||||
# Prefer if user has lowered Speed
|
||||
# TODO: Is a flat 1.3x for RaiseUserAtkSpd1 Dragon Dance (+Atk, +Spd).
|
||||
sum_stages = @user.stages[:SPEED]
|
||||
mini_score *= 1 - sum_stages * 0.05 if sum_stages < 0
|
||||
# Prefer if user has Moxie
|
||||
mini_score *= 1.3 if @user.hasActiveAbility?(:MOXIE)
|
||||
# Prefer if user has the Sweeper role
|
||||
mini_score *= 1.3 if check_battler_role(@user, BattleRole::SWEEPER)
|
||||
# Don't prefer if user is burned or paralysed
|
||||
mini_score *= 0.2 if @user.status == :PARALYSIS
|
||||
# Don't prefer if user has Speed Boost
|
||||
mini_score *= 0.6 if @user.hasActiveAbility?(:SPEEDBOOST)
|
||||
# if @user.hp == @user.totalhp &&
|
||||
# (@user.hasActiveItem?(:FOCUSSASH) || (!@battle.moldBreaker && @user.hasActiveAbility?(:STURDY)))
|
||||
# if !(@battle.pbWeather == :Sandstorm && @user.takesSandstormDamage?) &&
|
||||
# !(@battle.pbWeather == :Hail && @user.takesHailDamage?) &&
|
||||
# !(@battle.pbWeather == :ShadowSky && @user.takesShadowSkyDamage?)
|
||||
# mini_score *= 1.4
|
||||
# end
|
||||
# end
|
||||
# Prefer if user has the Sweeper role
|
||||
# mini_score *= 1.3 if check_battler_role(@user, BattleRole::SWEEPER)
|
||||
# TODO: Don't prefer if Trick Room applies or any foe has previously used
|
||||
# Trick Room.
|
||||
# mini_score *= 0.2 if @battle.field.effects[PBEffects::TrickRoom] > 0
|
||||
|
||||
# TODO: Don't prefer if target has raised defenses.
|
||||
sum_stages = 0
|
||||
[:DEFENSE, :SPECIAL_DEFENSE].each { |s| sum_stages += @target.stages[s] }
|
||||
mini_score *= 1 - sum_stages * 0.05 if sum_stages > 0
|
||||
# TODO: Don't prefer if the target has previously used a priority move.
|
||||
# TODO: Don't prefer if Trick Room applies or any foe has previously used
|
||||
# Trick Room.
|
||||
mini_score *= 0.2 if @battle.field.effects[PBEffects::TrickRoom] > 0
|
||||
|
||||
# TODO: Don't prefer if user is already faster than the target. Exception
|
||||
# for moves that benefit from a raised user's Speed?
|
||||
# TODO: Don't prefer if user is already faster than the target and there's
|
||||
# only 1 unfainted foe (this check is done by Agility/Autotomize
|
||||
# (both +2 Spd) only in Reborn.)
|
||||
# # Prefer if user's Attack/SpAtk stat (whichever is higher) is lowered
|
||||
# # TODO: Why?
|
||||
# if @user.attack > @user.spatk
|
||||
# sum_stages = @user.stages[:ATTACK]
|
||||
# mini_score *= 1 - sum_stages * 0.05 if sum_stages < 0
|
||||
# else
|
||||
# sum_stages = @user.stages[:SPATK]
|
||||
# mini_score *= 1 - sum_stages * 0.05 if sum_stages < 0
|
||||
# end
|
||||
# # Prefer if user has Moxie
|
||||
# mini_score *= 1.3 if @user.hasActiveAbility?(:MOXIE)
|
||||
# # Don't prefer if user is burned or paralysed
|
||||
# mini_score *= 0.2 if @user.status == :PARALYSIS
|
||||
# # TODO: Don't prefer if target has raised defenses.
|
||||
# sum_stages = 0
|
||||
# [:DEFENSE, :SPECIAL_DEFENSE].each { |s| sum_stages += @target.stages[s] }
|
||||
# mini_score *= 1 - sum_stages * 0.05 if sum_stages > 0
|
||||
# # TODO: Don't prefer if the target has previously used a priority move.
|
||||
# # TODO: Don't prefer if user is already faster than the target and there's
|
||||
# # only 1 unfainted foe (this check is done by Agility/Autotomize
|
||||
# # (both +2 Spd) only in Reborn.)
|
||||
|
||||
when :SPECIAL_ATTACK
|
||||
# Prefer if user can definitely survive a hit no matter how powerful, and
|
||||
# it won't be hurt by weather
|
||||
if @user.hp == @user.totalhp &&
|
||||
(@user.hasActiveItem?(:FOCUSSASH) || (!@battle.moldBreaker && @user.hasActiveAbility?(:STURDY)))
|
||||
if !(@battle.pbWeather == :Sandstorm && @user.takesSandstormDamage?) &&
|
||||
!(@battle.pbWeather == :Hail && @user.takesHailDamage?) &&
|
||||
!(@battle.pbWeather == :ShadowSky && @user.takesShadowSkyDamage?)
|
||||
mini_score *= 1.4
|
||||
end
|
||||
end
|
||||
# if @user.hp == @user.totalhp &&
|
||||
# (@user.hasActiveItem?(:FOCUSSASH) || (!@battle.moldBreaker && @user.hasActiveAbility?(:STURDY)))
|
||||
# if !(@battle.pbWeather == :Sandstorm && @user.takesSandstormDamage?) &&
|
||||
# !(@battle.pbWeather == :Hail && @user.takesHailDamage?) &&
|
||||
# !(@battle.pbWeather == :ShadowSky && @user.takesShadowSkyDamage?)
|
||||
# mini_score *= 1.4
|
||||
# end
|
||||
# end
|
||||
# Prefer if user has the Sweeper role
|
||||
mini_score *= 1.3 if check_battler_role(@user, BattleRole::SWEEPER)
|
||||
# Don't prefer if user's Speed stat is lowered
|
||||
sum_stages = @user.stages[:SPEED]
|
||||
mini_score *= 1 + sum_stages * 0.05 if sum_stages < 0
|
||||
# mini_score *= 1.3 if check_battler_role(@user, BattleRole::SWEEPER)
|
||||
|
||||
# TODO: Prefer if target has previously used a HP-restoring move.
|
||||
# TODO: Don't prefer if some of foes' stats are raised
|
||||
sum_stages = 0
|
||||
[:ATTACK, :SPECIAL_ATTACK, :SPEED].each do |s|
|
||||
sum_stages += @target.stages[s]
|
||||
end
|
||||
mini_score *= 1 - sum_stages * 0.05 if sum_stages > 0
|
||||
# TODO: Don't prefer if target has Speed Boost (+Spd at end of each round)
|
||||
mini_score *= 0.6 if @target.hasActiveAbility?(:SPEEDBOOST)
|
||||
# TODO: Don't prefer if the target has previously used a priority move.
|
||||
# # Don't prefer if user's Speed stat is lowered
|
||||
# sum_stages = @user.stages[:SPEED]
|
||||
# mini_score *= 1 + sum_stages * 0.05 if sum_stages < 0
|
||||
# # TODO: Prefer if target has previously used a HP-restoring move.
|
||||
# # TODO: Don't prefer if some of foes' stats are raised
|
||||
# sum_stages = 0
|
||||
# [:ATTACK, :SPECIAL_ATTACK, :SPEED].each do |s|
|
||||
# sum_stages += @target.stages[s]
|
||||
# end
|
||||
# mini_score *= 1 - sum_stages * 0.05 if sum_stages > 0
|
||||
# # TODO: Don't prefer if target has Speed Boost (+Spd at end of each round)
|
||||
# mini_score *= 0.6 if @target.hasActiveAbility?(:SPEEDBOOST)
|
||||
# # TODO: Don't prefer if the target has previously used a priority move.
|
||||
|
||||
when :SPECIAL_DEFENSE
|
||||
# Prefer if user has a healing item
|
||||
mini_score *= 1.2 if @user.hasActiveItem?(:LEFTOVERS) ||
|
||||
(@user.hasActiveItem?(:BLACKSLUDGE) && @user.pbHasType?(:POISON))
|
||||
# mini_score *= 1.2 if @user.hasActiveItem?(:LEFTOVERS) ||
|
||||
# (@user.hasActiveItem?(:BLACKSLUDGE) && @user.pbHasType?(:POISON))
|
||||
# Prefer if user knows any healing moves
|
||||
mini_score *= 1.3 if check_for_move(@user) { |move| move.healingMove? }
|
||||
# mini_score *= 1.3 if check_for_move(@user) { |move| move.healingMove? }
|
||||
# Prefer if user knows Pain Split or Leech Seed
|
||||
mini_score *= 1.2 if @user.pbHasMoveFunction?("UserTargetAverageHP") # Pain Split
|
||||
mini_score *= 1.3 if @user.pbHasMoveFunction?("StartLeechSeedTarget") # Leech Seed
|
||||
# mini_score *= 1.2 if @user.pbHasMoveFunction?("UserTargetAverageHP") # Pain Split
|
||||
# mini_score *= 1.3 if @user.pbHasMoveFunction?("StartLeechSeedTarget") # Leech Seed
|
||||
# Prefer if user has certain roles
|
||||
mini_score *= 1.3 if check_battler_role(@user, BattleRole::PHYSICALWALL, BattleRole::SPECIALWALL)
|
||||
# Don't prefer if user's Defense stat is raised
|
||||
sum_stages = @user.stages[:SPECIAL_DEFENSE]
|
||||
mini_score *= 1 - sum_stages * 0.15 if sum_stages > 0
|
||||
|
||||
# TODO: Prefer if foes have higher Special Attack than Attack.
|
||||
|
||||
# mini_score *= 1.3 if check_battler_role(@user, BattleRole::PHYSICALWALL, BattleRole::SPECIALWALL)
|
||||
# # TODO: Prefer if foes have higher Special Attack than Attack.
|
||||
# TODO: Don't prefer if previous damage done by foes wouldn't hurt the
|
||||
# user much.
|
||||
|
||||
when :ACCURACY
|
||||
|
||||
# Prefer if user knows any weaker moves
|
||||
mini_score *= 1.1 if check_for_move(@user) { |move| move.damagingMove? && move.basedamage < 95 }
|
||||
|
||||
# Prefer if target has a raised evasion
|
||||
sum_stages = @target.stages[:EVASION]
|
||||
mini_score *= 1 + sum_stages * 0.05 if sum_stages > 0
|
||||
@@ -355,20 +528,12 @@ class Battle::AI
|
||||
# Prefer if user has certain roles
|
||||
mini_score *= 1.3 if check_battler_role(@user, BattleRole::PHYSICALWALL, BattleRole::SPECIALWALL)
|
||||
# TODO: Don't prefer if user's evasion stat is raised
|
||||
|
||||
# TODO: Don't prefer if target has No Guard.
|
||||
mini_score *= 0.2 if @target.hasActiveAbility?(:NOGUARD)
|
||||
# TODO: Don't prefer if target has previously used any moves that never miss.
|
||||
|
||||
end
|
||||
|
||||
# Don't prefer if user has Contrary
|
||||
mini_score *= 0.5 if !@battle.moldBreaker && @user.hasActiveAbility?(:CONTRARY)
|
||||
# TODO: Don't prefer if target has Unaware? Reborn resets mini_score to 1.
|
||||
# This check needs more consideration. Note that @target is user for
|
||||
# status moves, so that part is wrong.
|
||||
# TODO: Is 0x for RaiseUserAtkDefAcc1, RaiseUserAtkSpd1 (all moves that raise multiple stats)
|
||||
mini_score *= 0.5 if @move.statusMove? && !@battle.moldBreaker && @target.hasActiveAbility?(:UNAWARE)
|
||||
|
||||
# TODO: Don't prefer if any foe has previously used a stat stage-clearing
|
||||
# move (Clear Smog/Haze).
|
||||
@@ -390,47 +555,6 @@ class Battle::AI
|
||||
return mini_score
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
#
|
||||
#=============================================================================
|
||||
def get_score_for_user_stat_raise(score)
|
||||
# Discard status move if user has Contrary
|
||||
return 0 if @move.statusMove? && !@battle.moldBreaker && @user.hasActiveAbility?(:CONTRARY)
|
||||
|
||||
# Discard move if it can't raise any stats
|
||||
can_change_any_stat = false
|
||||
@move.stat_up.each_with_index do |stat, idx|
|
||||
next if idx.odd?
|
||||
next if @user.statStageAtMax?(stat)
|
||||
can_change_any_stat = true
|
||||
break
|
||||
end
|
||||
if !can_change_any_stat
|
||||
return (@move.statusMove?) ? 0 : score
|
||||
end
|
||||
|
||||
# Get the main mini-score
|
||||
main_mini_score = calc_user_stat_raise_mini_score
|
||||
|
||||
# For each stat to be raised in turn, calculate a mini-score describing how
|
||||
# beneficial that stat being raised will be
|
||||
mini_score = 0
|
||||
num_stats = 0
|
||||
@move.stat_up.each_with_index do |stat, idx|
|
||||
next if idx.odd?
|
||||
next if @user.statStageAtMax?(stat)
|
||||
# TODO: Use the effective increment (e.g. 1 if the stat is raised by 2 but
|
||||
# the stat is already at +5).
|
||||
mini_score += calc_user_stat_raise_one(stat, @move.stat_up[idx + 1])
|
||||
num_stats += 1
|
||||
end
|
||||
|
||||
# Apply the average mini-score to the actual score
|
||||
score = apply_effect_chance_to_score(main_mini_score * mini_score / num_stats)
|
||||
|
||||
return score
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
#
|
||||
#=============================================================================
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.add("RaiseUserAttack1",
|
||||
proc { |move, user, target, ai, battle|
|
||||
@@ -9,77 +9,17 @@ Battle::AI::Handlers::MoveFailureCheck.add("RaiseUserAttack1",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserAttack1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score -= user.stages[:ATTACK] * 20
|
||||
if ai.trainer.medium_skill?
|
||||
hasPhysicalAttack = false
|
||||
user.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 user.stages[:ATTACK] < 0
|
||||
if ai.trainer.medium_skill?
|
||||
hasPhysicalAttack = false
|
||||
user.battler.eachMove do |m|
|
||||
next if !m.physicalMove?(m.type)
|
||||
hasPhysicalAttack = true
|
||||
break
|
||||
end
|
||||
score += 20 if hasPhysicalAttack
|
||||
end
|
||||
end
|
||||
next score
|
||||
next ai.get_score_for_user_stat_raise(score)
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAttack1",
|
||||
"RaiseUserAttack2")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserAttack2",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
next score - 90 if user.statStageAtMax?(:ATTACK)
|
||||
score += 40 if user.turnCount == 0
|
||||
score -= user.stages[:ATTACK] * 20
|
||||
if ai.trainer.medium_skill?
|
||||
hasPhysicalAttack = false
|
||||
user.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 user.stages[:ATTACK] < 0
|
||||
if ai.trainer.medium_skill?
|
||||
hasPhysicalAttack = false
|
||||
user.battler.eachMove do |m|
|
||||
next if !m.physicalMove?(m.type)
|
||||
hasPhysicalAttack = true
|
||||
break
|
||||
end
|
||||
score += 20 if hasPhysicalAttack
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAttack1",
|
||||
"RaiseUserAttack2")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
@@ -88,7 +28,7 @@ Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAttack2",
|
||||
"RaiseUserAttack2IfTargetFaints")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAttack2",
|
||||
"RaiseUserAttack3")
|
||||
@@ -131,225 +71,94 @@ Battle::AI::Handlers::MoveEffectScore.add("MaxUserAttackLoseHalfOfTotalHP",
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAttack1",
|
||||
"RaiseUserDefense1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserDefense1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
next score - user.stages[:DEFENSE] * 20
|
||||
elsif user.stages[:DEFENSE] < 0
|
||||
next score + 20
|
||||
end
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAttack1",
|
||||
"RaiseUserDefense1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserDefense1",
|
||||
"RaiseUserDefense1CurlUpUser")
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserDefense1",
|
||||
"RaiseUserDefense1CurlUpUser")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserDefense1CurlUpUser",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score = ai.get_score_for_user_stat_raise(score)
|
||||
if !user.effects[PBEffects::DefenseCurl] &&
|
||||
user.check_for_move { |move| move.function == "MultiTurnAttackPowersUpEachTurn" }
|
||||
score += 10
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserDefense1",
|
||||
"RaiseUserDefense2")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserDefense2",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score += 40 if user.turnCount == 0
|
||||
score -= user.stages[:DEFENSE] * 20
|
||||
else
|
||||
score += 10 if user.turnCount == 0
|
||||
score += 20 if user.stages[:DEFENSE] < 0
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserDefense1",
|
||||
"RaiseUserDefense2")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserDefense1",
|
||||
"RaiseUserDefense3")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserDefense3",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score += 40 if user.turnCount == 0
|
||||
score -= user.stages[:DEFENSE] * 30
|
||||
else
|
||||
score += 10 if user.turnCount == 0
|
||||
score += 30 if user.stages[:DEFENSE] < 0
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserDefense1",
|
||||
"RaiseUserDefense3")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAttack1",
|
||||
"RaiseUserSpAtk1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserSpAtk1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score -= user.stages[:SPECIAL_ATTACK] * 20
|
||||
if ai.trainer.medium_skill?
|
||||
hasSpecicalAttack = false
|
||||
user.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
|
||||
user.battler.eachMove do |m|
|
||||
next if !m.specialMove?(m.type)
|
||||
hasSpecicalAttack = true
|
||||
break
|
||||
end
|
||||
score += 20 if hasSpecicalAttack
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAttack1",
|
||||
"RaiseUserSpAtk1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserSpAtk1",
|
||||
"RaiseUserSpAtk2")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserSpAtk2",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score += 40 if user.turnCount == 0
|
||||
score -= user.stages[:SPECIAL_ATTACK] * 20
|
||||
if ai.trainer.medium_skill?
|
||||
hasSpecicalAttack = false
|
||||
user.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 user.stages[:SPECIAL_ATTACK] < 0
|
||||
if ai.trainer.medium_skill?
|
||||
hasSpecicalAttack = false
|
||||
user.battler.eachMove do |m|
|
||||
next if !m.specialMove?(m.type)
|
||||
hasSpecicalAttack = true
|
||||
break
|
||||
end
|
||||
score += 20 if hasSpecicalAttack
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserSpAtk1",
|
||||
"RaiseUserSpAtk2")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserSpAtk1",
|
||||
"RaiseUserSpAtk3")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserSpAtk3",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score += 40 if user.turnCount == 0
|
||||
score -= user.stages[:SPECIAL_ATTACK] * 30
|
||||
if ai.trainer.medium_skill?
|
||||
hasSpecicalAttack = false
|
||||
user.battler.eachMove do |m|
|
||||
next if !m.specialMove?(m.type)
|
||||
hasSpecicalAttack = true
|
||||
break
|
||||
end
|
||||
if hasSpecicalAttack
|
||||
score += 30
|
||||
elsif ai.trainer.high_skill?
|
||||
score -= 90
|
||||
end
|
||||
end
|
||||
else
|
||||
score += 10 if user.turnCount == 0
|
||||
score += 30 if user.stages[:SPECIAL_ATTACK] < 0
|
||||
if ai.trainer.medium_skill?
|
||||
hasSpecicalAttack = false
|
||||
user.battler.eachMove do |m|
|
||||
next if !m.specialMove?(m.type)
|
||||
hasSpecicalAttack = true
|
||||
break
|
||||
end
|
||||
score += 30 if hasSpecicalAttack
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserSpAtk1",
|
||||
"RaiseUserSpAtk3")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserDefense1",
|
||||
"RaiseUserSpDef1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserSpDef1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score += 40 if user.turnCount == 0
|
||||
score -= user.stages[:SPECIAL_DEFENSE] * 20
|
||||
else
|
||||
score += 10 if user.turnCount == 0
|
||||
score += 20 if user.stages[:SPECIAL_DEFENSE] < 0
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserDefense1",
|
||||
"RaiseUserSpDef1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserSpDef1",
|
||||
"RaiseUserSpDef1PowerUpElectricMove")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserSpDef1PowerUpElectricMove",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
foundMove = false
|
||||
user.battler.eachMove do |m|
|
||||
next if m.type != :ELECTRIC || !m.damagingMove?
|
||||
foundMove = true
|
||||
break
|
||||
end
|
||||
score += 20 if foundMove
|
||||
if move.statusMove?
|
||||
score -= user.stages[:SPECIAL_DEFENSE] * 20
|
||||
elsif user.stages[:SPECIAL_DEFENSE] < 0
|
||||
score += 20
|
||||
score = ai.get_score_for_user_stat_raise(score)
|
||||
if user.check_for_move { |move| move.damagingMove? && move.type == :ELECTRIC }
|
||||
score += 10
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserSpDef1",
|
||||
"RaiseUserSpDef2")
|
||||
@@ -357,7 +166,7 @@ Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserSpDef1",
|
||||
"RaiseUserSpDef2")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserSpDef1",
|
||||
"RaiseUserSpDef3")
|
||||
@@ -365,53 +174,23 @@ Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserSpDef1",
|
||||
"RaiseUserSpDef3")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserSpDef1",
|
||||
"RaiseUserSpeed1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserSpeed1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score -= user.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
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserSpDef1",
|
||||
"RaiseUserSpeed1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: This code shouldn't make use of target.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserSpeed1",
|
||||
"RaiseUserSpeed2")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserSpeed2",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score += 20 if user.turnCount == 0
|
||||
score -= user.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
|
||||
else
|
||||
score += 10 if user.turnCount == 0
|
||||
score += 20 if user.stages[:SPEED] < 0
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserSpeed1",
|
||||
"RaiseUserSpeed2")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: This code shouldn't make use of target.
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserSpeed2",
|
||||
"RaiseUserSpeed2LowerUserWeight")
|
||||
@@ -419,34 +198,23 @@ Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserSpeed2",
|
||||
"RaiseUserSpeed2LowerUserWeight")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: This code shouldn't make use of target.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserSpeed2",
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserSpeed1",
|
||||
"RaiseUserSpeed3")
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserSpeed2",
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserSpeed1",
|
||||
"RaiseUserSpeed3")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserSpeed1",
|
||||
"RaiseUserAccuracy1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserAccuracy1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score += 40 if user.turnCount == 0
|
||||
score -= user.stages[:ACCURACY] * 20
|
||||
else
|
||||
score += 10 if user.turnCount == 0
|
||||
score += 20 if user.stages[:ACCURACY] < 0
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserSpeed1",
|
||||
"RaiseUserAccuracy1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAccuracy1",
|
||||
"RaiseUserAccuracy2")
|
||||
@@ -454,7 +222,7 @@ Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAccuracy1",
|
||||
"RaiseUserAccuracy2")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAccuracy1",
|
||||
"RaiseUserAccuracy3")
|
||||
@@ -462,38 +230,20 @@ Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAccuracy1",
|
||||
"RaiseUserAccuracy3")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAccuracy1",
|
||||
"RaiseUserEvasion1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserEvasion1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score -= user.stages[:EVASION] * 10
|
||||
elsif user.stages[:EVASION] < 0
|
||||
score += 20
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAccuracy1",
|
||||
"RaiseUserEvasion1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserEvasion1",
|
||||
"RaiseUserEvasion2")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserEvasion2",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if move.statusMove?
|
||||
score += 40 if user.turnCount == 0
|
||||
score -= user.stages[:EVASION] * 10
|
||||
else
|
||||
score += 10 if user.turnCount == 0
|
||||
score += 20 if user.stages[:EVASION] < 0
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserEvasion1",
|
||||
"RaiseUserEvasion2")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
@@ -504,7 +254,7 @@ Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserEvasion2",
|
||||
"RaiseUserEvasion2MinimizeUser")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserEvasion2",
|
||||
"RaiseUserEvasion3")
|
||||
@@ -528,7 +278,7 @@ Battle::AI::Handlers::MoveEffectScore.add("RaiseUserCriticalHitRate2",
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.add("RaiseUserAtkDef1",
|
||||
proc { |move, user, target, ai, battle|
|
||||
@@ -543,106 +293,32 @@ Battle::AI::Handlers::MoveFailureCheck.add("RaiseUserAtkDef1",
|
||||
end
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserAtkDef1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score -= user.stages[:ATTACK] * 10
|
||||
score -= user.stages[:DEFENSE] * 10
|
||||
if ai.trainer.medium_skill?
|
||||
hasPhysicalAttack = false
|
||||
user.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
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAttack1",
|
||||
"RaiseUserAtkDef1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAtkDef1",
|
||||
"RaiseUserAtkDefAcc1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserAtkDefAcc1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score -= user.stages[:ATTACK] * 10
|
||||
score -= user.stages[:DEFENSE] * 10
|
||||
score -= user.stages[:ACCURACY] * 10
|
||||
if ai.trainer.medium_skill?
|
||||
hasPhysicalAttack = false
|
||||
user.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
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAtkDef1",
|
||||
"RaiseUserAtkDefAcc1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAtkDef1",
|
||||
"RaiseUserAtkSpAtk1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserAtkSpAtk1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score -= user.stages[:ATTACK] * 10
|
||||
score -= user.stages[:SPECIAL_ATTACK] * 10
|
||||
if ai.trainer.medium_skill?
|
||||
hasDamagingAttack = false
|
||||
user.battler.eachMove do |m|
|
||||
next if !m.damagingMove?
|
||||
hasDamagingAttack = true
|
||||
break
|
||||
end
|
||||
if hasDamagingAttack
|
||||
score += 20
|
||||
elsif ai.trainer.high_skill?
|
||||
score -= 90
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAtkDef1",
|
||||
"RaiseUserAtkSpAtk1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserAtkSpAtk1Or2InSun")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserAtkSpAtk1Or2InSun",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score -= user.stages[:ATTACK] * 10
|
||||
score -= user.stages[:SPECIAL_ATTACK] * 10
|
||||
if ai.trainer.medium_skill?
|
||||
hasDamagingAttack = false
|
||||
user.battler.eachMove do |m|
|
||||
next if !m.damagingMove?
|
||||
hasDamagingAttack = true
|
||||
break
|
||||
end
|
||||
if hasDamagingAttack
|
||||
score += 20
|
||||
elsif ai.trainer.high_skill?
|
||||
score -= 90
|
||||
end
|
||||
end
|
||||
score += 20 if [:Sun, :HarshSun].include?(user.battler.effectiveWeather)
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserAtkSpAtk1Or2InSun")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
@@ -684,190 +360,60 @@ Battle::AI::Handlers::MoveEffectScore.add("LowerUserDefSpDef1RaiseUserAtkSpAtkSp
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: This code shouldn't make use of target.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserAtkSpd1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserAtkSpd1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score += 40 if user.turnCount == 0 # Dragon Dance tends to be popular
|
||||
score -= user.stages[:ATTACK] * 10
|
||||
score -= user.stages[:SPEED] * 10
|
||||
if ai.trainer.medium_skill?
|
||||
hasPhysicalAttack = false
|
||||
user.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
|
||||
if ai.trainer.high_skill?
|
||||
aspeed = user.rough_stat(:SPEED)
|
||||
ospeed = target.rough_stat(:SPEED)
|
||||
score += 20 if aspeed < ospeed && aspeed * 2 > ospeed
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserAtkSpd1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: This code shouldn't make use of target.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserAtk1Spd2")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserAtk1Spd2",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score -= user.stages[:ATTACK] * 10
|
||||
score -= user.stages[:SPEED] * 10
|
||||
if ai.trainer.medium_skill?
|
||||
hasPhysicalAttack = false
|
||||
user.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
|
||||
if ai.trainer.high_skill?
|
||||
aspeed = user.rough_stat(:SPEED)
|
||||
ospeed = target.rough_stat(:SPEED)
|
||||
score += 30 if aspeed < ospeed && aspeed * 2 > ospeed
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserAtk1Spd2")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserAtkAcc1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserAtkAcc1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score -= user.stages[:ATTACK] * 10
|
||||
score -= user.stages[:ACCURACY] * 10
|
||||
if ai.trainer.medium_skill?
|
||||
hasPhysicalAttack = false
|
||||
user.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
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserAtkAcc1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserDefSpDef1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserDefSpDef1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score -= user.stages[:DEFENSE] * 10
|
||||
score -= user.stages[:SPECIAL_DEFENSE] * 10
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserDefSpDef1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserSpAtkSpDef1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserSpAtkSpDef1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score += 40 if user.turnCount == 0 # Calm Mind tends to be popular
|
||||
score -= user.stages[:SPECIAL_ATTACK] * 10
|
||||
score -= user.stages[:SPECIAL_DEFENSE] * 10
|
||||
if ai.trainer.medium_skill?
|
||||
hasSpecicalAttack = false
|
||||
user.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
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserSpAtkSpDef1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: This code shouldn't make use of target.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserSpAtkSpDefSpd1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserSpAtkSpDefSpd1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score += 40 if user.turnCount == 0 # Calm Mind tends to be popular
|
||||
score -= user.stages[:SPECIAL_ATTACK] * 10
|
||||
score -= user.stages[:SPECIAL_DEFENSE] * 10
|
||||
score -= user.stages[:SPEED] * 10
|
||||
if ai.trainer.medium_skill?
|
||||
hasSpecicalAttack = false
|
||||
user.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
|
||||
if ai.trainer.high_skill?
|
||||
aspeed = user.rough_stat(:SPEED)
|
||||
ospeed = target.rough_stat(:SPEED)
|
||||
score += 20 if aspeed < ospeed && aspeed * 2 > ospeed
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserSpAtkSpDefSpd1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserMainStats1")
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserMainStats1",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
GameData::Stat.each_main_battle { |s| score += 10 if user.stages[s.id] < 0 }
|
||||
if ai.trainer.medium_skill?
|
||||
hasDamagingAttack = false
|
||||
user.battler.eachMove do |m|
|
||||
next if !m.damagingMove?
|
||||
hasDamagingAttack = true
|
||||
break
|
||||
end
|
||||
score += 20 if hasDamagingAttack
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAtkSpAtk1",
|
||||
"RaiseUserMainStats1")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
@@ -1284,7 +830,7 @@ Battle::AI::Handlers::MoveFailureCheck.copy("LowerTargetDefense1",
|
||||
"LowerTargetDefense1PowersUpInGravity")
|
||||
Battle::AI::Handlers::MoveBasePower.add("LowerTargetDefense1PowersUpInGravity",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("LowerTargetDefense1PowersUpInGravity",
|
||||
@@ -1504,7 +1050,7 @@ Battle::AI::Handlers::MoveFailureCheck.copy("LowerTargetSpeed1",
|
||||
"LowerTargetSpeed1WeakerInGrassyTerrain")
|
||||
Battle::AI::Handlers::MoveBasePower.add("LowerTargetSpeed1WeakerInGrassyTerrain",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.copy("LowerTargetSpeed1",
|
||||
|
||||
@@ -425,7 +425,7 @@ Battle::AI::Handlers::MoveEffectScore.add("FlinchTargetFailsIfNotUserFirstTurn",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("FlinchTargetDoublePowerIfTargetInSky",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("FlinchTargetDoublePowerIfTargetInSky",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("FixedDamage20",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbFixedDamage(user.battler, target.battler)
|
||||
next move.move.pbFixedDamage(user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -12,7 +12,7 @@ Battle::AI::Handlers::MoveBasePower.add("FixedDamage20",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("FixedDamage40",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbFixedDamage(user.battler, target.battler)
|
||||
next move.move.pbFixedDamage(user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ Battle::AI::Handlers::MoveBasePower.add("FixedDamage40",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("FixedDamageHalfTargetHP",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbFixedDamage(user.battler, target.battler)
|
||||
next move.move.pbFixedDamage(user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -30,7 +30,7 @@ Battle::AI::Handlers::MoveBasePower.add("FixedDamageHalfTargetHP",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("FixedDamageUserLevel",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbFixedDamage(user.battler, target.battler)
|
||||
next move.move.pbFixedDamage(user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -53,7 +53,7 @@ Battle::AI::Handlers::MoveFailureCheck.add("LowerTargetHPToUserHP",
|
||||
)
|
||||
Battle::AI::Handlers::MoveBasePower.add("LowerTargetHPToUserHP",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbFixedDamage(user.battler, target.battler)
|
||||
next move.move.pbFixedDamage(user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -112,7 +112,7 @@ Battle::AI::Handlers::MoveEffectScore.add("DamageTargetAlly",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("PowerHigherWithUserHP",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -181,7 +181,7 @@ Battle::AI::Handlers::MoveBasePower.add("PowerHigherWithLessPP",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("PowerHigherWithTargetWeight",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -215,7 +215,7 @@ Battle::AI::Handlers::MoveBasePower.add("PowerHigherWithConsecutiveUseOnUserSide
|
||||
Battle::AI::Handlers::MoveBasePower.add("RandomPowerDoublePowerIfTargetUnderground",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
power = 71 # Average damage
|
||||
next move.pbModifyDamage(power, user.battler, target.battler)
|
||||
next move.move.pbModifyDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -224,7 +224,7 @@ Battle::AI::Handlers::MoveBasePower.add("RandomPowerDoublePowerIfTargetUndergrou
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("DoublePowerIfTargetHPLessThanHalf",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -251,7 +251,7 @@ Battle::AI::Handlers::MoveEffectScore.add("DoublePowerIfTargetAsleepCureTarget",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("DoublePowerIfTargetPoisoned",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -271,7 +271,7 @@ Battle::AI::Handlers::MoveEffectScore.add("DoublePowerIfTargetParalyzedCureTarge
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("DoublePowerIfTargetStatusProblem",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -289,7 +289,7 @@ Battle::AI::Handlers::MoveBasePower.add("DoublePowerIfUserHasNoItem",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("DoublePowerIfTargetUnderwater",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbModifyDamage(power, user.battler, target.battler)
|
||||
next move.move.pbModifyDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -304,7 +304,7 @@ Battle::AI::Handlers::MoveBasePower.copy("DoublePowerIfTargetUnderwater",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("DoublePowerIfTargetInSky",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -818,7 +818,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartNegateTargetEvasionStatStageAndD
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("TypeDependsOnUserIVs",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -834,8 +834,8 @@ Battle::AI::Handlers::MoveFailureCheck.add("TypeAndPowerDependOnUserBerry",
|
||||
)
|
||||
Battle::AI::Handlers::MoveBasePower.add("TypeAndPowerDependOnUserBerry",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
# TODO: Can't this just call move.pbBaseDamage?
|
||||
ret = move.pbNaturalGiftBaseDamage(user.item_id)
|
||||
# TODO: Can't this just call move.move.pbBaseDamage?
|
||||
ret = move.move.pbNaturalGiftBaseDamage(user.item_id)
|
||||
next (ret == 1) ? 0 : ret
|
||||
}
|
||||
)
|
||||
@@ -874,7 +874,7 @@ Battle::AI::Handlers::MoveEffectScore.add("TypeDependsOnUserMorpekoFormRaiseUser
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("TypeAndPowerDependOnWeather",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("HitTwoTimes",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next power * move.pbNumHits(user.battler, [target.battler])
|
||||
next power * move.move.pbNumHits(user.battler, [target.battler])
|
||||
}
|
||||
)
|
||||
|
||||
@@ -64,7 +64,7 @@ Battle::AI::Handlers::MoveBasePower.add("HitThreeTimesPowersUpWithEachHit",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("HitThreeTimesAlwaysCriticalHit",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next power * move.pbNumHits(user.battler, [target.battler])
|
||||
next power * move.move.pbNumHits(user.battler, [target.battler])
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("HitThreeTimesAlwaysCriticalHit",
|
||||
@@ -92,7 +92,7 @@ Battle::AI::Handlers::MoveBasePower.add("HitTwoToFiveTimes",
|
||||
Battle::AI::Handlers::MoveBasePower.add("HitTwoToFiveTimesOrThreeForAshGreninja",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
if user.battler.isSpecies?(:GRENINJA) && user.battler.form == 2
|
||||
next move.pbBaseDamage(power, user.battler, target.battler) * move.pbNumHits(user.battler, [target.battler])
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler) * move.move.pbNumHits(user.battler, [target.battler])
|
||||
end
|
||||
next power * 5 if user.has_active_ability?(:SKILLLINK)
|
||||
next power * 31 / 10 # Average damage dealt
|
||||
@@ -161,7 +161,7 @@ Battle::AI::Handlers::MoveBasePower.add("HitOncePerUserTeamMember",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("TwoTurnAttackOneTurnInSun",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamageMultiplier(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamageMultiplier(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -338,7 +338,7 @@ Battle::AI::Handlers::MoveFailureCheck.add("TwoTurnAttackInvulnerableInSkyTarget
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("MultiTurnAttackPowersUpEachTurn",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next power * 2 if user.effects[PBEffects::DefenseCurl]
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ Battle::AI::Handlers::MoveEffectScore.add("RestoreUserConsumedItem",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("RemoveTargetItem",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RemoveTargetItem",
|
||||
@@ -260,6 +260,6 @@ Battle::AI::Handlers::MoveFailureCheck.add("ThrowUserItemAtTarget",
|
||||
)
|
||||
Battle::AI::Handlers::MoveBasePower.add("ThrowUserItemAtTarget",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -110,7 +110,7 @@ Battle::AI::Handlers::MoveEffectScore.add("CurseTargetOrLowerUserSpd1RaiseUserAt
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("HitsAllFoesAndPowersUpInPsychicTerrain",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("HitsAllFoesAndPowersUpInPsychicTerrain",
|
||||
@@ -261,7 +261,7 @@ Battle::AI::Handlers::MoveFailureCheck.add("PowerDependsOnUserStockpile",
|
||||
)
|
||||
Battle::AI::Handlers::MoveBasePower.add("PowerDependsOnUserStockpile",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbBaseDamage(power, user.battler, target.battler)
|
||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ Battle::AI::Handlers::MoveEffectScore.add("BindTarget",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.add("BindTargetDoublePowerIfTargetUnderwater",
|
||||
proc { |power, move, user, target, ai, battle|
|
||||
next move.pbModifyDamage(power, user.battler, target.battler)
|
||||
next move.move.pbModifyDamage(power, user.battler, target.battler)
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("BindTargetDoublePowerIfTargetUnderwater",
|
||||
|
||||
@@ -24,7 +24,8 @@ class Battle::AI::AIBattler
|
||||
|
||||
def level; return @battler.level; end
|
||||
def hp; return @battler.hp; end
|
||||
def status; return @Battler.status; end
|
||||
def fainted?; return @battler.fainted?; end
|
||||
def status; return @battler.status; end
|
||||
def statusCount; return @battler.statusCount; end
|
||||
def totalhp; return @battler.totalhp; end
|
||||
def gender; return @battler.gender; end
|
||||
@@ -57,12 +58,103 @@ class Battle::AI::AIBattler
|
||||
|
||||
#=============================================================================
|
||||
|
||||
def check_for_move
|
||||
ret = false
|
||||
@battler.eachMove do |move|
|
||||
next unless yield move
|
||||
ret = true
|
||||
break
|
||||
# Returns how much damage this battler will take at the end of this round.
|
||||
def rough_end_of_round_damage
|
||||
ret = 0
|
||||
# Future Sight/Doom Desire
|
||||
# TODO
|
||||
# Wish
|
||||
if @ai.battle.positions[@index].effects[PBEffects::Wish] == 1 && @battler.canHeal?
|
||||
ret -= @ai.battle.positions[@index].effects[PBEffects::WishAmount]
|
||||
end
|
||||
# Sea of Fire
|
||||
if @ai.battle.sides[@side].effects[PBEffects::SeaOfFire] > 1 &&
|
||||
@battler.takesIndirectDamage? && !has_type?(:FIRE)
|
||||
ret += self.totalhp / 8
|
||||
end
|
||||
# Grassy Terrain (healing)
|
||||
if @ai.battle.field.terrain == :Grassy && @battler.affectedByTerrain? && @battler.canHeal?
|
||||
ret -= [battler.totalhp / 16, 1].max
|
||||
end
|
||||
# Leftovers/Black Sludge
|
||||
if has_active_item?(:BLACKSLUDGE)
|
||||
if has_type?(:POISON)
|
||||
ret -= [battler.totalhp / 16, 1].max if @battler.canHeal?
|
||||
else
|
||||
ret += [battler.totalhp / 8, 1].max if @battler.takesIndirectDamage?
|
||||
end
|
||||
elsif has_active_item?(:LEFTOVERS)
|
||||
ret -= [battler.totalhp / 16, 1].max if @battler.canHeal?
|
||||
end
|
||||
# Aqua Ring
|
||||
if self.effects[PBEffects::AquaRing] && @battler.canHeal?
|
||||
amt = battler.totalhp / 16
|
||||
amt = (amt * 1.3).floor if has_active_item?(:BIGROOT)
|
||||
ret -= [amt, 1].max
|
||||
end
|
||||
# Ingrain
|
||||
if self.effects[PBEffects::Ingrain] && @battler.canHeal?
|
||||
amt = battler.totalhp / 16
|
||||
amt = (amt * 1.3).floor if has_active_item?(:BIGROOT)
|
||||
ret -= [amt, 1].max
|
||||
end
|
||||
# Leech Seed
|
||||
if self.effects[PBEffects::LeechSeed] >= 0
|
||||
if @battler.takesIndirectDamage?
|
||||
ret += [battler.totalhp / 8, 1].max if @battler.takesIndirectDamage?
|
||||
end
|
||||
else
|
||||
@ai.each_battler do |b, i|
|
||||
next if i == @index || b.effects[PBEffects::LeechSeed] != @index
|
||||
amt = [[b.totalhp / 8, b.hp].min, 1].max
|
||||
amt = (amt * 1.3).floor if has_active_item?(:BIGROOT)
|
||||
ret -= [amt, 1].max
|
||||
end
|
||||
end
|
||||
# Hyper Mode (Shadow Pokémon)
|
||||
# TODO
|
||||
# Poison/burn/Nightmare
|
||||
if self.status == :POISON
|
||||
if has_active_ability?(:POISONHEAL)
|
||||
ret -= [battler.totalhp / 8, 1].max if @battler.canHeal?
|
||||
elsif @battler.takesIndirectDamage?
|
||||
mult = 2
|
||||
mult = [self.effects[PBEffects::Toxic] + 1, 16].min if self.statusCount > 0 # Toxic
|
||||
ret += [mult * battler.totalhp / 16, 1].max
|
||||
end
|
||||
elsif self.status == :BURN
|
||||
if @battler.takesIndirectDamage?
|
||||
amt = (Settings::MECHANICS_GENERATION >= 7) ? self.totalhp / 16 : self.totalhp / 8
|
||||
amt = (amt / 2.0).round if has_active_ability?(:HEATPROOF)
|
||||
ret += [amt, 1].max
|
||||
end
|
||||
elsif @battler.asleep? && self.statusCount > 1 && self.effects[PBEffects::Nightmare]
|
||||
ret += [battler.totalhp / 4, 1].max if @battler.takesIndirectDamage?
|
||||
end
|
||||
# Curse
|
||||
if self.effects[PBEffects::Curse]
|
||||
ret += [battler.totalhp / 4, 1].max if @battler.takesIndirectDamage?
|
||||
end
|
||||
# Trapping damage
|
||||
if self.effects[PBEffects::Trapping] > 1 && @battler.takesIndirectDamage?
|
||||
amt = (Settings::MECHANICS_GENERATION >= 6) ? self.totalhp / 8 : self.totalhp / 16
|
||||
if @battlers[self.effects[PBEffects::TrappingUser]].has_active_item?(:BINDINGBAND)
|
||||
amt = (Settings::MECHANICS_GENERATION >= 6) ? self.totalhp / 6 : self.totalhp / 8
|
||||
end
|
||||
ret += [amt, 1].max
|
||||
end
|
||||
# Perish Song
|
||||
# TODO
|
||||
# Bad Dreams
|
||||
if @battler.asleep? && self.statusCount > 1 && @battler.takesIndirectDamage?
|
||||
@ai.each_battler do |b, i|
|
||||
next if i == @index || !b.battler.near?(@battler) || !b.has_active_ability?(:BADDREAMS)
|
||||
ret += [battler.totalhp / 8, 1].max
|
||||
end
|
||||
end
|
||||
# Sticky Barb
|
||||
if has_active_item?(:STICKYBARB) && @battler.takesIndirectDamage?
|
||||
ret += [battler.totalhp / 8, 1].max
|
||||
end
|
||||
return ret
|
||||
end
|
||||
@@ -163,16 +255,16 @@ class Battle::AI::AIBattler
|
||||
|
||||
#=============================================================================
|
||||
|
||||
def can_switch_lax?
|
||||
return false if wild?
|
||||
@ai.battle.eachInTeamFromBattlerIndex(@index) do |pkmn, i|
|
||||
return true if @ai.battle.pbCanSwitchLax?(@index, i)
|
||||
def check_for_move
|
||||
ret = false
|
||||
@battler.eachMove do |move|
|
||||
next unless yield move
|
||||
ret = true
|
||||
break
|
||||
end
|
||||
return false
|
||||
return ret
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
|
||||
def immune_to_move?
|
||||
user = @ai.user
|
||||
user_battler = user.battler
|
||||
@@ -226,6 +318,16 @@ class Battle::AI::AIBattler
|
||||
|
||||
#=============================================================================
|
||||
|
||||
def can_switch_lax?
|
||||
return false if wild?
|
||||
@ai.battle.eachInTeamFromBattlerIndex(@index) do |pkmn, i|
|
||||
return true if @ai.battle.pbCanSwitchLax?(@index, i)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
|
||||
private
|
||||
|
||||
def effectiveness_of_type_against_single_battler_type(type, defend_type, user = nil)
|
||||
|
||||
@@ -1207,7 +1207,7 @@ Battle::AbilityEffects::DamageCalcFromUser.add(:ANALYTIC,
|
||||
# are being used), so I'm choosing to ignore it. The effect is thus:
|
||||
# "power up the move if all other battlers on the field right now have
|
||||
# already moved".
|
||||
if move.pbMoveFailedLastInRound?(user, false)
|
||||
if move.move.pbMoveFailedLastInRound?(user, false)
|
||||
mults[:base_damage_multiplier] *= 1.3
|
||||
end
|
||||
}
|
||||
@@ -1528,7 +1528,7 @@ Battle::AbilityEffects::DamageCalcFromTarget.add(:FLOWERGIFT,
|
||||
Battle::AbilityEffects::DamageCalcFromTarget.add(:FLUFFY,
|
||||
proc { |ability, user, target, move, mults, baseDmg, type|
|
||||
mults[:final_damage_multiplier] *= 2 if move.calcType == :FIRE
|
||||
mults[:final_damage_multiplier] /= 2 if move.pbContactMove?(user)
|
||||
mults[:final_damage_multiplier] /= 2 if move.move.pbContactMove?(user)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -540,7 +540,7 @@ class Pokemon
|
||||
# @return [Boolean] whether this Pokémon has a particular nature or a nature
|
||||
# at all
|
||||
def hasNature?(check_nature = nil)
|
||||
return !@nature_id.nil? if check_nature.nil?
|
||||
return !@nature.nil? if check_nature.nil?
|
||||
return self.nature == check_nature
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user