Rewrote AI calculations for moves that cause confusion, flinching and infatuation

This commit is contained in:
Maruno17
2022-10-09 18:37:19 +01:00
parent 9695094b02
commit 58a624060a
4 changed files with 241 additions and 213 deletions

View File

@@ -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
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
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) @newType = :NORMAL if !GameData::Type.exists?(@newType)
end
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

View File

@@ -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) ||
target.has_active_item?(:AIRBALLOON)
score += 5 if target.battler.inTwoTurnAttack?("TwoTurnAttackInvulnerableInSky",
"TwoTurnAttackInvulnerableInSkyParalyzeTarget", "TwoTurnAttackInvulnerableInSkyParalyzeTarget",
"TwoTurnAttackInvulnerableInSkyTargetCannotAct") "TwoTurnAttackInvulnerableInSkyTargetCannotAct")
score += 20 if target.has_type?(:FLYING)
score += 20 if target.has_active_ability?(:LEVITATE)
score += 20 if target.has_active_item?(:AIRBALLOON)
end end
next score next score
} }

View File

@@ -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",

View File

@@ -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)