mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-08 05:34:58 +00:00
Rewrote AI calculations for moves that cause confusion, flinching and infatuation
This commit is contained in:
@@ -651,6 +651,34 @@ end
|
|||||||
# Changes user's type depending on the environment. (Camouflage)
|
# Changes user's type depending on the environment. (Camouflage)
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class Battle::Move::SetUserTypesBasedOnEnvironment < Battle::Move
|
class Battle::Move::SetUserTypesBasedOnEnvironment < Battle::Move
|
||||||
|
TERRAIN_TYPES = {
|
||||||
|
:Electric => :ELECTRIC,
|
||||||
|
:Grassy => :GRASS,
|
||||||
|
:Misty => :FAIRY,
|
||||||
|
:Psychic => :PSYCHIC
|
||||||
|
}
|
||||||
|
ENVIRONMENT_TYPES = {
|
||||||
|
:None => :NORMAL,
|
||||||
|
:Grass => :GRASS,
|
||||||
|
:TallGrass => :GRASS,
|
||||||
|
:MovingWater => :WATER,
|
||||||
|
:StillWater => :WATER,
|
||||||
|
:Puddle => :WATER,
|
||||||
|
:Underwater => :WATER,
|
||||||
|
:Cave => :ROCK,
|
||||||
|
:Rock => :GROUND,
|
||||||
|
:Sand => :GROUND,
|
||||||
|
:Forest => :BUG,
|
||||||
|
:ForestGrass => :BUG,
|
||||||
|
:Snow => :ICE,
|
||||||
|
:Ice => :ICE,
|
||||||
|
:Volcano => :FIRE,
|
||||||
|
:Graveyard => :GHOST,
|
||||||
|
:Sky => :FLYING,
|
||||||
|
:Space => :DRAGON,
|
||||||
|
:UltraSpace => :PSYCHIC
|
||||||
|
}
|
||||||
|
|
||||||
def canSnatch?; return true; end
|
def canSnatch?; return true; end
|
||||||
|
|
||||||
def pbMoveFailed?(user, targets)
|
def pbMoveFailed?(user, targets)
|
||||||
@@ -659,56 +687,13 @@ class Battle::Move::SetUserTypesBasedOnEnvironment < Battle::Move
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@newType = :NORMAL
|
@newType = :NORMAL
|
||||||
checkedTerrain = false
|
terr_type = TERRAIN_TYPES[@battle.field.terrain]
|
||||||
case @battle.field.terrain
|
if terr_type && GameData::Type.exists?(terr_type)
|
||||||
when :Electric
|
@newType = terr_type
|
||||||
if GameData::Type.exists?(:ELECTRIC)
|
else
|
||||||
@newType = :ELECTRIC
|
@newType = ENVIRONMENT_TYPES[@battle.environment] || :NORMAL
|
||||||
checkedTerrain = true
|
@newType = :NORMAL if !GameData::Type.exists?(@newType)
|
||||||
end
|
|
||||||
when :Grassy
|
|
||||||
if GameData::Type.exists?(:GRASS)
|
|
||||||
@newType = :GRASS
|
|
||||||
checkedTerrain = true
|
|
||||||
end
|
|
||||||
when :Misty
|
|
||||||
if GameData::Type.exists?(:FAIRY)
|
|
||||||
@newType = :FAIRY
|
|
||||||
checkedTerrain = true
|
|
||||||
end
|
|
||||||
when :Psychic
|
|
||||||
if GameData::Type.exists?(:PSYCHIC)
|
|
||||||
@newType = :PSYCHIC
|
|
||||||
checkedTerrain = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
if !checkedTerrain
|
|
||||||
case @battle.environment
|
|
||||||
when :Grass, :TallGrass
|
|
||||||
@newType = :GRASS
|
|
||||||
when :MovingWater, :StillWater, :Puddle, :Underwater
|
|
||||||
@newType = :WATER
|
|
||||||
when :Cave
|
|
||||||
@newType = :ROCK
|
|
||||||
when :Rock, :Sand
|
|
||||||
@newType = :GROUND
|
|
||||||
when :Forest, :ForestGrass
|
|
||||||
@newType = :BUG
|
|
||||||
when :Snow, :Ice
|
|
||||||
@newType = :ICE
|
|
||||||
when :Volcano
|
|
||||||
@newType = :FIRE
|
|
||||||
when :Graveyard
|
|
||||||
@newType = :GHOST
|
|
||||||
when :Sky
|
|
||||||
@newType = :FLYING
|
|
||||||
when :Space
|
|
||||||
@newType = :DRAGON
|
|
||||||
when :UltraSpace
|
|
||||||
@newType = :PSYCHIC
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@newType = :NORMAL if !GameData::Type.exists?(@newType)
|
|
||||||
if !GameData::Type.exists?(@newType) || !user.pbHasOtherType?(@newType)
|
if !GameData::Type.exists?(@newType) || !user.pbHasOtherType?(@newType)
|
||||||
@battle.pbDisplay(_INTL("But it failed!"))
|
@battle.pbDisplay(_INTL("But it failed!"))
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -14,7 +14,13 @@ Battle::AI::Handlers::MoveEffectScore.add("SleepTarget",
|
|||||||
next score if target.faster_than?(user) &&
|
next score if target.faster_than?(user) &&
|
||||||
target.has_active_ability?(:HYDRATION) &&
|
target.has_active_ability?(:HYDRATION) &&
|
||||||
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
if move.statusMove? || target.battler.pbCanSleep?(user.battler, false, move.move)
|
if target.battler.pbCanSleep?(user.battler, false, move.move)
|
||||||
|
case move.additional_effect_usability(user, target)
|
||||||
|
when 1 # Additional effect will be negated
|
||||||
|
next score
|
||||||
|
when 3 # Additional effect has an increased chance to work
|
||||||
|
score += 5
|
||||||
|
end
|
||||||
# Inherent preference
|
# Inherent preference
|
||||||
score += 15
|
score += 15
|
||||||
# Prefer if the user or an ally has a move/ability that is better if the target is asleep
|
# Prefer if the user or an ally has a move/ability that is better if the target is asleep
|
||||||
@@ -95,7 +101,13 @@ Battle::AI::Handlers::MoveEffectScore.add("PoisonTarget",
|
|||||||
next score if target.faster_than?(user) &&
|
next score if target.faster_than?(user) &&
|
||||||
target.has_active_ability?(:HYDRATION) &&
|
target.has_active_ability?(:HYDRATION) &&
|
||||||
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
if move.statusMove? || target.battler.pbCanPoison?(user.battler, false, move.move)
|
if target.battler.pbCanPoison?(user.battler, false, move.move)
|
||||||
|
case move.additional_effect_usability(user, target)
|
||||||
|
when 1 # Additional effect will be negated
|
||||||
|
next score
|
||||||
|
when 3 # Additional effect has an increased chance to work
|
||||||
|
score += 5
|
||||||
|
end
|
||||||
# Inherent preference
|
# Inherent preference
|
||||||
score += 10
|
score += 10
|
||||||
# Prefer if the target is at high HP
|
# Prefer if the target is at high HP
|
||||||
@@ -176,7 +188,13 @@ Battle::AI::Handlers::MoveEffectScore.add("ParalyzeTarget",
|
|||||||
next score if target.faster_than?(user) &&
|
next score if target.faster_than?(user) &&
|
||||||
target.has_active_ability?(:HYDRATION) &&
|
target.has_active_ability?(:HYDRATION) &&
|
||||||
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
if move.statusMove? || target.battler.pbCanParalyze?(user.battler, false, move.move)
|
if target.battler.pbCanParalyze?(user.battler, false, move.move)
|
||||||
|
case move.additional_effect_usability(user, target)
|
||||||
|
when 1 # Additional effect will be negated
|
||||||
|
next score
|
||||||
|
when 3 # Additional effect has an increased chance to work
|
||||||
|
score += 5
|
||||||
|
end
|
||||||
# Inherent preference (because of the chance of full paralysis)
|
# Inherent preference (because of the chance of full paralysis)
|
||||||
score += 10
|
score += 10
|
||||||
# Prefer if the target is faster than the user but will become slower if
|
# Prefer if the target is faster than the user but will become slower if
|
||||||
@@ -238,10 +256,17 @@ Battle::AI::Handlers::MoveEffectScore.copy("ParalyzeTarget",
|
|||||||
"ParalyzeTargetAlwaysHitsInRainHitsTargetInSky")
|
"ParalyzeTargetAlwaysHitsInRainHitsTargetInSky")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.copy("ParalyzeTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("ParalyzeFlinchTarget",
|
||||||
"ParalyzeFlinchTarget")
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
score = Battle::AI::Handlers.apply_move_effect_score("ParalyzeTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
score = Battle::AI::Handlers.apply_move_effect_score("FlinchTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
next score
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
#
|
#
|
||||||
@@ -259,7 +284,13 @@ Battle::AI::Handlers::MoveEffectScore.add("BurnTarget",
|
|||||||
next score if target.faster_than?(user) &&
|
next score if target.faster_than?(user) &&
|
||||||
target.has_active_ability?(:HYDRATION) &&
|
target.has_active_ability?(:HYDRATION) &&
|
||||||
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
if move.statusMove? || target.battler.pbCanBurn?(user.battler, false, move.move)
|
if target.battler.pbCanBurn?(user.battler, false, move.move)
|
||||||
|
case move.additional_effect_usability(user, target)
|
||||||
|
when 1 # Additional effect will be negated
|
||||||
|
next score
|
||||||
|
when 3 # Additional effect has an increased chance to work
|
||||||
|
score += 5
|
||||||
|
end
|
||||||
# Inherent preference
|
# Inherent preference
|
||||||
score += 10
|
score += 10
|
||||||
# Prefer if the target knows any physical moves that will be weaked by a burn
|
# Prefer if the target knows any physical moves that will be weaked by a burn
|
||||||
@@ -304,10 +335,17 @@ Battle::AI::Handlers::MoveEffectScore.add("BurnTarget",
|
|||||||
# BurnTargetIfTargetStatsRaisedThisTurn
|
# BurnTargetIfTargetStatsRaisedThisTurn
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.copy("BurnTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("BurnFlinchTarget",
|
||||||
"BurnFlinchTarget")
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
score = Battle::AI::Handlers.apply_move_effect_score("BurnTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
score = Battle::AI::Handlers.apply_move_effect_score("FlinchTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
next score
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
#
|
#
|
||||||
@@ -325,7 +363,13 @@ Battle::AI::Handlers::MoveEffectScore.add("FreezeTarget",
|
|||||||
next score if target.faster_than?(user) &&
|
next score if target.faster_than?(user) &&
|
||||||
target.has_active_ability?(:HYDRATION) &&
|
target.has_active_ability?(:HYDRATION) &&
|
||||||
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
[:Rain, :HeavyRain].include?(target.battler.effectiveWeather)
|
||||||
if move.statusMove? || target.battler.pbCanFreeze?(user.battler, false, move.move)
|
if target.battler.pbCanFreeze?(user.battler, false, move.move)
|
||||||
|
case move.additional_effect_usability(user, target)
|
||||||
|
when 1 # Additional effect will be negated
|
||||||
|
next score
|
||||||
|
when 3 # Additional effect has an increased chance to work
|
||||||
|
score += 5
|
||||||
|
end
|
||||||
# Inherent preference
|
# Inherent preference
|
||||||
score += 15
|
score += 15
|
||||||
# Prefer if the user or an ally has a move/ability that is better if the target is frozen
|
# Prefer if the user or an ally has a move/ability that is better if the target is frozen
|
||||||
@@ -367,10 +411,17 @@ Battle::AI::Handlers::MoveEffectScore.copy("FreezeTarget",
|
|||||||
"FreezeTargetAlwaysHitsInHail")
|
"FreezeTargetAlwaysHitsInHail")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.copy("FreezeTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("FreezeTarget",
|
||||||
"FreezeFlinchTarget")
|
proc { |score, move, user, target, ai, battle|
|
||||||
|
score = Battle::AI::Handlers.apply_move_effect_score("FreezeTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
score = Battle::AI::Handlers.apply_move_effect_score("FlinchTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
next score
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
#
|
#
|
||||||
@@ -395,7 +446,7 @@ Battle::AI::Handlers::MoveEffectScore.add("ParalyzeBurnOrFreezeTarget",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("GiveUserStatusToTarget",
|
Battle::AI::Handlers::MoveFailureCheck.add("GiveUserStatusToTarget",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -405,12 +456,30 @@ Battle::AI::Handlers::MoveFailureCheck.add("GiveUserStatusToTarget",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("GiveUserStatusToTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("GiveUserStatusToTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next score + 40
|
score += 10 # For getting rid of the user's status problem
|
||||||
|
case user.status
|
||||||
|
when :SLEEP
|
||||||
|
next Battle::AI::Handlers.apply_move_effect_score("SleepTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
when :PARALYSIS
|
||||||
|
next Battle::AI::Handlers.apply_move_effect_score("ParalyzeTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
when :POISON
|
||||||
|
next Battle::AI::Handlers.apply_move_effect_score("PoisonTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
when :BURN
|
||||||
|
next Battle::AI::Handlers.apply_move_effect_score("BurnTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
when :FROZEN
|
||||||
|
next Battle::AI::Handlers.apply_move_effect_score("FreezeTarget",
|
||||||
|
score, move, user, target, ai, battle)
|
||||||
|
end
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("CureUserBurnPoisonParalysis",
|
Battle::AI::Handlers::MoveFailureCheck.add("CureUserBurnPoisonParalysis",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -419,26 +488,12 @@ Battle::AI::Handlers::MoveFailureCheck.add("CureUserBurnPoisonParalysis",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("CureUserBurnPoisonParalysis",
|
Battle::AI::Handlers::MoveEffectScore.add("CureUserBurnPoisonParalysis",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
case user.status
|
next score + 15
|
||||||
when :POISON
|
|
||||||
score += 40
|
|
||||||
if ai.trainer.medium_skill?
|
|
||||||
if user.hp < user.totalhp / 8
|
|
||||||
score += 60
|
|
||||||
elsif ai.trainer.high_skill? &&
|
|
||||||
user.hp < (user.effects[PBEffects::Toxic] + 1) * user.totalhp / 16
|
|
||||||
score += 60
|
|
||||||
end
|
|
||||||
end
|
|
||||||
when :BURN, :PARALYSIS
|
|
||||||
score += 40
|
|
||||||
end
|
|
||||||
next score
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("CureUserPartyStatus",
|
Battle::AI::Handlers::MoveFailureCheck.add("CureUserPartyStatus",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -451,11 +506,9 @@ Battle::AI::Handlers::MoveFailureCheck.add("CureUserPartyStatus",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("CureUserPartyStatus",
|
Battle::AI::Handlers::MoveEffectScore.add("CureUserPartyStatus",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
statuses = 0
|
|
||||||
battle.pbParty(user.index).each do |pkmn|
|
battle.pbParty(user.index).each do |pkmn|
|
||||||
statuses += 1 if pkmn && pkmn.status != :NONE
|
score += 10 if pkmn && pkmn.status != :NONE
|
||||||
end
|
end
|
||||||
score += 20 * statuses
|
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -487,73 +540,73 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartUserSideImmunityToInflictedStat
|
|||||||
Battle::AI::Handlers::MoveEffectScore.add("StartUserSideImmunityToInflictedStatus",
|
Battle::AI::Handlers::MoveEffectScore.add("StartUserSideImmunityToInflictedStatus",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if user.status != :NONE
|
if user.status != :NONE
|
||||||
score -= 40
|
score -= 20
|
||||||
else
|
else
|
||||||
score += 30
|
score += 10
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("FlinchTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("FlinchTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next score + 30 if (battle.moldBreaker || !target.has_active_ability?(:INNERFOCUS)) &&
|
next score if target.faster_than?(user) || target.effects[PBEffects::Substitute] > 0
|
||||||
target.effects[PBEffects::Substitute] == 0
|
next score if target.has_active_ability?(:INNERFOCUS) && !battle.moldBreaker
|
||||||
|
case move.additional_effect_usability(user, target)
|
||||||
|
when 1 # Additional effect will be negated
|
||||||
|
next score
|
||||||
|
when 3 # Additional effect has an increased chance to work
|
||||||
|
score += 5
|
||||||
|
end
|
||||||
|
# Inherent preference
|
||||||
|
score += 10
|
||||||
|
# Prefer if the target is paralysed, confused or infatuated, to compound the turn skipping
|
||||||
|
# TODO: Also prefer if the target is trapped in battle or can't switch out?
|
||||||
|
score += 5 if target.status == :PARALYSIS ||
|
||||||
|
target.effects[PBEffects::Confusion] > 1 ||
|
||||||
|
target.effects[PBEffects::Attract] >= 0
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("FlinchTargetFailsIfUserNotAsleep",
|
Battle::AI::Handlers::MoveFailureCheck.add("FlinchTargetFailsIfUserNotAsleep",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if !user.battler.asleep?
|
next true if !user.battler.asleep?
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("FlinchTargetFailsIfUserNotAsleep",
|
Battle::AI::Handlers::MoveEffectScore.copy("FlinchTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
"FlinchTargetFailsIfUserNotAsleep")
|
||||||
score += 100 # Because it can only be used while asleep
|
|
||||||
score += 30 if (battle.moldBreaker || !target.has_active_ability?(:INNERFOCUS)) &&
|
|
||||||
target.effects[PBEffects::Substitute] == 0
|
|
||||||
next score
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("FlinchTargetFailsIfNotUserFirstTurn",
|
Battle::AI::Handlers::MoveFailureCheck.add("FlinchTargetFailsIfNotUserFirstTurn",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if user.turnCount > 0
|
next true if user.turnCount > 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("FlinchTargetFailsIfNotUserFirstTurn",
|
Battle::AI::Handlers::MoveEffectScore.copy("FlinchTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
"FlinchTargetFailsIfNotUserFirstTurn")
|
||||||
next score + 30 if (battle.moldBreaker || !target.has_active_ability?(:INNERFOCUS)) &&
|
|
||||||
target.effects[PBEffects::Substitute] == 0
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveBasePower.add("FlinchTargetDoublePowerIfTargetInSky",
|
Battle::AI::Handlers::MoveBasePower.add("FlinchTargetDoublePowerIfTargetInSky",
|
||||||
proc { |power, move, user, target, ai, battle|
|
proc { |power, move, user, target, ai, battle|
|
||||||
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
next move.move.pbBaseDamage(power, user.battler, target.battler)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("FlinchTargetDoublePowerIfTargetInSky",
|
Battle::AI::Handlers::MoveEffectScore.copy("FlinchTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
"FlinchTargetDoublePowerIfTargetInSky")
|
||||||
next score + 30 if (battle.moldBreaker || !target.has_active_ability?(:INNERFOCUS)) &&
|
|
||||||
target.effects[PBEffects::Substitute] == 0
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("ConfuseTarget",
|
Battle::AI::Handlers::MoveFailureCheck.add("ConfuseTarget",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -562,18 +615,37 @@ Battle::AI::Handlers::MoveFailureCheck.add("ConfuseTarget",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("ConfuseTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("ConfuseTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
next score + 30 if target.battler.pbCanConfuse?(user.battler, false, move.move)
|
# No score modifier if the status problem will be removed immediately
|
||||||
|
next score if target.has_active_item?(:PERSIMBERRY)
|
||||||
|
if target.battler.pbCanConfuse?(user.battler, false, move.move)
|
||||||
|
case move.additional_effect_usability(user, target)
|
||||||
|
when 1 # Additional effect will be negated
|
||||||
|
next score
|
||||||
|
when 3 # Additional effect has an increased chance to work
|
||||||
|
score += 5
|
||||||
|
end
|
||||||
|
# Inherent preference
|
||||||
|
score += 5
|
||||||
|
# Prefer if the target is at high HP
|
||||||
|
score += 10 * target.hp / target.totalhp
|
||||||
|
# Prefer if the target is paralysed or infatuated, to compound the turn skipping
|
||||||
|
# TODO: Also prefer if the target is trapped in battle or can't switch out?
|
||||||
|
score += 5 if target.status == :PARALYSIS || target.effects[PBEffects::Attract] >= 0
|
||||||
|
# Don't prefer if target benefits from being confused
|
||||||
|
score -= 10 if target.has_active_ability?(:TANGLEDFEET)
|
||||||
|
end
|
||||||
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.copy("ConfuseTarget",
|
Battle::AI::Handlers::MoveEffectScore.copy("ConfuseTarget",
|
||||||
"ConfuseTargetAlwaysHitsInRainHitsTargetInSky")
|
"ConfuseTargetAlwaysHitsInRainHitsTargetInSky")
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("AttractTarget",
|
Battle::AI::Handlers::MoveFailureCheck.add("AttractTarget",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -583,11 +655,22 @@ Battle::AI::Handlers::MoveFailureCheck.add("AttractTarget",
|
|||||||
Battle::AI::Handlers::MoveEffectScore.add("AttractTarget",
|
Battle::AI::Handlers::MoveEffectScore.add("AttractTarget",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if target.battler.pbCanAttract?(user.battler, false)
|
if target.battler.pbCanAttract?(user.battler, false)
|
||||||
score += 30
|
case move.additional_effect_usability(user, target)
|
||||||
if target.has_active_item?(:DESTINYKNOT) &&
|
when 1 # Additional effect will be negated
|
||||||
user.battler.pbCanAttract?(target.battler, false)
|
next score
|
||||||
score -= 30
|
when 3 # Additional effect has an increased chance to work
|
||||||
|
score += 5
|
||||||
end
|
end
|
||||||
|
# Inherent preference
|
||||||
|
score += 10
|
||||||
|
# Prefer if the target is paralysed or confused, to compound the turn skipping
|
||||||
|
# TODO: Also prefer if the target is trapped in battle or can't switch out?
|
||||||
|
score += 5 if target.status == :PARALYSIS || target.effects[PBEffects::Confusion] > 1
|
||||||
|
# Don't prefer if the target can infatuate the user because of this move
|
||||||
|
score -= 10 if target.has_active_item?(:DESTINYKNOT) &&
|
||||||
|
user.battler.pbCanAttract?(target.battler, false)
|
||||||
|
# Don't prefer if the user has another way to infatuate the target
|
||||||
|
score -= 8 if move.statusMove? && user.has_active_ability?(:CUTECHARM)
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
@@ -600,43 +683,16 @@ Battle::AI::Handlers::MoveFailureCheck.add("SetUserTypesBasedOnEnvironment",
|
|||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if !user.battler.canChangeType?
|
next true if !user.battler.canChangeType?
|
||||||
new_type = nil
|
new_type = nil
|
||||||
case battle.field.terrain
|
terr_types = Battle::Move::SetUserTypesBasedOnEnvironment::TERRAIN_TYPES
|
||||||
when :Electric
|
terr_type = terr_types[battle.field.terrain]
|
||||||
new_type = :ELECTRIC if GameData::Type.exists?(:ELECTRIC)
|
if terr_type && GameData::Type.exists?(terr_type)
|
||||||
when :Grassy
|
new_type = terr_type
|
||||||
new_type = :GRASS if GameData::Type.exists?(:GRASS)
|
else
|
||||||
when :Misty
|
env_types = Battle::Move::SetUserTypesBasedOnEnvironment::ENVIRONMENT_TYPES
|
||||||
new_type = :FAIRY if GameData::Type.exists?(:FAIRY)
|
new_type = env_types[battle.environment] || :NORMAL
|
||||||
when :Psychic
|
new_type = :NORMAL if !GameData::Type.exists?(new_type)
|
||||||
new_type = :PSYCHIC if GameData::Type.exists?(:PSYCHIC)
|
|
||||||
end
|
end
|
||||||
if !new_type
|
next true if !GameData::Type.exists?(new_type) || !user.battler.pbHasOtherType?(new_type)
|
||||||
envtypes = {
|
|
||||||
:None => :NORMAL,
|
|
||||||
:Grass => :GRASS,
|
|
||||||
:TallGrass => :GRASS,
|
|
||||||
:MovingWater => :WATER,
|
|
||||||
:StillWater => :WATER,
|
|
||||||
:Puddle => :WATER,
|
|
||||||
:Underwater => :WATER,
|
|
||||||
:Cave => :ROCK,
|
|
||||||
:Rock => :GROUND,
|
|
||||||
:Sand => :GROUND,
|
|
||||||
:Forest => :BUG,
|
|
||||||
:ForestGrass => :BUG,
|
|
||||||
:Snow => :ICE,
|
|
||||||
:Ice => :ICE,
|
|
||||||
:Volcano => :FIRE,
|
|
||||||
:Graveyard => :GHOST,
|
|
||||||
:Sky => :FLYING,
|
|
||||||
:Space => :DRAGON,
|
|
||||||
:UltraSpace => :PSYCHIC
|
|
||||||
}
|
|
||||||
new_type = envtypes[battle.environment]
|
|
||||||
new_type = nil if !GameData::Type.exists?(new_type)
|
|
||||||
new_type ||= :NORMAL
|
|
||||||
end
|
|
||||||
next true if !user.battler.pbHasOtherType?(new_type)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -694,41 +750,27 @@ Battle::AI::Handlers::MoveFailureCheck.add("SetUserTypesToUserMoveType",
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("SetTargetTypesToPsychic",
|
Battle::AI::Handlers::MoveFailureCheck.add("SetTargetTypesToPsychic",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if !target.battler.canChangeType?
|
next move.move.pbFailsAgainstTarget?(user.battler, target.battler, false)
|
||||||
next true if !GameData::Type.exists?(:PSYCHIC) || !target.battler.pbHasOtherType?(:PSYCHIC)
|
|
||||||
next true if !target.battler.affectedByPowder?
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
# TODO: Review score modifiers.
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("SetTargetTypesToWater",
|
Battle::AI::Handlers::MoveFailureCheck.copy("SetTargetTypesToPsychic",
|
||||||
proc { |move, user, target, ai, battle|
|
"SetTargetTypesToWater")
|
||||||
next true if !target.battler.canChangeType?
|
|
||||||
next true if !GameData::Type.exists?(:WATER) || !target.battler.pbHasOtherType?(:WATER)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
# TODO: Review score modifiers.
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("AddGhostTypeToTarget",
|
Battle::AI::Handlers::MoveFailureCheck.copy("SetTargetTypesToWater",
|
||||||
proc { |move, user, target, ai, battle|
|
"AddGhostTypeToTarget")
|
||||||
next true if !target.battler.canChangeType?
|
|
||||||
next true if !GameData::Type.exists?(:GHOST) || target.has_type?(:GHOST)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
# TODO: Review score modifiers.
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("AddGrassTypeToTarget",
|
Battle::AI::Handlers::MoveFailureCheck.copy("AddGhostTypeToTarget",
|
||||||
proc { |move, user, target, ai, battle|
|
"AddGrassTypeToTarget")
|
||||||
next true if !target.battler.canChangeType?
|
|
||||||
next true if !GameData::Type.exists?(:GRASS) || target.has_type?(:GRASS)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
# TODO: Review score modifiers.
|
||||||
@@ -831,8 +873,7 @@ Battle::AI::Handlers::MoveEffectScore.add("UserTargetSwapAbilities",
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("NegateTargetAbility",
|
Battle::AI::Handlers::MoveFailureCheck.add("NegateTargetAbility",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if target.battler.unstoppableAbility? ||
|
next move.move.pbFailsAgainstTarget?(user.battler, target.battler, false)
|
||||||
target.effects[PBEffects::GastroAcid]
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -841,11 +882,7 @@ Battle::AI::Handlers::MoveFailureCheck.add("NegateTargetAbility",
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("NegateTargetAbilityIfTargetActed",
|
Battle::AI::Handlers::MoveEffectScore.add("NegateTargetAbilityIfTargetActed",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if ai.trainer.medium_skill?
|
score += 15 if target.faster_than?(user)
|
||||||
score += 30 if target.faster_than?(user)
|
|
||||||
else
|
|
||||||
score += 30
|
|
||||||
end
|
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -871,19 +908,12 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartUserAirborne",
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("StartTargetAirborneAndAlwaysHitByMoves",
|
Battle::AI::Handlers::MoveFailureCheck.add("StartTargetAirborneAndAlwaysHitByMoves",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if target.effects[PBEffects::Ingrain] ||
|
next move.move.pbFailsAgainstTarget?(user.battler, target.battler, false)
|
||||||
target.effects[PBEffects::SmackDown] ||
|
|
||||||
target.effects[PBEffects::Telekinesis] > 0
|
|
||||||
next true if target.battler.isSpecies?(:DIGLETT) ||
|
|
||||||
target.battler.isSpecies?(:DUGTRIO) ||
|
|
||||||
target.battler.isSpecies?(:SANDYGAST) ||
|
|
||||||
target.battler.isSpecies?(:PALOSSAND) ||
|
|
||||||
(target.battler.isSpecies?(:GENGAR) && target.battler.mega?)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# HitsTargetInSky
|
# HitsTargetInSky
|
||||||
|
|
||||||
@@ -917,22 +947,21 @@ Battle::AI::Handlers::MoveFailureCheck.add("StartGravity",
|
|||||||
Battle::AI::Handlers::MoveEffectScore.add("StartGravity",
|
Battle::AI::Handlers::MoveEffectScore.add("StartGravity",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if ai.trainer.medium_skill?
|
if ai.trainer.medium_skill?
|
||||||
score -= 30
|
score -= 15 if user.effects[PBEffects::SkyDrop] >= 0 ||
|
||||||
score -= 20 if user.effects[PBEffects::SkyDrop] >= 0
|
user.effects[PBEffects::MagnetRise] > 0 ||
|
||||||
score -= 20 if user.effects[PBEffects::MagnetRise] > 0
|
user.effects[PBEffects::Telekinesis] > 0 ||
|
||||||
score -= 20 if user.effects[PBEffects::Telekinesis] > 0
|
user.has_type?(:FLYING) ||
|
||||||
score -= 20 if user.has_type?(:FLYING)
|
user.has_active_ability?(:LEVITATE) ||
|
||||||
score -= 20 if user.has_active_ability?(:LEVITATE)
|
user.has_active_item?(:AIRBALLOON)
|
||||||
score -= 20 if user.has_active_item?(:AIRBALLOON)
|
score += 15 if target.effects[PBEffects::SkyDrop] >= 0 ||
|
||||||
score += 20 if target.effects[PBEffects::SkyDrop] >= 0
|
target.effects[PBEffects::MagnetRise] > 0 ||
|
||||||
score += 20 if target.effects[PBEffects::MagnetRise] > 0
|
target.effects[PBEffects::Telekinesis] > 0 ||
|
||||||
score += 20 if target.effects[PBEffects::Telekinesis] > 0
|
target.has_type?(:FLYING) ||
|
||||||
score += 20 if target.battler.inTwoTurnAttack?("TwoTurnAttackInvulnerableInSky",
|
target.has_active_ability?(:LEVITATE) ||
|
||||||
"TwoTurnAttackInvulnerableInSkyParalyzeTarget",
|
target.has_active_item?(:AIRBALLOON)
|
||||||
"TwoTurnAttackInvulnerableInSkyTargetCannotAct")
|
score += 5 if target.battler.inTwoTurnAttack?("TwoTurnAttackInvulnerableInSky",
|
||||||
score += 20 if target.has_type?(:FLYING)
|
"TwoTurnAttackInvulnerableInSkyParalyzeTarget",
|
||||||
score += 20 if target.has_active_ability?(:LEVITATE)
|
"TwoTurnAttackInvulnerableInSkyTargetCannotAct")
|
||||||
score += 20 if target.has_active_item?(:AIRBALLOON)
|
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,9 +134,8 @@ Battle::AI::Handlers::GeneralMoveScore.add(:target_semi_invulnerable,
|
|||||||
if move.rough_accuracy > 0 && target && user.faster_than?(target) &&
|
if move.rough_accuracy > 0 && target && user.faster_than?(target) &&
|
||||||
(target.battler.semiInvulnerable? || target.effects[PBEffects::SkyDrop] >= 0)
|
(target.battler.semiInvulnerable? || target.effects[PBEffects::SkyDrop] >= 0)
|
||||||
miss = true
|
miss = true
|
||||||
miss = false if user.has_active_ability?(:NOGUARD)
|
miss = false if user.has_active_ability?(:NOGUARD) || target.has_active_ability?(:NOGUARD)
|
||||||
miss = false if ai.trainer.best_skill? && target.has_active_ability?(:NOGUARD)
|
if ai.trainer.high_skill? && miss
|
||||||
if ai.trainer.best_skill? && miss
|
|
||||||
# Knows what can get past semi-invulnerability
|
# Knows what can get past semi-invulnerability
|
||||||
if target.effects[PBEffects::SkyDrop] >= 0 ||
|
if target.effects[PBEffects::SkyDrop] >= 0 ||
|
||||||
target.battler.inTwoTurnAttack?("TwoTurnAttackInvulnerableInSky",
|
target.battler.inTwoTurnAttack?("TwoTurnAttackInvulnerableInSky",
|
||||||
|
|||||||
@@ -545,6 +545,21 @@ class Battle::AI::AIMove
|
|||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
|
|
||||||
|
# Returns:
|
||||||
|
# 0 = move doesn't have an additional effect
|
||||||
|
# 1 = additional effect will be negated
|
||||||
|
# 2 = additional effect will work
|
||||||
|
# 3 = additional effect has an increased chance to work
|
||||||
|
def additional_effect_usability(user, target)
|
||||||
|
return 0 if @move.addlEffect == 0 # Doesn't have an additional effect
|
||||||
|
return 1 if target.has_active_ability?(:SHIELDDUST) && !battle.moldBreaker
|
||||||
|
return 3 if (Settings::MECHANICS_GENERATION >= 6 || self.function != "EffectDependsOnEnvironment") &&
|
||||||
|
(user.has_active_ability?(:SERENEGRACE) || user.pbOwnSide.effects[PBEffects::Rainbow] > 0)
|
||||||
|
return 2
|
||||||
|
end
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
# pbBaseAccuracy(@ai.user.battler, @ai.target.battler) if @ai.trainer.medium_skill?
|
# pbBaseAccuracy(@ai.user.battler, @ai.target.battler) if @ai.trainer.medium_skill?
|
||||||
# pbCriticalOverride(@ai.user.battler, @ai.target.battler)
|
# pbCriticalOverride(@ai.user.battler, @ai.target.battler)
|
||||||
|
|||||||
Reference in New Issue
Block a user