mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-07 13:15:01 +00:00
More AI function codes, tweaked AI score threshold, renumbered all PBEffects constants
This commit is contained in:
@@ -59,7 +59,7 @@ end
|
||||
|
||||
#===============================================================================
|
||||
# After inflicting damage, user switches out. Ignores trapping moves.
|
||||
# (U-turn, Volt Switch)
|
||||
# (Flip Turn, U-turn, Volt Switch)
|
||||
#===============================================================================
|
||||
class Battle::Move::SwitchOutUserDamagingMove < Battle::Move
|
||||
def pbEndOfMoveUsageEffect(user, targets, numHits, switchedBattlers)
|
||||
|
||||
@@ -6,7 +6,7 @@ class Battle::AI
|
||||
# Returns a value between 0.0 and 1.0. All move scores are lowered by this
|
||||
# value multiplied by the highest-scoring move's score.
|
||||
def move_score_threshold
|
||||
return 0.6 + 0.35 * (([@trainer.skill, 100].min / 100.0) ** 0.5) # 0.6 to 0.95
|
||||
return 0.6 + 0.3 * (([@trainer.skill, 100].min / 100.0) ** 0.5) # 0.6 to 0.9
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
@@ -147,8 +147,8 @@ class Battle::AI
|
||||
move.pbOnStartUse(@user.battler, []) # Determine which move is used instead
|
||||
move = Battle::Move.from_pokemon_move(@battle, Pokemon::Move.new(move.npMove))
|
||||
end
|
||||
@move.set_up(move)
|
||||
@battle.moldBreaker = @user.has_mold_breaker?
|
||||
@move.set_up(move)
|
||||
end
|
||||
|
||||
def set_up_move_check_target(target)
|
||||
@@ -158,6 +158,7 @@ class Battle::AI
|
||||
if @target.battler.lastRegularMoveUsed &&
|
||||
GameData::Move.get(@target.battler.lastRegularMoveUsed).has_flag?("CanMirrorMove")
|
||||
mov = Battle::Move.from_pokemon_move(@battle, Pokemon::Move.new(@target.battler.lastRegularMoveUsed))
|
||||
@battle.moldBreaker = @user.has_mold_breaker?
|
||||
@move.set_up(mov)
|
||||
end
|
||||
end
|
||||
@@ -291,7 +292,7 @@ class Battle::AI
|
||||
# TODO: The above also applies if the move is Heal Pulse or a few other moves
|
||||
# like that, which CAN target a foe but you'd never do so. Maybe use a
|
||||
# move flag to determine such moves? The implication is that such moves
|
||||
# wouldn't apply the "175 - score" bit, which would make their
|
||||
# wouldn't apply the "185 - score" bit, which would make their
|
||||
# MoveHandlers do the opposite calculations to other moves with the same
|
||||
# targets, but is this desirable?
|
||||
#=============================================================================
|
||||
@@ -322,7 +323,7 @@ class Battle::AI
|
||||
end
|
||||
# TODO: Is this reversal of the score okay?
|
||||
old_score = score
|
||||
score = 175 - score
|
||||
score = 185 - score
|
||||
PBDebug.log_score_change(score - old_score, "score inverted (move targets ally but can target foe)")
|
||||
end
|
||||
return score
|
||||
|
||||
@@ -299,6 +299,59 @@ class Battle::AI::AIBattler
|
||||
return false
|
||||
end
|
||||
|
||||
# NOTE: This specifically means "is not currently trapped but can become
|
||||
# trapped by an effect". Similar to def pbCanSwitchOut? but this returns
|
||||
# false if any certain switching OR certain trapping applies.
|
||||
def can_become_trapped?
|
||||
return false if fainted?
|
||||
# Ability/item effects that allow switching no matter what
|
||||
if ability_active? && Battle::AbilityEffects.triggerCertainSwitching(ability, @battler, @ai.battle)
|
||||
return false
|
||||
end
|
||||
if item_active? && Battle::ItemEffects.triggerCertainSwitching(item, @battler, @ai.battle)
|
||||
return false
|
||||
end
|
||||
# Other certain switching effects
|
||||
return false if Settings::MORE_TYPE_EFFECTS && has_type?(:GHOST)
|
||||
# Other certain trapping effects
|
||||
return false if @battler.trappedInBattle?
|
||||
# Trapping abilities/items
|
||||
ai.each_foe_battler(side) do |b, i|
|
||||
if b.ability_active? &&
|
||||
Battle::AbilityEffects.triggerTrappingByTarget(b.ability, @battler, b.battler, @ai.battle)
|
||||
return false
|
||||
end
|
||||
if b.item_active? &&
|
||||
Battle::ItemEffects.triggerTrappingByTarget(b.item, @battler, b.battler, @ai.battle)
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
|
||||
def wants_status_problem?(new_status)
|
||||
return true if new_status == :NONE
|
||||
if ability_active?
|
||||
case ability_id
|
||||
when :GUTS
|
||||
return true if stat_raise_worthwhile?(self, :ATTACK, true)
|
||||
when :MARVELSCALE
|
||||
return true if stat_raise_worthwhile?(self, :DEFENSE, true)
|
||||
when :QUICKFEET
|
||||
return true if stat_raise_worthwhile?(self, :SPEED, true)
|
||||
when :FLAREBOOST
|
||||
return true if new_status == :BURN && stat_raise_worthwhile?(self, :SPECIAL_ATTACK, true)
|
||||
end
|
||||
end
|
||||
return true if new_status == :SLEEP && check_for_move { |m| m.usableWhenAsleep? }
|
||||
if has_move_with_function?("DoublePowerIfUserPoisonedBurnedParalyzed")
|
||||
return true if [:POISON, :BURN, :PARALYSIS].include?(new_status)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
|
||||
# TODO: Add more items.
|
||||
|
||||
@@ -11,6 +11,8 @@ class Battle::AI::AIMove
|
||||
def set_up(move)
|
||||
@move = move
|
||||
@move.calcType = rough_type
|
||||
@ai.battle.moldBreaker ||= ["IgnoreTargetAbility",
|
||||
"CategoryDependsOnHigherDamageIgnoreTargetAbility"].include?(function)
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
|
||||
@@ -455,13 +455,7 @@ Battle::AI::Handlers::MoveEffectScore.copy("RaiseUserAtkSpAtk1",
|
||||
Battle::AI::Handlers::MoveFailureCheck.add("RaiseUserMainStats1LoseThirdOfTotalHP",
|
||||
proc { |move, user, ai, battle|
|
||||
next true if user.hp <= [user.totalhp / 3, 1].max
|
||||
will_fail = true
|
||||
(move.move.statUp.length / 2).times do |i|
|
||||
next if !user.battler.pbCanRaiseStatStage?(move.move.statUp[i * 2], user.battler, move.move)
|
||||
will_fail = false
|
||||
break
|
||||
end
|
||||
next will_fail
|
||||
next Battle::AI::Handlers.move_will_fail?("RaiseUserAtkDef1", move, user, ai, battle)
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserMainStats1LoseThirdOfTotalHP",
|
||||
@@ -478,27 +472,35 @@ Battle::AI::Handlers::MoveEffectScore.add("RaiseUserMainStats1LoseThirdOfTotalHP
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.add("RaiseUserMainStats1TrapUserInBattle",
|
||||
proc { |move, user, ai, battle|
|
||||
next true if user.effects[PBEffects::NoRetreat]
|
||||
will_fail = true
|
||||
(move.move.statUp.length / 2).times do |i|
|
||||
next if !user.battler.pbCanRaiseStatStage?(move.move.statUp[i * 2], user.battler, move.move)
|
||||
will_fail = false
|
||||
break
|
||||
end
|
||||
next will_fail
|
||||
next Battle::AI::Handlers.move_will_fail?("RaiseUserAtkDef1", move, user, ai, battle)
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("RaiseUserMainStats1TrapUserInBattle",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Score for stat increase
|
||||
score = ai.get_score_for_target_stat_raise(score, user, move.move.statUp)
|
||||
# Score for trapping user in battle
|
||||
if ai.trainer.medium_skill? && !user.battler.trappedInBattle?
|
||||
score -= 10 if user.hp <= user.totalhp / 2
|
||||
# Score for user becoming trapped in battle
|
||||
if user.can_become_trapped? && battle.pbCanChooseNonActive?(user.index)
|
||||
# Not worth trapping if user will faint this round anyway
|
||||
eor_damage = user.rough_end_of_round_damage
|
||||
if eor_damage >= user.hp
|
||||
next (move.damagingMove?) ? score : Battle::AI::MOVE_USELESS_SCORE
|
||||
end
|
||||
# Score for user becoming trapped in battle
|
||||
# TODO: These checks are related to desire to switch, and there can be a lot
|
||||
# more things to consider, e.g. effectiveness of the target's moves
|
||||
# against its foes. Also applies to other code that calls
|
||||
# can_become_trapped?
|
||||
if user.effects[PBEffects::PerishSong] > 0 ||
|
||||
user.effects[PBEffects::Attract] >= 0 ||
|
||||
eor_damage > 0
|
||||
score -= 12
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
|
||||
@@ -506,23 +506,16 @@ Battle::AI::Handlers::MoveEffectScore.add("CureUserPartyStatus",
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: target should probably be treated as an enemy when deciding the score,
|
||||
# since the score will be inverted elsewhere due to the target being an
|
||||
# ally.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CureTargetBurn",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
add_effect = move.get_score_change_for_additional_effect(user, target)
|
||||
next score if add_effect == -999 # Additional effect will be negated
|
||||
if target.status == :BURN
|
||||
if target.opposes?(user)
|
||||
score -= add_effect
|
||||
score -= 10
|
||||
else
|
||||
score += add_effect
|
||||
score += 10
|
||||
end
|
||||
score -= add_effect
|
||||
score -= 10
|
||||
score += 15 if target.wants_status_problem?(:BURN)
|
||||
end
|
||||
next score
|
||||
}
|
||||
@@ -1089,7 +1082,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("NegateTargetAbilityIfTar
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
# IgnoreTargetAbility
|
||||
|
||||
|
||||
@@ -267,13 +267,16 @@ Battle::AI::Handlers::MoveBasePower.copy("DoublePowerIfTargetHPLessThanHalf",
|
||||
"DoublePowerIfUserPoisonedBurnedParalyzed")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.copy("DoublePowerIfTargetHPLessThanHalf",
|
||||
"DoublePowerIfTargetAsleepCureTarget")
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DoublePowerIfTargetAsleepCureTarget",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score -= 20 if target.status == :SLEEP && target.statusCount > 1 # Will cure status
|
||||
if target.status == :SLEEP && target.statusCount > 1 # Will cure status
|
||||
score -= 10
|
||||
score += 15 if target.wants_status_problem?(:SLEEP)
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -288,13 +291,16 @@ Battle::AI::Handlers::MoveBasePower.add("DoublePowerIfTargetPoisoned",
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveBasePower.copy("DoublePowerIfTargetPoisoned",
|
||||
"DoublePowerIfTargetParalyzedCureTarget")
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DoublePowerIfTargetParalyzedCureTarget",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score -= 20 if target.status == :PARALYSIS # Will cure status
|
||||
if target.status == :PARALYSIS # Will cure status
|
||||
score -= 10
|
||||
score += 15 if target.wants_status_problem?(:PARALYSIS)
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -1284,7 +1290,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("PoisonTarget",
|
||||
"CategoryDependsOnHigherDamagePoisonTarget")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers. Category part is already accounted for.
|
||||
#
|
||||
#===============================================================================
|
||||
# CategoryDependsOnHigherDamageIgnoreTargetAbility
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ Battle::AI::Handlers::MoveEffectScore.add("HealUserHalfOfTotalHPLoseFlyingTypeTh
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("CureTargetStatusHealUserHalfOfTotalHP",
|
||||
proc { |move, user, target, ai, battle|
|
||||
@@ -125,13 +125,9 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("CureTargetStatusHealUse
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CureTargetStatusHealUserHalfOfTotalHP",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# TODO: Add high level checks for whether the target wants to lose their
|
||||
# status problem, and change the score accordingly.
|
||||
if target.opposes?(user)
|
||||
score -= 10
|
||||
else
|
||||
score += 15
|
||||
end
|
||||
# Will cure status
|
||||
score -= 10
|
||||
score += 15 if target.wants_status_problem?(target.status)
|
||||
# Consider how much HP will be restored
|
||||
if user.hp >= user.totalhp * 0.5
|
||||
score -= 10
|
||||
@@ -422,7 +418,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartLeechSeedTarget",
|
||||
score += 15
|
||||
end
|
||||
# Don't prefer if target can remove the seed
|
||||
if target.check_for_move { |m| m.is_a?(Battle::Move::RemoveUserBindingAndEntryHazards) }
|
||||
if target.has_move_with_function?("RemoveUserBindingAndEntryHazards")
|
||||
score -= 15
|
||||
end
|
||||
end
|
||||
|
||||
@@ -165,13 +165,40 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartTargetCannotUseItem
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: This code shouldn't make use of target.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartNegateHeldItems",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if battle.field.effects[PBEffects::MagicRoom] > 0
|
||||
score += 30 if !user.item # && target.item
|
||||
next if battle.field.effects[PBEffects::MagicRoom] == 1 # About to expire anyway
|
||||
any_held_items = false
|
||||
total_want = 0 # Positive means foes want their items more than allies do
|
||||
ai.each_battler do |b, i|
|
||||
next if !b.item
|
||||
# Skip b if its item is disabled
|
||||
if ai.trainer.medium_skill?
|
||||
if battle.field.effects[PBEffects::MagicRoom] > 0
|
||||
# NOTE: Same as b.item_active? but ignoring the Magic Room part.
|
||||
next if b.effects[PBEffects::Embargo] > 0
|
||||
next if battle.corrosiveGas[b.index % 2][b.party_index]
|
||||
next if b.has_active_ability?(:KLUTZ)
|
||||
else
|
||||
next if !b.item_active?
|
||||
end
|
||||
end
|
||||
# Rate b's held item and add it to total_want
|
||||
any_held_items = true
|
||||
want = b.wants_item?(b.item_id)
|
||||
total_want += (b.opposes?(user)) ? want : -want
|
||||
end
|
||||
# Alter score
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !any_held_items
|
||||
if battle.field.effects[PBEffects::MagicRoom] > 0
|
||||
next Battle::AI::MOVE_USELESS_SCORE if total_want >= 0
|
||||
score -= [total_want, -5].max * 5 # Will enable items, prefer if allies affected more
|
||||
else
|
||||
next Battle::AI::MOVE_USELESS_SCORE if total_want <= 0
|
||||
score += [total_want, 5].min * 5 # Will disable items, prefer if foes affected more
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ Battle::AI::Handlers::MoveFailureCheck.add("FleeFromBattle",
|
||||
Battle::AI::Handlers::MoveEffectScore.add("FleeFromBattle",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Generally don't prefer (don't want to end the battle too easily)
|
||||
next score - 15
|
||||
next score - 20
|
||||
}
|
||||
)
|
||||
|
||||
@@ -24,21 +24,19 @@ Battle::AI::Handlers::MoveFailureCheck.add("SwitchOutUserStatusMove",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserStatusMove",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next score + 10 if user.wild?
|
||||
# Wild Pokémon run from battle
|
||||
next score - 20 if user.wild?
|
||||
# Trainer-owned Pokémon switch out
|
||||
if ai.trainer.has_skill_flag?("ReserveLastPokemon") && battle.pbTeamAbleNonActiveCount(user.index) == 1
|
||||
score -= 60 # Don't switch in ace
|
||||
else
|
||||
score += 40 if user.effects[PBEffects::Confusion] > 0
|
||||
total = 0
|
||||
GameData::Stat.each_battle { |s| total += user.stages[s.id] }
|
||||
if total <= 0 || user.turnCount == 0
|
||||
score += 60
|
||||
else
|
||||
score -= total * 10
|
||||
# special case: user has no damaging moves
|
||||
score += 75 if !user.check_for_move { |m| m.damagingMove? }
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE # Don't switch in ace
|
||||
end
|
||||
# Prefer if the user switching out will lose a negative effect
|
||||
score += 10 if user.effects[PBEffects::Confusion] > 1
|
||||
# Prefer if the user doesn't have any damaging moves
|
||||
# TODO: Check effectiveness of moves.
|
||||
score += 15 if !user.check_for_move { |m| m.damagingMove? }
|
||||
# Don't prefer the more stat raises the user has
|
||||
GameData::Stat.each_battle { |s| score -= user.stages[s.id] * 5 }
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -48,8 +46,14 @@ Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserStatusMove",
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserDamagingMove",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next 0 if !battle.pbCanChooseNonActive?(user.index)
|
||||
next 0 if ai.trainer.has_skill_flag?("ReserveLastPokemon") && battle.pbTeamAbleNonActiveCount(user.index) == 1 # Don't switch in ace
|
||||
next score if !battle.pbCanChooseNonActive?(user.index)
|
||||
# Don't want to switch in ace
|
||||
score -= 20 if ai.trainer.has_skill_flag?("ReserveLastPokemon") &&
|
||||
battle.pbTeamAbleNonActiveCount(user.index) == 1
|
||||
# Prefer if the user switching out will lose a negative effect
|
||||
score += 10 if user.effects[PBEffects::Confusion] > 1
|
||||
# Don't prefer the more stat raises the user has
|
||||
GameData::Stat.each_battle { |s| score -= user.stages[s.id] * 5 }
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -72,6 +76,18 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("LowerTargetAtkSpAtk1Swi
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("LowerTargetAtkSpAtk1SwitchOutUser",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score = ai.get_score_for_target_stat_drop(score, target, move.move.statDown, false)
|
||||
if battle.pbCanChooseNonActive?(user.index)
|
||||
# Don't want to switch in ace
|
||||
score -= 20 if ai.trainer.has_skill_flag?("ReserveLastPokemon") &&
|
||||
battle.pbTeamAbleNonActiveCount(user.index) == 1
|
||||
# Prefer if the user switching out will lose a negative effect
|
||||
score += 10 if user.effects[PBEffects::Confusion] > 1
|
||||
# Prefer if the user doesn't have any damaging moves
|
||||
# TODO: Check effectiveness of moves.
|
||||
score += 15 if !user.check_for_move { |m| m.damagingMove? }
|
||||
# Don't prefer the more stat raises the user has
|
||||
GameData::Stat.each_battle { |s| score -= user.stages[s.id] * 5 }
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -86,20 +102,16 @@ Battle::AI::Handlers::MoveFailureCheck.add("SwitchOutUserPassOnEffects",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("SwitchOutUserPassOnEffects",
|
||||
proc { |score, move, user, ai, battle|
|
||||
if battle.pbCanChooseNonActive?(user.index)
|
||||
score -= 40 if user.effects[PBEffects::Confusion] > 0
|
||||
total = 0
|
||||
GameData::Stat.each_battle { |s| total += user.stages[s.id] }
|
||||
if total <= 0 || user.turnCount == 0
|
||||
score -= 60
|
||||
else
|
||||
score += total * 10
|
||||
# special case: user has no damaging moves
|
||||
score += 75 if !user.check_for_move { |m| m.damagingMove? }
|
||||
end
|
||||
else
|
||||
score -= 100
|
||||
end
|
||||
# Don't want to switch in ace
|
||||
score -= 20 if ai.trainer.has_skill_flag?("ReserveLastPokemon") &&
|
||||
battle.pbTeamAbleNonActiveCount(user.index) == 1
|
||||
# Don't prefer if the user will pass on a negative effect
|
||||
score -= 10 if user.effects[PBEffects::Confusion] > 1
|
||||
# Prefer if the user doesn't have any damaging moves
|
||||
# TODO: Check effectiveness of moves.
|
||||
score += 15 if !user.check_for_move { |m| m.damagingMove? }
|
||||
# Prefer if the user will pass on good stat stages
|
||||
GameData::Stat.each_battle { |s| score += user.stages[s.id] * 5 }
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -162,14 +174,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("BindTarget",
|
||||
# Target will take damage at the end of each round from the binding
|
||||
score += 8 if target.battler.takesIndirectDamage?
|
||||
# Check whether the target will be trapped in battle by the binding
|
||||
untrappable = Settings::MORE_TYPE_EFFECTS && target.has_type?(:GHOST)
|
||||
if !untrappable && target.ability_active?
|
||||
untrappable = Battle::AbilityEffects.triggerCertainSwitching(target.ability, target.battler, battle)
|
||||
end
|
||||
if !untrappable && target.item_active?
|
||||
untrappable = Battle::ItemEffects.triggerCertainSwitching(target.ability, target.battler, battle)
|
||||
end
|
||||
if !untrappable && !target.battler.trappedInBattle?
|
||||
if target.can_become_trapped?
|
||||
score += 8 # Prefer if the target will become trapped by this move
|
||||
eor_damage = target.rough_end_of_round_damage
|
||||
if eor_damage > 0
|
||||
@@ -185,8 +190,9 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("BindTarget",
|
||||
end
|
||||
# Don't prefer if the target can remove the binding (and the binding has an
|
||||
# effect)
|
||||
if (!untrappable && !target.battler.trappedInBattle?) || target.battler.takesIndirectDamage?
|
||||
if target.has_move_with_function?("RemoveUserBindingAndEntryHazards")
|
||||
if target.can_become_trapped? || target.battler.takesIndirectDamage?
|
||||
if ai.trainer.medium_skill? &&
|
||||
target.has_move_with_function?("RemoveUserBindingAndEntryHazards")
|
||||
score -= 8
|
||||
end
|
||||
end
|
||||
@@ -206,8 +212,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("BindTarget",
|
||||
"BindTargetDoublePowerIfTargetUnderwater")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: Include get_score_change_for_additional_effect usage.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("TrapTargetInBattle",
|
||||
proc { |move, user, target, ai, battle|
|
||||
@@ -217,15 +222,56 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("TrapTargetInBattle",
|
||||
next false
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TrapTargetInBattle",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if !target.can_become_trapped? || !battle.pbCanChooseNonActive?(target.index)
|
||||
next (move.damagingMove?) ? score : Battle::AI::MOVE_USELESS_SCORE
|
||||
end
|
||||
# Not worth trapping if target will faint this round anyway
|
||||
eor_damage = target.rough_end_of_round_damage
|
||||
if eor_damage >= target.hp
|
||||
next (move.damagingMove?) ? score : Battle::AI::MOVE_USELESS_SCORE
|
||||
end
|
||||
# Score for EOR damage (intentionally before Rapid Spin check)
|
||||
hp_fraction = (Settings::MECHANICS_GENERATION >= 6) ? 8 : 16
|
||||
if user.has_active_item?(:BINDINGBAND)
|
||||
hp_fraction = (Settings::MECHANICS_GENERATION >= 6) ? 6 : 8
|
||||
end
|
||||
rounds_to_deplete_hp = (hp_fraction.to_f * target.hp / target.totalhp).ceil
|
||||
score += 30 / rounds_to_deplete_hp
|
||||
# Not worth trapping if target can remove the binding
|
||||
if ai.trainer.medium_skill? &&
|
||||
target.has_move_with_function?("RemoveUserBindingAndEntryHazards")
|
||||
next (move.damagingMove?) ? score : Battle::AI::MOVE_USELESS_SCORE
|
||||
end
|
||||
# Score for being an additional effect
|
||||
add_effect = move.get_score_change_for_additional_effect(user, target)
|
||||
next score if add_effect == -999 # Additional effect will be negated
|
||||
score += add_effect
|
||||
# Score for target becoming trapped in battle
|
||||
# TODO: These checks are related to desire to switch, and there can be a lot
|
||||
# more things to consider, e.g. effectiveness of the target's moves
|
||||
# against its foes. Also applies to other code that calls
|
||||
# can_become_trapped?
|
||||
if target.effects[PBEffects::PerishSong] > 0 ||
|
||||
target.effects[PBEffects::Attract] >= 0 ||
|
||||
eor_damage > 0
|
||||
score += 12
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.copy("TrapTargetInBattle",
|
||||
"TrapTargetInBattleMainEffect")
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.copy("TrapTargetInBattle",
|
||||
"TrapTargetInBattleMainEffect")
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("TrapTargetInBattleLowerTargetDefSpDef1EachTurn",
|
||||
proc { |move, user, target, ai, battle|
|
||||
@@ -237,20 +283,63 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("TrapTargetInBattleLower
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TrapTargetInBattleLowerTargetDefSpDef1EachTurn",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
score += 30 if !target.battler.trappedInBattle?
|
||||
score -= 50 if !target.battler.pbCanLowerStatStage?(:DEFENSE, user.battler, move.move) &&
|
||||
!target.battler.pbCanLowerStatStage?(:SPECIAL_DEFENSE, user.battler, move.move)
|
||||
# Score for stat drop
|
||||
score = ai.get_score_for_target_stat_drop(score, target, [:DEFENSE, 1, :SPECIAL_DEFENSE], false)
|
||||
# Score for target becoming trapped in battle
|
||||
if target.can_become_trapped? && battle.pbCanChooseNonActive?(target.index)
|
||||
# Not worth trapping if target will faint this round anyway
|
||||
eor_damage = target.rough_end_of_round_damage
|
||||
if eor_damage >= target.hp
|
||||
next (move.damagingMove?) ? score : Battle::AI::MOVE_USELESS_SCORE
|
||||
end
|
||||
# Not worth trapping if target can remove the binding
|
||||
if target.has_move_with_function?("RemoveUserBindingAndEntryHazards")
|
||||
next (move.damagingMove?) ? score : Battle::AI::MOVE_USELESS_SCORE
|
||||
end
|
||||
# Score for target becoming trapped in battle
|
||||
# TODO: These checks are related to desire to switch, and there can be a lot
|
||||
# more things to consider, e.g. effectiveness of the target's moves
|
||||
# against its foes. Also applies to other code that calls
|
||||
# can_become_trapped?
|
||||
if target.effects[PBEffects::PerishSong] > 0 ||
|
||||
target.effects[PBEffects::Attract] >= 0 ||
|
||||
eor_damage > 0
|
||||
score += 12
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TrapUserAndTargetInBattle",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
if target.effects[PBEffects::JawLock] < 0
|
||||
score += 40 if !user.battler.trappedInBattle? && !target.battler.trappedInBattle?
|
||||
# NOTE: Don't worry about scoring for the user also becoming trapped in
|
||||
# battle, because it knows this move and accepts what it's getting
|
||||
# itself into.
|
||||
if target.can_become_trapped? && battle.pbCanChooseNonActive?(target.index)
|
||||
# Not worth trapping if target will faint this round anyway
|
||||
eor_damage = target.rough_end_of_round_damage
|
||||
if eor_damage >= target.hp
|
||||
next (move.damagingMove?) ? score : Battle::AI::MOVE_USELESS_SCORE
|
||||
end
|
||||
# Not worth trapping if target can remove the binding
|
||||
if ai.trainer.medium_skill? &&
|
||||
target.has_move_with_function?("RemoveUserBindingAndEntryHazards")
|
||||
next (move.damagingMove?) ? score : Battle::AI::MOVE_USELESS_SCORE
|
||||
end
|
||||
# Score for target becoming trapped in battle
|
||||
# TODO: These checks are related to desire to switch, and there can be a lot
|
||||
# more things to consider, e.g. effectiveness of the target's moves
|
||||
# against its foes. Also applies to other code that calls
|
||||
# can_become_trapped?
|
||||
if target.effects[PBEffects::PerishSong] > 0 ||
|
||||
target.effects[PBEffects::Attract] >= 0 ||
|
||||
eor_damage > 0
|
||||
score += 12
|
||||
end
|
||||
end
|
||||
next score
|
||||
}
|
||||
|
||||
@@ -28,92 +28,92 @@ module PBEffects
|
||||
Encore = 23
|
||||
EncoreMove = 24
|
||||
Endure = 25
|
||||
ExtraType = 111
|
||||
FirstPledge = 26
|
||||
FlashFire = 27
|
||||
Flinch = 28
|
||||
FocusEnergy = 29
|
||||
FocusPunch = 30
|
||||
FollowMe = 31
|
||||
Foresight = 32
|
||||
FuryCutter = 33
|
||||
GastroAcid = 34
|
||||
GemConsumed = 35
|
||||
Grudge = 36
|
||||
HealBlock = 37
|
||||
HelpingHand = 38
|
||||
HyperBeam = 39
|
||||
Illusion = 40
|
||||
Imprison = 41
|
||||
Ingrain = 42
|
||||
Instruct = 43
|
||||
Instructed = 44
|
||||
JawLock = 45
|
||||
KingsShield = 46
|
||||
LaserFocus = 47
|
||||
LeechSeed = 48
|
||||
LockOn = 49
|
||||
LockOnPos = 50
|
||||
MagicBounce = 51
|
||||
MagicCoat = 52
|
||||
MagnetRise = 53
|
||||
MeanLook = 54
|
||||
MeFirst = 55
|
||||
Metronome = 56
|
||||
MicleBerry = 57
|
||||
Minimize = 58
|
||||
MiracleEye = 59
|
||||
MirrorCoat = 60
|
||||
MirrorCoatTarget = 61
|
||||
MoveNext = 62
|
||||
MudSport = 63
|
||||
Nightmare = 64
|
||||
NoRetreat = 65
|
||||
Obstruct = 66
|
||||
Octolock = 67
|
||||
Outrage = 68
|
||||
ParentalBond = 69
|
||||
PerishSong = 70
|
||||
PerishSongUser = 71
|
||||
PickupItem = 72
|
||||
PickupUse = 73
|
||||
Pinch = 74 # Battle Palace only
|
||||
Powder = 75
|
||||
PowerTrick = 76
|
||||
Prankster = 77
|
||||
PriorityAbility = 78
|
||||
PriorityItem = 79
|
||||
Protect = 80
|
||||
ProtectRate = 81
|
||||
Quash = 82
|
||||
Rage = 83
|
||||
RagePowder = 84 # Used along with FollowMe
|
||||
Rollout = 85
|
||||
Roost = 86
|
||||
ShellTrap = 87
|
||||
SkyDrop = 88
|
||||
SlowStart = 89
|
||||
SmackDown = 90
|
||||
Snatch = 91
|
||||
SpikyShield = 92
|
||||
Spotlight = 93
|
||||
Stockpile = 94
|
||||
StockpileDef = 95
|
||||
StockpileSpDef = 96
|
||||
Substitute = 97
|
||||
TarShot = 98
|
||||
Taunt = 99
|
||||
Telekinesis = 100
|
||||
ThroatChop = 101
|
||||
Torment = 102
|
||||
Toxic = 103
|
||||
Transform = 104
|
||||
TransformSpecies = 105
|
||||
Trapping = 106 # Trapping move
|
||||
TrappingMove = 107
|
||||
TrappingUser = 108
|
||||
Truant = 109
|
||||
TwoTurnAttack = 110
|
||||
ExtraType = 26
|
||||
FirstPledge = 27
|
||||
FlashFire = 28
|
||||
Flinch = 29
|
||||
FocusEnergy = 30
|
||||
FocusPunch = 31
|
||||
FollowMe = 32
|
||||
Foresight = 33
|
||||
FuryCutter = 34
|
||||
GastroAcid = 35
|
||||
GemConsumed = 36
|
||||
Grudge = 37
|
||||
HealBlock = 38
|
||||
HelpingHand = 39
|
||||
HyperBeam = 40
|
||||
Illusion = 41
|
||||
Imprison = 42
|
||||
Ingrain = 43
|
||||
Instruct = 44
|
||||
Instructed = 45
|
||||
JawLock = 46
|
||||
KingsShield = 47
|
||||
LaserFocus = 48
|
||||
LeechSeed = 49
|
||||
LockOn = 50
|
||||
LockOnPos = 51
|
||||
MagicBounce = 52
|
||||
MagicCoat = 53
|
||||
MagnetRise = 54
|
||||
MeanLook = 55
|
||||
MeFirst = 56
|
||||
Metronome = 57
|
||||
MicleBerry = 58
|
||||
Minimize = 59
|
||||
MiracleEye = 60
|
||||
MirrorCoat = 61
|
||||
MirrorCoatTarget = 62
|
||||
MoveNext = 63
|
||||
MudSport = 64
|
||||
Nightmare = 65
|
||||
NoRetreat = 66
|
||||
Obstruct = 67
|
||||
Octolock = 68
|
||||
Outrage = 69
|
||||
ParentalBond = 70
|
||||
PerishSong = 71
|
||||
PerishSongUser = 72
|
||||
PickupItem = 73
|
||||
PickupUse = 74
|
||||
Pinch = 75 # Battle Palace only
|
||||
Powder = 76
|
||||
PowerTrick = 77
|
||||
Prankster = 78
|
||||
PriorityAbility = 79
|
||||
PriorityItem = 80
|
||||
Protect = 81
|
||||
ProtectRate = 82
|
||||
Quash = 83
|
||||
Rage = 84
|
||||
RagePowder = 85 # Used along with FollowMe
|
||||
Rollout = 86
|
||||
Roost = 87
|
||||
ShellTrap = 88
|
||||
SkyDrop = 89
|
||||
SlowStart = 90
|
||||
SmackDown = 91
|
||||
Snatch = 92
|
||||
SpikyShield = 93
|
||||
Spotlight = 94
|
||||
Stockpile = 95
|
||||
StockpileDef = 96
|
||||
StockpileSpDef = 97
|
||||
Substitute = 98
|
||||
TarShot = 99
|
||||
Taunt = 100
|
||||
Telekinesis = 101
|
||||
ThroatChop = 102
|
||||
Torment = 103
|
||||
Toxic = 104
|
||||
Transform = 105
|
||||
TransformSpecies = 106
|
||||
Trapping = 107 # Trapping move that deals EOR damage
|
||||
TrappingMove = 108
|
||||
TrappingUser = 109
|
||||
Truant = 110
|
||||
TwoTurnAttack = 111
|
||||
Unburden = 112
|
||||
Uproar = 113
|
||||
WaterSport = 114
|
||||
@@ -123,56 +123,56 @@ module PBEffects
|
||||
#=============================================================================
|
||||
# These effects apply to a battler position
|
||||
#=============================================================================
|
||||
FutureSightCounter = 0
|
||||
FutureSightMove = 1
|
||||
FutureSightUserIndex = 2
|
||||
FutureSightUserPartyIndex = 3
|
||||
HealingWish = 4
|
||||
LunarDance = 5
|
||||
Wish = 6
|
||||
WishAmount = 7
|
||||
WishMaker = 8
|
||||
FutureSightCounter = 700
|
||||
FutureSightMove = 701
|
||||
FutureSightUserIndex = 702
|
||||
FutureSightUserPartyIndex = 703
|
||||
HealingWish = 704
|
||||
LunarDance = 705
|
||||
Wish = 706
|
||||
WishAmount = 707
|
||||
WishMaker = 708
|
||||
|
||||
#=============================================================================
|
||||
# These effects apply to a side
|
||||
#=============================================================================
|
||||
AuroraVeil = 0
|
||||
CraftyShield = 1
|
||||
EchoedVoiceCounter = 2
|
||||
EchoedVoiceUsed = 3
|
||||
LastRoundFainted = 4
|
||||
LightScreen = 5
|
||||
LuckyChant = 6
|
||||
MatBlock = 7
|
||||
Mist = 8
|
||||
QuickGuard = 9
|
||||
Rainbow = 10
|
||||
Reflect = 11
|
||||
Round = 12
|
||||
Safeguard = 13
|
||||
SeaOfFire = 14
|
||||
Spikes = 15
|
||||
StealthRock = 16
|
||||
StickyWeb = 17
|
||||
Swamp = 18
|
||||
Tailwind = 19
|
||||
ToxicSpikes = 20
|
||||
WideGuard = 21
|
||||
AuroraVeil = 800
|
||||
CraftyShield = 801
|
||||
EchoedVoiceCounter = 802
|
||||
EchoedVoiceUsed = 803
|
||||
LastRoundFainted = 804
|
||||
LightScreen = 805
|
||||
LuckyChant = 806
|
||||
MatBlock = 807
|
||||
Mist = 808
|
||||
QuickGuard = 809
|
||||
Rainbow = 810
|
||||
Reflect = 811
|
||||
Round = 812
|
||||
Safeguard = 813
|
||||
SeaOfFire = 814
|
||||
Spikes = 815
|
||||
StealthRock = 816
|
||||
StickyWeb = 817
|
||||
Swamp = 818
|
||||
Tailwind = 819
|
||||
ToxicSpikes = 820
|
||||
WideGuard = 821
|
||||
|
||||
#=============================================================================
|
||||
# These effects apply to the battle (i.e. both sides)
|
||||
#=============================================================================
|
||||
AmuletCoin = 0
|
||||
FairyLock = 1
|
||||
FusionBolt = 2
|
||||
FusionFlare = 3
|
||||
Gravity = 4
|
||||
HappyHour = 5
|
||||
IonDeluge = 6
|
||||
MagicRoom = 7
|
||||
MudSportField = 8
|
||||
PayDay = 9
|
||||
TrickRoom = 10
|
||||
WaterSportField = 11
|
||||
WonderRoom = 12
|
||||
AmuletCoin = 900
|
||||
FairyLock = 901
|
||||
FusionBolt = 902
|
||||
FusionFlare = 903
|
||||
Gravity = 904
|
||||
HappyHour = 905
|
||||
IonDeluge = 906
|
||||
MagicRoom = 907
|
||||
MudSportField = 908
|
||||
PayDay = 909
|
||||
TrickRoom = 910
|
||||
WaterSportField = 911
|
||||
WonderRoom = 912
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user