mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-09 22:24:58 +00:00
Some more AI function code rewrites
This commit is contained in:
@@ -138,8 +138,16 @@ end
|
|||||||
# user's Attack and Defense by 1 stage each. (Curse)
|
# user's Attack and Defense by 1 stage each. (Curse)
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class Battle::Move::CurseTargetOrLowerUserSpd1RaiseUserAtkDef1 < Battle::Move
|
class Battle::Move::CurseTargetOrLowerUserSpd1RaiseUserAtkDef1 < Battle::Move
|
||||||
|
attr_reader :statUp, :statDown
|
||||||
|
|
||||||
def ignoresSubstitute?(user); return true; end
|
def ignoresSubstitute?(user); return true; end
|
||||||
|
|
||||||
|
def initialize(battle, move)
|
||||||
|
super
|
||||||
|
@statUp = [:ATTACK, 1, :DEFENSE, 1]
|
||||||
|
@statDown = [:SPEED, 1]
|
||||||
|
end
|
||||||
|
|
||||||
def pbTarget(user)
|
def pbTarget(user)
|
||||||
if user.pbHasType?(:GHOST)
|
if user.pbHasType?(:GHOST)
|
||||||
ghost_target = (Settings::MECHANICS_GENERATION >= 8) ? :RandomNearFoe : :NearFoe
|
ghost_target = (Settings::MECHANICS_GENERATION >= 8) ? :RandomNearFoe : :NearFoe
|
||||||
@@ -150,9 +158,18 @@ class Battle::Move::CurseTargetOrLowerUserSpd1RaiseUserAtkDef1 < Battle::Move
|
|||||||
|
|
||||||
def pbMoveFailed?(user, targets)
|
def pbMoveFailed?(user, targets)
|
||||||
return false if user.pbHasType?(:GHOST)
|
return false if user.pbHasType?(:GHOST)
|
||||||
if !user.pbCanLowerStatStage?(:SPEED, user, self) &&
|
failed = true
|
||||||
!user.pbCanRaiseStatStage?(:ATTACK, user, self) &&
|
(@statUp.length / 2).times do |i|
|
||||||
!user.pbCanRaiseStatStage?(:DEFENSE, user, self)
|
next if !user.pbCanRaiseStatStage?(@statUp[i * 2], user, self)
|
||||||
|
failed = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
(@statDown.length / 2).times do |i|
|
||||||
|
next if !user.pbCanLowerStatStage?(@statDown[i * 2], user, self)
|
||||||
|
failed = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if failed
|
||||||
@battle.pbDisplay(_INTL("But it failed!"))
|
@battle.pbDisplay(_INTL("But it failed!"))
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@@ -170,15 +187,19 @@ class Battle::Move::CurseTargetOrLowerUserSpd1RaiseUserAtkDef1 < Battle::Move
|
|||||||
def pbEffectGeneral(user)
|
def pbEffectGeneral(user)
|
||||||
return if user.pbHasType?(:GHOST)
|
return if user.pbHasType?(:GHOST)
|
||||||
# Non-Ghost effect
|
# Non-Ghost effect
|
||||||
if user.pbCanLowerStatStage?(:SPEED, user, self)
|
showAnim = true
|
||||||
user.pbLowerStatStage(:SPEED, 1, user)
|
(@statDown.length / 2).times do |i|
|
||||||
|
next if !user.pbCanLowerStatStage?(@statDown[i * 2], user, self)
|
||||||
|
if user.pbLowerStatStage(@statDown[i * 2], @statDown[(i * 2) + 1], user, showAnim)
|
||||||
|
showAnim = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
showAnim = true
|
showAnim = true
|
||||||
if user.pbCanRaiseStatStage?(:ATTACK, user, self)
|
(@statUp.length / 2).times do |i|
|
||||||
showAnim = false if user.pbRaiseStatStage(:ATTACK, 1, user, showAnim)
|
next if !user.pbCanRaiseStatStage?(@statUp[i * 2], user, self)
|
||||||
|
if user.pbRaiseStatStage(@statUp[i * 2], @statUp[(i * 2) + 1], user, showAnim)
|
||||||
|
showAnim = false
|
||||||
end
|
end
|
||||||
if user.pbCanRaiseStatStage?(:DEFENSE, user, self)
|
|
||||||
user.pbRaiseStatStage(:DEFENSE, 1, user, showAnim)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ class Battle::AI
|
|||||||
battler.turnCount && battler.turnCount >= 5
|
battler.turnCount && battler.turnCount >= 5
|
||||||
shouldSwitch = true
|
shouldSwitch = true
|
||||||
end
|
end
|
||||||
|
# Pokémon is about to faint because of Perish Song
|
||||||
|
if !shouldSwitch && battler.effects[PBEffects::PerishSong] == 1
|
||||||
|
shouldSwitch = true
|
||||||
|
end
|
||||||
# Pokémon is Perish Songed and has Baton Pass
|
# Pokémon is Perish Songed and has Baton Pass
|
||||||
if @trainer.high_skill? && battler.effects[PBEffects::PerishSong] == 1
|
if @trainer.high_skill? && battler.effects[PBEffects::PerishSong] == 1
|
||||||
battler.eachMoveWithIndex do |m, i|
|
battler.eachMoveWithIndex do |m, i|
|
||||||
@@ -87,15 +91,11 @@ class Battle::AI
|
|||||||
shouldSwitch = true
|
shouldSwitch = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Pokémon is about to faint because of Perish Song
|
|
||||||
if !shouldSwitch && battler.effects[PBEffects::PerishSong] == 1
|
|
||||||
shouldSwitch = true
|
|
||||||
end
|
|
||||||
if shouldSwitch
|
if shouldSwitch
|
||||||
list = []
|
list = []
|
||||||
idxPartyStart, idxPartyEnd = @battle.pbTeamIndexRangeFromBattlerIndex(battler.index)
|
idxPartyStart, idxPartyEnd = @battle.pbTeamIndexRangeFromBattlerIndex(battler.index)
|
||||||
@battle.pbParty(battler.index).each_with_index do |pkmn, i|
|
@battle.pbParty(battler.index).each_with_index do |pkmn, i|
|
||||||
next if i == idxPartyEnd - 1 # Don't choose to switch in ace
|
next if @trainer.has_skill_flag?("ReserveLastPokemon") && i == idxPartyEnd - 1 # Don't choose to switch in ace
|
||||||
next if !@battle.pbCanSwitch?(battler.index, i)
|
next if !@battle.pbCanSwitch?(battler.index, i)
|
||||||
# If perish count is 1, it may be worth it to switch
|
# If perish count is 1, it may be worth it to switch
|
||||||
# even with Spikes, since Perish Song's effect will end
|
# even with Spikes, since Perish Song's effect will end
|
||||||
@@ -152,7 +152,9 @@ class Battle::AI
|
|||||||
enemies = []
|
enemies = []
|
||||||
idxPartyStart, idxPartyEnd = @battle.pbTeamIndexRangeFromBattlerIndex(idxBattler)
|
idxPartyStart, idxPartyEnd = @battle.pbTeamIndexRangeFromBattlerIndex(idxBattler)
|
||||||
party.each_with_index do |_p, i|
|
party.each_with_index do |_p, i|
|
||||||
|
if @trainer.has_skill_flag?("ReserveLastPokemon")
|
||||||
next if i == idxPartyEnd - 1 && enemies.length > 0 # Ignore ace if possible
|
next if i == idxPartyEnd - 1 && enemies.length > 0 # Ignore ace if possible
|
||||||
|
end
|
||||||
enemies.push(i) if @battle.pbCanSwitchLax?(idxBattler, i)
|
enemies.push(i) if @battle.pbCanSwitchLax?(idxBattler, i)
|
||||||
end
|
end
|
||||||
return -1 if enemies.length == 0
|
return -1 if enemies.length == 0
|
||||||
|
|||||||
@@ -246,9 +246,9 @@ class Battle::AI
|
|||||||
score -= 20
|
score -= 20
|
||||||
else
|
else
|
||||||
has_special_moves = @user.check_for_move { |m| m.specialMove?(m.type) }
|
has_special_moves = @user.check_for_move { |m| m.specialMove?(m.type) }
|
||||||
inc = (has_special_moves) ? 5 : 10
|
inc = (has_special_moves) ? 10 : 20
|
||||||
score += inc * (2 - old_stage) * inc_mult
|
score += inc * inc_mult
|
||||||
score += 4 * inc_mult if @user.hp == @user.totalhp
|
score += 8 * inc_mult if @user.hp == @user.totalhp
|
||||||
end
|
end
|
||||||
|
|
||||||
when :DEFENSE
|
when :DEFENSE
|
||||||
@@ -256,8 +256,8 @@ class Battle::AI
|
|||||||
if old_stage >= 2
|
if old_stage >= 2
|
||||||
score -= 20
|
score -= 20
|
||||||
else
|
else
|
||||||
score += 5 * (2 - old_stage) * inc_mult
|
score += 10 * inc_mult
|
||||||
score += 4 * inc_mult if @user.hp == @user.totalhp
|
score += 8 * inc_mult if @user.hp == @user.totalhp
|
||||||
end
|
end
|
||||||
|
|
||||||
when :SPECIAL_ATTACK
|
when :SPECIAL_ATTACK
|
||||||
@@ -269,9 +269,9 @@ class Battle::AI
|
|||||||
has_physical_moves = @user.check_for_move { |m| m.physicalMove?(m.type) &&
|
has_physical_moves = @user.check_for_move { |m| m.physicalMove?(m.type) &&
|
||||||
m.function != "UseUserDefenseInsteadOfUserAttack" &&
|
m.function != "UseUserDefenseInsteadOfUserAttack" &&
|
||||||
m.function != "UseTargetAttackInsteadOfUserAttack" }
|
m.function != "UseTargetAttackInsteadOfUserAttack" }
|
||||||
inc = (has_physical_moves) ? 5 : 10
|
inc = (has_physical_moves) ? 10 : 20
|
||||||
score += inc * (2 - old_stage) * inc_mult
|
score += inc * inc_mult
|
||||||
score += 4 * inc_mult if @user.hp == @user.totalhp
|
score += 8 * inc_mult if @user.hp == @user.totalhp
|
||||||
end
|
end
|
||||||
|
|
||||||
when :SPECIAL_DEFENSE
|
when :SPECIAL_DEFENSE
|
||||||
@@ -279,8 +279,8 @@ class Battle::AI
|
|||||||
if old_stage >= 2
|
if old_stage >= 2
|
||||||
score -= 20
|
score -= 20
|
||||||
else
|
else
|
||||||
score += 5 * (2 - old_stage) * inc_mult
|
score += 10 * inc_mult
|
||||||
score += 4 * inc_mult if @user.hp == @user.totalhp
|
score += 8 * inc_mult if @user.hp == @user.totalhp
|
||||||
end
|
end
|
||||||
|
|
||||||
when :SPEED
|
when :SPEED
|
||||||
@@ -312,8 +312,8 @@ class Battle::AI
|
|||||||
end
|
end
|
||||||
min_accuracy = min_accuracy * stage_mul[old_stage] / stage_div[old_stage]
|
min_accuracy = min_accuracy * stage_mul[old_stage] / stage_div[old_stage]
|
||||||
if min_accuracy < 90
|
if min_accuracy < 90
|
||||||
score += 5 * (2 - old_stage) * inc_mult
|
score += 10 * inc_mult
|
||||||
score += 4 * inc_mult if @user.hp == @user.totalhp
|
score += 8 * inc_mult if @user.hp == @user.totalhp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -330,8 +330,8 @@ class Battle::AI
|
|||||||
if old_stage >= 2
|
if old_stage >= 2
|
||||||
score -= 20
|
score -= 20
|
||||||
else
|
else
|
||||||
score += 5 * (2 - old_stage) * inc_mult
|
score += 10 * (2 - old_stage) * inc_mult
|
||||||
score += 4 * inc_mult if @user.hp == @user.totalhp
|
score += 8 * inc_mult if @user.hp == @user.totalhp
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -404,22 +404,27 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartDamageTargetEachTur
|
|||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartLeechSeedTarget",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartLeechSeedTarget",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if target.effects[PBEffects::LeechSeed] >= 0
|
next true if target.effects[PBEffects::LeechSeed] >= 0
|
||||||
next true if target.has_type?(:GRASS)
|
next true if target.has_type?(:GRASS) || !target.battler.takesIndirectDamage?
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartLeechSeedTarget",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartLeechSeedTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
# Prefer early on
|
||||||
score += 10 if user.turnCount < 2
|
score += 10 if user.turnCount < 2
|
||||||
if ai.trainer.medium_skill?
|
if ai.trainer.medium_skill?
|
||||||
if !user.check_for_move { |m| m.damagingMove? }
|
# Prefer if the user has no damaging moves
|
||||||
score += 20
|
score += 20 if !user.check_for_move { |m| m.damagingMove? }
|
||||||
end
|
# Prefer if the target can't switch out to remove its seeding
|
||||||
score -= 20 if target.has_active_ability?([:LIQUIDOOZE]) || !target.battler.takesIndirectDamage?
|
score += 10 if !battle.pbCanChooseNonActive?(target.index)
|
||||||
|
# Don't prefer if the leeched HP will hurt the user
|
||||||
|
score -= 20 if target.has_active_ability?([:LIQUIDOOZE])
|
||||||
end
|
end
|
||||||
if ai.trainer.high_skill?
|
if ai.trainer.high_skill?
|
||||||
|
# Prefer if user can stall while damage is dealt
|
||||||
if user.check_for_move { |m| m.is_a?(Battle::Move::ProtectMove) }
|
if user.check_for_move { |m| m.is_a?(Battle::Move::ProtectMove) }
|
||||||
score += 15
|
score += 15
|
||||||
end
|
end
|
||||||
|
# Don't prefer if target can remove the seed
|
||||||
if target.check_for_move { |m| m.is_a?(Battle::Move::RemoveUserBindingAndEntryHazards) }
|
if target.check_for_move { |m| m.is_a?(Battle::Move::RemoveUserBindingAndEntryHazards) }
|
||||||
score -= 15
|
score -= 15
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,18 +1,32 @@
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("RedirectAllMovesToUser",
|
Battle::AI::Handlers::MoveEffectScore.add("RedirectAllMovesToUser",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
|
# Useless if there is no ally to redirect attacks from
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if user.battler.allAllies.length == 0
|
next Battle::AI::MOVE_USELESS_SCORE if user.battler.allAllies.length == 0
|
||||||
|
# Prefer if ally is at low HP and user is at high HP
|
||||||
|
if user.hp > user.totalhp * 2 / 3
|
||||||
|
ai.each_ally(user.index) do |b, i|
|
||||||
|
score += 10 if b.hp <= b.totalhp / 3
|
||||||
|
end
|
||||||
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RedirectAllMovesToTarget",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("RedirectAllMovesToTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
if target.opposes?(user)
|
||||||
|
# Useless if target is a foe but there is only one foe
|
||||||
|
next Battle::AI::MOVE_USELESS_SCORE if target.battler.allAllies.length == 0
|
||||||
|
# Useless if there is no ally to attack the spotlighted foe
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if user.battler.allAllies.length == 0
|
next Battle::AI::MOVE_USELESS_SCORE if user.battler.allAllies.length == 0
|
||||||
|
end
|
||||||
|
# Generaly don't prefer this move, as it's a waste of the user's turn
|
||||||
|
next score - 15
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,7 +63,7 @@ Battle::AI::Handlers::MoveBasePower.add("RandomlyDamageOrHealTarget",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("HealAllyOrDamageFoe",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("HealAllyOrDamageFoe",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -59,8 +73,12 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("HealAllyOrDamageFoe",
|
|||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealAllyOrDamageFoe",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealAllyOrDamageFoe",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if !target.opposes?(user)
|
if !target.opposes?(user)
|
||||||
score += 50
|
# Consider how much HP will be restored
|
||||||
score -= target.hp * 100 / target.totalhp
|
if target.hp >= target.totalhp * 0.5
|
||||||
|
score -= 10
|
||||||
|
else
|
||||||
|
score += 20 * (target.totalhp - target.hp) / target.totalhp
|
||||||
|
end
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
@@ -72,15 +90,26 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HealAllyOrDamageFoe",
|
|||||||
Battle::AI::Handlers::MoveFailureCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
Battle::AI::Handlers::MoveFailureCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
||||||
proc { |move, user, ai, battle|
|
proc { |move, user, ai, battle|
|
||||||
if !user.has_type?(:GHOST)
|
if !user.has_type?(:GHOST)
|
||||||
next true if !user.battler.pbCanLowerStatStage?(:SPEED, user.battler, move.move) &&
|
will_fail = true
|
||||||
!user.battler.pbCanRaiseStatStage?(:ATTACK, user.battler, move.move) &&
|
(move.move.statUp.length / 2).times do |i|
|
||||||
!user.battler.pbCanRaiseStatStage?(:DEFENSE, user.battler, move.move)
|
next if !user.battler.pbCanRaiseStatStage?(move.move.statUp[i * 2], user.battler, move.move)
|
||||||
|
will_fail = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
(move.move.statDown.length / 2).times do |i|
|
||||||
|
next if !user.battler.pbCanLowerStatStage?(move.move.statDown[i * 2], user.battler, move.move)
|
||||||
|
will_fail = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
next will_fail
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if user.has_type?(:GHOST) && target.effects[PBEffects::Curse]
|
if user.has_type?(:GHOST)
|
||||||
|
next true if target.effects[PBEffects::Curse] || !target.battler.takesIndirectDamage?
|
||||||
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
Battle::AI::Handlers::MoveEffectScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
||||||
@@ -96,12 +125,20 @@ Battle::AI::Handlers::MoveEffectScore.add("CurseTargetOrLowerUserSpd1RaiseUserAt
|
|||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CurseTargetOrLowerUserSpd1RaiseUserAtkDef1",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next score if !user.has_type?(:GHOST)
|
next score if !user.has_type?(:GHOST)
|
||||||
if user.hp <= user.totalhp / 2
|
# Don't prefer if user will faint because of using this move
|
||||||
if battle.pbAbleNonActiveCount(user.idxOwnSide) == 0
|
next Battle::AI::MOVE_USELESS_SCORE if user.hp <= user.totalhp / 2
|
||||||
score -= 90
|
# Prefer early on
|
||||||
else
|
score += 10 if user.turnCount < 2
|
||||||
score -= 50
|
if ai.trainer.medium_skill?
|
||||||
score -= 30 if battle.switchStyle
|
# Prefer if the user has no damaging moves
|
||||||
|
score += 20 if !user.check_for_move { |m| m.damagingMove? }
|
||||||
|
# Prefer if the target can't switch out to remove its curse
|
||||||
|
score += 10 if !battle.pbCanChooseNonActive?(target.index)
|
||||||
|
end
|
||||||
|
if ai.trainer.high_skill?
|
||||||
|
# Prefer if user can stall while damage is dealt
|
||||||
|
if user.check_for_move { |m| m.is_a?(Battle::Move::ProtectMove) }
|
||||||
|
score += 15
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
@@ -144,14 +181,30 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TargetNextFireMoveDamage
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# DoublePowerAfterFusionFlare
|
Battle::AI::Handlers::MoveEffectScore.add("DoublePowerAfterFusionFlare",
|
||||||
|
proc { |score, move, user, ai, battle|
|
||||||
|
# Prefer if an ally knows Fusion Flare
|
||||||
|
ai.each_ally(user.index) do |b, i|
|
||||||
|
score += 10 if b.check_for_move { |m| m.function == "DoublePowerAfterFusionBolt" }
|
||||||
|
end
|
||||||
|
next score
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# DoublePowerAfterFusionBolt
|
Battle::AI::Handlers::MoveEffectScore.add("DoublePowerAfterFusionBolt",
|
||||||
|
proc { |score, move, user, ai, battle|
|
||||||
|
# Prefer if an ally knows Fusion Bolt
|
||||||
|
ai.each_ally(user.index) do |b, i|
|
||||||
|
score += 10 if b.check_for_move { |m| m.function == "DoublePowerAfterFusionFlare" }
|
||||||
|
end
|
||||||
|
next score
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
# TODO: Review score modifiers.
|
||||||
@@ -287,19 +340,43 @@ Battle::AI::Handlers::MoveEffectScore.add("HealUserDependingOnUserStockpile",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# GrassPledge
|
Battle::AI::Handlers::MoveEffectScore.add("GrassPledge",
|
||||||
|
proc { |score, move, user, ai, battle|
|
||||||
|
# Prefer if an ally knows a different Pledge move
|
||||||
|
ai.each_ally(user.index) do |b, i|
|
||||||
|
score += 10 if b.check_for_move { |m| ["FirePledge", "WaterPledge"].include?(m.function) }
|
||||||
|
end
|
||||||
|
next score
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# FirePledge
|
Battle::AI::Handlers::MoveEffectScore.add("FirePledge",
|
||||||
|
proc { |score, move, user, ai, battle|
|
||||||
|
# Prefer if an ally knows a different Pledge move
|
||||||
|
ai.each_ally(user.index) do |b, i|
|
||||||
|
score += 10 if b.check_for_move { |m| ["GrassPledge", "WaterPledge"].include?(m.function) }
|
||||||
|
end
|
||||||
|
next score
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# WaterPledge
|
Battle::AI::Handlers::MoveEffectScore.add("WaterPledge",
|
||||||
|
proc { |score, move, user, ai, battle|
|
||||||
|
# Prefer if an ally knows a different Pledge move
|
||||||
|
ai.each_ally(user.index) do |b, i|
|
||||||
|
score += 10 if b.check_for_move { |m| ["GrassPledge", "FirePledge"].include?(m.function) }
|
||||||
|
end
|
||||||
|
next score
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
# TODO: Review score modifiers.
|
||||||
@@ -392,29 +469,36 @@ Battle::AI::Handlers::MoveFailureCheck.add("UseRandomUserMoveIfAsleep",
|
|||||||
# StealAndUseBeneficialStatusMove
|
# StealAndUseBeneficialStatusMove
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("ReplaceMoveThisBattleWithTargetLastMoveUsed",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("ReplaceMoveThisBattleWithTargetLastMoveUsed",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if user.effects[PBEffects::Transform] || user.battler.pbHasMove?(move.id)
|
next true if user.effects[PBEffects::Transform] || !user.battler.pbHasMove?(move.id)
|
||||||
|
if user.faster_than?(target)
|
||||||
last_move_data = GameData::Move.try_get(target.battler.lastRegularMoveUsed)
|
last_move_data = GameData::Move.try_get(target.battler.lastRegularMoveUsed)
|
||||||
next true if !last_move_data ||
|
next true if !last_move_data ||
|
||||||
user.battler.pbHasMove?(target.battler.lastRegularMoveUsed) ||
|
user.battler.pbHasMove?(target.battler.lastRegularMoveUsed) ||
|
||||||
move.move.moveBlacklist.include?(last_move_data.function_code) ||
|
move.move.moveBlacklist.include?(last_move_data.function_code) ||
|
||||||
last_move_data.type == :SHADOW
|
last_move_data.type == :SHADOW
|
||||||
|
end
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Battle::AI::Handlers::MoveEffectScore.add("ReplaceMoveThisBattleWithTargetLastMoveUsed",
|
||||||
|
proc { |score, move, user, ai, battle|
|
||||||
|
# Generally don't prefer, as this wastes the user's turn just to gain a move
|
||||||
|
# of unknown utility
|
||||||
|
score -= 8
|
||||||
|
# Slightly prefer if this move will definitely succeed, just for the sake of
|
||||||
|
# getting rid of this move
|
||||||
|
score += 5 if user.faster_than?(target)
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("ReplaceMoveWithTargetLastMoveUsed",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("ReplaceMoveThisBattleWithTargetLastMoveUsed",
|
||||||
proc { |move, user, target, ai, battle|
|
"ReplaceMoveWithTargetLastMoveUsed")
|
||||||
next true if user.effects[PBEffects::Transform] || !user.battler.pbHasMove?(move.id)
|
Battle::AI::Handlers::MoveEffectScore.copy("ReplaceMoveThisBattleWithTargetLastMoveUsed",
|
||||||
last_move_data = GameData::Move.try_get(target.battler.lastRegularMoveUsed)
|
"ReplaceMoveWithTargetLastMoveUsed")
|
||||||
next true if !last_move_data ||
|
|
||||||
user.battler.pbHasMove?(target.battler.lastRegularMoveUsed) ||
|
|
||||||
move.move.moveBlacklist.include?(last_move_data.function_code) ||
|
|
||||||
last_move_data.type == :SHADOW
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ Battle::AI::Handlers::MoveFailureCheck.add("SwitchOutUserStatusMove",
|
|||||||
Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserStatusMove",
|
Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserStatusMove",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
next score + 10 if user.wild?
|
next score + 10 if user.wild?
|
||||||
if battle.pbTeamAbleNonActiveCount(user.index) == 1 # Don't switch in ace
|
if ai.trainer.has_skill_flag?("ReserveLastPokemon") && battle.pbTeamAbleNonActiveCount(user.index) == 1
|
||||||
score -= 60
|
score -= 60 # Don't switch in ace
|
||||||
else
|
else
|
||||||
score += 40 if user.effects[PBEffects::Confusion] > 0
|
score += 40 if user.effects[PBEffects::Confusion] > 0
|
||||||
total = 0
|
total = 0
|
||||||
@@ -51,8 +51,8 @@ Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserStatusMove",
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserDamagingMove",
|
Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserDamagingMove",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
next 0 if !battle.pbCanChooseNonActive?(user.index) ||
|
next 0 if !battle.pbCanChooseNonActive?(user.index)
|
||||||
battle.pbTeamAbleNonActiveCount(user.index) == 1 # Don't switch in ace
|
next 0 if ai.trainer.has_skill_flag?("ReserveLastPokemon") && battle.pbTeamAbleNonActiveCount(user.index) == 1 # Don't switch in ace
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -326,20 +326,24 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("HigherPriorityInGrassyTe
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerPPOfTargetLastMoveBy3",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerPPOfTargetLastMoveBy3",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
if user.faster_than?(target)
|
||||||
last_move = target.battler.pbGetMoveWithID(target.battler.lastRegularMoveUsed)
|
last_move = target.battler.pbGetMoveWithID(target.battler.lastRegularMoveUsed)
|
||||||
if last_move && last_move.total_pp > 0 && last_move.pp <= 3
|
if last_move && last_move.total_pp > 0
|
||||||
score += 50
|
next score + 20 if last_move.pp <= 3 # Will fully deplete the move's PP
|
||||||
|
next score + 10 if last_move.pp <= 5
|
||||||
|
next score - 10 if last_move.pp > 9 # Too much PP left to make a difference
|
||||||
end
|
end
|
||||||
next score
|
end
|
||||||
|
next score # Don't know which move it will affect; treat as just a damaging move
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerPPOfTargetLastMoveBy4",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerPPOfTargetLastMoveBy4",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -349,7 +353,13 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerPPOfTargetLastMove
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerPPOfTargetLastMoveBy4",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerPPOfTargetLastMoveBy4",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next Battle::AI::MOVE_USELESS_SCORE
|
if user.faster_than?(target)
|
||||||
|
last_move = target.battler.pbGetMoveWithID(target.battler.lastRegularMoveUsed)
|
||||||
|
next score + 20 if last_move.pp <= 4 # Will fully deplete the move's PP
|
||||||
|
next score + 10 if last_move.pp <= 6
|
||||||
|
next score - 10 if last_move.pp > 10 # Too much PP left to make a difference
|
||||||
|
end
|
||||||
|
next score - 10 # Don't know which move it will affect; don't prefer
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
# TODO: Review score modifier.
|
# TODO: Review score modifier.
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO:
|
# TODO:
|
||||||
# => Prefer move if it will KO the target (moreso if user is slower than target)
|
|
||||||
# => Don't prefer damaging move if it won't KO, user has Stance Change and
|
# => Don't prefer damaging move if it won't KO, user has Stance Change and
|
||||||
# is in shield form, and user is slower than the target
|
# is in shield form, and user is slower than the target
|
||||||
# => Check memory for past damage dealt by a target's non-high priority move,
|
# => Check memory for past damage dealt by a target's non-high priority move,
|
||||||
@@ -38,6 +37,7 @@ Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:shiny_target,
|
|||||||
# => If target has previously used a move that will hurt the user by 30% of
|
# => If target has previously used a move that will hurt the user by 30% of
|
||||||
# its current HP or more, moreso don't prefer a status move.
|
# its current HP or more, moreso don't prefer a status move.
|
||||||
# => Include EOR damage in this?
|
# => Include EOR damage in this?
|
||||||
|
# => Prefer move if it will KO the target (moreso if user is slower than target)
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:add_predicted_damage,
|
Battle::AI::Handlers::GeneralMoveAgainstTargetScore.add(:add_predicted_damage,
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
# PredictMoveFailure
|
# PredictMoveFailure
|
||||||
# ScoreMoves
|
# ScoreMoves
|
||||||
# PreferMultiTargetMoves
|
# PreferMultiTargetMoves
|
||||||
|
# ReserveLastPokemon (don't switch it in if possible)
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class Battle::AI::AITrainer
|
class Battle::AI::AITrainer
|
||||||
attr_reader :side, :trainer_index
|
attr_reader :side, :trainer_index
|
||||||
@@ -36,6 +37,10 @@ class Battle::AI::AITrainer
|
|||||||
@skill_flags.push("ScoreMoves")
|
@skill_flags.push("ScoreMoves")
|
||||||
@skill_flags.push("PreferMultiTargetMoves")
|
@skill_flags.push("PreferMultiTargetMoves")
|
||||||
end
|
end
|
||||||
|
if @skill >= 100
|
||||||
|
# TODO: Also have flag "DontReserveLastPokemon" which negates this.
|
||||||
|
@skill_flags.push("ReserveLastPokemon")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_skill_flag?(flag)
|
def has_skill_flag?(flag)
|
||||||
|
|||||||
Reference in New Issue
Block a user