mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
Rewrote AI calculations for move effects relating to the user fainting
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
class Battle::AI
|
class Battle::AI
|
||||||
attr_reader :battle
|
attr_reader :battle
|
||||||
attr_reader :trainer
|
attr_reader :trainer
|
||||||
|
attr_reader :battlers
|
||||||
attr_reader :user, :target, :move
|
attr_reader :user, :target, :move
|
||||||
|
|
||||||
def initialize(battle)
|
def initialize(battle)
|
||||||
|
|||||||
@@ -330,112 +330,119 @@ Battle::AI::Handlers::MoveEffectScore.add("StartLeechSeedTarget",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("UserLosesHalfOfTotalHP",
|
Battle::AI::Handlers::MoveEffectScore.add("UserLosesHalfOfTotalHP",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next 0 if user.hp <= user.totalhp / 2
|
score -= 15 # User will lose 50% HP, don't prefer this move
|
||||||
|
if ai.trainer.medium_skill?
|
||||||
|
score += 10 if user.hp >= user.totalhp * 0.75 # User at 75% HP or more
|
||||||
|
score += 10 if user.hp <= user.totalhp * 0.25 # User at 25% HP or less
|
||||||
|
end
|
||||||
|
if ai.trainer.high_skill?
|
||||||
|
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
||||||
|
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
||||||
|
if reserves == 0 # AI is down to its last Pokémon
|
||||||
|
score += 30 # => Go out with a bang
|
||||||
|
elsif foes == 0 # Foe is down to their last Pokémon, AI has reserves
|
||||||
|
score += 20 # => Go for the kill
|
||||||
|
end
|
||||||
|
end
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("UserLosesHalfOfTotalHPExplosive",
|
Battle::AI::Handlers::MoveFailureCheck.add("UserLosesHalfOfTotalHPExplosive",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if !battle.moldBreaker && battle.pbCheckGlobalAbility(:DAMP)
|
next true if !battle.moldBreaker && battle.pbCheckGlobalAbility(:DAMP)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("UserLosesHalfOfTotalHPExplosive",
|
Battle::AI::Handlers::MoveEffectScore.copy("UserLosesHalfOfTotalHP",
|
||||||
proc { |score, move, user, target, ai, battle|
|
"UserLosesHalfOfTotalHPExplosive")
|
||||||
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
|
||||||
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
|
||||||
if ai.trainer.medium_skill? && reserves == 0 && foes > 0
|
|
||||||
score -= 60 # don't want to lose
|
|
||||||
elsif ai.trainer.high_skill? && reserves == 0 && foes == 0
|
|
||||||
score += 40 # want to draw
|
|
||||||
else
|
|
||||||
score -= (user.totalhp - user.hp) * 75 / user.totalhp
|
|
||||||
end
|
|
||||||
next score
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.copy("UserLosesHalfOfTotalHPExplosive",
|
Battle::AI::Handlers::MoveFailureCheck.copy("UserLosesHalfOfTotalHPExplosive",
|
||||||
"UserFaintsExplosive")
|
"UserFaintsExplosive")
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("UserFaintsExplosive",
|
Battle::AI::Handlers::MoveEffectScore.add("UserFaintsExplosive",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
score -= 25 # User will faint, don't prefer this move
|
||||||
|
if ai.trainer.medium_skill?
|
||||||
|
score -= 10 if user.hp >= user.totalhp * 0.5 # User at 50% HP or more
|
||||||
|
score += 10 if user.hp <= user.totalhp * 0.25 # User at 25% HP or less
|
||||||
|
end
|
||||||
|
if ai.trainer.high_skill?
|
||||||
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
||||||
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
||||||
if ai.trainer.medium_skill? && reserves == 0 && foes > 0
|
if reserves == 0 # AI is down to its last Pokémon
|
||||||
score -= 60 # don't want to lose
|
score += 30 # => Go out with a bang
|
||||||
elsif ai.trainer.high_skill? && reserves == 0 && foes == 0
|
elsif foes == 0 # Foe is down to their last Pokémon, AI has reserves
|
||||||
score += 40 # want to draw
|
score += 20 # => Go for the kill
|
||||||
else
|
end
|
||||||
score -= user.hp * 100 / user.totalhp
|
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.copy("UserLosesHalfOfTotalHPExplosive",
|
Battle::AI::Handlers::MoveFailureCheck.copy("UserFaintsExplosive",
|
||||||
"UserFaintsPowersUpInMistyTerrainExplosive")
|
"UserFaintsPowersUpInMistyTerrainExplosive")
|
||||||
Battle::AI::Handlers::MoveBasePower.add("UserFaintsPowersUpInMistyTerrainExplosive",
|
Battle::AI::Handlers::MoveBasePower.add("UserFaintsPowersUpInMistyTerrainExplosive",
|
||||||
proc { |power, move, user, target, ai, battle|
|
proc { |power, move, user, target, ai, battle|
|
||||||
next power * 3 / 2 if battle.field.terrain == :Misty
|
next power * 3 / 2 if battle.field.terrain == :Misty
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("UserFaintsPowersUpInMistyTerrainExplosive",
|
Battle::AI::Handlers::MoveEffectScore.copy("UserFaintsExplosive",
|
||||||
proc { |score, move, user, target, ai, battle|
|
"UserFaintsPowersUpInMistyTerrainExplosive")
|
||||||
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
|
||||||
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
|
||||||
if ai.trainer.medium_skill? && reserves == 0 && foes > 0
|
|
||||||
score -= 60 # don't want to lose
|
|
||||||
elsif ai.trainer.high_skill? && reserves == 0 && foes == 0
|
|
||||||
score += 40 # want to draw
|
|
||||||
else
|
|
||||||
score -= user.hp * 100 / user.totalhp
|
|
||||||
end
|
|
||||||
next score
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveBasePower.add("UserFaintsFixedDamageUserHP",
|
Battle::AI::Handlers::MoveBasePower.add("UserFaintsFixedDamageUserHP",
|
||||||
proc { |power, move, user, target, ai, battle|
|
proc { |power, move, user, target, ai, battle|
|
||||||
next user.hp
|
next user.hp
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Battle::AI::Handlers::MoveEffectScore.copy("UserFaintsExplosive",
|
||||||
|
"UserFaintsFixedDamageUserHP")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("UserFaintsLowerTargetAtkSpAtk2",
|
Battle::AI::Handlers::MoveEffectScore.add("UserFaintsLowerTargetAtkSpAtk2",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if !target.battler.pbCanLowerStatStage?(:ATTACK, user.battler) &&
|
next score - 40 if !target.battler.pbCanLowerStatStage?(:ATTACK, user.battler) &&
|
||||||
!target.battler.pbCanLowerStatStage?(:SPECIAL_ATTACK, user.battler)
|
!target.battler.pbCanLowerStatStage?(:SPECIAL_ATTACK, user.battler)
|
||||||
score -= 60
|
score -= 25 # User will faint, don't prefer this move
|
||||||
elsif battle.pbAbleNonActiveCount(user.idxOwnSide) == 0
|
# Check the impact of lowering the target's stats
|
||||||
score -= 60
|
if target.stages[:ATTACK] < 0 && target.stages[:SPECIAL_ATTACK] < 0
|
||||||
else
|
score -= 20
|
||||||
score += target.stages[:ATTACK] * 10
|
elsif target.stages[:ATTACK] > 0 || target.stages[:SPECIAL_ATTACK] > 0
|
||||||
score += target.stages[:SPECIAL_ATTACK] * 10
|
score += 10
|
||||||
score -= user.hp * 100 / user.totalhp
|
end
|
||||||
|
if ai.trainer.medium_skill?
|
||||||
|
score -= 10 if user.hp >= user.totalhp * 0.5 # User at 50% HP or more
|
||||||
|
score += 10 if user.hp <= user.totalhp * 0.25 # User at 25% HP or less
|
||||||
|
end
|
||||||
|
if ai.trainer.high_skill?
|
||||||
|
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
||||||
|
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
||||||
|
if reserves > 0 && foes == 0 # Foe is down to their last Pokémon, AI has reserves
|
||||||
|
score += 20 # => Can afford to lose this Pokémon
|
||||||
|
end
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("UserFaintsHealAndCureReplacement",
|
Battle::AI::Handlers::MoveFailureCheck.add("UserFaintsHealAndCureReplacement",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -444,12 +451,35 @@ Battle::AI::Handlers::MoveFailureCheck.add("UserFaintsHealAndCureReplacement",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("UserFaintsHealAndCureReplacement",
|
Battle::AI::Handlers::MoveEffectScore.add("UserFaintsHealAndCureReplacement",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next score - 70
|
score -= 25 # User will faint, don't prefer this move
|
||||||
|
# Check whether the replacement user needs healing, and don't make the below
|
||||||
|
# calculations if not
|
||||||
|
if ai.trainer.medium_skill?
|
||||||
|
need_healing = false
|
||||||
|
battle.eachInTeamFromBattlerIndex(user.index) do |pkmn, party_index|
|
||||||
|
next if pkmn.hp >= pkmn.totalhp * 0.75 && pkmn.status == :NONE
|
||||||
|
need_healing = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
next score - 15 if !need_healing
|
||||||
|
end
|
||||||
|
if ai.trainer.medium_skill?
|
||||||
|
score -= 10 if user.hp >= user.totalhp * 0.5 # User at 50% HP or more
|
||||||
|
score += 10 if user.hp <= user.totalhp * 0.25 # User at 25% HP or less
|
||||||
|
end
|
||||||
|
if ai.trainer.high_skill?
|
||||||
|
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
||||||
|
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
||||||
|
if reserves > 0 && foes == 0 # Foe is down to their last Pokémon, AI has reserves
|
||||||
|
score += 20 # => Can afford to lose this Pokémon
|
||||||
|
end
|
||||||
|
end
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.copy("UserFaintsHealAndCureReplacement",
|
Battle::AI::Handlers::MoveFailureCheck.copy("UserFaintsHealAndCureReplacement",
|
||||||
"UserFaintsHealAndCureReplacementRestorePP")
|
"UserFaintsHealAndCureReplacementRestorePP")
|
||||||
@@ -457,25 +487,60 @@ Battle::AI::Handlers::MoveEffectScore.copy("UserFaintsHealAndCureReplacement",
|
|||||||
"UserFaintsHealAndCureReplacementRestorePP")
|
"UserFaintsHealAndCureReplacementRestorePP")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
# TODO: This code shouldn't make use of target.
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("StartPerishCountsForAllBattlers",
|
Battle::AI::Handlers::MoveFailureCheck.add("StartPerishCountsForAllBattlers",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next target.effects[PBEffects::PerishSong] > 0
|
will_fail = true
|
||||||
|
battle.allBattlers.each do |b|
|
||||||
|
next if b.effects[PBEffects::PerishSong] > 0
|
||||||
|
next if Battle::AbilityEffects.triggerMoveImmunity(b.ability, user.battler, b,
|
||||||
|
move.move, move.rough_type, battle, false)
|
||||||
|
will_fail = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
next will_fail
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("StartPerishCountsForAllBattlers",
|
Battle::AI::Handlers::MoveEffectScore.add("StartPerishCountsForAllBattlers",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if battle.pbAbleNonActiveCount(user.idxOwnSide) == 0
|
score -= 15
|
||||||
score -= 60
|
# Check which battlers will be affected by this move
|
||||||
|
if ai.trainer.medium_skill?
|
||||||
|
allies_affected = 0
|
||||||
|
foes_affected = 0
|
||||||
|
foes_with_high_hp = 0
|
||||||
|
battle.allBattlers.each do |b|
|
||||||
|
next if b.effects[PBEffects::PerishSong] > 0
|
||||||
|
next if Battle::AbilityEffects.triggerMoveImmunity(b.ability, user.battler, b,
|
||||||
|
move.move, move.rough_type, battle, false)
|
||||||
|
if b.opposes?(user.index)
|
||||||
|
foes_affected += 1
|
||||||
|
foes_with_high_hp += 1 if b.hp >= b.totalhp * 0.75
|
||||||
|
else
|
||||||
|
allies_affected += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
next score - 25 if foes_affected == 0
|
||||||
|
score += 15 if allies_affected == 0 # No downside for user; cancel out inherent negative score
|
||||||
|
score += 15 * (foes_affected - allies_affected)
|
||||||
|
score += 5 * foes_with_high_hp
|
||||||
|
end
|
||||||
|
if ai.trainer.high_skill?
|
||||||
|
reserves = battle.pbAbleNonActiveCount(user.idxOwnSide)
|
||||||
|
foes = battle.pbAbleNonActiveCount(user.idxOpposingSide)
|
||||||
|
if foes == 0 # Foe is down to their last Pokémon, can't lose Perish count
|
||||||
|
score += 30 # => Want to auto-win in 3 turns
|
||||||
|
elsif reserves == 0 # AI is down to its last Pokémon, can't lose Perish count
|
||||||
|
score -= 20 # => Don't want to auto-lose in 3 turns
|
||||||
|
end
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("AttackerFaintsIfUserFaints",
|
Battle::AI::Handlers::MoveFailureCheck.add("AttackerFaintsIfUserFaints",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -484,21 +549,45 @@ Battle::AI::Handlers::MoveFailureCheck.add("AttackerFaintsIfUserFaints",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("AttackerFaintsIfUserFaints",
|
Battle::AI::Handlers::MoveEffectScore.add("AttackerFaintsIfUserFaints",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
score += 50
|
score -= 25
|
||||||
score -= user.hp * 100 / user.totalhp
|
# Check whether user is faster than its foe(s) and could use this move
|
||||||
score += 30 if user.hp <= user.totalhp / 10
|
user_faster_count = 0
|
||||||
|
ai.battlers.each_with_index do |b, i|
|
||||||
|
next if !user.opposes?(b) || b.battler.fainted?
|
||||||
|
user_faster_count += 1 if user.faster_than?(b)
|
||||||
|
end
|
||||||
|
next score if user_faster_count == 0 # Move will almost certainly have no effect
|
||||||
|
score += 5 * user_faster_count
|
||||||
|
# Prefer this move at lower user HP
|
||||||
|
if ai.trainer.medium_skill?
|
||||||
|
score += 20 if user.hp <= user.totalhp * 0.4
|
||||||
|
score += 10 if user.hp <= user.totalhp * 0.25
|
||||||
|
score += 15 if user.hp <= user.totalhp * 0.1
|
||||||
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("SetAttackerMovePPTo0IfUserFaints",
|
Battle::AI::Handlers::MoveEffectScore.add("SetAttackerMovePPTo0IfUserFaints",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
score += 50
|
score -= 25
|
||||||
score -= user.hp * 100 / user.totalhp
|
# Check whether user is faster than its foe(s) and could use this move
|
||||||
score += 30 if user.hp <= user.totalhp / 10
|
user_faster_count = 0
|
||||||
|
ai.battlers.each_with_index do |b, i|
|
||||||
|
next if !user.opposes?(b) || b.battler.fainted?
|
||||||
|
user_faster_count += 1 if user.faster_than?(b)
|
||||||
|
end
|
||||||
|
next score if user_faster_count == 0 # Move will almost certainly have no effect
|
||||||
|
score += 5 * user_faster_count
|
||||||
|
# Prefer this move at lower user HP (not as preferred as Destiny Bond, though)
|
||||||
|
if ai.trainer.medium_skill?
|
||||||
|
score += 15 if user.hp <= user.totalhp * 0.4
|
||||||
|
score += 10 if user.hp <= user.totalhp * 0.25
|
||||||
|
score += 10 if user.hp <= user.totalhp * 0.1
|
||||||
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user