mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
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:
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
#=============================================================================
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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."
|
||||
}
|
||||
})
|
||||
|
||||
21
Data/Scripts/022_Maruno/phone debug.rb
Normal file
21
Data/Scripts/022_Maruno/phone debug.rb
Normal 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.")
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user