mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
822 lines
29 KiB
Ruby
822 lines
29 KiB
Ruby
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
module Translator
|
|
module_function
|
|
|
|
def gather_script_and_event_texts
|
|
Graphics.update
|
|
begin
|
|
t = Time.now.to_i
|
|
texts = []
|
|
# Get script texts from Scripts.rxdata
|
|
$RGSS_SCRIPTS.each do |script|
|
|
if Time.now.to_i - t >= 5
|
|
t = Time.now.to_i
|
|
Graphics.update
|
|
end
|
|
scr = Zlib::Inflate.inflate(script[2])
|
|
find_translatable_text_from_RGSS_script(texts, scr)
|
|
end
|
|
# If Scripts.rxdata only has 1 section, scripts have been extracted. Get
|
|
# script texts from .rb files in Data/Scripts
|
|
if $RGSS_SCRIPTS.length == 1
|
|
Dir.all("Data/Scripts").each do |script_file|
|
|
if Time.now.to_i - t >= 5
|
|
t = Time.now.to_i
|
|
Graphics.update
|
|
end
|
|
File.open(script_file, "rb") do |f|
|
|
find_translatable_text_from_RGSS_script(texts, f.read)
|
|
end
|
|
end
|
|
end
|
|
# Get script texts from plugin script files
|
|
if safeExists?("Data/PluginScripts.rxdata")
|
|
plugin_scripts = load_data("Data/PluginScripts.rxdata")
|
|
plugin_scripts.each do |plugin|
|
|
plugin[2].each do |script|
|
|
if Time.now.to_i - t >= 5
|
|
t = Time.now.to_i
|
|
Graphics.update
|
|
end
|
|
scr = Zlib::Inflate.inflate(script[1]).force_encoding(Encoding::UTF_8)
|
|
find_translatable_text_from_RGSS_script(texts, scr)
|
|
end
|
|
end
|
|
end
|
|
MessageTypes.addMessagesAsHash(MessageTypes::SCRIPT_TEXTS, texts)
|
|
# Find all text in common events and add them to messages
|
|
commonevents = load_data("Data/CommonEvents.rxdata")
|
|
items = []
|
|
choices = []
|
|
commonevents.compact.each do |event|
|
|
if Time.now.to_i - t >= 5
|
|
t = Time.now.to_i
|
|
Graphics.update
|
|
end
|
|
begin
|
|
neednewline = false
|
|
lastitem = ""
|
|
event.list.size.times do |j|
|
|
list = event.list[j]
|
|
if neednewline && list.code != 401 # Continuation of 101 Show Text
|
|
if lastitem != ""
|
|
lastitem.gsub!(/([^\.\!\?])\s\s+/) { |m| $1 + " " }
|
|
items.push(lastitem)
|
|
lastitem = ""
|
|
end
|
|
neednewline = false
|
|
end
|
|
if list.code == 101 # Show Text
|
|
lastitem += list.parameters[0].to_s
|
|
neednewline = true
|
|
elsif list.code == 102 # Show Choices
|
|
list.parameters[0].length.times do |k|
|
|
choices.push(list.parameters[0][k])
|
|
end
|
|
neednewline = false
|
|
elsif list.code == 401 # Continuation of 101 Show Text
|
|
lastitem += " " if lastitem != ""
|
|
lastitem += list.parameters[0].to_s
|
|
neednewline = true
|
|
elsif list.code == 355 || list.code == 655 # Script or script continuation line
|
|
find_translatable_text_from_event_script(items, list.parameters[0])
|
|
elsif list.code == 111 && list.parameters[0] == 12 # Conditional Branch
|
|
find_translatable_text_from_event_script(items, list.parameters[1])
|
|
elsif list.code == 209 # Set Move Route
|
|
route = list.parameters[1]
|
|
route.list.size.times do |k|
|
|
if route.list[k].code == PBMoveRoute::SCRIPT
|
|
find_translatable_text_from_event_script(items, route.list[k].parameters[0])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if neednewline && lastitem != ""
|
|
items.push(lastitem)
|
|
lastitem = ""
|
|
end
|
|
end
|
|
end
|
|
if Time.now.to_i - t >= 5
|
|
t = Time.now.to_i
|
|
Graphics.update
|
|
end
|
|
items |= []
|
|
choices |= []
|
|
items.concat(choices)
|
|
MessageTypes.setMapMessagesAsHash(0, items)
|
|
# Find all text in map events and add them to messages
|
|
mapinfos = pbLoadMapInfos
|
|
mapinfos.each_key do |id|
|
|
if Time.now.to_i - t >= 5
|
|
t = Time.now.to_i
|
|
Graphics.update
|
|
end
|
|
filename = sprintf("Data/Map%03d.rxdata", id)
|
|
next if !pbRgssExists?(filename)
|
|
map = load_data(filename)
|
|
items = []
|
|
choices = []
|
|
map.events.each_value do |event|
|
|
if Time.now.to_i - t >= 5
|
|
t = Time.now.to_i
|
|
Graphics.update
|
|
end
|
|
begin
|
|
event.pages.size.times do |i|
|
|
neednewline = false
|
|
lastitem = ""
|
|
event.pages[i].list.size.times do |j|
|
|
list = event.pages[i].list[j]
|
|
if neednewline && list.code != 401 # Continuation of 101 Show Text
|
|
if lastitem != ""
|
|
lastitem.gsub!(/([^\.\!\?])\s\s+/) { |m| $1 + " " }
|
|
items.push(lastitem)
|
|
lastitem = ""
|
|
end
|
|
neednewline = false
|
|
end
|
|
if list.code == 101 # Show Text
|
|
lastitem += list.parameters[0].to_s
|
|
neednewline = true
|
|
elsif list.code == 102 # Show Choices
|
|
list.parameters[0].length.times do |k|
|
|
choices.push(list.parameters[0][k])
|
|
end
|
|
neednewline = false
|
|
elsif list.code == 401 # Continuation of 101 Show Text
|
|
lastitem += " " if lastitem != ""
|
|
lastitem += list.parameters[0].to_s
|
|
neednewline = true
|
|
elsif list.code == 355 || list.code == 655 # Script or script continuation line
|
|
find_translatable_text_from_event_script(items, list.parameters[0])
|
|
elsif list.code == 111 && list.parameters[0] == 12 # Conditional Branch
|
|
find_translatable_text_from_event_script(items, list.parameters[1])
|
|
elsif list.code == 209 # Set Move Route
|
|
route = list.parameters[1]
|
|
route.list.size.times do |k|
|
|
if route.list[k].code == PBMoveRoute::SCRIPT
|
|
find_translatable_text_from_event_script(items, route.list[k].parameters[0])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if neednewline && lastitem != ""
|
|
items.push(lastitem)
|
|
lastitem = ""
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if Time.now.to_i - t >= 5
|
|
t = Time.now.to_i
|
|
Graphics.update
|
|
end
|
|
items |= []
|
|
choices |= []
|
|
items.concat(choices)
|
|
MessageTypes.setMapMessagesAsHash(id, items) if items.length > 0
|
|
if Time.now.to_i - t >= 5
|
|
t = Time.now.to_i
|
|
Graphics.update
|
|
end
|
|
end
|
|
rescue Hangup
|
|
end
|
|
Graphics.update
|
|
end
|
|
|
|
def find_translatable_text_from_RGSS_script(items, script)
|
|
script.force_encoding(Encoding::UTF_8)
|
|
script.scan(/(?:_INTL|_ISPRINTF)\s*\(\s*\"((?:[^\\\"]*\\\"?)*[^\"]*)\"/) do |s|
|
|
string = s[0]
|
|
string.gsub!(/\\r/, "\r")
|
|
string.gsub!(/\\n/, "\n")
|
|
string.gsub!(/\\1/, "\1")
|
|
string.gsub!(/\\\"/, "\"")
|
|
string.gsub!(/\\\\/, "\\")
|
|
items.push(string)
|
|
end
|
|
end
|
|
|
|
def find_translatable_text_from_event_script(items, script)
|
|
script.force_encoding(Encoding::UTF_8)
|
|
script.scan(/(?:_I)\s*\(\s*\"((?:[^\\\"]*\\\"?)*[^\"]*)\"/) do |s|
|
|
string = s[0]
|
|
string.gsub!(/\\\"/, "\"")
|
|
string.gsub!(/\\\\/, "\\")
|
|
items.push(string)
|
|
end
|
|
end
|
|
|
|
def normalize_value(value)
|
|
if value[/[\r\n\t\x01]|^[\[\]]/]
|
|
ret = value.dup
|
|
ret.gsub!(/\r/, "<<r>>")
|
|
ret.gsub!(/\n/, "<<n>>")
|
|
ret.gsub!(/\t/, "<<t>>")
|
|
ret.gsub!(/\[/, "<<[>>")
|
|
ret.gsub!(/\]/, "<<]>>")
|
|
ret.gsub!(/\x01/, "<<1>>")
|
|
return ret
|
|
end
|
|
return value
|
|
end
|
|
|
|
def denormalize_value(value)
|
|
if value[/<<[rnt1\[\]]>>/]
|
|
ret = value.dup
|
|
ret.gsub!(/<<1>>/, "\1")
|
|
ret.gsub!(/<<r>>/, "\r")
|
|
ret.gsub!(/<<n>>/, "\n")
|
|
ret.gsub!(/<<\[>>/, "[")
|
|
ret.gsub!(/<<\]>>/, "]")
|
|
ret.gsub!(/<<t>>/, "\t")
|
|
return ret
|
|
end
|
|
return value
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def extract_text(language_name = "default", core_text = false, separate_map_files = false)
|
|
dir_name = sprintf("Text_%s_%s", language_name, (core_text) ? "core" : "game")
|
|
msg_window = pbCreateMessageWindow
|
|
# Get text for extraction
|
|
orig_messages = Translation.new(language_name)
|
|
if core_text
|
|
language_messages = orig_messages.core_messages
|
|
default_messages = orig_messages.default_core_messages
|
|
if !default_messages || default_messages.length == 0
|
|
pbMessageDisplay(msg_window, _INTL("The default core messages file \"messages_core.dat\" was not found."))
|
|
pbDisposeMessageWindow(msg_window)
|
|
return
|
|
end
|
|
else
|
|
language_messages = orig_messages.game_messages
|
|
default_messages = orig_messages.default_game_messages
|
|
if !default_messages || default_messages.length == 0
|
|
pbMessageDisplay(msg_window, _INTL("The default game messages file \"messages_game.dat\" was not found."))
|
|
pbDisposeMessageWindow(msg_window)
|
|
return
|
|
end
|
|
end
|
|
# Create folder for extracted text files, or delete existing text files from
|
|
# existing destination folder
|
|
if Dir.safe?(dir_name)
|
|
has_files = false
|
|
Dir.all(dir_name).each do |f|
|
|
has_files = true
|
|
break
|
|
end
|
|
if has_files && !pbConfirmMessageSerious(_INTL("Replace all text files in folder '{1}'?", dir_name))
|
|
pbDisposeMessageWindow(msg_window)
|
|
return
|
|
end
|
|
Dir.all(dir_name).each { |f| File.delete(f) }
|
|
else
|
|
Dir.create(dir_name)
|
|
end
|
|
# Create a lambda function that helps to write text files
|
|
write_header = lambda do |f, with_line|
|
|
f.write(0xEF.chr)
|
|
f.write(0xBB.chr)
|
|
f.write(0xBF.chr)
|
|
f.write("# To localize this text for a particular language, please" + "\r\n")
|
|
f.write("# translate every second line of this file." + "\r\n")
|
|
f.write("\#-------------------------------\r\n") if with_line
|
|
end
|
|
# Extract the text
|
|
pbMessageDisplay(msg_window, "\\ts[]" + _INTL("Extracting text, please wait.") + "\\wtnp[0]")
|
|
# Get all the section IDs to cycle through
|
|
max_section_id = default_messages.length
|
|
max_section_id = language_messages.length if language_messages && language_messages.length > max_section_id
|
|
max_section_id.times do |i|
|
|
section_name = getConstantName(MessageTypes, i, false)
|
|
next if !section_name
|
|
if i == MessageTypes::EVENT_TEXTS
|
|
if separate_map_files
|
|
map_infos = pbLoadMapInfos
|
|
default_messages[i].each_with_index do |map_msgs, map_id|
|
|
next if !map_msgs || map_msgs.length == 0
|
|
filename = sprintf("Map%03d", map_id)
|
|
filename += " " + map_infos[map_id].name if map_infos[map_id]
|
|
File.open(dir_name + "/" + filename + ".txt", "wb") do |f|
|
|
write_header.call(f, true)
|
|
translated_msgs = language_messages[i][map_id] if language_messages && language_messages[i]
|
|
write_section_texts_to_file(f, sprintf("Map%03d", map_id), translated_msgs, map_msgs)
|
|
end
|
|
end
|
|
else
|
|
next if !default_messages[i] || default_messages[i].length == 0
|
|
no_difference = true
|
|
default_messages[i].each do |map_msgs|
|
|
no_difference = false if map_msgs && map_msgs.length > 0
|
|
break if !map_msgs
|
|
end
|
|
next if no_difference
|
|
File.open(dir_name + "/" + section_name + ".txt", "wb") do |f|
|
|
write_header.call(f, false)
|
|
default_messages[i].each_with_index do |map_msgs, map_id|
|
|
next if !map_msgs || map_msgs.length == 0
|
|
f.write("\#-------------------------------\r\n")
|
|
translated_msgs = (language_messages && language_messages[i]) ? language_messages[i][map_id] : nil
|
|
write_section_texts_to_file(f, sprintf("Map%03d", map_id), translated_msgs, map_msgs)
|
|
end
|
|
end
|
|
end
|
|
else # MessageTypes sections
|
|
next if !default_messages[i] || default_messages[i].length == 0
|
|
File.open(dir_name + "/" + section_name + ".txt", "wb") do |f|
|
|
write_header.call(f, true)
|
|
translated_msgs = (language_messages) ? language_messages[i] : nil
|
|
write_section_texts_to_file(f, section_name, translated_msgs, default_messages[i])
|
|
end
|
|
end
|
|
end
|
|
msg_window.textspeed = MessageConfig.pbSettingToTextSpeed($PokemonSystem.textspeed)
|
|
if core_text
|
|
pbMessageDisplay(msg_window, _INTL("All core text was extracted to files in the folder \"{1}\".", dir_name) + "\1")
|
|
else
|
|
pbMessageDisplay(msg_window, _INTL("All game text was extracted to files in the folder \"{1}\".", dir_name) + "\1")
|
|
end
|
|
pbMessageDisplay(msg_window, _INTL("To localize this text, translate every second line in those files.") + "\1")
|
|
pbMessageDisplay(msg_window, _INTL("After translating, choose \"Compile Translated Text\" in the Debug menu."))
|
|
pbDisposeMessageWindow(msg_window)
|
|
end
|
|
|
|
def write_section_texts_to_file(f, section_name, language_msgs, original_msgs = nil)
|
|
return if !original_msgs
|
|
case original_msgs
|
|
when Array
|
|
f.write("[#{section_name}]\r\n")
|
|
original_msgs.length.times do |j|
|
|
next if nil_or_empty?(original_msgs[j])
|
|
f.write("#{j}\r\n")
|
|
f.write(normalize_value(original_msgs[j]) + "\r\n")
|
|
text = (language_msgs && language_msgs[j]) ? language_msgs[j] : original_msgs[j]
|
|
f.write(normalize_value(text) + "\r\n")
|
|
end
|
|
when Hash
|
|
f.write("[#{section_name}]\r\n")
|
|
keys = original_msgs.keys
|
|
keys.each do |key|
|
|
next if nil_or_empty?(original_msgs[key])
|
|
f.write(normalize_value(key) + "\r\n")
|
|
text = (language_msgs && language_msgs[key]) ? language_msgs[key] : original_msgs[key]
|
|
f.write(normalize_value(text) + "\r\n")
|
|
end
|
|
end
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def compile_text(dir_name, dat_filename)
|
|
msg_window = pbCreateMessageWindow
|
|
pbMessageDisplay(msg_window, "\\ts[]" + _INTL("Compiling text, please wait.") + "\\wtnp[0]")
|
|
outfile = File.open("Data/messages_" + dat_filename + ".dat", "wb")
|
|
all_text = []
|
|
begin
|
|
text_files = Dir.get("Text_" + dir_name, "*.txt")
|
|
text_files.each { |file| compile_text_from_file(file, all_text) }
|
|
Marshal.dump(all_text, outfile)
|
|
rescue
|
|
raise
|
|
ensure
|
|
outfile.close
|
|
end
|
|
msg_window.textspeed = MessageConfig.pbSettingToTextSpeed($PokemonSystem.textspeed)
|
|
pbMessageDisplay(msg_window,
|
|
_INTL("Text files in the folder \"Text_{1}\" were successfully compiled into file \"Data/messages_{2}.dat\".", dir_name, dat_filename))
|
|
pbMessageDisplay(msg_window, _INTL("You may need to close the game to see any changes to messages."))
|
|
pbDisposeMessageWindow(msg_window)
|
|
end
|
|
|
|
def compile_text_from_file(text_file, all_text)
|
|
begin
|
|
file = File.open(text_file, "rb")
|
|
rescue
|
|
raise _INTL("Can't find or open '{1}'.", text_file)
|
|
end
|
|
begin
|
|
Compiler.pbEachSection(file) do |contents, section_name|
|
|
next if contents.length == 0
|
|
# Get the section number and whether the section contains a map's event text
|
|
section_id = -1
|
|
is_map = false
|
|
if section_name.to_i != 0 # Section name is a number
|
|
section_id = section_name.to_i
|
|
elsif hasConst?(MessageTypes, section_name) # Section name is a constant from MessageTypes
|
|
section_id = getConst(MessageTypes, section_name)
|
|
elsif section_name[/^Map(\d+)$/i] # Section name is a map number (event text)
|
|
is_map = true
|
|
section_id = $~[1].to_i
|
|
end
|
|
raise _INTL("Invalid section name {1}", section_name) if section_id < 0
|
|
# Decide whether the section contains text stored in an ordered list (an
|
|
# array) or an ordered hash
|
|
item_length = 0
|
|
if contents[0][/^\d+$/] # If first line is a number, text is stored in an array
|
|
text_hash = []
|
|
item_length = 3
|
|
if is_map
|
|
raise _INTL("Section {1} can't be an ordered list (section was recognized as an ordered list because its first line is a number).", section_name)
|
|
end
|
|
if contents.length % 3 != 0
|
|
raise _INTL("Section {1}'s line count is not divisible by 3 (section was recognized as an ordered list because its first line is a number).", section_name)
|
|
end
|
|
else # Text is stored in a hash
|
|
text_hash = {}
|
|
item_length = 2
|
|
if contents.length.odd?
|
|
raise _INTL("Section {1} has an odd number of entries (section was recognized as a hash because its first line is not a number).", section_name)
|
|
end
|
|
end
|
|
# Add text in section to ordered list/hash
|
|
i = 0
|
|
loop do
|
|
if item_length == 3
|
|
if !contents[i][/^\d+$/]
|
|
raise _INTL("Expected a number in section {1}, got {2} instead", section_name, contents[i])
|
|
end
|
|
key = contents[i].to_i
|
|
i += 1
|
|
else
|
|
key = denormalize_value(contents[i])
|
|
key = Translation.stringToKey(key)
|
|
end
|
|
text_hash[key] = denormalize_value(contents[i + 1])
|
|
i += 2
|
|
break if i >= contents.length
|
|
end
|
|
# Add ordered list/hash (text_hash) to array of all text (all_text)
|
|
all_text[MessageTypes::EVENT_TEXTS] = [] if is_map && !all_text[MessageTypes::EVENT_TEXTS]
|
|
target_section = (is_map) ? all_text[MessageTypes::EVENT_TEXTS][section_id] : all_text[section_id]
|
|
if target_section
|
|
if text_hash.is_a?(Hash)
|
|
text_hash.each_key { |key| target_section[key] = text_hash[key] if text_hash[key] }
|
|
else # text_hash is an array
|
|
text_hash.each_with_index { |line, j| target_section[j] = line if line }
|
|
end
|
|
elsif is_map
|
|
all_text[MessageTypes::EVENT_TEXTS][section_id] = text_hash
|
|
else
|
|
all_text[section_id] = text_hash
|
|
end
|
|
end
|
|
ensure
|
|
file.close
|
|
end
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class Translation
|
|
attr_reader :core_messages, :game_messages
|
|
|
|
def self.stringToKey(str)
|
|
if str && str[/[\r\n\t\1]|^\s+|\s+$|\s{2,}/]
|
|
key = str.clone
|
|
key.gsub!(/^\s+/, "")
|
|
key.gsub!(/\s+$/, "")
|
|
key.gsub!(/\s{2,}/, " ")
|
|
return key
|
|
end
|
|
return str
|
|
end
|
|
|
|
def initialize(filename = nil, delay_load = false)
|
|
@default_core_messages = nil
|
|
@default_game_messages = nil
|
|
@core_messages = nil # A translation file
|
|
@game_messages = nil # A translation file
|
|
@filename = filename
|
|
load_message_files(@filename) if @filename && !delay_load
|
|
end
|
|
|
|
def default_core_messages
|
|
load_default_messages
|
|
return @default_core_messages
|
|
end
|
|
|
|
def default_game_messages
|
|
load_default_messages
|
|
return @default_game_messages
|
|
end
|
|
|
|
def load_message_files(filename)
|
|
begin
|
|
core_filename = sprintf("Data/messages_%s_core.dat", filename)
|
|
if safeExists?(core_filename)
|
|
pbRgssOpen(core_filename, "rb") { |f| @core_messages = Marshal.load(f) }
|
|
end
|
|
@core_messages = nil if !@core_messages.is_a?(Array)
|
|
game_filename = sprintf("Data/messages_%s_game.dat", filename)
|
|
if safeExists?(game_filename)
|
|
pbRgssOpen(game_filename, "rb") { |f| @game_messages = Marshal.load(f) }
|
|
end
|
|
@game_messages = nil if !@game_messages.is_a?(Array)
|
|
rescue
|
|
@core_messages = nil
|
|
@game_messages = nil
|
|
end
|
|
end
|
|
|
|
def load_default_messages
|
|
return if @default_core_messages
|
|
begin
|
|
if safeExists?("Data/messages_core.dat")
|
|
pbRgssOpen("Data/messages_core.dat", "rb") { |f| @default_core_messages = Marshal.load(f) }
|
|
end
|
|
@default_core_messages = [] if !@default_core_messages.is_a?(Array)
|
|
if safeExists?("Data/messages_game.dat")
|
|
pbRgssOpen("Data/messages_game.dat", "rb") { |f| @default_game_messages = Marshal.load(f) }
|
|
end
|
|
@default_game_messages = [] if !@default_game_messages.is_a?(Array)
|
|
rescue
|
|
@default_core_messages = []
|
|
@default_game_messages = []
|
|
end
|
|
end
|
|
|
|
def save_default_messages
|
|
File.open("Data/messages_core.dat", "wb") { |f| Marshal.dump(@default_core_messages, f) }
|
|
File.open("Data/messages_game.dat", "wb") { |f| Marshal.dump(@default_game_messages, f) }
|
|
end
|
|
|
|
def setMessages(type, array)
|
|
load_default_messages
|
|
@default_game_messages[type] = priv_add_to_array(type, array, nil)
|
|
end
|
|
|
|
def addMessages(type, array)
|
|
load_default_messages
|
|
@default_game_messages[type] = priv_add_to_array(type, array, @default_game_messages[type])
|
|
end
|
|
|
|
def setMessagesAsHash(type, array)
|
|
load_default_messages
|
|
@default_game_messages[type] = priv_add_to_hash(type, array, nil)
|
|
end
|
|
|
|
def addMessagesAsHash(type, array)
|
|
load_default_messages
|
|
@default_game_messages[type] = priv_add_to_hash(type, array, @default_game_messages[type])
|
|
end
|
|
|
|
def setMapMessagesAsHash(map_id, array)
|
|
load_default_messages
|
|
@default_game_messages[MessageTypes::EVENT_TEXTS] ||= []
|
|
@default_game_messages[MessageTypes::EVENT_TEXTS][map_id] = priv_add_to_hash(
|
|
MessageTypes::EVENT_TEXTS, array, nil, map_id
|
|
)
|
|
end
|
|
|
|
def addMapMessagesAsHash(map_id, array)
|
|
load_default_messages
|
|
@default_game_messages[MessageTypes::EVENT_TEXTS] ||= []
|
|
@default_game_messages[MessageTypes::EVENT_TEXTS][map_id] = priv_add_to_hash(
|
|
MessageTypes::EVENT_TEXTS, array, @default_game_messages[MessageTypes::EVENT_TEXTS][map_id], map_id
|
|
)
|
|
end
|
|
|
|
def get(type, id)
|
|
delayed_load_message_files
|
|
if @game_messages && @game_messages[type] && @game_messages[type][id]
|
|
return @game_messages[type][id]
|
|
end
|
|
if @core_messages && @core_messages[type] && @core_messages[type][id]
|
|
return @core_messages[type][id]
|
|
end
|
|
return ""
|
|
end
|
|
|
|
def getFromHash(type, text)
|
|
delayed_load_message_files
|
|
key = Translation.stringToKey(text)
|
|
return text if nil_or_empty?(key)
|
|
if @game_messages && @game_messages[type] && @game_messages[type][key]
|
|
return @game_messages[type][key]
|
|
end
|
|
if @core_messages && @core_messages[type] && @core_messages[type][key]
|
|
return @core_messages[type][key]
|
|
end
|
|
return text
|
|
end
|
|
|
|
def getFromMapHash(map_id, text)
|
|
delayed_load_message_files
|
|
key = Translation.stringToKey(text)
|
|
return text if nil_or_empty?(key)
|
|
if @game_messages && @game_messages[MessageTypes::EVENT_TEXTS]
|
|
if @game_messages[MessageTypes::EVENT_TEXTS][map_id] && @game_messages[MessageTypes::EVENT_TEXTS][map_id][key]
|
|
return @game_messages[MessageTypes::EVENT_TEXTS][map_id][key]
|
|
elsif @game_messages[MessageTypes::EVENT_TEXTS][0] && @game_messages[MessageTypes::EVENT_TEXTS][0][key]
|
|
return @game_messages[MessageTypes::EVENT_TEXTS][0][key]
|
|
end
|
|
end
|
|
if @core_messages && @core_messages[MessageTypes::EVENT_TEXTS]
|
|
if @core_messages[MessageTypes::EVENT_TEXTS][map_id] && @core_messages[MessageTypes::EVENT_TEXTS][map_id][key]
|
|
return @core_messages[MessageTypes::EVENT_TEXTS][map_id][key]
|
|
elsif @core_messages[MessageTypes::EVENT_TEXTS][0] && @core_messages[MessageTypes::EVENT_TEXTS][0][key]
|
|
return @core_messages[MessageTypes::EVENT_TEXTS][0][key]
|
|
end
|
|
end
|
|
return text
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
private
|
|
|
|
def delayed_load_message_files
|
|
return if !@filename || @core_messages
|
|
load_message_files(@filename)
|
|
@filename = nil
|
|
end
|
|
|
|
def priv_add_to_array(type, array, ret)
|
|
@default_core_messages[type] ||= []
|
|
ret = [] if !ret
|
|
array.each_with_index do |text, i|
|
|
ret[i] = text if !nil_or_empty?(text) && @default_core_messages[type][i] != text
|
|
end
|
|
return ret
|
|
end
|
|
|
|
def priv_add_to_hash(type, array, ret, map_id = 0)
|
|
if type == MessageTypes::EVENT_TEXTS
|
|
@default_core_messages[type] ||= []
|
|
@default_core_messages[type][map_id] ||= {}
|
|
default_keys = @default_core_messages[type][map_id].keys
|
|
else
|
|
@default_core_messages[type] ||= {}
|
|
default_keys = @default_core_messages[type].keys
|
|
end
|
|
ret = {} if !ret
|
|
array.each do |text|
|
|
next if !text
|
|
key = Translation.stringToKey(text)
|
|
ret[key] = text if !default_keys.include?(key)
|
|
end
|
|
return ret
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
module MessageTypes
|
|
# NOTE: These constants aren't numbered in any particular order, but these
|
|
# numbers are retained for backwards compatibility with older extracted
|
|
# text files.
|
|
EVENT_TEXTS = 0 # Used for text in both common events and map events
|
|
SPECIES_NAMES = 1
|
|
SPECIES_CATEGORIES = 2
|
|
POKEDEX_ENTRIES = 3
|
|
SPECIES_FORM_NAMES = 4
|
|
MOVE_NAMES = 5
|
|
MOVE_DESCRIPTIONS = 6
|
|
ITEM_NAMES = 7
|
|
ITEM_NAME_PLURALS = 8
|
|
ITEM_DESCRIPTIONS = 9
|
|
ABILITY_NAMES = 10
|
|
ABILITY_DESCRIPTIONS = 11
|
|
TYPE_NAMES = 12
|
|
TRAINER_TYPE_NAMES = 13
|
|
TRAINER_NAMES = 14
|
|
FRONTIER_INTRO_SPEECHES = 15
|
|
FRONTIER_END_SPEECHES_WIN = 16
|
|
FRONTIER_END_SPEECHES_LOSE = 17
|
|
REGION_NAMES = 18
|
|
REGION_LOCATION_NAMES = 19
|
|
REGION_LOCATION_DESCRIPTIONS = 20
|
|
MAP_NAMES = 21
|
|
PHONE_MESSAGES = 22
|
|
TRAINER_SPEECHES_LOSE = 23
|
|
SCRIPT_TEXTS = 24
|
|
RIBBON_NAMES = 25
|
|
RIBBON_DESCRIPTIONS = 26
|
|
STORAGE_CREATOR_NAME = 27
|
|
ITEM_PORTION_NAMES = 28
|
|
ITEM_PORTION_NAME_PLURALS = 29
|
|
POKEMON_NICKNAMES = 30
|
|
@@messages = Translation.new
|
|
|
|
def self.load_default_messages
|
|
@@messages.load_default_messages
|
|
end
|
|
|
|
def self.load_message_files(filename)
|
|
@@messages.load_message_files(filename)
|
|
end
|
|
|
|
def self.save_default_messages
|
|
@@messages.save_default_messages
|
|
end
|
|
|
|
def self.setMessages(type, array)
|
|
@@messages.setMessages(type, array)
|
|
end
|
|
|
|
def self.addMessages(type, array)
|
|
@@messages.addMessages(type, array)
|
|
end
|
|
|
|
def self.setMessagesAsHash(type, array)
|
|
@@messages.setMessagesAsHash(type, array)
|
|
end
|
|
|
|
def self.addMessagesAsHash(type, array)
|
|
@@messages.addMessagesAsHash(type, array)
|
|
end
|
|
|
|
def self.setMapMessagesAsHash(type, array)
|
|
@@messages.setMapMessagesAsHash(type, array)
|
|
end
|
|
|
|
def self.addMapMessagesAsHash(type, array)
|
|
@@messages.addMapMessagesAsHash(type, array)
|
|
end
|
|
|
|
def self.get(type, id)
|
|
return @@messages.get(type, id)
|
|
end
|
|
|
|
def self.getFromHash(type, key)
|
|
return @@messages.getFromHash(type, key)
|
|
end
|
|
|
|
def self.getFromMapHash(type, key)
|
|
return @@messages.getFromMapHash(type, key)
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
def pbGetMessage(type, id)
|
|
return MessageTypes.get(type, id)
|
|
end
|
|
|
|
def pbGetMessageFromHash(type, id)
|
|
return MessageTypes.getFromHash(type, id)
|
|
end
|
|
|
|
# Replaces first argument with a localized version and formats the other
|
|
# parameters by replacing {1}, {2}, etc. with those placeholders.
|
|
def _INTL(*arg)
|
|
begin
|
|
string = MessageTypes.getFromHash(MessageTypes::SCRIPT_TEXTS, arg[0])
|
|
rescue
|
|
string = arg[0]
|
|
end
|
|
string = string.clone
|
|
(1...arg.length).each do |i|
|
|
string.gsub!(/\{#{i}\}/, arg[i].to_s)
|
|
end
|
|
return string
|
|
end
|
|
|
|
# Replaces first argument with a localized version and formats the other
|
|
# parameters by replacing {1}, {2}, etc. with those placeholders.
|
|
# This version acts more like sprintf, supports e.g. {1:d} or {2:s}
|
|
def _ISPRINTF(*arg)
|
|
begin
|
|
string = MessageTypes.getFromHash(MessageTypes::SCRIPT_TEXTS, arg[0])
|
|
rescue
|
|
string = arg[0]
|
|
end
|
|
string = string.clone
|
|
(1...arg.length).each do |i|
|
|
string.gsub!(/\{#{i}\:([^\}]+?)\}/) { |m| next sprintf("%" + $1, arg[i]) }
|
|
end
|
|
return string
|
|
end
|
|
|
|
def _I(str, *arg)
|
|
return _MAPINTL($game_map.map_id, str, *arg)
|
|
end
|
|
|
|
def _MAPINTL(mapid, *arg)
|
|
string = MessageTypes.getFromMapHash(mapid, arg[0])
|
|
string = string.clone
|
|
(1...arg.length).each do |i|
|
|
string.gsub!(/\{#{i}\}/, arg[i].to_s)
|
|
end
|
|
return string
|
|
end
|
|
|
|
def _MAPISPRINTF(mapid, *arg)
|
|
string = MessageTypes.getFromMapHash(mapid, arg[0])
|
|
string = string.clone
|
|
(1...arg.length).each do |i|
|
|
string.gsub!(/\{#{i}\:([^\}]+?)\}/) { |m| next sprintf("%" + $1, arg[i]) }
|
|
end
|
|
return string
|
|
end
|