Под влиянием и при помощи некоторых товарищей написал простенький экспортер / импортер диалогов и БД игры.
Могут спросить, зачем оно, когда есть DrеaMaker?
Отвечаю по списку:
- DreaMaker - сторонняя программа, и работает в отрыве от мейкера. Вариант на скриптах же интересен тем, что текст можно загрузить на ходу, что позволит сделать, например, выбор языка при старте игры (как сделано в приложенной к топику демке)
- Энтузиасты, вроде Эльфа, замотивируются и допишут, наконец, аналогичный скрипт для ACE, под который, насколько мне известно, DreaMaker не существует
- В будущем, используя классы XP типа Window_Message, я планирую сделать подгонку текста под размер окна диалогов, учитывая часть системных значений, типа \w[21] - иконка+название оружия. Это поможет, в первую очередь, при переводе на языки типа немецкого (где там в интернетах эта картинка про длины слов? )
Итак, скрипт (положить выше main):
#===============================================================================
=begin
Автор - caveman + DeadElf79
Версия 1.03
Экспорт и импорт диалогов
Сделано по аналогии с DreaMaker, но внутри XP
История изменений:
1.02 - исправлен импорт выбора; добавлен экспорт/импорт для common events
1.03 - вывод разных типов объектов отделен друг от друга; добавлен экспорт/импорт для базы
=end
#===============================================================================
$max_maps=999
$counter=0
class Game_Event
attr_accessor :erased
def g_event
return @event
end
end
class Game_Map
def g_map
return @map
end
end
class Dial_Extract
#=============================================================================
# Необходимая инициализация
#=============================================================================
def initialize
$data_actors = load_data("Data/Actors.rxdata")
$data_classes = load_data("Data/Classes.rxdata")
$data_skills = load_data("Data/Skills.rxdata")
$data_items = load_data("Data/Items.rxdata")
$data_weapons = load_data("Data/Weapons.rxdata")
$data_armors = load_data("Data/Armors.rxdata")
$data_enemies = load_data("Data/Enemies.rxdata")
$data_troops = load_data("Data/Troops.rxdata")
$data_states = load_data("Data/States.rxdata")
$data_animations = load_data("Data/Animations.rxdata")
$data_tilesets = load_data("Data/Tilesets.rxdata")
$data_common_events = load_data("Data/CommonEvents.rxdata")
$data_system = load_data("Data/System.rxdata")
$data_mapinfos = load_data("Data/MapInfos.rxdata")
$game_system = Game_System.new
$game_temp = Game_Temp.new
$game_system = Game_System.new
$game_switches = Game_Switches.new
$game_variables = Game_Variables.new
$game_self_switches = Game_SelfSwitches.new
$game_screen = Game_Screen.new
$game_actors = Game_Actors.new
$game_party = Game_Party.new
$game_troop = Game_Troop.new
$game_map = Game_Map.new
$game_player = Game_Player.new
$game_party.setup_starting_members
end
#=============================================================================
# Функции для вызова
#=============================================================================
def export(filename)
@file=File.open(filename,"w")
export_database
$counter = 0
@file.write("=================== COMMON EVENTS ===================" + "\n")
export_common_events
$counter = 0
@file.write("=================== MAPS ===================" + "\n")
for map in 1..$max_maps
if FileTest.exist?(sprintf("Data/Map%03d.rxdata",map))
export_map(map)
else
next
end
end
@file.close
exit
end
def import(filename)
@file=File.open(filename,"r")
@lines = @file.readlines
@line = 0
import_database
@line += 1 # == COMMON EVENTS ==
import_common_events
@line += 1 # == MAPS ==
for map in 1..$max_maps
if FileTest.exist?(sprintf("Data/Map%03d.rxdata",map))
import_map(map)
save_data($game_map.g_map, sprintf("Data/Map%03d.rxdata", map))
else
next
end
end
save_data($data_mapinfos, "Data/MapInfos.rxdata")
save_data($data_common_events, "Data/CommonEvents.rxdata")
@file.close
end
#=============================================================================
# Экспорт и импорт Базы
#=============================================================================
def export_database
@file.write("=================== ACTORS ===================" + "\n")
for i in 1...$data_actors.size
text = i.to_s + ":" + $data_actors[i].name
@file.write(text + "\n")
end
@file.write("=================== CLASSES ===================" + "\n")
for i in 1...$data_classes.size
text = i.to_s + ":" + $data_classes[i].name
@file.write(text + "\n")
end
@file.write("=================== SKILLS ===================" + "\n")
for i in 1...$data_skills.size
text = i.to_s + ":" + $data_skills[i].name
@file.write(text + "\n")
@file.write($data_skills[i].description + "\n")
end
@file.write("=================== ITEMS ===================" + "\n")
for i in 1...$data_items.size
text = i.to_s + ":" + $data_items[i].name
@file.write(text + "\n")
@file.write($data_items[i].description + "\n")
end
@file.write("=================== WEAPONS ===================" + "\n")
for i in 1...$data_weapons.size
text = i.to_s + ":" + $data_weapons[i].name
@file.write(text + "\n")
@file.write($data_weapons[i].description + "\n")
end
@file.write("=================== ARMORS ===================" + "\n")
for i in 1...$data_armors.size
text = i.to_s + ":" + $data_armors[i].name
@file.write(text + "\n")
@file.write($data_armors[i].description + "\n")
end
@file.write("=================== ENEMIES ===================" + "\n")
for i in 1...$data_enemies.size
text = i.to_s + ":" + $data_enemies[i].name
@file.write(text + "\n")
end
@file.write("=================== TROOPS ===================" + "\n")
for i in 1...$data_troops.size
text = i.to_s + ":" + $data_troops[i].name
@file.write(text + "\n")
end
@file.write("=================== STATES ===================" + "\n")
for i in 1...$data_states.size
text = i.to_s + ":" + $data_states[i].name
@file.write(text + "\n")
end
@file.write("=================== ANIMATIONS ===================" + "\n")
for i in 1...$data_animations.size
text = i.to_s + ":" + $data_animations[i].name
@file.write(text + "\n")
end
@file.write("=================== TILESETS ===================" + "\n")
for i in 1...$data_tilesets.size
text = i.to_s + ":" + $data_tilesets[i].name
@file.write(text + "\n")
end
@file.write("=================== SYSTEM ===================" + "\n")
@file.write("ELEMENTS:" + "\n")
for i in 1...$data_system.elements.size
text = i.to_s + ":" + $data_system.elements[i]
@file.write(text + "\n")
end
@file.write("WORDS:" + "\n")
@file.write("gold:" + $data_system.words.gold + "\n")
@file.write("hp:" + $data_system.words.hp + "\n")
@file.write("sp:" + $data_system.words.sp + "\n")
@file.write("str:" + $data_system.words.str + "\n")
@file.write("dex:" + $data_system.words.dex + "\n")
@file.write("agi:" + $data_system.words.agi + "\n")
@file.write("int:" + $data_system.words.int + "\n")
@file.write("atk:" + $data_system.words.atk + "\n")
@file.write("pdef:" + $data_system.words.pdef + "\n")
@file.write("mdef:" + $data_system.words.mdef + "\n")
@file.write("weapon:" + $data_system.words.weapon + "\n")
@file.write("armor1:" + $data_system.words.armor1 + "\n")
@file.write("armor2:" + $data_system.words.armor2 + "\n")
@file.write("armor3:" + $data_system.words.armor3 + "\n")
@file.write("armor4:" + $data_system.words.armor4 + "\n")
@file.write("attack:" + $data_system.words.attack + "\n")
@file.write("skill:" + $data_system.words.skill + "\n")
@file.write("guard:" + $data_system.words.guard + "\n")
@file.write("item:" + $data_system.words.item + "\n")
@file.write("equip:" + $data_system.words.equip + "\n")
end
def import_database
@line += 1 #"=================== ACTORS ==================="
for i in 1...$data_actors.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_actors[i].name = $2.to_s
end
@line += 1
end
@line += 1 #"=================== CLASSES ==================="
for i in 1...$data_classes.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_classes[i].name = $2.to_s
end
@line += 1
end
@line += 1 #"=================== SKILLS ==================="
for i in 1...$data_skills.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_skills[i].name = $2.to_s
end
@line += 1
$data_skills[i].description = @lines[@line]
@line += 1
end
@line += 1 #"=================== ITEMS ==================="
for i in 1...$data_items.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_items[i].name = $2.to_s
end
@line += 1
$data_items[i].description = @lines[@line]
@line += 1
end
@line += 1 #"=================== WEAPONS ==================="
for i in 1...$data_weapons.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_weapons[i].name = $2.to_s
end
@line += 1
$data_weapons[i].description = @lines[@line]
@line += 1
end
@line += 1 #"=================== ARMORS ==================="
for i in 1...$data_armors.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_armors[i].name = $2.to_s
end
@line += 1
$data_armors[i].description = @lines[@line]
@line += 1
end
@line += 1 #"=================== ENEMIES ==================="
for i in 1...$data_enemies.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_enemies[i].name = $2.to_s
end
@line += 1
end
@line += 1 #"=================== TROOPS ==================="
for i in 1...$data_troops.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_troops[i].name = $2.to_s
end
@line += 1
end
@line += 1 #"=================== STATES ==================="
for i in 1...$data_states.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_states[i].name = $2.to_s
end
@line += 1
end
@line += 1 #"=================== ANIMATIONS ==================="
for i in 1...$data_animations.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_animations[i].name = $2.to_s
end
@line += 1
end
@line += 1 #"=================== TILESETS ==================="
for i in 1...$data_tilesets.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_tilesets[i].name = $2.to_s
end
@line += 1
end
@line += 1 #"=================== SYSTEM ==================="
@line += 1 # "ELEMENTS:"
for i in 1...$data_system.elements.size
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.elements[i] = $2.to_s
end
@line += 1
end
@line += 1 # "WORDS:"
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.gold = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.hp = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.sp = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.str = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.dex = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.agi = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.int = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.atk = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.pdef = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.mdef = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.weapon = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.armor1 = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.armor2 = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.armor3 = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.armor4 = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.attack = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.skill = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.guard = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.item = $2.to_s
end
@line += 1
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_system.words.equip = $2.to_s
end
@line += 1
save_data($data_actors, "Data/Actors.rxdata")
save_data($data_classes, "Data/Classes.rxdata")
save_data($data_skills, "Data/Skills.rxdata")
save_data($data_items, "Data/Items.rxdata")
save_data($data_weapons, "Data/Weapons.rxdata")
save_data($data_armors, "Data/Armors.rxdata")
save_data($data_enemies, "Data/Enemies.rxdata")
save_data($data_troops, "Data/Troops.rxdata")
save_data($data_states, "Data/States.rxdata")
save_data($data_animations, "Data/Animations.rxdata")
save_data($data_tilesets, "Data/Tilesets.rxdata")
save_data($data_system, "Data/System.rxdata")
end
#=============================================================================
# Экспорт и импорт COMMON EVENTS
#=============================================================================
def export_common_events
for i in 1...$data_common_events.size
ev_text = "common_event_id:" + i.to_s
@file.write(ev_text + "\n")
ev_text = "common_event_name:" + $data_common_events[i].name
@file.write(ev_text + "\n")
list = $data_common_events[i].list
if list != nil
for command in list
str4=""
case command.code
when 101
wait_flag = true
$counter+=1
@file.write((sprintf("%07d",$counter))+":")
@file.write("#{command.parameters[0]}"+"\n")
when 401 #message
if wait_flag
@file.write("#{command.parameters[0]}"+"\n")
end
when 102 #choices
wait_flag = false
$counter+=1
@file.write((sprintf("%07d",$counter))+":")
@file.write("CHOICE"+"\n")
for j in 0...command.parameters[0].size
@file.write("#{command.parameters[0][j]}"+"\n")
end
else
wait_flag = false
end
end
end
end
end
def import_common_events
choices = []
for i in 1...$data_common_events.size
@line += 1 # common_event_id
# common_event_name
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
$data_common_events[i].name = $2.to_s
end
@line += 1
list = $data_common_events[i].list
if list != nil
for command in list
case command.code
when 101 #message start
wait_flag = true
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
command.parameters[0] = $2.to_s
end
@line += 1
when 401 #message continue
if wait_flag
@lines[@line].gsub(/\A(.+?)\Z/) do
command.parameters[0] = $1.to_s
@line += 1
end
end
when 102 #choices list
wait_flag = false
@line += 1 # отметка CHOICE
for j in 0...command.parameters[0].size
@lines[@line].gsub(/\A(.+?)\Z/) do
command.parameters[0][j] = $1.to_s
choices.push($1.to_s)
@line += 1
end
end
choices.reverse! # нам нужен не стек, а очередь!
when 402 #choice
wait_flag = false
command.parameters[1] = choices.pop
else
wait_flag = false
end
end
end
end
end
#=============================================================================
# Экспорт и импорт карт
#=============================================================================
def export_map(map_id)
map_text = "=================== MAP " + map_id.to_s
map_text = map_text + " ==================="
@file.write(map_text + "\n")
str4="[map_name=#{$data_mapinfos[map_id].name}]"
@file.write((sprintf("%07d",$counter))+":#{str4}\n")
$game_map = Game_Map.new
$game_map.setup(map_id)
events=$game_map.events
wait_flag = true
for i in 1..9999
if events[i]!=nil
ev_text = "event_id:" + i.to_s
@file.write(ev_text + "\n")
for page in events[i].g_event.pages
unless page.list.nil?
for command in page.list
str4=""
case command.code
when 101
wait_flag = true
$counter+=1
@file.write((sprintf("%07d",$counter))+":")
@file.write("#{command.parameters[0]}"+"\n")
when 401 #message
if wait_flag
@file.write("#{command.parameters[0]}"+"\n")
end
when 102 #choices
wait_flag = false
$counter+=1
@file.write((sprintf("%07d",$counter))+":")
@file.write("CHOICE"+"\n")
for j in 0...command.parameters[0].size
@file.write("#{command.parameters[0][j]}"+"\n")
end
else
wait_flag = false
end
end
end
end
end
end
end
def import_map(map_id)
@line += 1 # == MAP map_id ==
$game_map = Game_Map.new
$game_map.setup(map_id)
events=$game_map.events
choices = []
@lines[@line].gsub(/\A(.+?)\[(.+?)\=(.+?)\]\Z/) do
$data_mapinfos[map_id].name = $3.to_s
end
@line += 1
wait_flag = true
for i in 1..9999
if events[i]!=nil
@line += 1 # event_id
for page in events[i].g_event.pages
unless page.list.nil?
for command in page.list
case command.code
when 101 #message start
wait_flag = true
@lines[@line].gsub(/\A(.+?)\:(.+?)\Z/) do
command.parameters[0] = $2.to_s
end
@line += 1
when 401 #message continue
if wait_flag
@lines[@line].gsub(/\A(.+?)\Z/) do
command.parameters[0] = $1.to_s
@line += 1
end
end
when 102 #choices list
wait_flag = false
@line += 1 # отметка CHOICE
for j in 0...command.parameters[0].size
@lines[@line].gsub(/\A(.+?)\Z/) do
command.parameters[0][j] = $1.to_s
choices.push($1.to_s)
@line += 1
end
end
choices.reverse! # нам нужен не стек, а очередь!
when 402 #choice
wait_flag = false
command.parameters[1] = choices.pop
else
wait_flag = false
end
end
end
end
end
end
end
end
Он умеет экспортировать текст, выборы и названия карт в текстовый файл простого формата, а также импортировать его обратно (обратите внимание, что для того, чтобы увидеть изменения в редакторе Maker XP, нужно его перезагрузить)
Вызов команд простой:
@extractor = Dial_Extract.new
- создать экземпляр класса экстрактора
@extractor.export("dials.txt")
- экспортировать диалоги в файл dials.txt
@extractor.import("dials.txt")
- импортировать диалоги из файла dials.txt
На закуску - демка, в которой добавлен еще один класс
Scene_Language, вызывающийся перед титульным экраном (в Main вместо
$scene = Scene_Title.new =>
$scene = Scene_Language.new), позволяющий выбрать язык перед началом игры.
В папке с демой лежит экспортированный файл dials_rus.txt и, кривопереведенный, dials_eng.txt. Нужный файл подгружается на лету и меняет язык диалогов и названия карты.
yadi.sk/d/UEacESFV6iOMj
Скрипт будет дорабатываться, избавляться от багов, если таковые проявятся, и будет дополнен реализацией пункта три из объяснения.