mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-10 06:34:59 +00:00
More AI move effect calculation rewrites
This commit is contained in:
@@ -747,6 +747,7 @@ class Battle
|
|||||||
battler.lastHPLostFromFoe = 0
|
battler.lastHPLostFromFoe = 0
|
||||||
battler.droppedBelowHalfHP = false
|
battler.droppedBelowHalfHP = false
|
||||||
battler.statsDropped = false
|
battler.statsDropped = false
|
||||||
|
battler.tookMoveDamageThisRound = false
|
||||||
battler.tookDamageThisRound = false
|
battler.tookDamageThisRound = false
|
||||||
battler.tookPhysicalHit = false
|
battler.tookPhysicalHit = false
|
||||||
battler.statsRaisedThisRound = false
|
battler.statsRaisedThisRound = false
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ class Battle::Battler
|
|||||||
attr_accessor :currentMove # ID of multi-turn move currently being used
|
attr_accessor :currentMove # ID of multi-turn move currently being used
|
||||||
attr_accessor :droppedBelowHalfHP # Used for Emergency Exit/Wimp Out
|
attr_accessor :droppedBelowHalfHP # Used for Emergency Exit/Wimp Out
|
||||||
attr_accessor :statsDropped # Used for Eject Pack
|
attr_accessor :statsDropped # Used for Eject Pack
|
||||||
|
attr_accessor :tookMoveDamageThisRound # Boolean for Focus Punch
|
||||||
attr_accessor :tookDamageThisRound # Boolean for whether self took damage this round
|
attr_accessor :tookDamageThisRound # Boolean for whether self took damage this round
|
||||||
attr_accessor :tookPhysicalHit
|
attr_accessor :tookPhysicalHit
|
||||||
attr_accessor :statsRaisedThisRound # Boolean for whether self's stat(s) raised this round
|
attr_accessor :statsRaisedThisRound # Boolean for whether self's stat(s) raised this round
|
||||||
|
|||||||
@@ -125,27 +125,28 @@ class Battle::Battler
|
|||||||
@effects[PBEffects::Substitute] = 0
|
@effects[PBEffects::Substitute] = 0
|
||||||
@effects[PBEffects::Telekinesis] = 0
|
@effects[PBEffects::Telekinesis] = 0
|
||||||
end
|
end
|
||||||
@fainted = (@hp == 0)
|
@fainted = (@hp == 0)
|
||||||
@lastAttacker = []
|
@lastAttacker = []
|
||||||
@lastFoeAttacker = []
|
@lastFoeAttacker = []
|
||||||
@lastHPLost = 0
|
@lastHPLost = 0
|
||||||
@lastHPLostFromFoe = 0
|
@lastHPLostFromFoe = 0
|
||||||
@droppedBelowHalfHP = false
|
@droppedBelowHalfHP = false
|
||||||
@statsDropped = false
|
@statsDropped = false
|
||||||
@tookDamageThisRound = false
|
@tookMoveDamageThisRound = false
|
||||||
@tookPhysicalHit = false
|
@tookDamageThisRound = false
|
||||||
@statsRaisedThisRound = false
|
@tookPhysicalHit = false
|
||||||
@statsLoweredThisRound = false
|
@statsRaisedThisRound = false
|
||||||
@canRestoreIceFace = false
|
@statsLoweredThisRound = false
|
||||||
@lastMoveUsed = nil
|
@canRestoreIceFace = false
|
||||||
@lastMoveUsedType = nil
|
@lastMoveUsed = nil
|
||||||
@lastRegularMoveUsed = nil
|
@lastMoveUsedType = nil
|
||||||
@lastRegularMoveTarget = -1
|
@lastRegularMoveUsed = nil
|
||||||
@lastRoundMoved = -1
|
@lastRegularMoveTarget = -1
|
||||||
@lastMoveFailed = false
|
@lastRoundMoved = -1
|
||||||
@lastRoundMoveFailed = false
|
@lastMoveFailed = false
|
||||||
@movesUsed = []
|
@lastRoundMoveFailed = false
|
||||||
@turnCount = 0
|
@movesUsed = []
|
||||||
|
@turnCount = 0
|
||||||
@effects[PBEffects::Attract] = -1
|
@effects[PBEffects::Attract] = -1
|
||||||
@battle.allBattlers.each do |b| # Other battlers no longer attracted to self
|
@battle.allBattlers.each do |b| # Other battlers no longer attracted to self
|
||||||
b.effects[PBEffects::Attract] = -1 if b.effects[PBEffects::Attract] == @index
|
b.effects[PBEffects::Attract] = -1 if b.effects[PBEffects::Attract] == @index
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class Battle::Battler
|
|||||||
if amt > 0 && registerDamage
|
if amt > 0 && registerDamage
|
||||||
@droppedBelowHalfHP = true if @hp < @totalhp / 2 && @hp + amt >= @totalhp / 2
|
@droppedBelowHalfHP = true if @hp < @totalhp / 2 && @hp + amt >= @totalhp / 2
|
||||||
@tookDamageThisRound = true
|
@tookDamageThisRound = true
|
||||||
|
@tookMoveDamageThisRound = true
|
||||||
end
|
end
|
||||||
return amt
|
return amt
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -383,7 +383,8 @@ class Battle::Move
|
|||||||
target.effects[PBEffects::BideTarget] = user.index
|
target.effects[PBEffects::BideTarget] = user.index
|
||||||
end
|
end
|
||||||
target.damageState.fainted = true if target.fainted?
|
target.damageState.fainted = true if target.fainted?
|
||||||
target.lastHPLost = damage # For Focus Punch
|
target.lastHPLost = damage
|
||||||
|
target.tookMoveDamageThisRound = true if damage > 0 && !target.damageState.substitute # For Focus Punch
|
||||||
target.tookDamageThisRound = true if damage > 0 # For Assurance
|
target.tookDamageThisRound = true if damage > 0 # For Assurance
|
||||||
target.lastAttacker.push(user.index) # For Revenge
|
target.lastAttacker.push(user.index) # For Revenge
|
||||||
if target.opposes?(user)
|
if target.opposes?(user)
|
||||||
|
|||||||
@@ -174,11 +174,11 @@ class Battle::Move::FailsIfUserDamagedThisTurn < Battle::Move
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pbDisplayUseMessage(user)
|
def pbDisplayUseMessage(user)
|
||||||
super if !user.effects[PBEffects::FocusPunch] || user.lastHPLost == 0
|
super if !user.effects[PBEffects::FocusPunch] || !user.tookMoveDamageThisRound
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbMoveFailed?(user, targets)
|
def pbMoveFailed?(user, targets)
|
||||||
if user.effects[PBEffects::FocusPunch] && user.lastHPLost > 0
|
if user.effects[PBEffects::FocusPunch] && user.tookMoveDamageThisRound
|
||||||
@battle.pbDisplay(_INTL("{1} lost its focus and couldn't move!", user.pbThis))
|
@battle.pbDisplay(_INTL("{1} lost its focus and couldn't move!", user.pbThis))
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@@ -187,7 +187,7 @@ class Battle::Move::FailsIfUserDamagedThisTurn < Battle::Move
|
|||||||
end
|
end
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# Fails if the target didn't chose a damaging move to use this round, or has
|
# Fails if the target didn't choose a damaging move to use this round, or has
|
||||||
# already moved. (Sucker Punch)
|
# already moved. (Sucker Punch)
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class Battle::Move::FailsIfTargetActed < Battle::Move
|
class Battle::Move::FailsIfTargetActed < Battle::Move
|
||||||
|
|||||||
@@ -1,25 +1,24 @@
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# Struggle
|
# Struggle
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# None
|
# None
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("DoesNothingCongratulations",
|
Battle::AI::Handlers::MoveEffectScore.add("DoesNothingCongratulations",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next 0 if ai.trainer.high_skill?
|
next score - 60
|
||||||
next score - 95
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("DoesNothingFailsIfNoAlly",
|
Battle::AI::Handlers::MoveFailureCheck.add("DoesNothingFailsIfNoAlly",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -30,33 +29,38 @@ Battle::AI::Handlers::MoveEffectScore.copy("DoesNothingCongratulations",
|
|||||||
"DoesNothingFailsIfNoAlly")
|
"DoesNothingFailsIfNoAlly")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.copy("DoesNothingCongratulations",
|
Battle::AI::Handlers::MoveEffectScore.copy("DoesNothingCongratulations",
|
||||||
"DoesNothingUnusableInGravity")
|
"DoesNothingUnusableInGravity")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
|
#===============================================================================
|
||||||
|
# AddMoneyGainedFromBattle
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.copy("DoesNothingCongratulations",
|
Battle::AI::Handlers::MoveEffectScore.copy("DoesNothingCongratulations",
|
||||||
"DoubleMoneyGainedFromBattle")
|
"DoubleMoneyGainedFromBattle")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
|
||||||
# AddMoneyGainedFromBattle
|
|
||||||
|
|
||||||
#===============================================================================
|
|
||||||
# TODO: Review score modifiers.
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("FailsIfNotUserFirstTurn",
|
Battle::AI::Handlers::MoveFailureCheck.add("FailsIfNotUserFirstTurn",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if user.turnCount > 0
|
next true if user.turnCount > 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Battle::AI::Handlers::MoveEffectScore.add("FailsIfNotUserFirstTurn",
|
||||||
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
next score + 25 # Use it or lose it
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("FailsIfUserHasUnusedMove",
|
Battle::AI::Handlers::MoveFailureCheck.add("FailsIfUserHasUnusedMove",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -74,7 +78,7 @@ Battle::AI::Handlers::MoveFailureCheck.add("FailsIfUserHasUnusedMove",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("FailsIfUserNotConsumedBerry",
|
Battle::AI::Handlers::MoveFailureCheck.add("FailsIfUserNotConsumedBerry",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -83,58 +87,92 @@ Battle::AI::Handlers::MoveFailureCheck.add("FailsIfUserNotConsumedBerry",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("FailsIfTargetHasNoItem",
|
Battle::AI::Handlers::MoveFailureCheck.add("FailsIfTargetHasNoItem",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if !target.item || !target.item_active?
|
next true if !target.item || !target.item_active?
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("FailsIfTargetHasNoItem",
|
|
||||||
proc { |score, move, user, target, ai, battle|
|
|
||||||
next score + 50 if ai.trainer.medium_skill?
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("FailsUnlessTargetSharesTypeWithUser",
|
Battle::AI::Handlers::MoveFailureCheck.add("FailsUnlessTargetSharesTypeWithUser",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
user_types = user.battler.pbTypes(true)
|
user_types = user.pbTypes(true)
|
||||||
target_types = target.battler.pbTypes(true)
|
target_types = target.pbTypes(true)
|
||||||
next true if (user_types & target_types).empty?
|
next true if (user_types & target_types).empty?
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("FailsIfUserDamagedThisTurn",
|
Battle::AI::Handlers::MoveEffectScore.add("FailsIfUserDamagedThisTurn",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
score += 50 if target.effects[PBEffects::HyperBeam] > 0
|
# Check whether user is faster than its foe(s) and could use this move
|
||||||
score -= 35 if target.hp <= target.totalhp / 2 # If target is weak, no
|
user_faster_count = 0
|
||||||
score -= 70 if target.hp <= target.totalhp / 4 # need to risk this move
|
foe_faster_count = 0
|
||||||
|
ai.battlers.each_with_index do |b, i|
|
||||||
|
next if !user.opposes?(b) || b.battler.fainted?
|
||||||
|
if user.faster_than?(b)
|
||||||
|
user_faster_count += 1
|
||||||
|
else
|
||||||
|
foe_faster_count += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
next score - 40 if user_faster_count == 0
|
||||||
|
score += 10 if foe_faster_count == 0
|
||||||
|
# Effects that make the target unlikely to act before the user
|
||||||
|
if ai.trainer.high_skill?
|
||||||
|
if target.effects[PBEffects::HyperBeam] > 0 ||
|
||||||
|
target.effects[PBEffects::Truant] ||
|
||||||
|
(target.battler.asleep? && target.statusCount > 1) ||
|
||||||
|
target.frozen?
|
||||||
|
score += 20
|
||||||
|
elsif target.effects[PBEffects::Confusion] > 1 ||
|
||||||
|
target.effects[PBEffects::Attract] == user.index
|
||||||
|
score += 10
|
||||||
|
elsif target.paralyzed?
|
||||||
|
score += 5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Don't risk using this move if target is weak
|
||||||
|
score -= 10 if target.hp <= target.totalhp / 2
|
||||||
|
score -= 10 if target.hp <= target.totalhp / 4
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# FailsIfTargetActed
|
Battle::AI::Handlers::MoveEffectScore.add("FailsIfTargetActed",
|
||||||
|
|
||||||
#===============================================================================
|
|
||||||
# TODO: Review score modifiers.
|
|
||||||
#===============================================================================
|
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("CrashDamageIfFailsUnusableInGravity",
|
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next score + 10 * (user.stages[:ACCURACY] - target.stages[:EVASION])
|
# Check whether user is faster than its foe(s) and could use this move
|
||||||
|
next score - 40 if target.faster_than?(user)
|
||||||
|
score += 10
|
||||||
|
# TODO: Predict the target switching/using an item.
|
||||||
|
# TODO: Predict the target using a damaging move or Me First.
|
||||||
|
# Don't risk using this move if target is weak
|
||||||
|
score -= 10 if target.hp <= target.totalhp / 2
|
||||||
|
score -= 10 if target.hp <= target.totalhp / 4
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
|
#===============================================================================
|
||||||
|
Battle::AI::Handlers::MoveEffectScore.add("CrashDamageIfFailsUnusableInGravity",
|
||||||
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
next score - (100 - move.rough_accuracy) if user.takesIndirectDamage?
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("StartSunWeather",
|
Battle::AI::Handlers::MoveFailureCheck.add("StartSunWeather",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -144,64 +182,166 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartSunWeather",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("StartSunWeather",
|
Battle::AI::Handlers::MoveEffectScore.add("StartSunWeather",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
next score - 40 if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
||||||
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
||||||
next score - 50
|
score += 10 if battle.field.weather != :None # Prefer replacing another weather
|
||||||
else
|
score += 15 if user.has_active_item?(:HEATROCK)
|
||||||
user.battler.eachMove do |m|
|
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||||
next if !m.damagingMove? || m.type != :FIRE
|
# Check for Fire/Water moves
|
||||||
score += 20
|
ai.battlers.each do |b|
|
||||||
|
next if !b || b.battler.fainted?
|
||||||
|
if b.check_for_move { |move| move.type == :FIRE && move.damagingMove? }
|
||||||
|
score += (b.opposes?(user)) ? -15 : 15
|
||||||
|
end
|
||||||
|
if b.check_for_move { |move| move.type == :WATER && move.damagingMove? }
|
||||||
|
score += (b.opposes?(user)) ? 15 : -15
|
||||||
end
|
end
|
||||||
next score
|
|
||||||
end
|
end
|
||||||
|
# TODO: Check for freezing moves.
|
||||||
|
# Check for abilities/other moves affected by sun
|
||||||
|
# TODO: Check other battlers for these as well?
|
||||||
|
if ai.trainer.medium_skill? && !user.has_active_item?(:UTILITYUMBRELLA)
|
||||||
|
if user.has_active_ability?([:CHLOROPHYLL, :FLOWERGIFT, :FORECAST, :HARVEST, :LEAFGUARD, :SOLARPOWER])
|
||||||
|
score += 15
|
||||||
|
elsif user.has_active_ability?(:DRYSKIN)
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
if user.check_for_move { |move| ["HealUserDependingOnWeather",
|
||||||
|
"RaiseUserAtkSpAtk1Or2InSun",
|
||||||
|
"TwoTurnAttackOneTurnInSun",
|
||||||
|
"TypeAndPowerDependOnWeather"].include?(move.function) }
|
||||||
|
score += 10
|
||||||
|
end
|
||||||
|
if user.check_for_move { |move| ["ConfuseTargetAlwaysHitsInRainHitsTargetInSky",
|
||||||
|
"ParalyzeTargetAlwaysHitsInRainHitsTargetInSky"].include?(move.function) }
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
end
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.copy("StartSunWeather",
|
Battle::AI::Handlers::MoveFailureCheck.copy("StartSunWeather",
|
||||||
"StartRainWeather")
|
"StartRainWeather")
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("StartRainWeather",
|
Battle::AI::Handlers::MoveEffectScore.add("StartRainWeather",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
next score - 40 if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
||||||
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
||||||
next score - 50
|
score += 10 if battle.field.weather != :None # Prefer replacing another weather
|
||||||
else
|
score += 15 if user.has_active_item?(:DAMPROCK)
|
||||||
user.battler.eachMove do |m|
|
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||||
next if !m.damagingMove? || m.type != :WATER
|
# Check for Fire/Water moves
|
||||||
score += 20
|
ai.battlers.each do |b|
|
||||||
|
next if !b || b.battler.fainted?
|
||||||
|
if b.check_for_move { |move| move.type == :WATER && move.damagingMove? }
|
||||||
|
score += (b.opposes?(user)) ? -15 : 15
|
||||||
|
end
|
||||||
|
if b.check_for_move { |move| move.type == :FIRE && move.damagingMove? }
|
||||||
|
score += (b.opposes?(user)) ? 15 : -15
|
||||||
end
|
end
|
||||||
next score
|
|
||||||
end
|
end
|
||||||
|
# Check for abilities/other moves affected by rain
|
||||||
|
# TODO: Check other battlers for these as well?
|
||||||
|
if ai.trainer.medium_skill? && !user.has_active_item?(:UTILITYUMBRELLA)
|
||||||
|
if user.has_active_ability?([:DRYSKIN, :FORECAST, :HYDRATION, :RAINDISH, :SWIFTSWIM])
|
||||||
|
score += 15
|
||||||
|
end
|
||||||
|
if user.check_for_move { |move| ["ConfuseTargetAlwaysHitsInRainHitsTargetInSky",
|
||||||
|
"ParalyzeTargetAlwaysHitsInRainHitsTargetInSky",
|
||||||
|
"TypeAndPowerDependOnWeather"].include?(move.function) }
|
||||||
|
score += 10
|
||||||
|
end
|
||||||
|
if user.check_for_move { |move| ["HealUserDependingOnWeather",
|
||||||
|
"TwoTurnAttackOneTurnInSun"].include?(move.function) }
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
end
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.copy("StartSunWeather",
|
Battle::AI::Handlers::MoveFailureCheck.copy("StartSunWeather",
|
||||||
"StartSandstormWeather")
|
"StartSandstormWeather")
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("StartSandstormWeather",
|
Battle::AI::Handlers::MoveEffectScore.add("StartSandstormWeather",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
next score - 40 if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
||||||
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
||||||
next score - 50
|
score += 10 if battle.field.weather != :None # Prefer replacing another weather
|
||||||
|
score += 15 if user.has_active_item?(:SMOOTHROCK)
|
||||||
|
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||||
|
# Check for battlers affected by sandstorm's effects
|
||||||
|
ai.battlers.each do |b|
|
||||||
|
next if !b || b.battler.fainted?
|
||||||
|
if b.battler.takesSandstormDamage? # End of round damage
|
||||||
|
score += (b.opposes?(user)) ? 15 : -15
|
||||||
|
end
|
||||||
|
if b.has_type?(:ROCK) # +SpDef for Rock types
|
||||||
|
score += (b.opposes?(user)) ? -15 : 15
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
# Check for abilities/moves affected by sandstorm
|
||||||
|
# TODO: Check other battlers for these as well?
|
||||||
|
if ai.trainer.medium_skill? && !user.has_active_item?(:UTILITYUMBRELLA)
|
||||||
|
if user.has_active_ability?([:SANDFORCE, :SANDRUSH, :SANDVEIL])
|
||||||
|
score += 15
|
||||||
|
end
|
||||||
|
if user.check_for_move { |move| ["HealUserDependingOnSandstorm",
|
||||||
|
"TypeAndPowerDependOnWeather"].include?(move.function) }
|
||||||
|
score += 10
|
||||||
|
end
|
||||||
|
if user.check_for_move { |move| ["HealUserDependingOnWeather",
|
||||||
|
"TwoTurnAttackOneTurnInSun"].include?(move.function) }
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
end
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.copy("StartSunWeather",
|
Battle::AI::Handlers::MoveFailureCheck.copy("StartSunWeather",
|
||||||
"StartHailWeather")
|
"StartHailWeather")
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("StartHailWeather",
|
Battle::AI::Handlers::MoveEffectScore.add("StartHailWeather",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
next score - 40 if battle.pbCheckGlobalAbility(:AIRLOCK) ||
|
||||||
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
battle.pbCheckGlobalAbility(:CLOUDNINE)
|
||||||
next score - 50
|
score += 10 if battle.field.weather != :None # Prefer replacing another weather
|
||||||
|
score += 15 if user.has_active_item?(:ICYROCK)
|
||||||
|
score -= 10 if user.hp < user.totalhp / 2 # Not worth it at lower HP
|
||||||
|
# Check for battlers affected by hail's effects
|
||||||
|
ai.battlers.each do |b|
|
||||||
|
next if !b || b.battler.fainted?
|
||||||
|
if b.battler.takesHailDamage? # End of round damage
|
||||||
|
score += (b.opposes?(user)) ? 15 : -15
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
# Check for abilities/moves affected by hail
|
||||||
|
# TODO: Check other battlers for these as well?
|
||||||
|
if ai.trainer.medium_skill? && !user.has_active_item?(:UTILITYUMBRELLA)
|
||||||
|
if user.has_active_ability?([:FORECAST, :ICEBODY, :SLUSHRUSH, :SNOWCLOAK])
|
||||||
|
score += 15
|
||||||
|
elsif user.ability == :ICEFACE
|
||||||
|
score += 15
|
||||||
|
end
|
||||||
|
if user.check_for_move { |move| ["FreezeTargetAlwaysHitsInHail",
|
||||||
|
"StartWeakenDamageAgainstUserSideIfHail",
|
||||||
|
"TypeAndPowerDependOnWeather"].include?(move.function) }
|
||||||
|
score += 10
|
||||||
|
end
|
||||||
|
if user.check_for_move { |move| ["HealUserDependingOnWeather",
|
||||||
|
"TwoTurnAttackOneTurnInSun"].include?(move.function) }
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
end
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -91,9 +91,12 @@ class Battle::AI::AIBattler
|
|||||||
#=============================================================================
|
#=============================================================================
|
||||||
|
|
||||||
def types; return @battler.types; end
|
def types; return @battler.types; end
|
||||||
|
def pbTypes(withType3 = false); return @battler.pbTypes(withType3); end
|
||||||
|
|
||||||
def has_type?(type)
|
def has_type?(type)
|
||||||
return @battler.pbHasType?(type)
|
return false if !type
|
||||||
|
active_types = pbTypes(true)
|
||||||
|
return active_types.include?(GameData::Type.get(type).id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def effectiveness_of_type_against_battler(type, user = nil)
|
def effectiveness_of_type_against_battler(type, user = nil)
|
||||||
@@ -131,10 +134,10 @@ class Battle::AI::AIBattler
|
|||||||
return @battler.abilityActive?
|
return @battler.abilityActive?
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_active_ability?(ability, check_mold_breaker = false)
|
def has_active_ability?(ability, ignore_fainted = false)
|
||||||
# Only a high skill AI knows what an opponent's ability is
|
# Only a high skill AI knows what an opponent's ability is
|
||||||
# return false if @ai.trainer.side != @side && !@ai.trainer.high_skill?
|
# return false if @ai.trainer.side != @side && !@ai.trainer.high_skill?
|
||||||
return @battler.hasActiveAbility?(ability)
|
return @battler.hasActiveAbility?(ability, ignore_fainted)
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_mold_breaker?
|
def has_mold_breaker?
|
||||||
|
|||||||
Reference in New Issue
Block a user