Pokémon sent into battle now default to the Fight option, fixed bugs in Instruct, fixed some AI bugs, fixed parameter mixup for def pbMoveCanTarget?, renamed function to function_code everywhere, fixed black party Pokémon icons in storage, added some more AI testing code

This commit is contained in:
Maruno17
2023-06-18 20:12:36 +01:00
parent 9c2a9130a5
commit b5e37248b9
42 changed files with 305 additions and 174 deletions

View File

@@ -41,7 +41,7 @@ class Battle::AI
# Prefer using Baton Pass instead of switching
baton_pass = -1
@user.battler.eachMoveWithIndex do |m, i|
next if m.function != "SwitchOutUserPassOnEffects" # Baton Pass
next if m.function_code != "SwitchOutUserPassOnEffects" # Baton Pass
next if !@battle.pbCanChooseMove?(@user.index, i, false)
baton_pass = i
break
@@ -379,7 +379,7 @@ Battle::AI::Handlers::ShouldSwitch.add(:asleep,
# Doesn't benefit from being asleep
next false if battler.has_active_ability?(:MARVELSCALE)
# Doesn't know Rest (if it does, sleep is expected, so don't apply this check)
next false if battler.check_for_move { |m| m.function == "HealUserFullyAndFallAsleep" }
next false if battler.check_for_move { |m| m.function_code == "HealUserFullyAndFallAsleep" }
# Not trapping another battler in battle
if ai.trainer.high_skill?
next false if ai.battlers.any? do |b|
@@ -457,7 +457,7 @@ Battle::AI::Handlers::ShouldSwitch.add(:foe_absorbs_all_moves_with_its_ability,
battler.battler.eachMove do |move|
next if move.statusMove?
if ["IgnoreTargetAbility",
"CategoryDependsOnHigherDamageIgnoreTargetAbility"].include?(move.function)
"CategoryDependsOnHigherDamageIgnoreTargetAbility"].include?(move.function_code)
can_damage_foe = true
break
end

View File

@@ -23,6 +23,13 @@ class Battle::AI
def pbGetMoveScores
choices = []
@user.battler.eachMoveWithIndex do |orig_move, idxMove|
# TODO: Delete this after testing AI.
if $tested_moves
$tested_moves[orig_move.id] ||= 0
$tested_moves[orig_move.id] += 1
end
# Unchoosable moves aren't considered
if !@battle.pbCanChooseMove?(@user.index, idxMove, false)
if orig_move.pp == 0 && orig_move.total_pp > 0
@@ -43,7 +50,7 @@ class Battle::AI
end
# Get the move's target type
target_data = @move.pbTarget(@user.battler)
if @move.function == "CurseTargetOrLowerUserSpd1RaiseUserAtkDef1" &&
if @move.function_code == "CurseTargetOrLowerUserSpd1RaiseUserAtkDef1" &&
@move.rough_type == :GHOST && @user.has_active_ability?([:LIBERO, :PROTEAN])
target_data = GameData::Target.get((Settings::MECHANICS_GENERATION >= 8) ? :RandomNearFoe : :NearFoe)
end
@@ -140,7 +147,7 @@ class Battle::AI
# Set some extra class variables for the move being assessed.
def set_up_move_check(move)
case move.function
case move.function_code
when "UseLastMoveUsed"
if @battle.lastMoveUsed &&
GameData::Move.exists?(@battle.lastMoveUsed) &&
@@ -159,7 +166,7 @@ class Battle::AI
def set_up_move_check_target(target)
@target = (target) ? @battlers[target.index] : nil
@target&.refresh_battler
if @target && @move.function == "UseLastMoveUsedByTarget"
if @target && @move.function_code == "UseLastMoveUsedByTarget"
if @target.battler.lastRegularMoveUsed &&
GameData::Move.exists?(@target.battler.lastRegularMoveUsed) &&
GameData::Move.get(@target.battler.lastRegularMoveUsed).has_flag?("CanMirrorMove")
@@ -187,7 +194,7 @@ class Battle::AI
return true if @battle.pbWeather == :HeavyRain && @move.rough_type == :FIRE
return true if @battle.pbWeather == :HarshSun && @move.rough_type == :WATER
# Move effect-specific checks
return true if Battle::AI::Handlers.move_will_fail?(@move.function, @move, @user, self, @battle)
return true if Battle::AI::Handlers.move_will_fail?(@move.function_code, @move, @user, self, @battle)
return false
end
@@ -195,7 +202,7 @@ class Battle::AI
# no battle conditions change between now and using the move).
def pbPredictMoveFailureAgainstTarget
# Move effect-specific checks
return true if Battle::AI::Handlers.move_will_fail_against_target?(@move.function, @move, @user, @target, self, @battle)
return true if Battle::AI::Handlers.move_will_fail_against_target?(@move.function_code, @move, @user, @target, self, @battle)
# Immunity to priority moves because of Psychic Terrain
return true if @battle.field.terrain == :Psychic && @target.battler.affectedByTerrain? &&
@target.opposes?(@user) && @move.rough_priority(@user) > 0
@@ -273,7 +280,7 @@ class Battle::AI
if @trainer.has_skill_flag?("ScoreMoves")
# Modify the score according to the move's effect
old_score = score
score = Battle::AI::Handlers.apply_move_effect_score(@move.function,
score = Battle::AI::Handlers.apply_move_effect_score(@move.function_code,
score, @move, @user, self, @battle)
PBDebug.log_score_change(score - old_score, "function code modifier (generic)")
# Modify the score according to various other effects
@@ -302,7 +309,7 @@ class Battle::AI
if @trainer.has_skill_flag?("ScoreMoves")
# Modify the score according to the move's effect against the target
old_score = score
score = Battle::AI::Handlers.apply_move_effect_against_target_score(@move.function,
score = Battle::AI::Handlers.apply_move_effect_against_target_score(@move.function_code,
MOVE_BASE_SCORE, @move, @user, @target, self, @battle)
PBDebug.log_score_change(score - old_score, "function code modifier (against target)")
# Modify the score according to various other effects against the target

View File

@@ -102,12 +102,12 @@ class Battle::AI
case stat
when :ATTACK
return false if !target.check_for_move { |m| m.physicalMove?(m.type) &&
m.function != "UseUserDefenseInsteadOfUserAttack" &&
m.function != "UseTargetAttackInsteadOfUserAttack" }
m.function_code != "UseUserDefenseInsteadOfUserAttack" &&
m.function_code != "UseTargetAttackInsteadOfUserAttack" }
when :DEFENSE
each_foe_battler(target.side) do |b, i|
return true if b.check_for_move { |m| m.physicalMove?(m.type) ||
m.function == "UseTargetDefenseInsteadOfTargetSpDef" }
m.function_code == "UseTargetDefenseInsteadOfTargetSpDef" }
end
return false
when :SPECIAL_ATTACK
@@ -115,7 +115,7 @@ class Battle::AI
when :SPECIAL_DEFENSE
each_foe_battler(target.side) do |b, i|
return true if b.check_for_move { |m| m.specialMove?(m.type) &&
m.function != "UseTargetDefenseInsteadOfTargetSpDef" }
m.function_code != "UseTargetDefenseInsteadOfTargetSpDef" }
end
return false
when :SPEED
@@ -215,8 +215,8 @@ class Battle::AI
score -= 10 * ((target.opposes?(@user)) ? 1 : desire_mult)
else
has_physical_moves = target.check_for_move { |m| m.physicalMove?(m.type) &&
m.function != "UseUserDefenseInsteadOfUserAttack" &&
m.function != "UseTargetAttackInsteadOfUserAttack" }
m.function_code != "UseUserDefenseInsteadOfUserAttack" &&
m.function_code != "UseTargetAttackInsteadOfUserAttack" }
inc = (has_physical_moves) ? 8 : 12
score += inc * inc_mult
end
@@ -398,12 +398,12 @@ class Battle::AI
case stat
when :ATTACK
return false if !target.check_for_move { |m| m.physicalMove?(m.type) &&
m.function != "UseUserDefenseInsteadOfUserAttack" &&
m.function != "UseTargetAttackInsteadOfUserAttack" }
m.function_code != "UseUserDefenseInsteadOfUserAttack" &&
m.function_code != "UseTargetAttackInsteadOfUserAttack" }
when :DEFENSE
each_foe_battler(target.side) do |b, i|
return true if b.check_for_move { |m| m.physicalMove?(m.type) ||
m.function == "UseTargetDefenseInsteadOfTargetSpDef" }
m.function_code == "UseTargetDefenseInsteadOfTargetSpDef" }
end
return false
when :SPECIAL_ATTACK
@@ -411,7 +411,7 @@ class Battle::AI
when :SPECIAL_DEFENSE
each_foe_battler(target.side) do |b, i|
return true if b.check_for_move { |m| m.specialMove?(m.type) &&
m.function != "UseTargetDefenseInsteadOfTargetSpDef" }
m.function_code != "UseTargetDefenseInsteadOfTargetSpDef" }
end
return false
when :SPEED
@@ -507,8 +507,8 @@ class Battle::AI
score -= 10 * ((target.opposes?(@user)) ? 1 : desire_mult)
else
has_physical_moves = target.check_for_move { |m| m.physicalMove?(m.type) &&
m.function != "UseUserDefenseInsteadOfUserAttack" &&
m.function != "UseTargetAttackInsteadOfUserAttack" }
m.function_code != "UseUserDefenseInsteadOfUserAttack" &&
m.function_code != "UseTargetAttackInsteadOfUserAttack" }
dec = (has_physical_moves) ? 8 : 12
score += dec * dec_mult
end

View File

@@ -154,7 +154,7 @@ Battle::AI::Handlers::GeneralMoveScore.add(:good_move_for_choice_item,
!user.has_active_ability?(:GORILLATACTICS)
old_score = score
# Really don't prefer status moves (except Trick)
if move.statusMove? && move.function != "UserTargetSwapItems"
if move.statusMove? && move.function_code != "UserTargetSwapItems"
score -= 25
PBDebug.log_score_change(score - old_score, "don't want to be Choiced into a status move")
next score

View File

@@ -243,7 +243,7 @@ class Battle::AI::AIBattler
battler.pbTypes(true).each do |defend_type|
mult = effectiveness_of_type_against_single_battler_type(type, defend_type, user)
if move
case move.function
case move.function_code
when "HitsTargetInSkyGroundsTarget"
mult = Effectiveness::NORMAL_EFFECTIVE_MULTIPLIER if type == :GROUND && defend_type == :FLYING
when "FreezeTargetSuperEffectiveAgainstWater"
@@ -308,7 +308,7 @@ class Battle::AI::AIBattler
end
def has_move_with_function?(*functions)
check_for_move { |m| return true if functions.include?(m.function) }
check_for_move { |m| return true if functions.include?(m.function_code) }
return false
end

View File

@@ -12,7 +12,7 @@ class Battle::AI::AIMove
@move = move
@move.calcType = rough_type
@ai.battle.moldBreaker ||= ["IgnoreTargetAbility",
"CategoryDependsOnHigherDamageIgnoreTargetAbility"].include?(function)
"CategoryDependsOnHigherDamageIgnoreTargetAbility"].include?(function_code)
end
#-----------------------------------------------------------------------------
@@ -23,7 +23,7 @@ class Battle::AI::AIMove
def specialMove?(thisType = nil); return @move.specialMove?(thisType); end
def damagingMove?; return @move.damagingMove?; end
def statusMove?; return @move.statusMove?; end
def function; return @move.function; end
def function_code; return @move.function_code; end
#-----------------------------------------------------------------------------
@@ -82,7 +82,7 @@ class Battle::AI::AIMove
ret = @move.power
ret = 60 if ret == 1
return ret if !@ai.trainer.medium_skill?
return Battle::AI::Handlers.get_base_power(function,
return Battle::AI::Handlers.get_base_power(function_code,
ret, self, @ai.user, @ai.target, @ai, @ai.battle)
end
@@ -106,7 +106,7 @@ class Battle::AI::AIMove
Battle::Move::CRITICAL_HIT_RATIOS[crit_stage] <= 2
##### Calculate user's attack stat #####
if ["CategoryDependsOnHigherDamagePoisonTarget",
"CategoryDependsOnHigherDamageIgnoreTargetAbility"].include?(function)
"CategoryDependsOnHigherDamageIgnoreTargetAbility"].include?(function_code)
@move.pbOnStartUse(user.battler, [target.battler]) # Calculate category
end
atk, atk_stage = @move.pbGetAttackStats(user.battler, target.battler)
@@ -301,7 +301,7 @@ class Battle::AI::AIMove
end
when :Sandstorm
if target.has_type?(:ROCK) && specialMove?(calc_type) &&
function != "UseTargetDefenseInsteadOfTargetSpDef" # Psyshock
function_code != "UseTargetDefenseInsteadOfTargetSpDef" # Psyshock
multipliers[:defense_multiplier] *= 1.5
end
end
@@ -390,7 +390,7 @@ class Battle::AI::AIMove
# OHKO move accuracy
if @move.is_a?(Battle::Move::OHKO)
ret = self.accuracy + user.level - target.level
ret -= 10 if function == "OHKOIce" && !user.has_type?(:ICE)
ret -= 10 if function_code == "OHKOIce" && !user.has_type?(:ICE)
return [ret, 0].max
end
# "Always hit" effects and "always hit" accuracy
@@ -478,13 +478,13 @@ class Battle::AI::AIMove
modifiers[:evasion_stage] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[:evasion_stage] > 0
end
# "AI-specific calculations below"
modifiers[:evasion_stage] = 0 if function == "IgnoreTargetDefSpDefEvaStatStages" # Chip Away
modifiers[:evasion_stage] = 0 if function_code == "IgnoreTargetDefSpDefEvaStatStages" # Chip Away
if @ai.trainer.medium_skill?
modifiers[:base_accuracy] = 0 if user.effects[PBEffects::LockOn] > 0 &&
user.effects[PBEffects::LockOnPos] == target.index
end
if @ai.trainer.medium_skill?
case function
case function_code
when "BadPoisonTarget"
modifiers[:base_accuracy] = 0 if Settings::MORE_TYPE_EFFECTS &&
@move.statusMove? && user.has_type?(:POISON)
@@ -554,7 +554,7 @@ class Battle::AI::AIMove
target.has_active_ability?(:SHIELDDUST) && !@ai.battle.moldBreaker
# Prefer if the additional effect will have an increased chance of working
return 5 if @move.addlEffect < 100 &&
(Settings::MECHANICS_GENERATION >= 6 || self.function != "EffectDependsOnEnvironment") &&
(Settings::MECHANICS_GENERATION >= 6 || function_code != "EffectDependsOnEnvironment") &&
(user.has_active_ability?(:SERENEGRACE) || user.pbOwnSide.effects[PBEffects::Rainbow] > 0)
# No change to score
return 0