mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
1797 lines
75 KiB
Ruby
1797 lines
75 KiB
Ruby
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
module Compiler
|
|
SCRIPT_REPLACEMENTS = [
|
|
["Kernel.", ""],
|
|
["$PokemonBag.pbQuantity", "$bag.quantity"],
|
|
["$PokemonBag.pbHasItem?", "$bag.has?"],
|
|
["$PokemonBag.pbCanStore?", "$bag.can_add?"],
|
|
["$PokemonBag.pbStoreItem", "$bag.add"],
|
|
["$PokemonBag.pbStoreAllOrNone", "$bag.add_all"],
|
|
["$PokemonBag.pbChangeItem", "$bag.replace_item"],
|
|
["$PokemonBag.pbDeleteItem", "$bag.remove"],
|
|
["$PokemonBag.pbIsRegistered?", "$bag.registered?"],
|
|
["$PokemonBag.pbRegisterItem", "$bag.register"],
|
|
["$PokemonBag.pbUnregisterItem", "$bag.unregister"],
|
|
["$PokemonBag", "$bag"],
|
|
["pbQuantity", "$bag.quantity"],
|
|
["pbHasItem?", "$bag.has?"],
|
|
["pbCanStore?", "$bag.can_add?"],
|
|
["pbStoreItem", "$bag.add"],
|
|
["pbStoreAllOrNone", "$bag.add_all"],
|
|
["$player", "$player"],
|
|
["$SaveVersion", "$save_engine_version"],
|
|
["$game_version", "$save_game_version"],
|
|
["$MapFactory", "$map_factory"],
|
|
["pbDayCareDeposited", "DayCare.count"],
|
|
["pbDayCareGetDeposited", "DayCare.get_details"],
|
|
["pbDayCareGetLevelGain", "DayCare.get_level_gain"],
|
|
["pbDayCareDeposit", "DayCare.deposit"],
|
|
["pbDayCareWithdraw", "DayCare.withdraw"],
|
|
["pbDayCareChoose", "DayCare.choose"],
|
|
["pbDayCareGetCompatibility", "DayCare.get_compatibility"],
|
|
["pbEggGenerated?", "DayCare.egg_generated?"],
|
|
["pbDayCareGenerateEgg", "DayCare.collect_egg"],
|
|
["get_character(0)", "get_self"],
|
|
["get_character(-1)", "get_player"],
|
|
["pbCheckAble", "$player.has_other_able_pokemon?"],
|
|
["$PokemonTemp.lastbattle", "$game_temp.last_battle_record"],
|
|
["calcStats", "calc_stats"]
|
|
]
|
|
|
|
@@categories[:import_new_maps] = {
|
|
:should_compile => proc { |compiling| next !new_maps_to_import.nil? },
|
|
:header_text => proc { next _INTL("Importing new maps") },
|
|
:skipped_text => proc { next _INTL("None found") },
|
|
:compile => proc { import_new_maps }
|
|
}
|
|
|
|
@@categories[:map_data] = {
|
|
:header_text => proc { next _INTL("Modifying map data") },
|
|
:skipped_text => proc { next _INTL("Not modified") },
|
|
:compile => proc { compile_trainer_events }
|
|
}
|
|
|
|
@@categories[:messages] = {
|
|
:should_compile => proc { |compiling| next compiling.include?(:pbs_files) || compiling.include?(:map_data) },
|
|
:header_text => proc { next _INTL("Gathering messages for translations") },
|
|
:skipped_text => proc { next _INTL("Not gathered") },
|
|
:compile => proc {
|
|
Console.echo_li(_INTL("Finding messages..."))
|
|
Translator.gather_script_and_event_texts
|
|
Console.echo_done(true)
|
|
Console.echo_li(_INTL("Saving messages..."))
|
|
MessageTypes.save_default_messages
|
|
MessageTypes.load_default_messages if FileTest.exist?("Data/messages_core.dat")
|
|
Console.echo_done(true)
|
|
}
|
|
}
|
|
|
|
module_function
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Add new map files to the map tree.
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def new_maps_to_import
|
|
return nil if !$DEBUG
|
|
mapfiles = {}
|
|
# Get IDs of all maps in the Data folder
|
|
Dir.chdir("Data") do
|
|
mapData = sprintf("Map*.rxdata")
|
|
Dir.glob(mapData).each do |map|
|
|
mapfiles[$1.to_i(10)] = true if map[/map(\d+)\.rxdata/i]
|
|
end
|
|
end
|
|
mapinfos = pbLoadMapInfos
|
|
maxOrder = 0
|
|
# Exclude maps found in mapinfos
|
|
mapinfos.each_key do |id|
|
|
next if !mapinfos[id]
|
|
mapfiles.delete(id) if mapfiles[id]
|
|
maxOrder = [maxOrder, mapinfos[id].order].max
|
|
end
|
|
return (mapfiles.empty?) ? nil : mapfiles
|
|
end
|
|
|
|
def import_new_maps
|
|
mapfiles = new_maps_to_import
|
|
return false if !mapfiles
|
|
# Get maxOrder to add new maps at
|
|
maxOrder = 0
|
|
mapinfos = pbLoadMapInfos
|
|
mapinfos.each_key do |id|
|
|
next if !mapinfos[id]
|
|
maxOrder = [maxOrder, mapinfos[id].order].max
|
|
end
|
|
# Import maps not found in mapinfos
|
|
maxOrder += 1
|
|
imported = false
|
|
count = 0
|
|
mapfiles.each_key do |id|
|
|
next if id == 999 # Ignore 999 (random dungeon map)
|
|
mapinfo = RPG::MapInfo.new
|
|
mapinfo.order = maxOrder
|
|
mapinfo.name = sprintf("MAP%03d", id)
|
|
maxOrder += 1
|
|
mapinfos[id] = mapinfo
|
|
imported = true
|
|
count += 1
|
|
end
|
|
if imported
|
|
save_data(mapinfos, "Data/MapInfos.rxdata")
|
|
$game_temp.map_infos = nil
|
|
Console.echoln_li_done(_INTL("{1} map(s) imported", count))
|
|
Console.echo_warn(_INTL("RMXP data was altered. Close RMXP now without saving to ensure changes are applied."))
|
|
end
|
|
return imported
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Generate and modify event commands.
|
|
#-----------------------------------------------------------------------------
|
|
def generate_move_route(commands)
|
|
route = RPG::MoveRoute.new
|
|
route.repeat = false
|
|
route.skippable = true
|
|
route.list.clear
|
|
i = 0
|
|
while i < commands.length
|
|
case commands[i]
|
|
when PBMoveRoute::WAIT, PBMoveRoute::SWITCH_ON, PBMoveRoute::SWITCH_OFF,
|
|
PBMoveRoute::CHANGE_SPEED, PBMoveRoute::CHANGE_FREQUENCY, PBMoveRoute::OPACITY,
|
|
PBMoveRoute::BLENDING, PBMoveRoute::PLAY_SE, PBMoveRoute::SCRIPT
|
|
route.list.push(RPG::MoveCommand.new(commands[i], [commands[i + 1]]))
|
|
i += 1
|
|
when PBMoveRoute::SCRIPT_ASYNC
|
|
route.list.push(RPG::MoveCommand.new(PBMoveRoute::SCRIPT, [commands[i + 1]]))
|
|
route.list.push(RPG::MoveCommand.new(PBMoveRoute::WAIT, [0]))
|
|
i += 1
|
|
when PBMoveRoute::JUMP
|
|
route.list.push(RPG::MoveCommand.new(commands[i], [commands[i + 1], commands[i + 2]]))
|
|
i += 2
|
|
when PBMoveRoute::GRAPHIC
|
|
route.list.push(RPG::MoveCommand.new(commands[i], [commands[i + 1], commands[i + 2], commands[i + 3], commands[i + 4]]))
|
|
i += 4
|
|
else
|
|
route.list.push(RPG::MoveCommand.new(commands[i]))
|
|
end
|
|
i += 1
|
|
end
|
|
route.list.push(RPG::MoveCommand.new(0))
|
|
return route
|
|
end
|
|
|
|
def push_move_route(list, character, route, indent = 0)
|
|
route = generate_move_route(route) if route.is_a?(Array)
|
|
route.list.length.times do |i|
|
|
list.push(
|
|
RPG::EventCommand.new((i == 0) ? 209 : 509, indent,
|
|
(i == 0) ? [character, route] : [route.list[i - 1]])
|
|
)
|
|
end
|
|
end
|
|
|
|
def push_move_route_and_wait(list, character, route, indent = 0)
|
|
push_move_route(list, character, route, indent)
|
|
push_event(list, 210, [], indent)
|
|
end
|
|
|
|
def push_wait(list, frames, indent = 0)
|
|
push_event(list, 106, [frames], indent)
|
|
end
|
|
|
|
def push_event(list, cmd, params = nil, indent = 0)
|
|
list.push(RPG::EventCommand.new(cmd, indent, params || []))
|
|
end
|
|
|
|
def push_end(list)
|
|
list.push(RPG::EventCommand.new(0, 0, []))
|
|
end
|
|
|
|
def push_comment(list, cmt, indent = 0)
|
|
textsplit2 = cmt.split(/\n/)
|
|
textsplit2.length.times do |i|
|
|
list.push(RPG::EventCommand.new((i == 0) ? 108 : 408, indent, [textsplit2[i].gsub(/\s+$/, "")]))
|
|
end
|
|
end
|
|
|
|
def push_text(list, text, indent = 0)
|
|
return if !text
|
|
textsplit = text.split(/\\m/)
|
|
textsplit.each do |t|
|
|
first = true
|
|
textsplit2 = t.split(/\n/)
|
|
textsplit2.length.times do |i|
|
|
textchunk = textsplit2[i].gsub(/\s+$/, "")
|
|
if textchunk && textchunk != ""
|
|
list.push(RPG::EventCommand.new((first) ? 101 : 401, indent, [textchunk]))
|
|
first = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def push_script(list, script, indent = 0)
|
|
return if !script
|
|
first = true
|
|
textsplit2 = script.split(/\n/)
|
|
textsplit2.length.times do |i|
|
|
textchunk = textsplit2[i].gsub(/\s+$/, "")
|
|
if textchunk && textchunk != ""
|
|
list.push(RPG::EventCommand.new((first) ? 355 : 655, indent, [textchunk]))
|
|
first = false
|
|
end
|
|
end
|
|
end
|
|
|
|
def push_exit(list, indent = 0)
|
|
list.push(RPG::EventCommand.new(115, indent, []))
|
|
end
|
|
|
|
def push_else(list, indent = 0)
|
|
list.push(RPG::EventCommand.new(0, indent, []))
|
|
list.push(RPG::EventCommand.new(411, indent - 1, []))
|
|
end
|
|
|
|
def push_branch(list, script, indent = 0)
|
|
list.push(RPG::EventCommand.new(111, indent, [12, script]))
|
|
end
|
|
|
|
def push_branch_end(list, indent = 0)
|
|
list.push(RPG::EventCommand.new(0, indent, []))
|
|
list.push(RPG::EventCommand.new(412, indent - 1, []))
|
|
end
|
|
|
|
# cancel is 1/2/3/4 for the options, 0 for disallow, 5 for branch
|
|
def push_choices(list, choices, cancel = 0, indent = 0)
|
|
list.push(RPG::EventCommand.new(102, indent, [choices, cancel, [0, 1, 2, 3]]))
|
|
end
|
|
|
|
def push_choice(list, index, text, indent = 0)
|
|
list.push(RPG::EventCommand.new(0, indent, [])) if index > 0
|
|
list.push(RPG::EventCommand.new(402, indent - 1, [index, text]))
|
|
end
|
|
|
|
def push_choices_end(list, indent = 0)
|
|
list.push(RPG::EventCommand.new(0, indent, []))
|
|
list.push(RPG::EventCommand.new(404, indent - 1, []))
|
|
end
|
|
|
|
def push_self_switch(list, swtch, switchOn, indent = 0)
|
|
list.push(RPG::EventCommand.new(123, indent, [swtch, switchOn ? 0 : 1]))
|
|
end
|
|
|
|
def apply_pages(page, pages)
|
|
pages.each do |p|
|
|
p.graphic = page.graphic
|
|
p.walk_anime = page.walk_anime
|
|
p.step_anime = page.step_anime
|
|
p.direction_fix = page.direction_fix
|
|
p.through = page.through
|
|
p.always_on_top = page.always_on_top
|
|
end
|
|
end
|
|
|
|
def add_passage_list(event, mapData)
|
|
return if !event || event.pages.length == 0
|
|
page = RPG::Event::Page.new
|
|
page.condition.switch1_valid = true
|
|
page.condition.switch1_id = mapData.registerSwitch('s:tsOff?("A")')
|
|
page.graphic.character_name = ""
|
|
page.trigger = 3 # Autorun
|
|
page.list.clear
|
|
list = page.list
|
|
push_branch(list, "get_self.onEvent?")
|
|
push_event(list, 208, [0], 1) # Change Transparent Flag
|
|
push_wait(list, 6, 1) # Wait
|
|
push_event(list, 208, [1], 1) # Change Transparent Flag
|
|
push_move_route_and_wait(list, -1, [PBMoveRoute::DOWN], 1)
|
|
push_branch_end(list, 1)
|
|
push_script(list, "setTempSwitchOn(\"A\")")
|
|
push_end(list)
|
|
event.pages.push(page)
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def safequote(x)
|
|
x = x.gsub(/\"\#\'\\/) { |a| "\\" + a }
|
|
x = x.gsub(/\t/, "\\t")
|
|
x = x.gsub(/\r/, "\\r")
|
|
x = x.gsub(/\n/, "\\n")
|
|
return x
|
|
end
|
|
|
|
def safequote2(x)
|
|
x = x.gsub(/\"\#\'\\/) { |a| "\\" + a }
|
|
x = x.gsub(/\t/, "\\t")
|
|
x = x.gsub(/\r/, "\\r")
|
|
x = x.gsub(/\n/, " ")
|
|
return x
|
|
end
|
|
|
|
def pbEventId(event)
|
|
list = event.pages[0].list
|
|
return nil if list.length == 0
|
|
codes = []
|
|
i = 0
|
|
while i < list.length
|
|
codes.push(list[i].code)
|
|
i += 1
|
|
end
|
|
end
|
|
|
|
def pbEachPage(e)
|
|
return true if !e
|
|
if e.is_a?(RPG::CommonEvent)
|
|
yield e
|
|
else
|
|
e.pages.each { |page| yield page }
|
|
end
|
|
end
|
|
|
|
#=============================================================================
|
|
#
|
|
#=============================================================================
|
|
class MapData
|
|
attr_reader :mapinfos
|
|
|
|
def initialize
|
|
@mapinfos = pbLoadMapInfos
|
|
@system = load_data("Data/System.rxdata")
|
|
@tilesets = load_data("Data/Tilesets.rxdata")
|
|
@mapxy = []
|
|
@mapWidths = []
|
|
@mapHeights = []
|
|
@maps = []
|
|
@registeredSwitches = {}
|
|
end
|
|
|
|
def switchName(id)
|
|
return @system.switches[id] || ""
|
|
end
|
|
|
|
def mapFilename(mapID)
|
|
return sprintf("Data/Map%03d.rxdata", mapID)
|
|
end
|
|
|
|
def getMap(mapID)
|
|
return @maps[mapID] if @maps[mapID]
|
|
begin
|
|
@maps[mapID] = load_data(mapFilename(mapID))
|
|
return @maps[mapID]
|
|
rescue
|
|
return nil
|
|
end
|
|
end
|
|
|
|
def getEventFromXY(mapID, x, y)
|
|
return nil if x < 0 || y < 0
|
|
mapPositions = @mapxy[mapID]
|
|
return mapPositions[(y * @mapWidths[mapID]) + x] if mapPositions
|
|
map = getMap(mapID)
|
|
return nil if !map
|
|
@mapWidths[mapID] = map.width
|
|
@mapHeights[mapID] = map.height
|
|
mapPositions = []
|
|
width = map.width
|
|
map.events.each_value do |e|
|
|
mapPositions[(e.y * width) + e.x] = e if e
|
|
end
|
|
@mapxy[mapID] = mapPositions
|
|
return mapPositions[(y * width) + x]
|
|
end
|
|
|
|
def getEventFromID(mapID, id)
|
|
map = getMap(mapID)
|
|
return nil if !map
|
|
return map.events[id]
|
|
end
|
|
|
|
def getTilesetPassages(map, mapID)
|
|
begin
|
|
return @tilesets[map.tileset_id].passages
|
|
rescue
|
|
raise "Tileset data for tileset number #{map.tileset_id} used on map #{mapID} was not found. " +
|
|
"The tileset was likely deleted, but one or more maps still use it."
|
|
end
|
|
end
|
|
|
|
def getTilesetPriorities(map, mapID)
|
|
begin
|
|
return @tilesets[map.tileset_id].priorities
|
|
rescue
|
|
raise "Tileset data for tileset number #{map.tileset_id} used on map #{mapID} was not found. " +
|
|
"The tileset was likely deleted, but one or more maps still use it."
|
|
end
|
|
end
|
|
|
|
def isPassable?(mapID, x, y)
|
|
map = getMap(mapID)
|
|
return false if !map
|
|
return false if x < 0 || x >= map.width || y < 0 || y >= map.height
|
|
passages = getTilesetPassages(map, mapID)
|
|
priorities = getTilesetPriorities(map, mapID)
|
|
[2, 1, 0].each do |i|
|
|
tile_id = map.data[x, y, i]
|
|
return false if tile_id.nil?
|
|
passage = passages[tile_id]
|
|
if !passage
|
|
raise "The tile used on map #{mapID} at coordinates (#{x}, #{y}) on layer #{i + 1} doesn't exist in the tileset. " +
|
|
"It should be deleted to prevent errors."
|
|
end
|
|
return false if passage & 0x0f == 0x0f
|
|
return true if priorities[tile_id] == 0
|
|
end
|
|
return true
|
|
end
|
|
|
|
def isCounterTile?(mapID, x, y)
|
|
map = getMap(mapID)
|
|
return false if !map
|
|
passages = getTilesetPassages(map, mapID)
|
|
[2, 1, 0].each do |i|
|
|
tile_id = map.data[x, y, i]
|
|
return false if tile_id.nil?
|
|
passage = passages[tile_id]
|
|
if !passage
|
|
raise "The tile used on map #{mapID} at coordinates (#{x}, #{y}) on layer #{i + 1} doesn't exist in the tileset. " +
|
|
"It should be deleted to prevent errors."
|
|
end
|
|
return true if passage & 0x80 == 0x80
|
|
end
|
|
return false
|
|
end
|
|
|
|
def setCounterTile(mapID, x, y)
|
|
map = getMap(mapID)
|
|
return if !map
|
|
passages = getTilesetPassages(map, mapID)
|
|
[2, 1, 0].each do |i|
|
|
tile_id = map.data[x, y, i]
|
|
next if tile_id == 0
|
|
passages[tile_id] |= 0x80
|
|
break
|
|
end
|
|
end
|
|
|
|
def registerSwitch(switch)
|
|
return @registeredSwitches[switch] if @registeredSwitches[switch]
|
|
(1..5000).each do |id|
|
|
name = @system.switches[id]
|
|
next if name && name != "" && name != switch
|
|
@system.switches[id] = switch
|
|
@registeredSwitches[switch] = id
|
|
return id
|
|
end
|
|
return 1
|
|
end
|
|
|
|
def saveMap(mapID)
|
|
save_data(getMap(mapID), mapFilename(mapID)) rescue nil
|
|
end
|
|
|
|
def saveTilesets
|
|
save_data(@tilesets, "Data/Tilesets.rxdata")
|
|
save_data(@system, "Data/System.rxdata")
|
|
end
|
|
end
|
|
|
|
#=============================================================================
|
|
#
|
|
#=============================================================================
|
|
class TrainerChecker
|
|
def initialize
|
|
@dontaskagain = false
|
|
end
|
|
|
|
def pbTrainerTypeCheck(trainer_type)
|
|
return if !$DEBUG || @dontaskagain
|
|
return if GameData::TrainerType.exists?(trainer_type)
|
|
if pbConfirmMessage(_INTL("Add new trainer type {1}?", trainer_type.to_s))
|
|
pbTrainerTypeEditorNew(trainer_type.to_s)
|
|
end
|
|
end
|
|
|
|
def pbTrainerBattleCheck(tr_type, tr_name, tr_version)
|
|
return if !$DEBUG || @dontaskagain
|
|
# Check for existence of trainer type
|
|
pbTrainerTypeCheck(tr_type)
|
|
return if !GameData::TrainerType.exists?(tr_type)
|
|
tr_type = GameData::TrainerType.get(tr_type).id
|
|
# Check for existence of trainer
|
|
return if GameData::Trainer.exists?(tr_type, tr_name, tr_version)
|
|
# Add new trainer
|
|
cmd = pbMissingTrainer(tr_type, tr_name, tr_version)
|
|
if cmd == 2
|
|
@dontaskagain = true
|
|
Graphics.update
|
|
end
|
|
end
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# Convert trainer comments to trainer event.
|
|
def convert_to_trainer_event(event, trainerChecker)
|
|
return nil if !event || event.pages.length == 0
|
|
list = event.pages[0].list
|
|
return nil if list.length < 2
|
|
commands = []
|
|
isFirstCommand = false
|
|
# Find all the trainer comments in the event
|
|
list.length.times do |i|
|
|
next if list[i].code != 108 # Comment (first line)
|
|
command = list[i].parameters[0]
|
|
((i + 1)...list.length).each do |j|
|
|
break if list[j].code != 408 # Comment (continuation line)
|
|
command += "\r\n" + list[j].parameters[0]
|
|
end
|
|
if command[/^(Battle\:|Type\:|Name\:|BattleID\:|DoubleBattle\:|Backdrop\:|EndSpeech\:|Outcome\:|Continue\:|EndBattle\:|EndIfSwitch\:|VanishIfSwitch\:|RegSpeech\:)/i]
|
|
commands.push(command)
|
|
isFirstCommand = true if i == 0
|
|
end
|
|
end
|
|
return nil if commands.length == 0
|
|
# Found trainer comments; create a new Event object to replace this event
|
|
ret = RPG::Event.new(event.x, event.y)
|
|
ret.name = event.name
|
|
ret.id = event.id
|
|
firstpage = Marshal.load(Marshal.dump(event.pages[0])) # Copy event's first page
|
|
firstpage.trigger = 2 # On event touch
|
|
firstpage.list = [] # Clear page's commands
|
|
# Rename the event if there's nothing above the trainer comments
|
|
if isFirstCommand
|
|
if !event.name[/trainer/i]
|
|
ret.name = "Trainer(3)"
|
|
elsif event.name[/^\s*trainer\s*\((\d+)\)\s*$/i]
|
|
ret.name = "Trainer(#{$1})"
|
|
end
|
|
end
|
|
# Compile the trainer comments
|
|
rewriteComments = false # You can change this
|
|
battles = []
|
|
trtype = nil
|
|
trname = nil
|
|
battleid = 0
|
|
doublebattle = false
|
|
backdrop = nil
|
|
outcome = 0
|
|
continue = false
|
|
endbattles = []
|
|
endifswitch = []
|
|
vanishifswitch = []
|
|
regspeech = nil
|
|
common_event = 0
|
|
commands.each do |command|
|
|
if command[/^Battle\:\s*([\s\S]+)$/i]
|
|
battles.push($~[1])
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^Type\:\s*([\s\S]+)$/i]
|
|
trtype = $~[1].gsub(/^\s+/, "").gsub(/\s+$/, "")
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^Name\:\s*([\s\S]+)$/i]
|
|
trname = $~[1].gsub(/^\s+/, "").gsub(/\s+$/, "")
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^BattleID\:\s*(\d+)$/i]
|
|
battleid = $~[1].to_i
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^DoubleBattle\:\s*([\s\S]+)$/i]
|
|
value = $~[1].gsub(/^\s+/, "").gsub(/\s+$/, "")
|
|
doublebattle = true if value.upcase == "TRUE" || value.upcase == "YES"
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^Continue\:\s*([\s\S]+)$/i]
|
|
value = $~[1].gsub(/^\s+/, "").gsub(/\s+$/, "")
|
|
continue = true if value.upcase == "TRUE" || value.upcase == "YES"
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^EndIfSwitch\:\s*([\s\S]+)$/i]
|
|
endifswitch.push(($~[1].gsub(/^\s+/, "").gsub(/\s+$/, "")).to_i)
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^VanishIfSwitch\:\s*([\s\S]+)$/i]
|
|
vanishifswitch.push(($~[1].gsub(/^\s+/, "").gsub(/\s+$/, "")).to_i)
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^Backdrop\:\s*([\s\S]+)$/i]
|
|
backdrop = $~[1].gsub(/^\s+/, "").gsub(/\s+$/, "")
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^Outcome\:\s*(\d+)$/i]
|
|
outcome = $~[1].to_i
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^EndBattle\:\s*([\s\S]+)$/i]
|
|
endbattles.push($~[1].gsub(/^\s+/, "").gsub(/\s+$/, ""))
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^RegSpeech\:\s*([\s\S]+)$/i]
|
|
regspeech = $~[1].gsub(/^\s+/, "").gsub(/\s+$/, "")
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
elsif command[/^CommonEvent\:\s*(\d+)$/i]
|
|
common_event = $~[1].to_i
|
|
push_comment(firstpage.list, command) if rewriteComments
|
|
end
|
|
end
|
|
return nil if battles.length <= 0
|
|
endbattles.push("...") if endbattles.length == 0
|
|
# Run trainer check now, except in editor
|
|
trainerChecker.pbTrainerBattleCheck(trtype, trname, battleid)
|
|
# Set the event's charset to one depending on the trainer type if the event
|
|
# doesn't have a charset
|
|
if firstpage.graphic.character_name == "" && GameData::TrainerType.exists?(trtype)
|
|
trainerid = GameData::TrainerType.get(trtype).id
|
|
filename = GameData::TrainerType.charset_filename_brief(trainerid)
|
|
if FileTest.image_exist?("Graphics/Characters/" + filename)
|
|
firstpage.graphic.character_name = filename
|
|
end
|
|
end
|
|
# Create strings that will be used repeatedly
|
|
safetrcombo = sprintf(":%s, \"%s\"", trtype, safequote(trname)) # :YOUNGSTER, "Joey"
|
|
brieftrcombo = safetrcombo
|
|
safetrcombo = sprintf("%s, %d", safetrcombo, battleid) if battleid > 0 # :YOUNGSTER, "Joey", 1
|
|
introplay = sprintf("pbTrainerIntro(:%s)", trtype)
|
|
# Write first page
|
|
push_script(firstpage.list, introplay) # pbTrainerIntro
|
|
push_script(firstpage.list, "pbNoticePlayer(get_self)")
|
|
push_text(firstpage.list, battles[0])
|
|
if battles.length > 1 # Has rematches
|
|
if battleid > 0
|
|
push_script(firstpage.list, sprintf("pbTrainerCheck(%s, %d, %d)", brieftrcombo, battles.length, battleid))
|
|
else
|
|
push_script(firstpage.list, sprintf("pbTrainerCheck(%s, %d)", brieftrcombo, battles.length))
|
|
end
|
|
end
|
|
push_script(firstpage.list, "setBattleRule(\"double\")") if doublebattle
|
|
push_script(firstpage.list, sprintf("setBattleRule(\n \"backdrop\", \"%s\"\n)", safequote(backdrop))) if backdrop
|
|
push_script(firstpage.list, sprintf("setBattleRule(\"outcomeVar\", %d)", outcome)) if outcome > 1
|
|
push_script(firstpage.list, "setBattleRule(\"canLose\")") if continue
|
|
battleString = sprintf("TrainerBattle.start(%s)", safetrcombo)
|
|
push_branch(firstpage.list, battleString)
|
|
if battles.length > 1 # Has rematches
|
|
push_branch(firstpage.list, sprintf("Phone.can_add?(%s)", safetrcombo), 1)
|
|
push_text(firstpage.list, regspeech, 2)
|
|
push_choices(firstpage.list, ["Yes", "No"], 2, 2)
|
|
push_choice(firstpage.list, 0, "Yes", 3)
|
|
if common_event > 0
|
|
if battleid > 0
|
|
push_script(firstpage.list, sprintf("Phone.add(get_self,\n %s, %d, %d, %d\n)",
|
|
brieftrcombo, battles.length, battleid, common_event), 3)
|
|
else
|
|
push_script(firstpage.list, sprintf("Phone.add(get_self,\n %s, %d, nil, %d\n)",
|
|
brieftrcombo, battles.length, common_event), 3)
|
|
end
|
|
else
|
|
if battleid > 0
|
|
push_script(firstpage.list, sprintf("Phone.add(get_self,\n %s, %d, %d\n)",
|
|
brieftrcombo, battles.length, battleid), 3)
|
|
else
|
|
push_script(firstpage.list, sprintf("Phone.add(get_self,\n %s, %d\n)",
|
|
brieftrcombo, battles.length), 3)
|
|
end
|
|
end
|
|
push_choice(firstpage.list, 1, "No", 3)
|
|
push_choices_end(firstpage.list, 3)
|
|
push_branch_end(firstpage.list, 2)
|
|
end
|
|
push_self_switch(firstpage.list, "A", true, 1)
|
|
push_self_switch(firstpage.list, "B", true, 1) if battles.length > 1
|
|
push_branch_end(firstpage.list, 1)
|
|
push_script(firstpage.list, "pbTrainerEnd", 0)
|
|
push_end(firstpage.list)
|
|
# Copy first page to last page and make changes to its properties
|
|
lastpage = Marshal.load(Marshal.dump(firstpage))
|
|
lastpage.trigger = 0 # On action
|
|
lastpage.list = [] # Clear page's commands
|
|
lastpage.condition = firstpage.condition.clone
|
|
lastpage.condition.self_switch_valid = true
|
|
lastpage.condition.self_switch_ch = "A"
|
|
# Copy last page to rematch page
|
|
rematchpage = Marshal.load(Marshal.dump(lastpage))
|
|
rematchpage.list = lastpage.list.clone # Copy the last page's commands
|
|
rematchpage.condition = lastpage.condition.clone
|
|
rematchpage.condition.self_switch_valid = true
|
|
rematchpage.condition.self_switch_ch = "B"
|
|
# Write rematch page
|
|
push_script(rematchpage.list, introplay, 0) # pbTrainerIntro
|
|
if battles.length == 2
|
|
push_text(rematchpage.list, battles[1], 0)
|
|
else
|
|
(1...battles.length).each do |i|
|
|
# Run trainer check now, except in editor
|
|
trainerChecker.pbTrainerBattleCheck(trtype, trname, battleid + i)
|
|
case i
|
|
when 1
|
|
push_branch(rematchpage.list, sprintf("Phone.variant(%s) <= %d", safetrcombo, i))
|
|
when battles.length - 1
|
|
push_branch(rematchpage.list, sprintf("Phone.variant(%s) >= %d", safetrcombo, i))
|
|
else
|
|
push_branch(rematchpage.list, sprintf("Phone.variant(%s) == %d", safetrcombo, i))
|
|
end
|
|
push_text(rematchpage.list, battles[i], 1)
|
|
push_branch_end(rematchpage.list, 1)
|
|
end
|
|
end
|
|
push_script(rematchpage.list, "setBattleRule(\"double\")", 1) if doublebattle
|
|
push_script(rematchpage.list, sprintf("setBattleRule(\n \"backdrop\", %s\n)", safequote(backdrop)), 1) if backdrop
|
|
push_script(rematchpage.list, sprintf("setBattleRule(\"outcomeVar\", %d)", outcome), 1) if outcome > 1
|
|
push_script(rematchpage.list, "setBattleRule(\"canLose\")", 1) if continue
|
|
battleString = sprintf("Phone.battle(%s)", safetrcombo)
|
|
push_branch(rematchpage.list, battleString, 0)
|
|
push_script(rematchpage.list, sprintf("Phone.reset_after_win(\n %s\n)", safetrcombo), 1)
|
|
push_self_switch(rematchpage.list, "A", true, 1)
|
|
push_script(rematchpage.list, "pbTrainerEnd", 1)
|
|
push_branch_end(rematchpage.list, 1)
|
|
push_end(rematchpage.list)
|
|
# Write last page
|
|
if endbattles.length > 0
|
|
if battles.length == 1
|
|
push_text(lastpage.list, endbattles[0], 0)
|
|
else
|
|
(0...battles.length).each do |i|
|
|
if i == battles.length - 1
|
|
push_branch(lastpage.list, sprintf("Phone.variant(%s) >= %d", safetrcombo, i))
|
|
else
|
|
push_branch(lastpage.list, sprintf("Phone.variant(%s) == %d", safetrcombo, i))
|
|
end
|
|
ebattle = (endbattles[i]) ? endbattles[i] : endbattles[endbattles.length - 1]
|
|
push_text(lastpage.list, ebattle, 1)
|
|
push_branch_end(lastpage.list, 1)
|
|
end
|
|
end
|
|
end
|
|
if battles.length > 1
|
|
push_branch(lastpage.list, sprintf("Phone.can_add?(%s)", safetrcombo), 0)
|
|
push_text(lastpage.list, regspeech, 1)
|
|
push_choices(lastpage.list, ["Yes", "No"], 2, 1)
|
|
push_choice(lastpage.list, 0, "Yes", 2)
|
|
if common_event > 0
|
|
if battleid > 0
|
|
push_script(lastpage.list, sprintf("Phone.add(get_self,\n %s, %d, %d, %d\n)",
|
|
brieftrcombo, battles.length, battleid, common_event), 2)
|
|
else
|
|
push_script(lastpage.list, sprintf("Phone.add(get_self,\n %s, %d, nil, %d\n)",
|
|
brieftrcombo, battles.length, common_event), 2)
|
|
end
|
|
else
|
|
if battleid > 0
|
|
push_script(lastpage.list, sprintf("Phone.add(get_self,\n %s, %d, %d\n)",
|
|
brieftrcombo, battles.length, battleid), 2)
|
|
else
|
|
push_script(lastpage.list, sprintf("Phone.add(get_self,\n %s, %d\n)",
|
|
brieftrcombo, battles.length), 2)
|
|
end
|
|
end
|
|
push_choice(lastpage.list, 1, "No", 2)
|
|
push_choices_end(lastpage.list, 2)
|
|
push_branch_end(lastpage.list, 1)
|
|
end
|
|
push_end(lastpage.list)
|
|
# Add pages to the new event
|
|
if battles.length == 1 # Only one battle
|
|
ret.pages = [firstpage, lastpage]
|
|
else # Has rematches
|
|
ret.pages = [firstpage, rematchpage, lastpage]
|
|
end
|
|
# Copy last page to endIfSwitch page
|
|
endifswitch.each do |endswitch|
|
|
endIfSwitchPage = Marshal.load(Marshal.dump(lastpage))
|
|
endIfSwitchPage.condition = lastpage.condition.clone
|
|
if endIfSwitchPage.condition.switch1_valid # Add another page condition
|
|
endIfSwitchPage.condition.switch2_valid = true
|
|
endIfSwitchPage.condition.switch2_id = endswitch
|
|
else
|
|
endIfSwitchPage.condition.switch1_valid = true
|
|
endIfSwitchPage.condition.switch1_id = endswitch
|
|
end
|
|
endIfSwitchPage.condition.self_switch_valid = false
|
|
endIfSwitchPage.list = [] # Clear page's commands
|
|
ebattle = (endbattles[0]) ? endbattles[0] : "..."
|
|
push_text(endIfSwitchPage.list, ebattle)
|
|
push_end(endIfSwitchPage.list)
|
|
ret.pages.push(endIfSwitchPage)
|
|
end
|
|
# Copy last page to vanishIfSwitch page
|
|
vanishifswitch.each do |vanishswitch|
|
|
vanishIfSwitchPage = Marshal.load(Marshal.dump(lastpage))
|
|
vanishIfSwitchPage.graphic.character_name = "" # No charset
|
|
vanishIfSwitchPage.condition = lastpage.condition.clone
|
|
if vanishIfSwitchPage.condition.switch1_valid # Add another page condition
|
|
vanishIfSwitchPage.condition.switch2_valid = true
|
|
vanishIfSwitchPage.condition.switch2_id = vanishswitch
|
|
else
|
|
vanishIfSwitchPage.condition.switch1_valid = true
|
|
vanishIfSwitchPage.condition.switch1_id = vanishswitch
|
|
end
|
|
vanishIfSwitchPage.condition.self_switch_valid = false
|
|
vanishIfSwitchPage.list = [] # Clear page's commands
|
|
push_end(vanishIfSwitchPage.list)
|
|
ret.pages.push(vanishIfSwitchPage)
|
|
end
|
|
return ret
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# Convert event name to item event.
|
|
# Checks if the event's name is "Item:POTION" or "HiddenItem:POTION". If so,
|
|
# rewrites the whole event into one now named "Item"/"HiddenItem" which gives
|
|
# that item when interacted with.
|
|
def convert_to_item_event(event)
|
|
return nil if !event || event.pages.length == 0
|
|
name = event.name
|
|
ret = RPG::Event.new(event.x, event.y)
|
|
ret.name = event.name
|
|
ret.id = event.id
|
|
ret.pages = []
|
|
itemName = ""
|
|
hidden = false
|
|
if name[/^hiddenitem\:\s*(\w+)\s*$/i]
|
|
itemName = $1
|
|
return nil if !GameData::Item.exists?(itemName)
|
|
ret.name = "HiddenItem"
|
|
hidden = true
|
|
elsif name[/^item\:\s*(\w+)\s*$/i]
|
|
itemName = $1
|
|
return nil if !GameData::Item.exists?(itemName)
|
|
ret.name = "Item"
|
|
else
|
|
return nil
|
|
end
|
|
# Event page 1
|
|
page = RPG::Event::Page.new
|
|
page.graphic.character_name = "Object ball" if !hidden
|
|
page.list = []
|
|
push_branch(page.list, sprintf("pbItemBall(:%s)", itemName))
|
|
push_self_switch(page.list, "A", true, 1)
|
|
push_else(page.list, 1)
|
|
push_branch_end(page.list, 1)
|
|
push_end(page.list)
|
|
ret.pages.push(page)
|
|
# Event page 2
|
|
page = RPG::Event::Page.new
|
|
page.condition.self_switch_valid = true
|
|
page.condition.self_switch_ch = "A"
|
|
ret.pages.push(page)
|
|
return ret
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# Checks whether a given event is likely to be a door. If so, rewrite it to
|
|
# include animating the event as though it was a door opening and closing as the
|
|
# player passes through.
|
|
def update_door_event(event, mapData)
|
|
changed = false
|
|
return false if event.is_a?(RPG::CommonEvent)
|
|
# Check if event has 2+ pages and the last page meets all of these criteria:
|
|
# - Has a condition of a Switch being ON
|
|
# - The event has a charset graphic
|
|
# - There are more than 5 commands in that page, the first of which is a
|
|
# Conditional Branch
|
|
lastPage = event.pages[event.pages.length - 1]
|
|
if event.pages.length >= 2 &&
|
|
lastPage.condition.switch1_valid &&
|
|
lastPage.graphic.character_name != "" &&
|
|
lastPage.list.length > 5 &&
|
|
lastPage.list[0].code == 111
|
|
# This bit of code is just in case Switch 22 has been renamed/repurposed,
|
|
# which is highly unlikely. It changes the Switch used in the condition to
|
|
# whichever is named 's:tsOff?("A")'.
|
|
if lastPage.condition.switch1_id == 22 &&
|
|
mapData.switchName(lastPage.condition.switch1_id) != 's:tsOff?("A")'
|
|
lastPage.condition.switch1_id = mapData.registerSwitch('s:tsOff?("A")')
|
|
changed = true
|
|
end
|
|
# If the last page's Switch condition uses a Switch named 's:tsOff?("A")',
|
|
# check the penultimate page. If it contains exactly 1 "Transfer Player"
|
|
# command and does NOT contain a "Change Transparent Flag" command, rewrite
|
|
# both the penultimate page and the last page.
|
|
if mapData.switchName(lastPage.condition.switch1_id) == 's:tsOff?("A")'
|
|
list = event.pages[event.pages.length - 2].list
|
|
transferCommand = list.find_all { |cmd| cmd.code == 201 } # Transfer Player
|
|
if transferCommand.length == 1 && list.none? { |cmd| cmd.code == 208 } # Change Transparent Flag
|
|
# Rewrite penultimate page
|
|
list.clear
|
|
push_move_route_and_wait( # Move Route for door opening
|
|
list, 0,
|
|
[PBMoveRoute::PLAY_SE, RPG::AudioFile.new("Door enter"), PBMoveRoute::WAIT, 2,
|
|
PBMoveRoute::TURN_LEFT, PBMoveRoute::WAIT, 2,
|
|
PBMoveRoute::TURN_RIGHT, PBMoveRoute::WAIT, 2,
|
|
PBMoveRoute::TURN_UP, PBMoveRoute::WAIT, 2]
|
|
)
|
|
push_move_route_and_wait( # Move Route for player entering door
|
|
list, -1,
|
|
[PBMoveRoute::THROUGH_ON, PBMoveRoute::UP, PBMoveRoute::THROUGH_OFF]
|
|
)
|
|
push_event(list, 208, [0]) # Change Transparent Flag (invisible)
|
|
push_script(list, "Followers.follow_into_door")
|
|
push_event(list, 210, []) # Wait for Move's Completion
|
|
push_move_route_and_wait( # Move Route for door closing
|
|
list, 0,
|
|
[PBMoveRoute::WAIT, 2,
|
|
PBMoveRoute::TURN_RIGHT, PBMoveRoute::WAIT, 2,
|
|
PBMoveRoute::TURN_LEFT, PBMoveRoute::WAIT, 2,
|
|
PBMoveRoute::TURN_DOWN, PBMoveRoute::WAIT, 2]
|
|
)
|
|
push_event(list, 223, [Tone.new(-255, -255, -255), 6]) # Change Screen Color Tone
|
|
push_wait(list, 8) # Wait
|
|
push_event(list, 208, [1]) # Change Transparent Flag (visible)
|
|
push_event(list, transferCommand[0].code, transferCommand[0].parameters) # Transfer Player
|
|
push_event(list, 223, [Tone.new(0, 0, 0), 6]) # Change Screen Color Tone
|
|
push_end(list)
|
|
# Rewrite last page
|
|
list = lastPage.list
|
|
list.clear
|
|
push_branch(list, "get_self.onEvent?") # Conditional Branch
|
|
push_event(list, 208, [0], 1) # Change Transparent Flag (invisible)
|
|
push_script(list, "Followers.hide_followers", 1)
|
|
push_move_route_and_wait( # Move Route for setting door to open
|
|
list, 0,
|
|
[PBMoveRoute::TURN_LEFT, PBMoveRoute::WAIT, 6],
|
|
1
|
|
)
|
|
push_event(list, 208, [1], 1) # Change Transparent Flag (visible)
|
|
push_move_route_and_wait(list, -1, [PBMoveRoute::DOWN], 1) # Move Route for player exiting door
|
|
push_script(list, "Followers.put_followers_on_player", 1)
|
|
push_move_route_and_wait( # Move Route for door closing
|
|
list, 0,
|
|
[PBMoveRoute::TURN_UP, PBMoveRoute::WAIT, 2,
|
|
PBMoveRoute::TURN_RIGHT, PBMoveRoute::WAIT, 2,
|
|
PBMoveRoute::TURN_DOWN, PBMoveRoute::WAIT, 2],
|
|
1
|
|
)
|
|
push_branch_end(list, 1)
|
|
push_script(list, "setTempSwitchOn(\"A\")")
|
|
push_end(list)
|
|
changed = true
|
|
end
|
|
end
|
|
end
|
|
return changed
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Fix up standard code snippets.
|
|
#-----------------------------------------------------------------------------
|
|
def event_is_empty?(e)
|
|
return true if !e
|
|
return false if e.is_a?(RPG::CommonEvent)
|
|
return e.pages.length == 0
|
|
end
|
|
|
|
# Checks if the event has exactly 1 page, said page has no graphic, it has
|
|
# less than 12 commands and at least one is a Transfer Player, and the tiles
|
|
# to the left/right/upper left/upper right are not passable but the event's
|
|
# tile is. Causes a second page to be added to the event which is the "is
|
|
# player on me?" check that occurs when the map is entered.
|
|
def likely_passage?(thisEvent, mapID, mapData)
|
|
return false if !thisEvent || thisEvent.pages.length == 0
|
|
return false if thisEvent.pages.length != 1
|
|
if thisEvent.pages[0].graphic.character_name == "" &&
|
|
thisEvent.pages[0].list.length <= 12 &&
|
|
thisEvent.pages[0].list.any? { |cmd| cmd.code == 201 } && # Transfer Player
|
|
# mapData.isPassable?(mapID, thisEvent.x, thisEvent.y + 1) &&
|
|
mapData.isPassable?(mapID, thisEvent.x, thisEvent.y) &&
|
|
!mapData.isPassable?(mapID, thisEvent.x - 1, thisEvent.y) &&
|
|
!mapData.isPassable?(mapID, thisEvent.x + 1, thisEvent.y) &&
|
|
!mapData.isPassable?(mapID, thisEvent.x - 1, thisEvent.y - 1) &&
|
|
!mapData.isPassable?(mapID, thisEvent.x + 1, thisEvent.y - 1)
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
def fix_event_name(event)
|
|
return false if !event
|
|
case event.name.downcase
|
|
when "tree"
|
|
event.name = "CutTree"
|
|
when "rock"
|
|
event.name = "SmashRock"
|
|
when "boulder"
|
|
event.name = "StrengthBoulder"
|
|
else
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
def replace_scripts(script)
|
|
ret = false
|
|
SCRIPT_REPLACEMENTS.each { |pair| ret = true if script.gsub!(pair[0], pair[1]) }
|
|
ret = true if script.gsub!(/\$game_variables\[(\d+)\](?!\s*(?:\=|\!|<|>))/) { |m| "pbGet(" + $~[1] + ")" }
|
|
ret = true if script.gsub!(/\$player\.party\[\s*pbGet\((\d+)\)\s*\]/) { |m| "pbGetPokemon(" + $~[1] + ")" }
|
|
return ret
|
|
end
|
|
|
|
def fix_event_scripts(event)
|
|
return false if event_is_empty?(event)
|
|
ret = false
|
|
pbEachPage(event) do |page|
|
|
page.list.each do |cmd|
|
|
params = cmd.parameters
|
|
case cmd.code
|
|
when 355, 655 # Script (first line, continuation line)
|
|
ret = true if params[0].is_a?(String) && replace_scripts(params[0])
|
|
when 111 # Conditional Branch
|
|
ret = true if params[0] == 12 && replace_scripts(params[1])
|
|
end
|
|
end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
# Splits the given code string into an array of parameters (all strings),
|
|
# using "," as the delimiter. It will not split in the middle of a string
|
|
# parameter. Used to extract parameters from a script call in an event.
|
|
def split_string_with_quotes(str)
|
|
ret = []
|
|
new_str = ""
|
|
in_msg = false
|
|
str.scan(/./) do |s|
|
|
if s == "," && !in_msg
|
|
ret.push(new_str.strip)
|
|
new_str = ""
|
|
else
|
|
in_msg = !in_msg if s == "\""
|
|
new_str += s
|
|
end
|
|
end
|
|
new_str.strip!
|
|
ret.push(new_str) if !new_str.empty?
|
|
return ret
|
|
end
|
|
|
|
def replace_old_battle_scripts(event, list, index)
|
|
changed = false
|
|
script = list[index].parameters[1]
|
|
if script[/^\s*pbWildBattle\((.+)\)\s*$/]
|
|
battle_params = split_string_with_quotes($1) # Split on commas
|
|
list[index].parameters[1] = sprintf("WildBattle.start(#{battle_params[0]}, #{battle_params[1]})")
|
|
old_indent = list[index].indent
|
|
new_events = []
|
|
if battle_params[3] && battle_params[3][/false/]
|
|
push_script(new_events, "setBattleRule(\"cannotRun\")", old_indent)
|
|
end
|
|
if battle_params[4] && battle_params[4][/true/]
|
|
push_script(new_events, "setBattleRule(\"canLose\")", old_indent)
|
|
end
|
|
if battle_params[2] && battle_params[2] != "1"
|
|
push_script(new_events, "setBattleRule(\"outcome\", #{battle_params[2]})", old_indent)
|
|
end
|
|
list[index, 0] = new_events if new_events.length > 0
|
|
changed = true
|
|
elsif script[/^\s*pbDoubleWildBattle\((.+)\)\s*$/]
|
|
battle_params = split_string_with_quotes($1) # Split on commas
|
|
pkmn1 = "#{battle_params[0]}, #{battle_params[1]}"
|
|
pkmn2 = "#{battle_params[2]}, #{battle_params[3]}"
|
|
list[index].parameters[1] = sprintf("WildBattle.start(#{pkmn1}, #{pkmn2})")
|
|
old_indent = list[index].indent
|
|
new_events = []
|
|
if battle_params[5] && battle_params[5][/false/]
|
|
push_script(new_events, "setBattleRule(\"cannotRun\")", old_indent)
|
|
end
|
|
if battle_params[6] && battle_params[6][/true/]
|
|
push_script(new_events, "setBattleRule(\"canLose\")", old_indent)
|
|
end
|
|
if battle_params[4] && battle_params[4] != "1"
|
|
push_script(new_events, "setBattleRule(\"outcome\", #{battle_params[4]})", old_indent)
|
|
end
|
|
list[index, 0] = new_events if new_events.length > 0
|
|
changed = true
|
|
elsif script[/^\s*pbTripleWildBattle\((.+)\)\s*$/]
|
|
battle_params = split_string_with_quotes($1) # Split on commas
|
|
pkmn1 = "#{battle_params[0]}, #{battle_params[1]}"
|
|
pkmn2 = "#{battle_params[2]}, #{battle_params[3]}"
|
|
pkmn3 = "#{battle_params[4]}, #{battle_params[5]}"
|
|
list[index].parameters[1] = sprintf("WildBattle.start(#{pkmn1}, #{pkmn2}, #{pkmn3})")
|
|
old_indent = list[index].indent
|
|
new_events = []
|
|
if battle_params[7] && battle_params[7][/false/]
|
|
push_script(new_events, "setBattleRule(\"cannotRun\")", old_indent)
|
|
end
|
|
if battle_params[8] && battle_params[8][/true/]
|
|
push_script(new_events, "setBattleRule(\"canLose\")", old_indent)
|
|
end
|
|
if battle_params[6] && battle_params[6] != "1"
|
|
push_script(new_events, "setBattleRule(\"outcome\", #{battle_params[6]})", old_indent)
|
|
end
|
|
list[index, 0] = new_events if new_events.length > 0
|
|
changed = true
|
|
elsif script[/^\s*pbTrainerBattle\((.+)\)\s*$/]
|
|
battle_params = split_string_with_quotes($1) # Split on commas
|
|
trainer1 = "#{battle_params[0]}, #{battle_params[1]}"
|
|
trainer1 += ", #{battle_params[4]}" if battle_params[4] && battle_params[4] != "nil"
|
|
list[index].parameters[1] = "TrainerBattle.start(#{trainer1})"
|
|
old_indent = list[index].indent
|
|
new_events = []
|
|
if battle_params[2] && !battle_params[2].empty? && battle_params[2] != "nil"
|
|
speech = battle_params[2].gsub(/^\s*_I\(\s*"\s*/, "").gsub(/\"\s*\)\s*$/, "")
|
|
push_comment(new_events, "EndSpeech: #{speech.strip}", old_indent)
|
|
end
|
|
if battle_params[3] && battle_params[3][/true/]
|
|
push_script(new_events, "setBattleRule(\"double\")", old_indent)
|
|
end
|
|
if battle_params[5] && battle_params[5][/true/]
|
|
push_script(new_events, "setBattleRule(\"canLose\")", old_indent)
|
|
end
|
|
if battle_params[6] && battle_params[6] != "1"
|
|
push_script(new_events, "setBattleRule(\"outcome\", #{battle_params[6]})", old_indent)
|
|
end
|
|
list[index, 0] = new_events if new_events.length > 0
|
|
changed = true
|
|
elsif script[/^\s*pbDoubleTrainerBattle\((.+)\)\s*$/]
|
|
battle_params = split_string_with_quotes($1) # Split on commas
|
|
trainer1 = "#{battle_params[0]}, #{battle_params[1]}"
|
|
trainer1 += ", #{battle_params[2]}" if battle_params[2] && battle_params[2] != "nil"
|
|
trainer2 = "#{battle_params[4]}, #{battle_params[5]}"
|
|
trainer2 += ", #{battle_params[6]}" if battle_params[6] && battle_params[6] != "nil"
|
|
list[index].parameters[1] = "TrainerBattle.start(#{trainer1}, #{trainer2})"
|
|
old_indent = list[index].indent
|
|
new_events = []
|
|
if battle_params[3] && !battle_params[3].empty? && battle_params[3] != "nil"
|
|
speech = battle_params[3].gsub(/^\s*_I\(\s*"\s*/, "").gsub(/\"\s*\)\s*$/, "")
|
|
push_comment(new_events, "EndSpeech1: #{speech.strip}", old_indent)
|
|
end
|
|
if battle_params[7] && !battle_params[7].empty? && battle_params[7] != "nil"
|
|
speech = battle_params[7].gsub(/^\s*_I\(\s*"\s*/, "").gsub(/\"\s*\)\s*$/, "")
|
|
push_comment(new_events, "EndSpeech2: #{speech.strip}", old_indent)
|
|
end
|
|
if battle_params[8] && battle_params[8][/true/]
|
|
push_script(new_events, "setBattleRule(\"canLose\")", old_indent)
|
|
end
|
|
if battle_params[9] && battle_params[9] != "1"
|
|
push_script(new_events, "setBattleRule(\"outcome\", #{battle_params[9]})", old_indent)
|
|
end
|
|
list[index, 0] = new_events if new_events.length > 0
|
|
changed = true
|
|
elsif script[/^\s*pbTripleTrainerBattle\((.+)\)\s*$/]
|
|
battle_params = split_string_with_quotes($1) # Split on commas
|
|
trainer1 = "#{battle_params[0]}, #{battle_params[1]}"
|
|
trainer1 += ", #{battle_params[2]}" if battle_params[2] && battle_params[2] != "nil"
|
|
trainer2 = "#{battle_params[4]}, #{battle_params[5]}"
|
|
trainer2 += ", #{battle_params[6]}" if battle_params[6] && battle_params[6] != "nil"
|
|
trainer3 = "#{battle_params[8]}, #{battle_params[9]}"
|
|
trainer3 += ", #{battle_params[10]}" if battle_params[10] && battle_params[10] != "nil"
|
|
list[index].parameters[1] = "TrainerBattle.start(#{trainer1}, #{trainer2}, #{trainer3})"
|
|
old_indent = list[index].indent
|
|
new_events = []
|
|
if battle_params[3] && !battle_params[3].empty? && battle_params[3] != "nil"
|
|
speech = battle_params[3].gsub(/^\s*_I\(\s*"\s*/, "").gsub(/\"\s*\)\s*$/, "")
|
|
push_comment(new_events, "EndSpeech1: #{speech.strip}", old_indent)
|
|
end
|
|
if battle_params[7] && !battle_params[7].empty? && battle_params[7] != "nil"
|
|
speech = battle_params[7].gsub(/^\s*_I\(\s*"\s*/, "").gsub(/\"\s*\)\s*$/, "")
|
|
push_comment(new_events, "EndSpeech2: #{speech.strip}", old_indent)
|
|
end
|
|
if battle_params[11] && !battle_params[11].empty? && battle_params[11] != "nil"
|
|
speech = battle_params[11].gsub(/^\s*_I\(\s*"\s*/, "").gsub(/\"\s*\)\s*$/, "")
|
|
push_comment(new_events, "EndSpeech3: #{speech.strip}", old_indent)
|
|
end
|
|
if battle_params[12] && battle_params[12][/true/]
|
|
push_script(new_events, "setBattleRule(\"canLose\")", old_indent)
|
|
end
|
|
if battle_params[13] && battle_params[13] != "1"
|
|
push_script(new_events, "setBattleRule(\"outcome\", #{battle_params[13]})", old_indent)
|
|
end
|
|
list[index, 0] = new_events if new_events.length > 0
|
|
changed = true
|
|
end
|
|
return changed
|
|
end
|
|
|
|
def fix_event_use(event, _mapID, mapData)
|
|
return nil if event_is_empty?(event)
|
|
changed = false
|
|
trainerMoneyRE = /^\s*\$player\.money\s*(<|<=|>|>=)\s*(\d+)\s*$/
|
|
itemBallRE = /^\s*(Kernel\.)?pbItemBall/
|
|
# Rewrite event if it looks like a door
|
|
changed = true if update_door_event(event, mapData)
|
|
# Check through each page of the event in turn
|
|
pbEachPage(event) do |page|
|
|
i = 0
|
|
list = page.list
|
|
while i < list.length
|
|
params = list[i].parameters
|
|
case list[i].code
|
|
# when 655 # Script (continuation line)
|
|
when 355 # Script (first line)
|
|
lastScript = i
|
|
if !params[0].is_a?(String)
|
|
i += 1
|
|
next
|
|
end
|
|
# Check if the script is an old way of healing the entire party, and if
|
|
# so, replace it with a better version that uses event commands
|
|
if params[0][0, 1] != "f" && params[0][0, 1] != "p" && params[0][0, 1] != "K"
|
|
i += 1
|
|
next
|
|
end
|
|
# Script begins with "f" (for...), "p" (pbMethod) or "K" (Kernel.)
|
|
script = " " + params[0]
|
|
j = i + 1
|
|
while j < list.length
|
|
break if list[j].code != 655 # Script (continuation line)
|
|
script += list[j].parameters[0]
|
|
lastScript = j
|
|
j += 1
|
|
end
|
|
script.gsub!(/\s+/, "")
|
|
# Using old method of recovering
|
|
case script
|
|
when "foriin$player.partyi.healend"
|
|
(lastScript - i).times { list.delete_at(i) }
|
|
list.insert(i,
|
|
RPG::EventCommand.new(314, list[i].indent, [0])) # Recover All
|
|
changed = true
|
|
when "pbFadeOutIn(99999){foriin$player.partyi.healend}"
|
|
oldIndent = list[i].indent
|
|
(lastScript - i).times { list.delete_at(i) }
|
|
list.insert(
|
|
i,
|
|
RPG::EventCommand.new(223, oldIndent, [Tone.new(-255, -255, -255), 6]), # Fade to black
|
|
RPG::EventCommand.new(106, oldIndent, [6]), # Wait
|
|
RPG::EventCommand.new(314, oldIndent, [0]), # Recover All
|
|
RPG::EventCommand.new(223, oldIndent, [Tone.new(0, 0, 0), 6]), # Fade to normal
|
|
RPG::EventCommand.new(106, oldIndent, [6]) # Wait
|
|
)
|
|
changed = true
|
|
end
|
|
when 108 # Comment (first line)
|
|
# Replace a "SellItem:POTION,200" comment with event commands that do so
|
|
if params[0][/SellItem\s*\(\s*(\w+)\s*\,\s*(\d+)\s*\)/]
|
|
itemname = $1
|
|
cost = $2.to_i
|
|
if GameData::Item.exists?(itemname)
|
|
oldIndent = list[i].indent
|
|
list.delete_at(i)
|
|
newEvents = []
|
|
if cost == 0
|
|
push_branch(newEvents, "$bag.can_add?(:#{itemname})", oldIndent)
|
|
push_text(newEvents, _INTL("Here you go!"), oldIndent + 1)
|
|
push_script(newEvents, "pbReceiveItem(:#{itemname})", oldIndent + 1)
|
|
push_else(newEvents, oldIndent + 1)
|
|
push_text(newEvents, _INTL("You have no room left in the Bag."), oldIndent + 1)
|
|
else
|
|
push_event(newEvents, 111, [7, cost, 0], oldIndent)
|
|
push_branch(newEvents, "$bag.can_add?(:#{itemname})", oldIndent + 1)
|
|
push_event(newEvents, 125, [1, 0, cost], oldIndent + 2)
|
|
push_text(newEvents, _INTL("\\GHere you go!"), oldIndent + 2)
|
|
push_script(newEvents, "pbReceiveItem(:#{itemname})", oldIndent + 2)
|
|
push_else(newEvents, oldIndent + 2)
|
|
push_text(newEvents, _INTL("\\GYou have no room left in the Bag."), oldIndent + 2)
|
|
push_branch_end(newEvents, oldIndent + 2)
|
|
push_else(newEvents, oldIndent + 1)
|
|
push_text(newEvents, _INTL("\\GYou don't have enough money."), oldIndent + 1)
|
|
end
|
|
push_branch_end(newEvents, oldIndent + 1)
|
|
list[i, 0] = newEvents # insert 'newEvents' at index 'i'
|
|
changed = true
|
|
end
|
|
end
|
|
when 115 # Exit Event Processing
|
|
if i == list.length - 2
|
|
# Superfluous exit command, delete it
|
|
list.delete_at(i)
|
|
changed = true
|
|
end
|
|
when 201 # Transfer Player
|
|
if list.length <= 8
|
|
=begin
|
|
if params[0]==0
|
|
# Look for another event just above the position this Transfer
|
|
# Player command will transfer to - it may be a door, in which case
|
|
# this command should transfer the player onto the door instead of
|
|
# in front of it.
|
|
e = mapData.getEventFromXY(params[1],params[2],params[3]-1)
|
|
# This bit of code is just in case Switch 22 has been renamed/
|
|
# repurposed, which is highly unlikely. It changes the Switch used
|
|
# in the found event's condition to whichever is named
|
|
# 's:tsOff?("A")'.
|
|
if e && e.pages.length>=2 &&
|
|
e.pages[e.pages.length-1].condition.switch1_valid &&
|
|
e.pages[e.pages.length-1].condition.switch1_id==22 &&
|
|
mapData.switchName(e.pages[e.pages.length-1].condition.switch1_id)!='s:tsOff?("A")' &&
|
|
e.pages[e.pages.length-1].list.length>5 &&
|
|
e.pages[e.pages.length-1].list[0].code==111 # Conditional Branch
|
|
e.pages[e.pages.length-1].condition.switch1_id = mapData.registerSwitch('s:tsOff?("A")')
|
|
mapData.saveMap(params[1])
|
|
changed = true
|
|
end
|
|
# Checks if the found event is a simple Transfer Player one nestled
|
|
# between tiles that aren't passable - it is likely a door, so give
|
|
# it a second page with an "is player on me?" check.
|
|
if likely_passage?(e,params[1],mapData) # Checks the first page
|
|
add_passage_list(e,mapData)
|
|
mapData.saveMap(params[1])
|
|
changed = true
|
|
end
|
|
# If the found event's last page's Switch condition uses a Switch
|
|
# named 's:tsOff?("A")', it really does look like a door. Make this
|
|
# command transfer the player on top of it rather than in front of
|
|
# it.
|
|
if e && e.pages.length>=2 &&
|
|
e.pages[e.pages.length-1].condition.switch1_valid &&
|
|
mapData.switchName(e.pages[e.pages.length-1].condition.switch1_id)=='s:tsOff?("A")'
|
|
# If this is really a door, move transfer target to it
|
|
params[3] -= 1 # Move this command's destination up 1 tile (onto the found event)
|
|
params[5] = 1 # No fade (the found event should take care of that)
|
|
changed = true
|
|
end
|
|
deletedRoute = nil
|
|
deleteMoveRouteAt = proc { |list,i|
|
|
arr = []
|
|
if list[i] && list[i].code==209 # Set Move Route
|
|
arr.push(list[i])
|
|
list.delete_at(i)
|
|
while i<list.length
|
|
break if !list[i] || list[i].code!=509 # Set Move Route (continuation line)
|
|
arr.push(list[i])
|
|
list.delete_at(i)
|
|
end
|
|
end
|
|
next arr
|
|
}
|
|
insertMoveRouteAt = proc { |list,i,route|
|
|
j = route.length-1
|
|
while j>=0
|
|
list.insert(i,route[j])
|
|
j -= 1
|
|
end
|
|
}
|
|
# If the next event command is a Move Route that moves the player,
|
|
# check whether all it does is turn the player in a direction (or
|
|
# its first item is to move the player in a direction). If so, this
|
|
# Transfer Player command may as well set the player's direction
|
|
# instead; make it do so and delete that Move Route.
|
|
if params[4]==0 && # Retain direction
|
|
i+1<list.length && list[i+1].code==209 && list[i+1].parameters[0]==-1 # Set Move Route
|
|
route = list[i+1].parameters[1]
|
|
if route && route.list.length<=2
|
|
# Delete superfluous move route command if necessary
|
|
if route.list[0].code==16 # Player Turn Down
|
|
deleteMoveRouteAt.call(list,i+1)
|
|
params[4] = 2
|
|
changed = true
|
|
elsif route.list[0].code==17 # Player Turn Left
|
|
deleteMoveRouteAt.call(list,i+1)
|
|
params[4] = 4
|
|
changed = true
|
|
elsif route.list[0].code==18 # Player Turn Right
|
|
deleteMoveRouteAt.call(list,i+1)
|
|
params[4] = 6
|
|
changed = true
|
|
elsif route.list[0].code==19 # Player Turn Up
|
|
deleteMoveRouteAt.call(list,i+1)
|
|
params[4] = 8
|
|
changed = true
|
|
elsif (route.list[0].code==1 || route.list[0].code==2 || # Player Move (4-dir)
|
|
route.list[0].code==3 || route.list[0].code==4) && list.length==4
|
|
params[4] = [0,2,4,6,8][route.list[0].code]
|
|
deletedRoute = deleteMoveRouteAt.call(list,i+1)
|
|
changed = true
|
|
end
|
|
end
|
|
# If an event command before this one is a Move Route that just
|
|
# turns the player, delete it and make this Transfer Player command
|
|
# set the player's direction instead.
|
|
# (I don't know if it makes sense to do this, as there could be a
|
|
# lot of commands between then and this Transfer Player which this
|
|
# code can't recognise and deal with, so I've quoted this code out.)
|
|
elsif params[4]==0 && i>3 # Retain direction
|
|
# for j in 0...i
|
|
# if list[j].code==209 && list[j].parameters[0]==-1 # Set Move Route
|
|
# route = list[j].parameters[1]
|
|
# if route && route.list.length<=2
|
|
# oldlistlength = list.length
|
|
# # Delete superfluous move route command if necessary
|
|
# if route.list[0].code==16 # Player Turn Down
|
|
# deleteMoveRouteAt.call(list,j)
|
|
# params[4] = 2
|
|
# changed = true
|
|
# i -= (oldlistlength-list.length)
|
|
# elsif route.list[0].code==17 # Player Turn Left
|
|
# deleteMoveRouteAt.call(list,j)
|
|
# params[4] = 4
|
|
# changed = true
|
|
# i -= (oldlistlength-list.length)
|
|
# elsif route.list[0].code==18 # Player Turn Right
|
|
# deleteMoveRouteAt.call(list,j)
|
|
# params[4] = 6
|
|
# changed = true
|
|
# i -= (oldlistlength-list.length)
|
|
# elsif route.list[0].code==19 # Player Turn Up
|
|
# deleteMoveRouteAt.call(list,j)
|
|
# params[4] = 8
|
|
# changed = true
|
|
# i -= (oldlistlength-list.length)
|
|
# end
|
|
# end
|
|
# end
|
|
# end
|
|
# If the next event command changes the screen color, and the one
|
|
# after that is a Move Route which only turns the player in a
|
|
# direction, this Transfer Player command may as well set the
|
|
# player's direction instead; make it do so and delete that Move
|
|
# Route.
|
|
elsif params[4]==0 && # Retain direction
|
|
i+2<list.length &&
|
|
list[i+1].code==223 && # Change Screen Color Tone
|
|
list[i+2].code==209 && # Set Move Route
|
|
list[i+2].parameters[0]==-1
|
|
route = list[i+2].parameters[1]
|
|
if route && route.list.length<=2
|
|
# Delete superfluous move route command if necessary
|
|
if route.list[0].code==16 # Player Turn Down
|
|
deleteMoveRouteAt.call(list,i+2)
|
|
params[4] = 2
|
|
changed = true
|
|
elsif route.list[0].code==17 # Player Turn Left
|
|
deleteMoveRouteAt.call(list,i+2)
|
|
params[4] = 4
|
|
changed = true
|
|
elsif route.list[0].code==18 # Player Turn Right
|
|
deleteMoveRouteAt.call(list,i+2)
|
|
params[4] = 6
|
|
changed = true
|
|
elsif route.list[0].code==19 # Player Turn Up
|
|
deleteMoveRouteAt.call(list,i+2)
|
|
params[4] = 8
|
|
changed = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
=end
|
|
# If this is the only event command, convert to a full event
|
|
if list.length == 2 || (list.length == 3 && (list[0].code == 250 || list[1].code == 250)) # Play SE
|
|
params[5] = 1 # No fade
|
|
fullTransfer = list[i]
|
|
indent = list[i].indent
|
|
(list.length - 1).times { list.delete_at(0) }
|
|
list.insert(
|
|
0,
|
|
RPG::EventCommand.new(250, indent, [RPG::AudioFile.new("Exit Door", 80, 100)]), # Play SE
|
|
RPG::EventCommand.new(223, indent, [Tone.new(-255, -255, -255), 6]), # Fade to black
|
|
RPG::EventCommand.new(106, indent, [8]), # Wait
|
|
fullTransfer, # Transfer event
|
|
RPG::EventCommand.new(223, indent, [Tone.new(0, 0, 0), 6]) # Fade to normal
|
|
)
|
|
changed = true
|
|
end
|
|
# if deletedRoute
|
|
# insertMoveRouteAt.call(list,list.length-1,deletedRoute)
|
|
# changed = true
|
|
# end
|
|
end
|
|
when 101 # Show Text
|
|
# Capitalise/decapitalise various text formatting codes
|
|
if list[i].parameters[0][0, 1] == "\\"
|
|
newx = list[i].parameters[0].clone
|
|
newx.sub!(/^\\[Bb]\s+/, "\\b")
|
|
newx.sub!(/^\\[Rr]\s+/, "\\r")
|
|
newx.sub!(/^\\[Pp][Gg]\s+/, "\\pg")
|
|
newx.sub!(/^\\[Pp][Oo][Gg]\s+/, "\\pog")
|
|
newx.sub!(/^\\[Gg]\s+/, "\\G")
|
|
newx.sub!(/^\\[Cc][Nn]\s+/, "\\CN")
|
|
if list[i].parameters[0] != newx
|
|
list[i].parameters[0] = newx
|
|
changed = true
|
|
end
|
|
end
|
|
# Split Show Text commands with 5+ lines into multiple Show Text
|
|
# commands each with a maximum of 4 lines
|
|
lines = 1
|
|
j = i + 1
|
|
while j < list.length
|
|
break if list[j].code != 401 # Show Text (continuation line)
|
|
if lines % 4 == 0
|
|
list[j].code = 101 # Show Text
|
|
changed = true
|
|
end
|
|
lines += 1
|
|
j += 1
|
|
end
|
|
# If this Show Text command has 2+ lines of text but not much actual
|
|
# text in the first line, merge the second line into it
|
|
if lines >= 2 && list[i].parameters[0].length > 0 && list[i].parameters[0].length <= 20 &&
|
|
!list[i].parameters[0][/\\n/]
|
|
# Very short line
|
|
list[i].parameters[0] += "\\n" + list[i + 1].parameters[0]
|
|
list.delete_at(i + 1)
|
|
i -= 1 # revisit this text command
|
|
changed = true
|
|
# Check whether this Show Text command has 3+ lines and the next command
|
|
# is also a Show Text
|
|
elsif lines >= 3 && list[i + lines] && list[i + lines].code == 101 # Show Text
|
|
# Check whether a sentence is being broken midway between two Text
|
|
# commands (i.e. the first Show Text doesn't end in certain punctuation)
|
|
lastLine = list[i + lines - 1].parameters[0].sub(/\s+$/, "")
|
|
if lastLine.length > 0 && !lastLine[/[\\<]/] && lastLine[/[^\.,\!\?\;\-\"]$/]
|
|
message = list[i].parameters[0]
|
|
j = i + 1
|
|
while j < list.length
|
|
break if list[j].code != 401 # Show Text (continuation line)
|
|
message += "\n" + list[j].parameters[0]
|
|
j += 1
|
|
end
|
|
# Find a punctuation mark to split at
|
|
punct = [message.rindex(". "), message.rindex(".\n"),
|
|
message.rindex("!"), message.rindex("?"), -1].compact.max
|
|
if punct == -1
|
|
punct = [message.rindex(", "), message.rindex(",\n"), -1].compact.max
|
|
end
|
|
if punct != -1
|
|
# Delete old message
|
|
indent = list[i].indent
|
|
newMessage = message[0, punct + 1].split("\n")
|
|
nextMessage = message[punct + 1, message.length].sub(/^\s+/, "").split("\n")
|
|
list[i + lines].code = 401
|
|
lines.times { list.delete_at(i) }
|
|
j = nextMessage.length - 1
|
|
while j >= 0
|
|
list.insert(i, RPG::EventCommand.new((j == 0) ? 101 : 401, indent, [nextMessage[j]]))
|
|
j -= 1
|
|
end
|
|
j = newMessage.length - 1
|
|
while j >= 0
|
|
list.insert(i, RPG::EventCommand.new((j == 0) ? 101 : 401, indent, [newMessage[j]]))
|
|
j -= 1
|
|
end
|
|
changed = true
|
|
i += 1
|
|
next
|
|
end
|
|
end
|
|
end
|
|
when 111 # Conditional Branch
|
|
if list[i].parameters[0] == 12 # script
|
|
script = list[i].parameters[1]
|
|
changed = true if replace_old_battle_scripts(event, list, i)
|
|
if script[trainerMoneyRE] # Compares $player.money with a value
|
|
# Checking money directly
|
|
operator = $1
|
|
amount = $2.to_i
|
|
case operator
|
|
when "<"
|
|
params[0] = 7 # gold
|
|
params[2] = 1
|
|
params[1] = amount - 1
|
|
changed = true
|
|
when "<="
|
|
params[0] = 7 # gold
|
|
params[2] = 1
|
|
params[1] = amount
|
|
changed = true
|
|
when ">"
|
|
params[0] = 7 # gold
|
|
params[2] = 0
|
|
params[1] = amount + 1
|
|
changed = true
|
|
when ">="
|
|
params[0] = 7 # gold
|
|
params[2] = 0
|
|
params[1] = amount
|
|
changed = true
|
|
end
|
|
elsif script[itemBallRE] && i > 0 # Contains pbItemBall after another command
|
|
# Using pbItemBall on non-item events, change it
|
|
list[i].parameters[1] = script.sub(/pbItemBall/, "pbReceiveItem")
|
|
changed = true
|
|
elsif script[/^\s*(TrainerBattle.start)/]
|
|
# Check if trainer battle conditional branch is empty
|
|
j = i + 1
|
|
isempty = true
|
|
elseIndex = -1
|
|
# Check if page is empty
|
|
while j < page.list.length
|
|
if list[j].indent <= list[i].indent
|
|
if list[j].code == 411 # Else
|
|
elseIndex = j
|
|
else
|
|
break # Reached end of Conditional Branch
|
|
end
|
|
end
|
|
if list[j].code != 0 && list[j].code != 411 # Else
|
|
isempty = false
|
|
break
|
|
end
|
|
j += 1
|
|
end
|
|
if isempty
|
|
if elseIndex >= 0
|
|
list.insert(
|
|
elseIndex + 1,
|
|
RPG::EventCommand.new(115, list[i].indent + 1, []) # Exit Event Processing
|
|
)
|
|
else
|
|
list.insert(
|
|
i + 1,
|
|
RPG::EventCommand.new(0, list[i].indent + 1, []), # Empty Event
|
|
RPG::EventCommand.new(411, list[i].indent, []), # Else
|
|
RPG::EventCommand.new(115, list[i].indent + 1, []) # Exit Event Processing
|
|
)
|
|
end
|
|
changed = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
i += 1
|
|
end
|
|
end
|
|
return (changed) ? event : nil
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Convert events used as counters into proper counters.
|
|
#-----------------------------------------------------------------------------
|
|
# Checks if the event has just 1 page, which has no conditions and no commands
|
|
# and whose movement type is "Fixed".
|
|
def plain_event?(event)
|
|
return false unless event
|
|
return false if event.pages.length > 1
|
|
return false if event.pages[0].move_type != 0
|
|
return false if event.pages[0].condition.switch1_valid ||
|
|
event.pages[0].condition.switch2_valid ||
|
|
event.pages[0].condition.variable_valid ||
|
|
event.pages[0].condition.self_switch_valid
|
|
return true if event.pages[0].list.length <= 1
|
|
return false
|
|
end
|
|
|
|
# Checks if the event has just 1 page, which has no conditions and whose
|
|
# movement type is "Fixed". Then checks if there are no commands, or it looks
|
|
# like a simple Mart or a Poké Center nurse event.
|
|
def plain_event_or_mart?(event)
|
|
return false unless event
|
|
return false if event.pages.length > 1
|
|
return false if event.pages[0].move_type != 0
|
|
return false if event.pages[0].condition.switch1_valid ||
|
|
event.pages[0].condition.switch2_valid ||
|
|
event.pages[0].condition.variable_valid ||
|
|
event.pages[0].condition.self_switch_valid
|
|
# No commands in the event
|
|
return true if event.pages[0].list.length <= 1
|
|
# pbPokemonMart events
|
|
return true if event.pages[0].list.length <= 12 &&
|
|
event.pages[0].graphic.character_name != "" && # Has charset
|
|
event.pages[0].list[0].code == 355 && # First line is Script
|
|
event.pages[0].list[0].parameters[0][/^pbPokemonMart/]
|
|
# pbSetPokemonCenter events
|
|
return true if event.pages[0].list.length > 8 &&
|
|
event.pages[0].graphic.character_name != "" && # Has charset
|
|
event.pages[0].list[0].code == 355 && # First line is Script
|
|
event.pages[0].list[0].parameters[0][/^pbSetPokemonCenter/]
|
|
return false
|
|
end
|
|
|
|
# Given two events that are next to each other, decides whether otherEvent is
|
|
# likely to be a "counter event", i.e. is placed on a tile with the Counter
|
|
# flag, or is on a non-passable tile between two passable tiles (e.g. a desk)
|
|
# where one of those two tiles is occupied by thisEvent.
|
|
def likely_counter?(thisEvent, otherEvent, mapID, mapData)
|
|
# Check whether otherEvent is on a counter tile
|
|
return true if mapData.isCounterTile?(mapID, otherEvent.x, otherEvent.y)
|
|
# Check whether otherEvent is between an event with a graphic (e.g. an NPC)
|
|
# and a spot where the player can be
|
|
yonderX = otherEvent.x + (otherEvent.x - thisEvent.x)
|
|
yonderY = otherEvent.y + (otherEvent.y - thisEvent.y)
|
|
return thisEvent.pages[0].graphic.character_name != "" && # Has charset
|
|
otherEvent.pages[0].graphic.character_name == "" && # Has no charset
|
|
otherEvent.pages[0].trigger == 0 && # Action trigger
|
|
mapData.isPassable?(mapID, thisEvent.x, thisEvent.y) &&
|
|
!mapData.isPassable?(mapID, otherEvent.x, otherEvent.y) &&
|
|
mapData.isPassable?(mapID, yonderX, yonderY)
|
|
end
|
|
|
|
# Checks all events in the given map to see if any look like they've been
|
|
# placed on a desk with an NPC behind it, where the event on the desk is the
|
|
# actual interaction with the NPC. In other words, it's not making proper use
|
|
# of the counter flag (which lets the player interact with an event on the
|
|
# other side of counter tiles).
|
|
# Any events found to be like this have their contents merged into the NPC
|
|
# event and the counter event itself is deleted. The tile below the counter
|
|
# event gets its counter flag set (if it isn't already).
|
|
def check_counters(map, mapID, mapData)
|
|
toDelete = []
|
|
changed = false
|
|
map.events.each_key do |key|
|
|
event = map.events[key]
|
|
next if !plain_event_or_mart?(event)
|
|
# Found an event that is empty or looks like a simple Mart or a Poké
|
|
# Center nurse. Check adjacent events to see if they are "counter events".
|
|
neighbors = []
|
|
neighbors.push(mapData.getEventFromXY(mapID, event.x, event.y - 1))
|
|
neighbors.push(mapData.getEventFromXY(mapID, event.x, event.y + 1))
|
|
neighbors.push(mapData.getEventFromXY(mapID, event.x - 1, event.y))
|
|
neighbors.push(mapData.getEventFromXY(mapID, event.x + 1, event.y))
|
|
neighbors.compact!
|
|
neighbors.each do |otherEvent|
|
|
next if plain_event?(otherEvent) # Blank/cosmetic-only event
|
|
next if !likely_counter?(event, otherEvent, mapID, mapData)
|
|
# Found an adjacent event that looks like it's supposed to be a counter.
|
|
# Set the counter flag of the tile beneath the counter event, copy the
|
|
# counter event's pages to the NPC event, and delete the counter event.
|
|
mapData.setCounterTile(mapID, otherEvent.x, otherEvent.y)
|
|
savedPage = event.pages[0]
|
|
event.pages = otherEvent.pages
|
|
apply_pages(savedPage, event.pages) # Apply NPC's visuals to new event pages
|
|
toDelete.push(otherEvent.id)
|
|
changed = true
|
|
end
|
|
end
|
|
toDelete.each { |key| map.events.delete(key) }
|
|
return changed
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Main compiler method for events.
|
|
#-----------------------------------------------------------------------------
|
|
def compile_trainer_events
|
|
mapData = MapData.new
|
|
t = System.uptime
|
|
Graphics.update
|
|
trainerChecker = TrainerChecker.new
|
|
change_record = []
|
|
Console.echo_li(_INTL("Processing {1} maps...", mapData.mapinfos.keys.length))
|
|
idx = 0
|
|
mapData.mapinfos.keys.sort.each do |id|
|
|
echo "." if idx % 100 == 0
|
|
idx += 1
|
|
Graphics.update if idx % 500 == 0
|
|
changed = false
|
|
map = mapData.getMap(id)
|
|
next if !map || !mapData.mapinfos[id]
|
|
map.events.each_key do |key|
|
|
if System.uptime - t >= 5
|
|
t += 5
|
|
Graphics.update
|
|
end
|
|
newevent = convert_to_trainer_event(map.events[key], trainerChecker)
|
|
if newevent
|
|
map.events[key] = newevent
|
|
changed = true
|
|
end
|
|
newevent = convert_to_item_event(map.events[key])
|
|
if newevent
|
|
map.events[key] = newevent
|
|
changed = true
|
|
end
|
|
changed = true if fix_event_name(map.events[key])
|
|
changed = true if fix_event_scripts(map.events[key])
|
|
newevent = fix_event_use(map.events[key], id, mapData)
|
|
if newevent
|
|
map.events[key] = newevent
|
|
changed = true
|
|
end
|
|
end
|
|
if System.uptime - t >= 5
|
|
t += 5
|
|
Graphics.update
|
|
end
|
|
changed = true if check_counters(map, id, mapData)
|
|
if changed
|
|
mapData.saveMap(id)
|
|
mapData.saveTilesets
|
|
change_record.push(_INTL("Map {1}: '{2}' was modified and saved.", id, mapData.mapinfos[id].name))
|
|
end
|
|
end
|
|
Console.echo_done(true)
|
|
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..."))
|
|
commonEvents.length.times do |key|
|
|
newevent = fix_event_use(commonEvents[key], 0, mapData)
|
|
if newevent
|
|
commonEvents[key] = newevent
|
|
changed = true
|
|
end
|
|
end
|
|
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 without saving to ensure changes are applied."))
|
|
end
|
|
end
|
|
end
|