Merge branch 'dev' into ai

This commit is contained in:
Maruno17
2022-11-05 20:42:12 +00:00
33 changed files with 198 additions and 168 deletions

View File

@@ -87,6 +87,13 @@ module Console
echoln ""
end
# Same as echoln_li but text is in green
def echoln_li_done(msg)
self.echo_li(markup_style(msg, text: :green), 0, :green)
echoln ""
echoln ""
end
# paragraph with markup
def echo_p(msg)
echoln markup(msg)
@@ -170,7 +177,7 @@ module Console
options_pool = options.select { |key, val| font_options.key?(key) && val }
markup_pool = options_pool.keys.map { |opt| font_options[opt] }.join(";").squeeze
# return formatted string
"\e[#{code_bg};#{markup_pool};#{code_text}m#{string}\e[0m".squeeze(";")
return "\e[#{code_bg};#{markup_pool};#{code_text}m#{string}\e[0m".squeeze(";")
end
#-----------------------------------------------------------------------------

View File

@@ -295,7 +295,7 @@ module PluginManager
def self.error(msg)
Graphics.update
t = Thread.new do
Console.echo_error "Plugin Error:\r\n#{msg}"
Console.echo_error("Plugin Error:\r\n#{msg}")
print("Plugin Error:\r\n#{msg}")
Thread.exit
end
@@ -594,7 +594,7 @@ module PluginManager
# Check if plugins need compiling
#-----------------------------------------------------------------------------
def self.compilePlugins(order, plugins)
Console.echo_li "Compiling plugin scripts..."
Console.echo_li("Compiling plugin scripts...")
scripts = []
# go through the entire order one by one
order.each do |o|
@@ -617,20 +617,19 @@ module PluginManager
# collect garbage
GC.start
Console.echo_done(true)
echoln "" if scripts.length == 0
end
#-----------------------------------------------------------------------------
# Check if plugins need compiling
#-----------------------------------------------------------------------------
def self.runPlugins
Console.echo_h1 "Checking plugins"
Console.echo_h1("Checking plugins")
# get the order of plugins to interpret
order, plugins = self.getPluginOrder
# compile if necessary
if self.needCompiling?(order, plugins)
self.compilePlugins(order, plugins)
else
Console.echoln_li "Plugins were not compiled."
Console.echoln_li("Plugins were not compiled")
end
# load plugins
scripts = load_data("Data/PluginScripts.rxdata")
@@ -639,7 +638,7 @@ module PluginManager
# get the required data
name, meta, script = plugin
if !meta[:essentials] || !meta[:essentials].include?(Essentials::VERSION)
Console.echo_warn "Plugin '#{name}' may not be compatible with Essentials v#{Essentials::VERSION}. Trying to load anyway."
Console.echo_warn("Plugin '#{name}' may not be compatible with Essentials v#{Essentials::VERSION}. Trying to load anyway.")
end
# register plugin
self.register(meta)
@@ -655,7 +654,7 @@ module PluginManager
# try to run the code
begin
eval(code, TOPLEVEL_BINDING, fname)
Console.echoln_li "Loaded plugin: ==#{name}== (ver. #{meta[:version]})" if !echoed_plugins.include?(name)
Console.echoln_li("Loaded plugin: ==#{name}== (ver. #{meta[:version]})") if !echoed_plugins.include?(name)
echoed_plugins.push(name)
rescue Exception # format error message to display
self.pluginErrorMsg(name, sname)
@@ -664,10 +663,9 @@ module PluginManager
end
end
if scripts.length > 0
echoln ""
Console.echo_h2("Successfully loaded #{scripts.length} plugin(s)", text: :green)
Console.echoln_li_done("Successfully loaded #{scripts.length} plugin(s)")
else
Console.echo_h2("No plugins found", text: :green)
Console.echoln_li_done("No plugins found")
end
end
#-----------------------------------------------------------------------------

View File

@@ -195,14 +195,13 @@ module SaveData
conversions_to_run = self.get_conversions(save_data)
return false if conversions_to_run.none?
File.open(SaveData::FILE_PATH + ".bak", "wb") { |f| Marshal.dump(save_data, f) }
Console.echo_h1 "Running #{conversions_to_run.length} save file conversions"
Console.echo_h1(_INTL("Converting save file"))
conversions_to_run.each do |conversion|
Console.echo_li "#{conversion.title}..."
Console.echo_li("#{conversion.title}...")
conversion.run(save_data)
Console.echo_done(true)
end
echoln "" if conversions_to_run.length > 0
Console.echo_h2("All save file conversions applied successfully", text: :green)
Console.echoln_li_done(_INTL("Successfully applied #{conversions_to_run.length} save file conversion(s)"))
save_data[:essentials_version] = Essentials::VERSION
save_data[:game_version] = Settings::GAME_VERSION
return true

View File

@@ -42,6 +42,8 @@ module Game
end
$game_temp.common_event_id = 0 if $game_temp
$game_temp.begun_new_game = true
pbMapInterpreter&.clear
pbMapInterpreter&.setup(nil, 0, 0)
$scene = Scene_Map.new
SaveData.load_new_game_values
$stats.play_sessions += 1

View File

@@ -59,10 +59,9 @@ class Scene_Map
return if !playingBGM && !playingBGS
map = load_data(sprintf("Data/Map%03d.rxdata", mapid))
if playingBGM && map.autoplay_bgm
if (PBDayNight.isNight? && FileTest.audio_exist?("Audio/BGM/" + map.bgm.name + "_n") &&
playingBGM.name != map.bgm.name + "_n") || playingBGM.name != map.bgm.name
pbBGMFade(0.8)
end
test_filename = map.bgm.name
test_filename += "_n" if PBDayNight.isNight? && FileTest.audio_exist?("Audio/BGM/" + test_filename + "_n")
pbBGMFade(0.8) if playingBGM.name != test_filename
end
if playingBGS && map.autoplay_bgs && playingBGS.name != map.bgs.name
pbBGMFade(0.8)

View File

@@ -163,13 +163,13 @@ end
class HandlerHashSymbol
def initialize
@hash = {}
@add_ifs = []
@add_ifs = {}
end
def [](sym)
sym = sym.id if !sym.is_a?(Symbol) && sym.respond_to?("id")
return @hash[sym] if sym && @hash[sym]
@add_ifs.each do |add_if|
@add_ifs.each_value do |add_if|
return add_if[1] if add_if[0].call(sym)
end
return nil
@@ -182,11 +182,11 @@ class HandlerHashSymbol
@hash[sym] = handler || handlerBlock if sym
end
def addIf(conditionProc, handler = nil, &handlerBlock)
def addIf(sym, conditionProc, handler = nil, &handlerBlock)
if ![Proc, Hash].include?(handler.class) && !block_given?
raise ArgumentError, "addIf call for #{self.class.name} has no valid handler (#{handler.inspect} was given)"
raise ArgumentError, "addIf call for #{sym} in #{self.class.name} has no valid handler (#{handler.inspect} was given)"
end
@add_ifs.push([conditionProc, handler || handlerBlock])
@add_ifs[sym] = [conditionProc, handler || handlerBlock]
end
def copy(src, *dests)
@@ -271,13 +271,6 @@ class HandlerHashEnum
@hash[symbol] = handler || handlerBlock if symbol
end
def addIf(conditionProc, handler = nil, &handlerBlock)
if ![Proc, Hash].include?(handler.class) && !block_given?
raise ArgumentError, "addIf call for #{self.class.name} has no valid handler (#{handler.inspect} was given)"
end
@addIfs.push([conditionProc, handler || handlerBlock])
end
def copy(src, *dests)
handler = self[src]
return if !handler

View File

@@ -529,11 +529,17 @@ class Game_Player < Game_Character
end
end
# Center player on-screen
# Track the player on-screen as they move
def update_screen_position(last_real_x, last_real_y)
return if self.map.scrolling? || !(@moved_last_frame || @moved_this_frame)
self.map.display_x = @real_x - SCREEN_CENTER_X
self.map.display_y = @real_y - SCREEN_CENTER_Y
if (@real_x < last_real_x && @real_x - $game_map.display_x < SCREEN_CENTER_X) ||
(@real_x > last_real_x && @real_x - $game_map.display_x > SCREEN_CENTER_X)
self.map.display_x += @real_x - last_real_x
end
if (@real_y < last_real_y && @real_y - $game_map.display_y < SCREEN_CENTER_Y) ||
(@real_y > last_real_y && @real_y - $game_map.display_y > SCREEN_CENTER_Y)
self.map.display_y += @real_y - last_real_y
end
end
def update_event_triggering

View File

@@ -428,7 +428,7 @@ class TilemapRenderer
tile.z = 0
else
priority = tile.priority
tile.z = (priority == 0) ? 0 : (y * SOURCE_TILE_HEIGHT) + (priority * SOURCE_TILE_HEIGHT) + SOURCE_TILE_HEIGHT
tile.z = (priority == 0) ? 0 : (y * SOURCE_TILE_HEIGHT) + (priority * SOURCE_TILE_HEIGHT) + SOURCE_TILE_HEIGHT + 1
end
end

View File

@@ -942,14 +942,10 @@ def drawSingleFormattedChar(bitmap, ch)
graphic.dispose
return
end
bitmap.font.bold = ch[6] if bitmap.font.bold != ch[6]
bitmap.font.italic = ch[7] if bitmap.font.italic != ch[7]
bitmap.font.name = ch[12] if bitmap.font.name != ch[12]
bitmap.font.size = ch[13] if bitmap.font.size != ch[13]
if ch[9] # shadow
if ch[10] # underline
bitmap.fill_rect(ch[1], ch[2] + ch[4] - [(ch[4] - bitmap.font.size) / 2, 0].max - 2,
ch[3], 4, ch[9])
bitmap.fill_rect(ch[1], ch[2] + ch[4] - [(ch[4] - bitmap.font.size) / 2, 0].max - 2, ch[3], 4, ch[9])
end
if ch[11] # strikeout
bitmap.fill_rect(ch[1], ch[2] + 2 + (ch[4] / 2), ch[3], 4, ch[9])
@@ -958,6 +954,9 @@ def drawSingleFormattedChar(bitmap, ch)
if ch[0] == "\n" || ch[0] == "\r" || ch[0] == " " || isWaitChar(ch[0])
bitmap.font.color = ch[8] if bitmap.font.color != ch[8]
else
bitmap.font.bold = ch[6] if bitmap.font.bold != ch[6]
bitmap.font.italic = ch[7] if bitmap.font.italic != ch[7]
bitmap.font.name = ch[12] if bitmap.font.name != ch[12]
offset = 0
if ch[9] # shadow
bitmap.font.color = ch[9]
@@ -991,8 +990,7 @@ def drawSingleFormattedChar(bitmap, ch)
bitmap.draw_text(ch[1] + offset, ch[2] + offset, ch[3], ch[4], ch[0])
end
if ch[10] # underline
bitmap.fill_rect(ch[1], ch[2] + ch[4] - [(ch[4] - bitmap.font.size) / 2, 0].max - 2,
ch[3] - 2, 2, ch[8])
bitmap.fill_rect(ch[1], ch[2] + ch[4] - [(ch[4] - bitmap.font.size) / 2, 0].max - 2, ch[3] - 2, 2, ch[8])
end
if ch[11] # strikeout
bitmap.fill_rect(ch[1], ch[2] + 2 + (ch[4] / 2), ch[3] - 2, 2, ch[8])

View File

@@ -156,7 +156,6 @@ module GameData
pkmn.name = pkmn_data[:name] if pkmn_data[:name] && !pkmn_data[:name].empty?
if pkmn_data[:shadowness]
pkmn.makeShadow
pkmn.update_shadow_moves(true)
pkmn.shiny = false
end
pkmn.poke_ball = pkmn_data[:poke_ball] if pkmn_data[:poke_ball]

View File

@@ -35,7 +35,7 @@ class Battle::Battler
end
def pbRecoverHPFromDrain(amt, target, msg = nil)
if target.hasActiveAbility?(:LIQUIDOOZE)
if target.hasActiveAbility?(:LIQUIDOOZE, true)
@battle.pbShowAbilitySplash(target)
pbReduceHP(amt)
@battle.pbDisplay(_INTL("{1} sucked up the liquid ooze!", pbThis))

View File

@@ -160,17 +160,19 @@ class Battle::Battler
# Start using the move
pbBeginTurn(choice)
# Force the use of certain moves if they're already being used
if usingMultiTurnAttack?
choice[2] = Battle::Move.from_pokemon_move(@battle, Pokemon::Move.new(@currentMove))
specialUsage = true
elsif @effects[PBEffects::Encore] > 0 && choice[1] >= 0 &&
@battle.pbCanShowCommands?(@index)
idxEncoredMove = pbEncoredMoveIndex
if idxEncoredMove >= 0 && choice[1] != idxEncoredMove &&
@battle.pbCanChooseMove?(@index, idxEncoredMove, false) # Change move if battler was Encored mid-round
choice[1] = idxEncoredMove
choice[2] = @moves[idxEncoredMove]
choice[3] = -1 # No target chosen
if !@battle.futureSight
if usingMultiTurnAttack?
choice[2] = Battle::Move.from_pokemon_move(@battle, Pokemon::Move.new(@currentMove))
specialUsage = true
elsif @effects[PBEffects::Encore] > 0 && choice[1] >= 0 &&
@battle.pbCanShowCommands?(@index)
idxEncoredMove = pbEncoredMoveIndex
if idxEncoredMove >= 0 && choice[1] != idxEncoredMove &&
@battle.pbCanChooseMove?(@index, idxEncoredMove, false) # Change move if battler was Encored mid-round
choice[1] = idxEncoredMove
choice[2] = @moves[idxEncoredMove]
choice[3] = -1 # No target chosen
end
end
end
# Labels the move being used as "move"
@@ -361,6 +363,8 @@ class Battle::Battler
targets = pbFindTargets(choice, move, user)
end
end
# For two-turn moves when they charge and attack in the same turn
move.pbQuickChargingMove(user, targets)
#---------------------------------------------------------------------------
magicCoater = -1
magicBouncer = -1

View File

@@ -27,8 +27,8 @@ class Battle::Move
#=============================================================================
#
#=============================================================================
# Whether the move is currently in the "charging" turn of a two turn attack.
# Is false if Power Herb or another effect lets a two turn move charge and
# Whether the move is currently in the "charging" turn of a two-turn move.
# Is false if Power Herb or another effect lets a two-turn move charge and
# attack in the same turn.
# user.effects[PBEffects::TwoTurnAttack] is set to the move's ID during the
# charging turn, and is nil during the attack turn.
@@ -52,6 +52,9 @@ class Battle::Move
return 1
end
# For two-turn moves when they charge and attack in the same turn.
def pbQuickChargingMove(user, targets); end
#=============================================================================
# Effect methods per hit
#=============================================================================
@@ -271,6 +274,7 @@ class Battle::Move
# Messages upon being hit
#=============================================================================
def pbEffectivenessMessage(user, target, numTargets = 1)
return if self.is_a?(Battle::Move::FixedDamageMove)
return if target.damageState.disguise || target.damageState.iceFace
if Effectiveness.super_effective?(target.damageState.typeMod)
if numTargets > 1

View File

@@ -323,33 +323,41 @@ class Battle::Move::TwoTurnMove < Battle::Move
return super
end
# Does the charging part of this move, for when this move only takes one round
# to use.
def pbQuickChargingMove(user, targets)
return if !@chargingTurn || !@damagingTurn # Move only takes one turn to use
pbChargingTurnMessage(user, targets)
pbShowAnimation(@id, user, targets, 1) # Charging anim
targets.each { |b| pbChargingTurnEffect(user, b) }
if @powerHerb
# Moves that would make the user semi-invulnerable will hide the user
# after the charging animation, so the "UseItem" animation shouldn't show
# for it
if !["TwoTurnAttackInvulnerableInSky",
"TwoTurnAttackInvulnerableUnderground",
"TwoTurnAttackInvulnerableUnderwater",
"TwoTurnAttackInvulnerableInSkyParalyzeTarget",
"TwoTurnAttackInvulnerableRemoveProtections",
"TwoTurnAttackInvulnerableInSkyTargetCannotAct"].include?(@function)
@battle.pbCommonAnimation("UseItem", user)
end
@battle.pbDisplay(_INTL("{1} became fully charged due to its Power Herb!", user.pbThis))
user.pbConsumeItem
end
end
def pbAccuracyCheck(user, target)
return true if !@damagingTurn
return super
end
def pbInitialEffect(user, targets, hitNum)
pbChargingTurnMessage(user, targets) if @chargingTurn
if @chargingTurn && @damagingTurn # Move only takes one turn to use
pbShowAnimation(@id, user, targets, 1) # Charging anim
targets.each { |b| pbChargingTurnEffect(user, b) }
if @powerHerb
# Moves that would make the user semi-invulnerable will hide the user
# after the charging animation, so the "UseItem" animation shouldn't show
# for it
if !["TwoTurnAttackInvulnerableInSky",
"TwoTurnAttackInvulnerableUnderground",
"TwoTurnAttackInvulnerableUnderwater",
"TwoTurnAttackInvulnerableInSkyParalyzeTarget",
"TwoTurnAttackInvulnerableRemoveProtections",
"TwoTurnAttackInvulnerableInSkyTargetCannotAct"].include?(@function)
@battle.pbCommonAnimation("UseItem", user)
end
@battle.pbDisplay(_INTL("{1} became fully charged due to its Power Herb!", user.pbThis))
user.pbConsumeItem
end
if @damagingTurn
pbAttackingTurnMessage(user, targets)
elsif @chargingTurn
pbChargingTurnMessage(user, targets)
end
pbAttackingTurnMessage(user, targets) if @damagingTurn
end
def pbChargingTurnMessage(user, targets)
@@ -359,14 +367,6 @@ class Battle::Move::TwoTurnMove < Battle::Move
def pbAttackingTurnMessage(user, targets)
end
def pbChargingTurnEffect(user, target)
# Skull Bash/Sky Drop are the only two-turn moves with an effect here, and
# the latter just records the target is being Sky Dropped
end
def pbAttackingTurnEffect(user, target)
end
def pbEffectAgainstTarget(user, target)
if @damagingTurn
pbAttackingTurnEffect(user, target)
@@ -375,6 +375,14 @@ class Battle::Move::TwoTurnMove < Battle::Move
end
end
def pbChargingTurnEffect(user, target)
# Skull Bash/Sky Drop are the only two-turn moves with an effect here, and
# the latter just records the target is being Sky Dropped
end
def pbAttackingTurnEffect(user, target)
end
def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true)
hitNum = 1 if @chargingTurn && !@damagingTurn # Charging anim
super

View File

@@ -141,7 +141,7 @@ class Battle::Move::HealUserByTargetAttackLowerTargetAttack1 < Battle::Move
target.pbLowerStatStage(:ATTACK, 1, user)
end
# Heal user
if target.hasActiveAbility?(:LIQUIDOOZE)
if target.hasActiveAbility?(:LIQUIDOOZE, true)
@battle.pbShowAbilitySplash(target)
user.pbReduceHP(healAmt)
@battle.pbDisplay(_INTL("{1} sucked up the liquid ooze!", user.pbThis))

View File

@@ -388,6 +388,7 @@ class Battle::Scene::FightMenu < Battle::Scene::MenuBase
def refreshMoveData(move)
# Write PP and type of the selected move
if !USE_GRAPHICS
return if !move
moveType = GameData::Type.get(move.display_type(@battler)).name
if move.total_pp <= 0
@msgBox.text = _INTL("PP: ---<br>TYPE/{1}", moveType)

View File

@@ -347,7 +347,7 @@ class WildBattle
# roaming Pokémon, Safari battles, Bug Contest battles)
if foe_party.length == 1 && can_override
handled = [nil]
EventHandlers.trigger(:on_calling_wild_battle, foe_party[0].species, foe_party[0].level, handled)
EventHandlers.trigger(:on_calling_wild_battle, foe_party[0], handled)
return handled[0] if !handled[0].nil?
end
# Perform the battle

View File

@@ -6,7 +6,8 @@ class PokemonGlobalMetadata
attr_writer :roamPokemonCaught
def roamPokemonCaught
return @roamPokemonCaught || []
@roamPokemonCaught = [] if !@roamPokemonCaught
return @roamPokemonCaught
end
end
@@ -185,23 +186,27 @@ EventHandlers.add(:on_wild_species_chosen, :roaming_pokemon,
)
EventHandlers.add(:on_calling_wild_battle, :roaming_pokemon,
proc { |species, level, handled|
proc { |pkmn, handled|
# handled is an array: [nil]. If [true] or [false], the battle has already
# been overridden (the boolean is its outcome), so don't do anything that
# would override it again
next if !handled[0].nil?
next if !$PokemonGlobal.roamEncounter || $game_temp.roamer_index_for_encounter.nil?
handled[0] = pbRoamingPokemonBattle(species, level)
handled[0] = pbRoamingPokemonBattle(pkmn)
}
)
def pbRoamingPokemonBattle(species, level)
def pbRoamingPokemonBattle(pkmn, level = 1)
# Get the roaming Pokémon to encounter; generate it based on the species and
# level if it doesn't already exist
idxRoamer = $game_temp.roamer_index_for_encounter
if !$PokemonGlobal.roamPokemon[idxRoamer] ||
!$PokemonGlobal.roamPokemon[idxRoamer].is_a?(Pokemon)
$PokemonGlobal.roamPokemon[idxRoamer] = pbGenerateWildPokemon(species, level, true)
if pkmn.is_a?(Pokemon)
$PokemonGlobal.roamPokemon[idxRoamer] = pbGenerateWildPokemon(pkmn.species_data.id, pkmn.level, true)
else
$PokemonGlobal.roamPokemon[idxRoamer] = pbGenerateWildPokemon(pkmn, level, true)
end
end
# Set some battle rules
setBattleRule("single")
@@ -217,7 +222,7 @@ def pbRoamingPokemonBattle(species, level)
$PokemonGlobal.roamedAlready = true
$game_temp.roamer_index_for_encounter = nil
# Used by the Poké Radar to update/break the chain
EventHandlers.trigger(:on_wild_battle_end, species, level, decision)
EventHandlers.trigger(:on_wild_battle_end, pkmn.species_data.id, pkmn.level, decision)
# Return false if the player lost or drew the battle, and true if any other result
return (decision != 2 && decision != 5)
end

View File

@@ -150,9 +150,8 @@ class DayCare
egg.nature = new_natures.sample
end
# If a Pokémon is bred with a Ditto, that Pokémon can pass down its Hidden
# Ability (60% chance). If neither Pokémon are Ditto, then the mother can
# pass down its ability (60% chance if Hidden, 80% chance if not).
# The female parent (or the non-Ditto parent) can pass down its Hidden
# Ability (60% chance) or its regular ability (80% chance).
# NOTE: This is how ability inheritance works in Gen 6+. Gen 5 is more
# restrictive, and even works differently between BW and B2W2, and I
# don't think that is worth adding in. Gen 4 and lower don't have
@@ -164,26 +163,25 @@ class DayCare
parent = (mother[1]) ? father[0] : mother[0] # The female or non-Ditto parent
if parent.hasHiddenAbility?
egg.ability_index = parent.ability_index if rand(100) < 60
elsif !mother[1] && !father[1] # If neither parent is a Ditto
if rand(100) < 80
egg.ability_index = mother[0].ability_index
else
egg.ability_index = (mother[0].ability_index + 1) % 2
end
elsif rand(100) < 80
egg.ability_index = parent.ability_index
else
egg.ability_index = (parent.ability_index + 1) % 2
end
end
def inherit_IVs(egg, mother, father)
# Get all stats
stats = []
GameData::Stat.each_main { |s| stats.push(s) }
# Get the number of stats to inherit
GameData::Stat.each_main { |s| stats.push(s.id) }
# Get the number of stats to inherit (includes ones inherited via Power items)
inherit_count = 3
if Settings::MECHANICS_GENERATION >= 6
inherit_count = 5 if mother.hasItem?(:DESTINYKNOT) || father.hasItem?(:DESTINYKNOT)
end
# Inherit IV because of Power items (if both parents have a Power item,
# then only a random one of them is inherited)
# Inherit IV because of Power items (if both parents have the same Power
# item, then the parent that passes that Power item's stat down is chosen
# randomly)
power_items = [
[:POWERWEIGHT, :HP],
[:POWERBRACER, :ATTACK],
@@ -192,18 +190,20 @@ class DayCare
[:POWERBAND, :SPECIAL_DEFENSE],
[:POWERANKLET, :SPEED]
]
power_stats = []
power_stats = {}
[mother, father].each do |parent|
power_items.each do |item|
next if !parent.hasItem?(item[0])
power_stats.push(item[1], parent.iv[item[1]])
power_stats[item[1]] ||= []
power_stats[item[1]].push(parent.iv[item[1]])
break
end
end
if power_stats.length > 0
power_stat = power_stats.sample
egg.iv[power_stat[0]] = power_stat[1]
stats.delete(power_stat[0]) # Don't try to inherit this stat's IV again
power_stats.each_pair do |stat, new_stats|
next if !new_stats || new_stats.length == 0
new_stat = new_stats.sample
egg.iv[stat] = new_stat
stats.delete(stat) # Don't try to inherit this stat's IV again
inherit_count -= 1
end
# Inherit the rest of the IVs

View File

@@ -64,7 +64,8 @@ ItemHandlers::UseFromBag.add(:TOWNMAP, proc { |item|
next ($game_temp.fly_destination) ? 2 : 0
})
ItemHandlers::UseFromBag.addIf(proc { |item| GameData::Item.get(item).is_machine? },
ItemHandlers::UseFromBag.addIf(:move_machines,
proc { |item| GameData::Item.get(item).is_machine? },
proc { |item|
if $player.pokemon_count == 0
pbMessage(_INTL("There is no Pokémon."))
@@ -361,7 +362,8 @@ ItemHandlers::UseInField.add(:EXPALLOFF, proc { |item|
# Applies to all items defined as an evolution stone.
# No need to add more code for new ones.
ItemHandlers::UseOnPokemon.addIf(proc { |item| GameData::Item.get(item).is_evolution_stone? },
ItemHandlers::UseOnPokemon.addIf(:evolution_stones,
proc { |item| GameData::Item.get(item).is_evolution_stone? },
proc { |item, qty, pkmn, scene|
if pkmn.shadowPokemon?
scene.pbDisplay(_INTL("It won't have any effect."))

View File

@@ -25,7 +25,8 @@ ItemHandlers::CanUseInBattle.add(:POKEDOLL, proc { |item, pokemon, battler, move
ItemHandlers::CanUseInBattle.copy(:POKEDOLL, :FLUFFYTAIL, :POKETOY)
ItemHandlers::CanUseInBattle.addIf(proc { |item| GameData::Item.get(item).is_poke_ball? }, # Poké Balls
ItemHandlers::CanUseInBattle.addIf(:poke_balls,
proc { |item| GameData::Item.get(item).is_poke_ball? },
proc { |item, pokemon, battler, move, firstAction, battle, scene, showMessages|
if battle.pbPlayer.party_full? && $PokemonStorage.full?
scene.pbDisplay(_INTL("There is no room left in the PC!")) if showMessages
@@ -314,7 +315,8 @@ ItemHandlers::UseInBattle.add(:POKEFLUTE, proc { |item, battler, battle|
battle.pbDisplay(_INTL("All Pokémon were roused by the tune!"))
})
ItemHandlers::UseInBattle.addIf(proc { |item| GameData::Item.get(item).is_poke_ball? }, # Poké Balls
ItemHandlers::UseInBattle.addIf(:poke_balls,
proc { |item| GameData::Item.get(item).is_poke_ball? },
proc { |item, battler, battle|
battle.pbThrowPokeBall(battler.index, item)
}

View File

@@ -44,7 +44,7 @@ end
def pbUsePokeRadar
return false if !pbCanUsePokeRadar?
$stats.poke_radar_count += 1
$game_temp.poke_radar_data = [0, 0, 0, [], false] if !$game_temp.poke_radar_data
$game_temp.poke_radar_data = [nil, 0, 0, [], false] if !$game_temp.poke_radar_data
$game_temp.poke_radar_data[4] = false
$PokemonGlobal.pokeradarBattery = 50
pbPokeRadarHighlightGrass

View File

@@ -9,8 +9,8 @@ module MultipleForms
@@formSpecies.add(sym, hash)
end
def self.registerIf(cond, hash)
@@formSpecies.addIf(cond, hash)
def self.registerIf(sym, cond, hash)
@@formSpecies.addIf(sym, cond, hash)
end
def self.hasFunction?(pkmn, func)

View File

@@ -141,7 +141,7 @@ class Pokemon
end
end
def update_shadow_moves(relearn_all_moves = false)
def update_shadow_moves
return if !@shadow_moves || @shadow_moves.empty?
# Not a Shadow Pokémon (any more); relearn all its original moves
if !shadowPokemon?
@@ -159,7 +159,7 @@ class Pokemon
@shadow_moves.each_with_index { |m, i| new_moves.push(m) if m && i < MAX_MOVES }
num_shadow_moves = new_moves.length
# Add some original moves (skipping ones in the same slot as a Shadow Move)
num_original_moves = (relearn_all_moves) ? 3 : [3, 3, 2, 1, 1, 0][self.heartStage]
num_original_moves = [3, 3, 2, 1, 1, 0][self.heartStage]
if num_original_moves > 0
relearned_count = 0
@shadow_moves.each_with_index do |m, i|
@@ -174,17 +174,16 @@ class Pokemon
end
def replace_moves(new_moves)
# Forget any known moves that aren't in new_moves
@moves.each_with_index do |m, i|
@moves[i] = nil if !new_moves.include?(m.id)
end
@moves.compact!
# Learn any moves in new_moves that aren't known
new_moves.each do |move|
next if !move || !GameData::Move.exists?(move) || hasMove?(move)
if numMoves < Pokemon::MAX_MOVES # Has an empty slot; just learn move
learn_move(move)
next
end
@moves.each do |m|
next if new_moves.include?(m.id)
m.id = GameData::Move.get(move).id
break
end
break if numMoves >= Pokemon::MAX_MOVES
learn_move(move)
end
end

View File

@@ -105,19 +105,19 @@ EventHandlers.add(:on_player_step_taken_can_transfer, :safari_game_counter,
#
#===============================================================================
EventHandlers.add(:on_calling_wild_battle, :safari_battle,
proc { |species, level, handled|
proc { |pkmn, handled|
# handled is an array: [nil]. If [true] or [false], the battle has already
# been overridden (the boolean is its outcome), so don't do anything that
# would override it again
next if !handled[0].nil?
next if !pbInSafari?
handled[0] = pbSafariBattle(species, level)
handled[0] = pbSafariBattle(pkmn)
}
)
def pbSafariBattle(species, level)
def pbSafariBattle(pkmn, level = 1)
# Generate a wild Pokémon based on the species and level
pkmn = pbGenerateWildPokemon(species, level)
pkmn = pbGenerateWildPokemon(pkmn, level) if !pkmn.is_a?(Pokemon)
foeParty = [pkmn]
# Calculate who the trainer is
playerTrainer = $player
@@ -156,7 +156,7 @@ def pbSafariBattle(species, level)
end
pbSet(1, decision)
# Used by the Poké Radar to update/break the chain
EventHandlers.trigger(:on_wild_battle_end, species, level, decision)
EventHandlers.trigger(:on_wild_battle_end, pkmn.species_data.id, pkmn.level, decision)
# Return the outcome of the battle
return decision
end

View File

@@ -355,22 +355,22 @@ EventHandlers.add(:on_leave_map, :end_bug_contest,
#
#===============================================================================
EventHandlers.add(:on_calling_wild_battle, :bug_contest_battle,
proc { |species, level, handled|
proc { |pkmn, handled|
# handled is an array: [nil]. If [true] or [false], the battle has already
# been overridden (the boolean is its outcome), so don't do anything that
# would override it again
next if !handled[0].nil?
next if !pbInBugContest?
handled[0] = pbBugContestBattle(species, level)
handled[0] = pbBugContestBattle(pkmn)
}
)
def pbBugContestBattle(species, level)
def pbBugContestBattle(pkmn, level = 1)
# Record information about party Pokémon to be used at the end of battle (e.g.
# comparing levels for an evolution check)
EventHandlers.trigger(:on_start_battle)
# Generate a wild Pokémon based on the species and level
pkmn = pbGenerateWildPokemon(species, level)
pkmn = pbGenerateWildPokemon(pkmn, level) if !pkmn.is_a?(Pokemon)
foeParty = [pkmn]
# Calculate who the trainers and their party are
playerTrainer = [$player]
@@ -405,7 +405,7 @@ def pbBugContestBattle(species, level)
# Save the result of the battle in Game Variable 1
BattleCreationHelperMethods.set_outcome(decision, 1)
# Used by the Poké Radar to update/break the chain
EventHandlers.trigger(:on_wild_battle_end, species, level, decision)
EventHandlers.trigger(:on_wild_battle_end, pkmn.species_data.id, pkmn.level, decision)
# Return false if the player lost or drew the battle, and true if any other result
return (decision != 2 && decision != 5)
end

View File

@@ -466,6 +466,11 @@ def pbDebugRoamers
Graphics.update
Input.update
pbUpdateSpriteHash(sprites)
if cmdwindow.index < cmdwindow.roamerCount
pkmn = Settings::ROAMING_SPECIES[cmdwindow.index]
else
pkmn = nil
end
if Input.trigger?(Input::ACTION) && cmdwindow.index < cmdwindow.roamerCount &&
(pkmn[2] <= 0 || $game_switches[pkmn[2]]) &&
$PokemonGlobal.roamPokemon[cmdwindow.index] != true
@@ -494,7 +499,6 @@ def pbDebugRoamers
if cmdwindow.index < cmdwindow.roamerCount
pbPlayDecisionSE
# Toggle through roaming, not roaming, defeated
pkmn = Settings::ROAMING_SPECIES[cmdwindow.index]
if pkmn[2] > 0 && !$game_switches[pkmn[2]]
# not roaming -> roaming
$game_switches[pkmn[2]] = true
@@ -507,7 +511,7 @@ def pbDebugRoamers
# defeated -> caught
$PokemonGlobal.roamPokemonCaught[cmdwindow.index] = true
elsif pkmn[2] > 0
# caught -> not roaming (or roaming if Switch ID is 0
# caught -> not roaming (or roaming if Switch ID is 0)
$game_switches[pkmn[2]] = false if pkmn[2] > 0
$PokemonGlobal.roamPokemon[cmdwindow.index] = nil
$PokemonGlobal.roamPokemonCaught[cmdwindow.index] = false
@@ -701,7 +705,7 @@ def pbDebugFixInvalidTiles
t = Time.now.to_i
Graphics.update
total_maps = mapData.mapinfos.keys.length
Console.echo_h1 _INTL("Checking {1} maps for invalid tiles", total_maps)
Console.echo_h1(_INTL("Checking {1} maps for invalid tiles", total_maps))
mapData.mapinfos.keys.sort.each do |id|
if Time.now.to_i - t >= 5
Graphics.update
@@ -734,7 +738,7 @@ def pbDebugFixInvalidTiles
end
next if map_errors == 0
# Map was changed; save it
Console.echoln_li _INTL("{1} error tile(s) found on map {2}: {3}.", map_errors, id, mapData.mapinfos[id].name)
Console.echoln_li(_INTL("{1} error tile(s) found on map {2}: {3}.", map_errors, id, mapData.mapinfos[id].name))
total_errors += map_errors
num_error_maps += 1
mapData.saveMap(id)
@@ -745,7 +749,7 @@ def pbDebugFixInvalidTiles
else
echoln ""
Console.echo_h2(_INTL("Done. {1} errors found and fixed.", total_errors), text: :green)
Console.echo_warn _INTL("RMXP data was altered. Close RMXP now to ensure changes are applied.")
Console.echo_warn(_INTL("RMXP data was altered. Close RMXP now to ensure changes are applied."))
echoln ""
pbMessage(_INTL("{1} error(s) were found across {2} map(s) and fixed.", total_errors, num_error_maps))
pbMessage(_INTL("Close RPG Maker XP to ensure the changes are applied properly."))

View File

@@ -17,7 +17,7 @@ module FilenameUpdater
def rename_berry_plant_charsets
src_dir = "Graphics/Characters/"
return false if !FileTest.directory?(src_dir)
Console.echo_li _INTL("Renaming berry tree charsets...")
Console.echo_li(_INTL("Renaming berry tree charsets..."))
ret = false
# generates a list of all graphic files
files = readDirectoryFiles(src_dir, ["berrytree*.png"])
@@ -38,7 +38,7 @@ module FilenameUpdater
mapData = Compiler::MapData.new
t = Time.now.to_i
Graphics.update
Console.echo_li _INTL("Checking {1} maps for used berry tree charsets...", mapData.mapinfos.keys.length)
Console.echo_li(_INTL("Checking {1} maps for used berry tree charsets...", mapData.mapinfos.keys.length))
idx = 0
mapData.mapinfos.keys.sort.each do |id|
echo "." if idx % 20 == 0
@@ -71,19 +71,19 @@ module FilenameUpdater
end
def rename_files
Console.echo_h1 "Updating file names and locations"
Console.echo_h1(_INTL("Updating file names and locations"))
change_record = []
# Add underscore to berry plant charsets
if rename_berry_plant_charsets
Console.echo_warn _INTL("Berry plant charset files were renamed.")
Console.echo_warn(_INTL("Berry plant charset files were renamed."))
end
change_record += update_berry_tree_event_charsets
# Warn if any map data has been changed
if !change_record.empty?
change_record.each { |msg| Console.echo_warn msg }
Console.echo_warn _INTL("RMXP data was altered. Close RMXP now to ensure changes are applied.")
change_record.each { |msg| Console.echo_warn(msg) }
Console.echo_warn(_INTL("RMXP data was altered. Close RMXP now to ensure changes are applied."))
end
echoln ""
Console.echo_h2("Finished updating file names and locations", text: :green)
Console.echo_h2(_INTL("Finished updating file names and locations"), text: :green)
end
end

View File

@@ -740,12 +740,12 @@ module Compiler
#=============================================================================
def compile_pbs_file_message_start(filename)
# The `` around the file's name turns it cyan
Console.echo_li _INTL("Compiling PBS file `{1}`...", filename.split("/").last)
Console.echo_li(_INTL("Compiling PBS file `{1}`...", filename.split("/").last))
end
def write_pbs_file_message_start(filename)
# The `` around the file's name turns it cyan
Console.echo_li _INTL("Writing PBS file `{1}`...", filename.split("/").last)
Console.echo_li(_INTL("Writing PBS file `{1}`...", filename.split("/").last))
end
def process_pbs_file_message_end
@@ -780,25 +780,25 @@ module Compiler
end
def compile_all(mustCompile)
Console.echo_h1(_INTL("Checking game data"))
if !mustCompile
Console.echo_h1(_INTL("Game did not compile data"))
Console.echoln_li(_INTL("Game data was not compiled"))
echoln ""
return
end
FileLineData.clear
Console.echo_h1 _INTL("Compiling all data")
compile_pbs_files
compile_animations
compile_trainer_events(mustCompile)
Console.echo_li _INTL("Saving messages...")
Console.echo_li(_INTL("Saving messages..."))
pbSetTextMessages
MessageTypes.saveMessages
MessageTypes.loadMessageFile("Data/messages.dat") if safeExists?("Data/messages.dat")
Console.echo_done(true)
Console.echo_li _INTL("Reloading cache...")
Console.echo_li(_INTL("Reloading cache..."))
System.reload_cache
Console.echo_done(true)
echoln ""
Console.echo_h2("Successfully compiled all data", text: :green)
Console.echoln_li_done(_INTL("Successfully compiled all game data"))
end
def main

View File

@@ -1956,7 +1956,7 @@ module Compiler
# Compile battle animations
#=============================================================================
def compile_animations
Console.echo_li _INTL("Compiling animations...")
Console.echo_li(_INTL("Compiling animations..."))
begin
pbanims = load_data("Data/PkmnAnimations.rxdata")
rescue

View File

@@ -962,7 +962,7 @@ module Compiler
# Save all data to PBS files
#=============================================================================
def write_all
Console.echo_h1 _INTL("Writing all PBS files")
Console.echo_h1(_INTL("Writing all PBS files"))
write_town_map
write_connections
write_types
@@ -986,6 +986,6 @@ module Compiler
write_dungeon_parameters
write_phone
echoln ""
Console.echo_h2("Successfully rewrote all PBS files", text: :green)
Console.echo_h2(_INTL("Successfully rewrote all PBS files"), text: :green)
end
end

View File

@@ -1681,7 +1681,7 @@ module Compiler
Graphics.update
trainerChecker = TrainerChecker.new
change_record = []
Console.echo_li _INTL("Processing {1} maps...", mapData.mapinfos.keys.length)
Console.echo_li(_INTL("Processing {1} maps...", mapData.mapinfos.keys.length))
idx = 0
mapData.mapinfos.keys.sort.each do |id|
echo "." if idx % 20 == 0
@@ -1725,11 +1725,11 @@ module Compiler
end
end
Console.echo_done(true)
change_record.each { |msg| Console.echo_warn msg }
change_record.each { |msg| Console.echo_warn(msg) }
changed = false
Graphics.update
commonEvents = load_data("Data/CommonEvents.rxdata")
Console.echo_li _INTL("Processing common events...")
Console.echo_li(_INTL("Processing common events..."))
commonEvents.length.times do |key|
newevent = fix_event_use(commonEvents[key], 0, mapData)
if newevent
@@ -1740,7 +1740,7 @@ module Compiler
save_data(commonEvents, "Data/CommonEvents.rxdata") if changed
Console.echo_done(true)
if change_record.length > 0 || changed
Console.echo_warn _INTL("RMXP data was altered. Close RMXP now to ensure changes are applied.")
Console.echo_warn(_INTL("RMXP data was altered. Close RMXP now to ensure changes are applied."))
end
end
end

View File

@@ -10,7 +10,7 @@ ShowArea = true
MapPosition = 0,13,12
BattleBack = field
#-------------------------------
[003] # \PN's house
[003] # Player's house
Name = \PN's house
HealingSpot = 2,8,8
MapPosition = 0,13,12