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

@@ -170,7 +170,7 @@ class SpriteAnimation
def animation_set_sprites(sprites, cell_data, position, quick_update = false)
sprite_x = 320
sprite_y = 240
if position == 3
if position == 3 # Screen
if self.viewport
sprite_x = self.viewport.rect.width / 2
sprite_y = self.viewport.rect.height - 160
@@ -178,8 +178,10 @@ class SpriteAnimation
else
sprite_x = self.x - self.ox + (self.src_rect.width / 2)
sprite_y = self.y - self.oy
sprite_y += self.src_rect.height / 2 if position == 1
sprite_y += self.src_rect.height if position == 2
if self.src_rect.height > 1
sprite_y += self.src_rect.height / 2 if position == 1 # Middle
sprite_y += self.src_rect.height if position == 2 # Bottom
end
end
16.times do |i|
sprite = sprites[i]

View File

@@ -46,8 +46,8 @@ module Settings
AFFECTION_EFFECTS = false
# Whether a Pokémon's happiness is limited to 179, and can only be increased
# further with friendship-raising berries. Related to AFFECTION_EFFECTS by
# default as affection effects only start applying above a happiness of 179.
# Also lowers the happiness evolution threshold to 160.
# default because affection effects only start applying above a happiness of
# 179. Also lowers the happiness evolution threshold to 160.
APPLY_HAPPINESS_SOFT_CAP = AFFECTION_EFFECTS
#=============================================================================

View File

@@ -588,13 +588,13 @@ class Interpreter
end
when 7 # other
case @parameters[4]
when 0 then value = $game_map.map_id # map ID
when 1 then value = $player.pokemon_party.length # party members
when 2 then value = $player.money # gold
when 3 then value = $stats.distance_moved # steps
when 4 then value = $stats.play_time # play time
when 5 then value = $game_system.timer # timer
when 6 then value = $game_system.save_count # save count
when 0 then value = $game_map.map_id # map ID
when 1 then value = $player.pokemon_count # party members
when 2 then value = $player.money # gold
when 3 then value = $stats.distance_moved # steps
when 4 then value = $stats.play_time # play time
when 5 then value = $game_system.timer # timer
when 6 then value = $game_system.save_count # save count
end
end
# Apply value and operation to all specified game variables

View File

@@ -89,7 +89,7 @@ class Battle
def pbChoseMoveFunctionCode?(idxBattler, code)
return false if @battlers[idxBattler].fainted?
if @choices[idxBattler][0] == :UseMove && @choices[idxBattler][1]
return @choices[idxBattler][2].function == code
return @choices[idxBattler][2].function_code == code
end
return false
end

View File

@@ -290,7 +290,7 @@ class Battle
sendOuts.each { |b| @peer.pbOnEnteringBattle(self, @battlers[b[0]], b[1]) }
@scene.pbSendOutBattlers(sendOuts, startBattle)
sendOuts.each do |b|
@scene.pbResetMoveIndex(b[0])
@scene.pbResetCommandsIndex(b[0])
pbSetSeen(@battlers[b[0]])
@usedInBattle[b[0] & 1][b[0] / 2] = true
end

View File

@@ -477,7 +477,7 @@ class Battle::Battler
def pbHasMoveFunction?(*arg)
return false if !arg
eachMove do |m|
arg.each { |code| return true if m.function == code }
arg.each { |code| return true if m.function_code == code }
end
return false
end

View File

@@ -293,7 +293,7 @@ class Battle::Battler
end
# "But it failed!" checks
if move.pbMoveFailed?(user, targets)
PBDebug.log(sprintf("[Move failed] In function code %s's def pbMoveFailed?", move.function))
PBDebug.log(sprintf("[Move failed] In function code %s's def pbMoveFailed?", move.function_code))
user.lastMoveFailed = true
pbCancelMoves
pbEndTurn(choice)
@@ -356,7 +356,7 @@ class Battle::Battler
# Pokémon which becomes Ghost-type because of Protean, it should
# target and curse itself. I think this is silly, so I'm making it
# choose a random opponent to curse instead.
if move.function == "CurseTargetOrLowerUserSpd1RaiseUserAtkDef1" && targets.length == 0
if move.function_code == "CurseTargetOrLowerUserSpd1RaiseUserAtkDef1" && targets.length == 0
choice[3] = -1
targets = pbFindTargets(choice, move, user)
end
@@ -528,7 +528,7 @@ class Battle::Battler
oldLastRoundMoved = b.lastRoundMoved
@battle.pbDisplay(_INTL("{1} used the move instructed by {2}!", b.pbThis, user.pbThis(true)))
b.effects[PBEffects::Instructed] = true
if b.pbCanChooseMove?(@moves[idxMove], false)
if b.pbCanChooseMove?(b.moves[idxMove], false)
PBDebug.logonerr do
b.pbUseMoveSimple(b.lastMoveUsed, b.lastRegularMoveTarget, idxMove, false)
end

View File

@@ -87,7 +87,7 @@ class Battle::Battler
end
# Assault Vest (prevents choosing status moves but doesn't prevent
# executing them)
if hasActiveItem?(:ASSAULTVEST) && move.statusMove? && move.function != "UseMoveTargetIsAboutToUse" && commandPhase
if hasActiveItem?(:ASSAULTVEST) && move.statusMove? && move.function_code != "UseMoveTargetIsAboutToUse" && commandPhase
if showMessages
msg = _INTL("The effects of the {1} prevent status moves from being used!", itemName)
(commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg)
@@ -308,7 +308,7 @@ class Battle::Battler
return true if user.effects[PBEffects::TwoTurnAttack]
# Move-specific failures
if move.pbFailsAgainstTarget?(user, target, show_message)
PBDebug.log(sprintf("[Move failed] In function code %s's def pbFailsAgainstTarget?", move.function))
PBDebug.log(sprintf("[Move failed] In function code %s's def pbFailsAgainstTarget?", move.function_code))
return false
end
# Immunity to priority moves because of Psychic Terrain
@@ -545,7 +545,7 @@ class Battle::Battler
# Future Sight
hitsInvul = true if @battle.futureSight
# Helping Hand
hitsInvul = true if move.function == "PowerUpAllyMove"
hitsInvul = true if move.function_code == "PowerUpAllyMove"
if !hitsInvul
# Semi-invulnerable moves
if target.effects[PBEffects::TwoTurnAttack]

View File

@@ -135,7 +135,7 @@ class Battle::Battler
end
end
# Room Service
if move.function == "StartSlowerBattlersActFirst" && @battle.field.effects[PBEffects::TrickRoom] > 0
if move.function_code == "StartSlowerBattlersActFirst" && @battle.field.effects[PBEffects::TrickRoom] > 0
@battle.allBattlers.each do |b|
next if !b.hasActiveItem?(:ROOMSERVICE)
next if !b.pbCanLowerStatStage?(:SPEED)

View File

@@ -3,7 +3,7 @@ class Battle::Move
attr_reader :realMove
attr_accessor :id
attr_reader :name
attr_reader :function
attr_reader :function_code
attr_reader :power
attr_reader :type
attr_reader :category
@@ -32,23 +32,23 @@ class Battle::Move
# Creating a move
#=============================================================================
def initialize(battle, move)
@battle = battle
@realMove = move
@id = move.id
@name = move.name # Get the move's name
@battle = battle
@realMove = move
@id = move.id
@name = move.name # Get the move's name
# Get data on the move
@function = move.function_code
@power = move.power
@type = move.type
@category = move.category
@accuracy = move.accuracy
@pp = move.pp # Can be changed with Mimic/Transform
@target = move.target
@priority = move.priority
@flags = move.flags.clone
@addlEffect = move.effect_chance
@powerBoost = false # For Aerilate, Pixilate, Refrigerate, Galvanize
@snatched = false
@function_code = move.function_code
@power = move.power
@type = move.type
@category = move.category
@accuracy = move.accuracy
@pp = move.pp # Can be changed with Mimic/Transform
@target = move.target
@priority = move.priority
@flags = move.flags.clone
@addlEffect = move.effect_chance
@powerBoost = false # For Aerilate, Pixilate, Refrigerate, Galvanize
@snatched = false
end
# This is the code actually used to generate a Battle::Move object. The
@@ -154,7 +154,7 @@ class Battle::Move
end
def display_type(battler)
case @function
case @function_code
when "TypeDependsOnUserMorpekoFormRaiseUserSpeed1"
if battler.isSpecies?(:MORPEKO) || battler.effects[PBEffects::TransformSpecies] == :MORPEKO
return pbBaseType(battler)
@@ -172,7 +172,7 @@ class Battle::Move
def display_damage(battler)
=begin
case @function
case @function_code
when "TypeAndPowerDependOnUserBerry"
return pbNaturalGiftBaseDamage(battler.item_id)
when "TypeAndPowerDependOnWeather", "TypeAndPowerDependOnTerrain",
@@ -187,7 +187,7 @@ class Battle::Move
def display_category(battler)
=begin
case @function
case @function_code
when "CategoryDependsOnHigherDamageIgnoreTargetAbility"
pbOnStartUse(user, nil)
return @calcCategory

View File

@@ -373,7 +373,7 @@ class Battle::Move
# regardless of its calculated type. Hence the following two lines of
# code.
moveType = nil
moveType = :NORMAL if @function == "TypeDependsOnUserIVs" # Hidden Power
moveType = :NORMAL if @function_code == "TypeDependsOnUserIVs" # Hidden Power
if !target.damageState.substitute
if physicalMove?(moveType)
target.effects[PBEffects::Counter] = damage

View File

@@ -416,7 +416,7 @@ class Battle::Move
multipliers[:final_damage_multiplier] *= 1.5
end
when :Sandstorm
if target.pbHasType?(:ROCK) && specialMove? && @function != "UseTargetDefenseInsteadOfTargetSpDef"
if target.pbHasType?(:ROCK) && specialMove? && @function_code != "UseTargetDefenseInsteadOfTargetSpDef"
multipliers[:defense_multiplier] *= 1.5
end
when :ShadowSky
@@ -489,7 +489,7 @@ class Battle::Move
def pbAdditionalEffectChance(user, target, effectChance = 0)
return 0 if target.hasActiveAbility?(:SHIELDDUST) && !@battle.moldBreaker
ret = (effectChance > 0) ? effectChance : @addlEffect
if (Settings::MECHANICS_GENERATION >= 6 || @function != "EffectDependsOnEnvironment") &&
if (Settings::MECHANICS_GENERATION >= 6 || @function_code != "EffectDependsOnEnvironment") &&
(user.hasActiveAbility?(:SERENEGRACE) || user.pbOwnSide.effects[PBEffects::Rainbow] > 0)
ret *= 2
end

View File

@@ -22,22 +22,22 @@ end
#===============================================================================
class Battle::Move::Confusion < Battle::Move
def initialize(battle, move)
@battle = battle
@realMove = move
@id = :CONFUSEDAMAGE
@name = ""
@function = "None"
@power = 40
@type = nil
@category = 0
@accuracy = 100
@pp = -1
@target = :User
@priority = 0
@flags = []
@addlEffect = 0
@powerBoost = false
@snatched = false
@battle = battle
@realMove = move
@id = :CONFUSEDAMAGE
@name = ""
@function_code = "None"
@power = 40
@type = nil
@category = 0
@accuracy = 100
@pp = -1
@target = :User
@priority = 0
@flags = []
@addlEffect = 0
@powerBoost = false
@snatched = false
end
def physicalMove?(thisType = nil); return true; end
@@ -50,22 +50,22 @@ end
#===============================================================================
class Battle::Move::Struggle < Battle::Move
def initialize(battle, move)
@battle = battle
@realMove = nil # Not associated with a move
@id = :STRUGGLE
@name = _INTL("Struggle")
@function = "Struggle"
@power = 50
@type = nil
@category = 0
@accuracy = 0
@pp = -1
@target = :RandomNearFoe
@priority = 0
@flags = ["Contact", "CanProtect"]
@addlEffect = 0
@powerBoost = false
@snatched = false
@battle = battle
@realMove = nil # Not associated with a move
@id = :STRUGGLE
@name = _INTL("Struggle")
@function_code = "Struggle"
@power = 50
@type = nil
@category = 0
@accuracy = 0
@pp = -1
@target = :RandomNearFoe
@priority = 0
@flags = ["Contact", "CanProtect"]
@addlEffect = 0
@powerBoost = false
@snatched = false
end
def physicalMove?(thisType = nil); return true; end
@@ -339,7 +339,7 @@ class Battle::Move::TwoTurnMove < Battle::Move
"TwoTurnAttackInvulnerableUnderwater",
"TwoTurnAttackInvulnerableInSkyParalyzeTarget",
"TwoTurnAttackInvulnerableRemoveProtections",
"TwoTurnAttackInvulnerableInSkyTargetCannotAct"].include?(@function)
"TwoTurnAttackInvulnerableInSkyTargetCannotAct"].include?(@function_code)
@battle.pbCommonAnimation("UseItem", user)
end
@battle.pbDisplay(_INTL("{1} became fully charged due to its Power Herb!", user.pbThis))
@@ -549,7 +549,7 @@ class Battle::Move::PledgeMove < Battle::Move
move = @battle.choices[b.index][2]
next if !move
@combos.each do |i|
next if i[0] != move.function
next if i[0] != move.function_code
@pledgeSetup = true
@pledgeOtherUser = b
break
@@ -584,7 +584,7 @@ class Battle::Move::PledgeMove < Battle::Move
return if !@pledgeSetup
@battle.pbDisplay(_INTL("{1} is waiting for {2}'s move...",
user.pbThis, @pledgeOtherUser.pbThis(true)))
@pledgeOtherUser.effects[PBEffects::FirstPledge] = @function
@pledgeOtherUser.effects[PBEffects::FirstPledge] = @function_code
@pledgeOtherUser.effects[PBEffects::MoveNext] = true
user.lastMoveFailed = true # Treated as a failure for Stomping Tantrum
end

View File

@@ -198,7 +198,7 @@ class Battle::Move::FailsIfTargetActed < Battle::Move
end
oppMove = @battle.choices[target.index][2]
if !oppMove ||
(oppMove.function != "UseMoveTargetIsAboutToUse" &&
(oppMove.function_code != "UseMoveTargetIsAboutToUse" &&
(target.movedThisRound? || oppMove.statusMove?))
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true

View File

@@ -343,13 +343,20 @@ end
# stage. On the second turn, does damage. (Meteor Beam)
#===============================================================================
class Battle::Move::TwoTurnAttackChargeRaiseUserSpAtk1 < Battle::Move::TwoTurnMove
attr_reader :statUp
def initialize(battle, move)
super
@statUp = [:SPECIAL_ATTACK, 1]
end
def pbChargingTurnMessage(user, targets)
@battle.pbDisplay(_INTL("{1} is overflowing with space power!", user.pbThis))
end
def pbChargingTurnEffect(user, target)
if user.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user, self)
user.pbRaiseStatStage(:SPECIAL_ATTACK, 1, user)
if user.pbCanRaiseStatStage?(@statUp[0], user, self)
user.pbRaiseStatStage(@statUp[0], @statUp[1], user)
end
end
end

View File

@@ -812,6 +812,8 @@ end
# (Me First)
#===============================================================================
class Battle::Move::UseMoveTargetIsAboutToUse < Battle::Move
attr_reader :moveBlacklist
def ignoresSubstitute?(user); return true; end
def callsAnotherMove?; return true; end
@@ -836,7 +838,7 @@ class Battle::Move::UseMoveTargetIsAboutToUse < Battle::Move
def pbFailsAgainstTarget?(user, target, show_message)
return true if pbMoveFailedTargetAlreadyMoved?(target, show_message)
oppMove = @battle.choices[target.index][2]
if !oppMove || oppMove.statusMove? || @moveBlacklist.include?(oppMove.function)
if !oppMove || oppMove.statusMove? || @moveBlacklist.include?(oppMove.function_code)
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
@@ -919,6 +921,8 @@ end
# Uses a random move that exists. (Metronome)
#===============================================================================
class Battle::Move::UseRandomMove < Battle::Move
attr_reader :moveBlacklist
def callsAnotherMove?; return true; end
def initialize(battle, move)
@@ -1179,7 +1183,7 @@ class Battle::Move::UseRandomUserMoveIfAsleep < Battle::Move
def pbMoveFailed?(user, targets)
@sleepTalkMoves = []
user.eachMoveWithIndex do |m, i|
next if @moveBlacklist.include?(m.function)
next if @moveBlacklist.include?(m.function_code)
next if !@battle.pbCanChooseMove?(user.index, i, false, true)
@sleepTalkMoves.push(i)
end

View File

@@ -477,7 +477,7 @@ class Battle::Move::UsedAfterAllyRoundWithDoublePower < Battle::Move
user.pbOwnSide.effects[PBEffects::Round] = true
user.allAllies.each do |b|
next if @battle.choices[b.index][0] != :UseMove || b.movedThisRound?
next if @battle.choices[b.index][2].function != @function
next if @battle.choices[b.index][2].function_code != @function_code
b.effects[PBEffects::MoveNext] = true
b.effects[PBEffects::Quash] = 0
break
@@ -620,9 +620,9 @@ class Battle::Move::TargetUsesItsLastUsedMoveAgain < Battle::Move
return true
end
targetMove = @battle.choices[target.index][2]
if targetMove && (targetMove.function == "FailsIfUserDamagedThisTurn" || # Focus Punch
targetMove.function == "UsedAfterUserTakesPhysicalDamage" || # Shell Trap
targetMove.function == "BurnAttackerBeforeUserActs") # Beak Blast
if targetMove && (targetMove.function_code == "FailsIfUserDamagedThisTurn" || # Focus Punch
targetMove.function_code == "UsedAfterUserTakesPhysicalDamage" || # Shell Trap
targetMove.function_code == "BurnAttackerBeforeUserActs") # Beak Blast
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end

View File

@@ -393,7 +393,8 @@ class Battle::Scene
shadowSprite.visible = pkmn.species_data.shows_shadow? if shadowSprite && !back
end
def pbResetMoveIndex(idxBattler)
def pbResetCommandsIndex(idxBattler)
@lastCmd[idxBattler] = 0
@lastMove[idxBattler] = 0
end

View File

@@ -346,7 +346,7 @@ class Battle::Scene
when :BothSides
showName = true
else
showName = @battle.pbMoveCanTarget?(i, idxBattler, target_data)
showName = @battle.pbMoveCanTarget?(idxBattler, i, target_data)
end
next nil if !showName
next (@battle.battlers[i].fainted?) ? "" : @battle.battlers[i].name

View File

@@ -65,7 +65,7 @@ class Battle::DebugSceneNoVisuals
def pbSendOutBattlers(sendOuts, startBattle = false); end
def pbRecall(idxBattler); end
def pbItemMenu(idxBattler, firstAction); return -1; end
def pbResetMoveIndex(idxBattler); end
def pbResetCommandsIndex(idxBattler); end
def pbHPChanged(battler, oldHP, showAnim = false); end
def pbChangePokemon(idxBattler, pkmn); end

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

View File

@@ -1428,7 +1428,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartUserSideImmunityToStatStageLower
m.is_a?(Battle::Move::TargetMultiStatDownMove) ||
["LowerPoisonedTargetAtkSpAtkSpd1",
"PoisonTargetLowerTargetSpeed1",
"HealUserByTargetAttackLowerTargetAttack1"].include?(m.function) }
"HealUserByTargetAttackLowerTargetAttack1"].include?(m.function_code) }
score += 15
has_move = true
end

View File

@@ -128,7 +128,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("PoisonTarget",
score -= 5 if target.has_move_with_function?("DoublePowerIfUserPoisonedBurnedParalyzed",
"CureUserBurnPoisonParalysis")
score -= 15 if target.check_for_move { |m|
m.function == "GiveUserStatusToTarget" && user.battler.pbCanPoison?(target.battler, false, m)
m.function_code == "GiveUserStatusToTarget" && user.battler.pbCanPoison?(target.battler, false, m)
}
# Don't prefer if the target won't take damage from the poison
score -= 20 if !target.battler.takesIndirectDamage?
@@ -218,7 +218,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ParalyzeTarget",
score -= 5 if target.has_move_with_function?("DoublePowerIfUserPoisonedBurnedParalyzed",
"CureUserBurnPoisonParalysis")
score -= 15 if target.check_for_move { |m|
m.function == "GiveUserStatusToTarget" && user.battler.pbCanParalyze?(target.battler, false, m)
m.function_code == "GiveUserStatusToTarget" && user.battler.pbCanParalyze?(target.battler, false, m)
}
# Don't prefer if the target can heal itself (or be healed by an ally)
if target.has_active_ability?(:SHEDSKIN)
@@ -313,7 +313,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("BurnTarget",
score -= 5 if target.has_move_with_function?("DoublePowerIfUserPoisonedBurnedParalyzed",
"CureUserBurnPoisonParalysis")
score -= 15 if target.check_for_move { |m|
m.function == "GiveUserStatusToTarget" && user.battler.pbCanBurn?(target.battler, false, m)
m.function_code == "GiveUserStatusToTarget" && user.battler.pbCanBurn?(target.battler, false, m)
}
# Don't prefer if the target won't take damage from the burn
score -= 20 if !target.battler.takesIndirectDamage?

View File

@@ -189,7 +189,7 @@ Battle::AI::Handlers::MoveBasePower.add("PowerHigherWithLessPP",
proc { |power, move, user, target, ai, battle|
next 0 if move.move.pp == 0 && move.move.totalpp > 0
dmgs = [200, 80, 60, 50, 40]
ppLeft = [move.pp - 1, dmgs.length - 1].min
ppLeft = [move.move.pp - 1, dmgs.length - 1].min
next dmgs[ppLeft]
}
)
@@ -463,7 +463,7 @@ Battle::AI::Handlers::MoveEffectScore.add("EnsureNextCriticalHit",
next Battle::AI::MOVE_USELESS_SCORE
end
# Prefer if user knows a damaging move which won't definitely critical hit
if user.check_for_move { |m| m.damagingMove? && m.function != "AlwaysCriticalHit"}
if user.check_for_move { |m| m.damagingMove? && m.function_code != "AlwaysCriticalHit"}
score += 15
end
next score

View File

@@ -77,7 +77,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserTargetSwapItems",
# Don't prefer if user used this move in the last round
score -= 15 if user.battler.lastMoveUsed &&
GameData::Move.exists?(user.battler.lastMoveUsed) &&
GameData::Move.get(user.battler.lastMoveUsed).function_code == move.function
GameData::Move.get(user.battler.lastMoveUsed).function_code == move.function_code
next score
}
)

View File

@@ -155,18 +155,23 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("EffectDependsOnEnvironme
function_code = "ParalyzeTarget"
when 9
function_code = "FreezeTarget"
when 5
function_code = "LowerTargetAttack1"
when 14
function_code = "LowerTargetDefense1"
when 3
function_code = "LowerTargetSpAtk1"
when 4, 6, 12
function_code = "LowerTargetSpeed1"
when 8
function_code = "LowerTargetAccuracy1"
when 7, 11, 13
function_code = "FlinchTarget"
else
stat_lowered = nil
case move.move.secretPower
when 5
function_code = :ATTACK
when 14
function_code = :DEFENSE
when 3
function_code = :SPECIAL_ATTACK
when 4, 6, 12
function_code = :SPEED
when 8
function_code = :ACCURACY
end
next ai.get_score_for_target_stat_drop(score, target, [stat_lowered, 1]) if stat_lowered
end
if function_code
next Battle::AI::Handlers.apply_move_effect_against_target_score(function_code,
@@ -531,7 +536,7 @@ Battle::AI::Handlers::MoveFailureCheck.add("UseRandomUserMoveIfAsleep",
proc { |move, user, ai, battle|
will_fail = true
user.battler.eachMoveWithIndex do |m, i|
next if move.move.moveBlacklist.include?(m.function)
next if move.move.moveBlacklist.include?(m.function_code)
next if !battle.pbCanChooseMove?(user.index, i, false, true)
will_fail = false
break

View File

@@ -458,7 +458,7 @@ Battle::AI::Handlers::MoveEffectScore.add("UsedAfterAllyRoundWithDoublePower",
# No score change if no allies know this move
ally_has_move = false
ai.each_same_side_battler(user.side) do |b, i|
next if !b.has_move_with_function?(move.function)
next if !b.has_move_with_function?(move.function_code)
ally_has_move = true
break
end
@@ -556,7 +556,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TargetUsesItsLastUsedMov
break if mov
end
next Battle::AI::MOVE_USELESS_SCORE if mov.nil? || (mov.pp == 0 && mov.total_pp > 0)
next Battle::AI::MOVE_USELESS_SCORE if move.move.moveBlacklist.include?(mov.function)
next Battle::AI::MOVE_USELESS_SCORE if move.move.moveBlacklist.include?(mov.function_code)
# Without lots of code here to determine good/bad moves, using this move is
# likely to just be a waste of a turn
# NOTE: Because this move can be used against a foe but is being used on an
@@ -802,7 +802,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("DisableTargetStatusMoves
"ProtectUserFromTargetingMovesSpikyShield", # Spiky Shield
"ProtectUserBanefulBunker" # Baneful Bunker
]
if target.check_for_move { |m| m.statusMove? && protection_moves.include?(m.function) }
if target.check_for_move { |m| m.statusMove? && protection_moves.include?(m.function_code) }
score += 10
end
next score

View File

@@ -25,12 +25,12 @@ class Battle
def pbJudgeCheckpoint(user, move = nil)
if pbAllFainted?(0) && pbAllFainted?(1)
if @rules["drawclause"] # NOTE: Also includes Life Orb (not implemented)
if !(move && move.function == "HealUserByHalfOfDamageDone")
if !(move && move.function_code == "HealUserByHalfOfDamageDone")
# Not a draw if fainting occurred due to Liquid Ooze
@decision = (user.opposes?) ? 1 : 2 # win / loss
end
elsif @rules["modifiedselfdestructclause"]
if move && move.function == "UserFaintsExplosive" # Self-Destruct
if move && move.function_code == "UserFaintsExplosive" # Self-Destruct
@decision = (user.opposes?) ? 1 : 2 # win / loss
end
end

View File

@@ -1420,7 +1420,7 @@ Battle::AbilityEffects::DamageCalcFromUser.add(:SWARM,
Battle::AbilityEffects::DamageCalcFromUser.add(:TECHNICIAN,
proc { |ability, user, target, move, mults, power, type|
if user.index != target.index && move && move.function != "Struggle" &&
if user.index != target.index && move && move.function_code != "Struggle" &&
power * mults[:power_multiplier] <= 60
mults[:power_multiplier] *= 1.5
end
@@ -1536,7 +1536,7 @@ Battle::AbilityEffects::DamageCalcFromTarget.add(:FLUFFY,
Battle::AbilityEffects::DamageCalcFromTarget.add(:FURCOAT,
proc { |ability, user, target, move, mults, power, type|
mults[:defense_multiplier] *= 2 if move.physicalMove? ||
move.function == "UseTargetDefenseInsteadOfTargetSpDef" # Psyshock
move.function_code == "UseTargetDefenseInsteadOfTargetSpDef" # Psyshock
}
)
@@ -2596,14 +2596,14 @@ Battle::AbilityEffects::OnSwitchIn.add(:ANTICIPATION,
next if m.statusMove?
if types.length > 0
moveType = m.type
if Settings::MECHANICS_GENERATION >= 6 && m.function == "TypeDependsOnUserIVs" # Hidden Power
if Settings::MECHANICS_GENERATION >= 6 && m.function_code == "TypeDependsOnUserIVs" # Hidden Power
moveType = pbHiddenPower(b.pokemon)[0]
end
eff = Effectiveness.calculate(moveType, *types)
next if Effectiveness.ineffective?(eff)
next if !Effectiveness.super_effective?(eff) &&
!["OHKO", "OHKOIce", "OHKOHitsUndergroundTarget"].include?(m.function)
elsif !["OHKO", "OHKOIce", "OHKOHitsUndergroundTarget"].include?(m.function)
!["OHKO", "OHKOIce", "OHKOHitsUndergroundTarget"].include?(m.function_code)
elsif !["OHKO", "OHKOIce", "OHKOHitsUndergroundTarget"].include?(m.function_code)
next
end
found = true
@@ -2743,12 +2743,12 @@ Battle::AbilityEffects::OnSwitchIn.add(:FOREWARN,
battle.allOtherSideBattlers(battler.index).each do |b|
b.eachMove do |m|
power = m.power
power = 160 if ["OHKO", "OHKOIce", "OHKOHitsUndergroundTarget"].include?(m.function)
power = 150 if ["PowerHigherWithUserHP"].include?(m.function) # Eruption
power = 160 if ["OHKO", "OHKOIce", "OHKOHitsUndergroundTarget"].include?(m.function_code)
power = 150 if ["PowerHigherWithUserHP"].include?(m.function_code) # Eruption
# Counter, Mirror Coat, Metal Burst
power = 120 if ["CounterPhysicalDamage",
"CounterSpecialDamage",
"CounterDamagePlusHalf"].include?(m.function)
"CounterDamagePlusHalf"].include?(m.function_code)
# Sonic Boom, Dragon Rage, Night Shade, Endeavor, Psywave,
# Return, Frustration, Crush Grip, Gyro Ball, Hidden Power,
# Natural Gift, Trump Card, Flail, Grass Knot
@@ -2764,8 +2764,8 @@ Battle::AbilityEffects::OnSwitchIn.add(:FOREWARN,
"TypeAndPowerDependOnUserBerry",
"PowerHigherWithLessPP",
"PowerLowerWithUserHP",
"PowerHigherWithTargetWeight"].include?(m.function)
power = 80 if Settings::MECHANICS_GENERATION <= 5 && m.function == "TypeDependsOnUserIVs"
"PowerHigherWithTargetWeight"].include?(m.function_code)
power = 80 if Settings::MECHANICS_GENERATION <= 5 && m.function_code == "TypeDependsOnUserIVs"
next if power < highestPower
forewarnMoves = [] if power > highestPower
forewarnMoves.push(m.name)

View File

@@ -677,7 +677,7 @@ Battle::ItemEffects::PriorityBracketUse.add(:QUICKCLAW,
Battle::ItemEffects::OnMissingTarget.add(:BLUNDERPOLICY,
proc { |item, user, target, move, hit_num, battle|
next if hit_num > 0 || target.damageState.invulnerable
next if ["OHKO", "OHKOIce", "OHKOHitsUndergroundTarget"].include?(move.function)
next if ["OHKO", "OHKOIce", "OHKOHitsUndergroundTarget"].include?(move.function_code)
next if !user.pbCanRaiseStatStage?(:SPEED, user)
battle.pbCommonAnimation("UseItem", user)
user.pbRaiseStatStageByCause(:SPEED, 2, user, user.itemName)

View File

@@ -65,10 +65,10 @@ class BattlePalaceBattle < Battle
end
def pbMoveCategory(move)
if move.target == :User || move.function == "MultiTurnAttackBideThenReturnDoubleDamage"
if move.target == :User || move.function_code == "MultiTurnAttackBideThenReturnDoubleDamage"
return 1
elsif move.statusMove? ||
move.function == "CounterPhysicalDamage" || move.function == "CounterSpecialDamage"
move.function_code == "CounterPhysicalDamage" || move.function_code == "CounterSpecialDamage"
return 2
else
return 0

View File

@@ -94,14 +94,14 @@ class BattleArenaBattle < Battle
end
def pbMindScore(move)
if move.function == "ProtectUser" || # Detect/Protect
move.function == "UserEnduresFaintingThisTurn" || # Endure
move.function == "FlinchTargetFailsIfNotUserFirstTurn" # Fake Out
if move.function_code == "ProtectUser" || # Detect/Protect
move.function_code == "UserEnduresFaintingThisTurn" || # Endure
move.function_code == "FlinchTargetFailsIfNotUserFirstTurn" # Fake Out
return -1
end
if move.function == "CounterPhysicalDamage" || # Counter
move.function == "CounterSpecialDamage" || # Mirror Coat
move.function == "MultiTurnAttackBideThenReturnDoubleDamage" # Bide
if move.function_code == "CounterPhysicalDamage" || # Counter
move.function_code == "CounterSpecialDamage" || # Mirror Coat
move.function_code == "MultiTurnAttackBideThenReturnDoubleDamage" # Bide
return 0
end
return 0 if move.statusMove?

View File

@@ -29,12 +29,12 @@ class PokemonBoxIcon < IconSprite
def update
super
self.color = Color.new(0, 0, 0, 0)
if releasing?
time_now = System.uptime
self.zoom_x = lerp(1.0, 0.0, 1.5, @release_timer_start, System.uptime)
self.zoom_y = self.zoom_x
self.opacity = lerp(255, 0, 1.5, @release_timer_start, System.uptime)
self.color = Color.new(0, 0, 0, 0)
if self.opacity == 0
@release_timer_start = nil
dispose

View File

@@ -181,8 +181,8 @@ def pbTimeEventValid(variableNumber)
value = $game_variables[variableNumber]
if value.is_a?(Array)
timenow = pbGetTimeNow
ret = (timenow.to_f - value[0] > value[1]) # value[1] is age in seconds
ret = false if value[1] <= 0 # zero age
ret = (timenow.to_f - value[0] > value[1]) # value[1] is age in seconds
ret = false if value[1] <= 0 # zero age
end
if !ret
$game_variables[variableNumber] = 0
@@ -212,8 +212,8 @@ def pbExclaim(event, id = Settings::EXCLAMATION_ANIMATION_ID, tinting = false)
end
end
def pbNoticePlayer(event)
if !pbFacingEachOther(event, $game_player)
def pbNoticePlayer(event, always_show_exclaim = false)
if always_show_exclaim || !pbFacingEachOther(event, $game_player)
pbExclaim(event)
end
pbTurnTowardEvent($game_player, event)

View File

@@ -754,7 +754,10 @@ module Compiler
later_value_found = true if !rec[j].nil?
break if later_value_found
end
break if !later_value_found
if !later_value_found
start = -1
break
end
end
file.write(",") if index > 0
if value.nil?

View File

@@ -3,6 +3,8 @@
# battle, so their moves won't be score).
# TODO: Add held items.
AI_MOVE_TESTING_THRESHOLD = 100
#===============================================================================
#
#===============================================================================
@@ -40,6 +42,16 @@ def debug_set_up_trainer
pkmn = Pokemon.new(this_species, this_level, trainer, false)
all_moves = pkmn.getMoveList.map { |m| m[1] }
all_moves.uniq!
all_moves.reject! { |m| $tested_moves[m] && $tested_moves[m] > AI_MOVE_TESTING_THRESHOLD }
if all_moves.length == 0
all_moves = GameData::Move.keys
all_moves.reject! { |m| $tested_moves[m] && $tested_moves[m] > AI_MOVE_TESTING_THRESHOLD }
end
if all_moves.length == 0
echoln "All moves have been tested at least #{AI_MOVE_TESTING_THRESHOLD} times!"
end
all_moves = pkmn.getMoveList.map { |m| m[1] }
all_moves.uniq!
moves = all_moves.sample(4)
moves.each { |m| pkmn.learn_move(m) }
trainer.party.push(pkmn)
@@ -51,6 +63,8 @@ def debug_set_up_trainer
end
def debug_test_auto_battle(logging = false, console_messages = true)
mar_load_tested_moves_record
old_internal = $INTERNAL
$INTERNAL = logging
if console_messages
@@ -116,6 +130,17 @@ def debug_test_auto_battle(logging = false, console_messages = true)
echoln ""
end
$INTERNAL = old_internal
mar_save_tested_moves_record
end
def mar_load_tested_moves_record
return if $tested_moves
pbRgssOpen("tested_moves.dat", "rb") { |f| $tested_moves = Marshal.load(f) }
end
def mar_save_tested_moves_record
File.open("tested_moves.dat", "wb") { |f| Marshal.dump($tested_moves || {}, f) }
end
#===============================================================================
@@ -156,3 +181,59 @@ MenuHandlers.add(:debug_menu, :bulk_test_auto_battle, {
echoln "Done!"
}
})
MenuHandlers.add(:debug_menu, :load_tested_moves, {
"name" => "Load tested moves",
"parent" => :main,
"description" => "Load tested moves",
"always_show" => false,
"effect" => proc {
mar_load_tested_moves_record
}
})
MenuHandlers.add(:debug_menu, :review_tested_moves, {
"name" => "Review tested moves",
"parent" => :main,
"description" => "List all tested moves and how much they have been tested.",
"always_show" => false,
"effect" => proc {
mar_save_tested_moves_record
thresholded_moves = []
($tested_moves || {}).each_pair do |move, count|
next if !count || count < AI_MOVE_TESTING_THRESHOLD
thresholded_moves.push([move, count])
end
thresholded_moves.sort! { |a, b| a[0].to_s <=> b[0].to_s }
remaining_moves = GameData::Move.keys.clone
thresholded_moves.each { |m| remaining_moves.delete(m[0]) }
remaining_moves.sort! { |a, b| a.to_s <=> b.to_s }
File.open("tested moves summary.txt", "wb") do |f|
f.write(0xEF.chr)
f.write(0xBB.chr)
f.write(0xBF.chr)
f.write("================================================\r\n")
f.write("Met threshold of #{AI_MOVE_TESTING_THRESHOLD}: #{thresholded_moves.length}\r\n")
f.write("================================================\r\n")
thresholded_moves.each do |m|
f.write("#{m[0]} = #{m[1]}\r\n")
end
f.write("\r\n")
f.write("\r\n")
f.write("\r\n")
f.write("================================================\r\n")
f.write("Remaining moves: #{remaining_moves.length}\r\n")
f.write("================================================\r\n")
remaining_moves.each do |m|
if $tested_moves && $tested_moves[m]
f.write("#{m} = #{$tested_moves[m]}\r\n")
else
f.write("#{m}\r\n")
end
end
end
echoln "Done."
}
})

View File

@@ -0,0 +1,21 @@
#===============================================================================
#
#===============================================================================
MenuHandlers.add(:debug_menu, :add_phone_contacts, {
"name" => "Add Phone Contacts",
"parent" => :main,
"description" => "Add 10 different contacts to the phone.",
"effect" => proc {
Phone.add_silent(31, 6, :PICNICKER, "Susie", 2)
Phone.add_silent(52, 1, :POKEMANIAC, "Peter", 2, nil, 1)
Phone.add_silent(26, 1, :POKEMONBREEDER, "Bob", 2)
Phone.add_silent(7, 1, :SCIENTIST, "Cedric", 2)
Phone.add_silent(69, 1, :SWIMMER_F, "Ariel", 2)
Phone.add_silent(5, 1, :BIRDKEEPER, "Sylvie", 2)
Phone.add_silent(72, 1, :BLACKBELT, "Jackie", 2)
Phone.add_silent(28, 1, :BUGCATCHER, "Tommy", 2)
Phone.add_silent(31, 5, :CAMPER, "Jeff", 2)
Phone.add_silent(49, 1, :HIKER, "Ford", 2)
pbMessage("Done.")
}
})