注册会员 登录
Project1 返回首页

喵呜喵5的树洞 https://rpg.blue/?291206 [收藏] [复制] [分享] [RSS]

日志

【脚本】导入、导出文本

热度 7已有 4919 次阅读2014-3-11 19:33 |个人分类:脚本

=begin
===============================================================================
  导入、导出文本 By喵呜喵5
===============================================================================

【说明】

  将每个事件的文本导出到单独的TXT文件中去  
  修改TXT的内容后可以把这些内容再重新导入回游戏中
  
  可以让文本量较大的游戏能够更方便的对每一句对话进行纠错
  也可以方便汉化组对游戏的汉化
  
  使用过程中碰到什么BUG请及时汇报
  
  【关于使用的一些注意事项】
  
  使用本脚本前请备份好你的工程,我不负责修复任何因为本脚本造成的工程数据丢失  
  游戏正式发布时请删除这个脚本
  
  请不要删除导出的TXT中的特殊符号,否则导入将出现异常
  
  请不要在导出的TXT中添加原本没有的换行(比如一行空格),否则导入将出现异常
  
  显示文字指令中两个特殊符号之间(默认为●●、●●之间)的内容不受上一条的制约
  你可以随意增加显示内容的长短,即使与原本的文本行数不同也没有关系
  
  由于编辑器的限制,导入后的内容在编辑器中会出现下面两种情况:
  1.显示文字指令显示的内容超过4行
  2.显示选项指令中《显示选项XXX》和《如果选择XXX》的提示不符合
  重新编辑这个指令(不需要修改文字)可以使编辑器中显示的内容恢复正常
  即使没有重新编辑这些指令,实际运行游戏时也不会出现什么问题
  
=end
#==============================================================================
# 设定部分
#==============================================================================

   M5MARK = "●"
  
  #这里设置一个【永远不会】在对话文本中出现的特殊符号
  #(导入文本时包含这个特殊符号的行将被忽略)
  #(可以用这个符号来实现给TXT添加注释的效果,
  #  包含这个符号的行将不会被导入进游戏中)
  
  M5MARK2 = "○"
  
  #这里再设置一个【永远不会】在对话文本中出现的特殊符号
  #(这个符号表示显示了一段空白的文字,请不要删除文本中的这个特殊符号)
  
  SCRIPT = false   # true / false
  
  #需要导出/导入事件中的脚本的话这里填写true
  #如果事件脚本中没有包含显示的文字的话,导入以及导出其实没有什么意义(还可能出错)
  
  COMMON = true   # true / false
  
  #需要导出/导入公共事件中的文本的话这里填写true
  
  TROOP = true    # true / false
  
  #需要导出/导入敌群事件中的文本的话这里填写true
  
  #【姓名表】
  #(设置姓名表可以增加导出后TXT的可读性,角色姓名的判断依赖于对话时显示的脸图)
  #(即使不设置姓名表,本脚本仍然可以正常的进行导入、导出的操作)
  
  NAMELIST = {
  
  #从这里开始添加姓名
  #添加的格式为:
  # "脸图的文件名" => ["第一个角色的姓名","第二个角色的姓名","第X个角色的姓名"],
  #(注意标点符号,特别是最后的逗号)
  #角色依照脸图从左至右从上至下的顺序排列
  
  "Actor1" => ["拉尔夫","女人","男人","吴莉嘉","劳伦斯"], 
  "Actor2" => ["男人","女人","班尼特","女人","男人","伊尔维亚"], 
  "Actor3" => ["男人","薇拉","艾尔玛"], 
  "Actor4" => ["艾里克","娜塔丽","泰伦斯","女人","阿奈思特","女人","龙马"],    
  "Actor5" => ["男人","布伦达","瑞克","女人","男人","爱丽丝","诺亚","伊萨贝拉"],  
  
  #添加姓名结束
  }
  
  
  
  LOADMODE = true  # true / false
  
  #需要导入修改好了的文本的话,这里修改为false
  
  
  
#==============================================================================
# 设定结束
#==============================================================================
#==============================================================================
# 脚本部分
#==============================================================================  
def read_txt(file_name)
  @file = @temp_text = []
  @text = nil
  @text_flag = false
  IO.foreach("Event/#{file_name}.txt") do |line|
    @text = line.split("\n")[0]
    if @text and @text.include?("#{M5MARK}#{M5MARK}")        
      if @text_flag
        @text_flag = false
        @file.push(@temp_text)
      else
        @text_flag = true
        @temp_text = []
      end
    else
      @temp_text.push("#{@text ? @text : ""}") if @text_flag          
      @file.push(@text) if !@text_flag and @text
    end
  end
  @file.delete_if{|text| text.include? "#{M5MARK}"}
end
def save_event_list(event_list)
  @ignor_times = 0
  event_list.each_with_index do |command,index|
    next if ((@ignor_times -= 1) > 0 )
    case command.code
    when 401,405
      @all_text = @file.delete_at(0).reverse
      @ignor_times = @all_text.size
      old = index + @all_text.size
      while @all_text != []
        text = @all_text.delete_at(0)
        text = "" if text == M5MARK2
        event_list.insert(index,RPG::EventCommand.new(command.code,command.indent,[text]))
      end
      while event_list[old].code == 401 or event_list[old].code == 405
        event_list.delete_at(old)
      end
    when 102
      command.parameters[0].size.times do |choice|
        command.parameters[0][choice] = @file.delete_at(0)
      end
    when 655
      next unless SCRIPT
      @ignor_times = @all_text.size
      old = index + @all_text.size
      while @all_text != []
        text = @all_text.delete_at(0)
        event_list.insert(index,RPG::EventCommand.new(655,command.indent,[text]))
      end
      while event_list[old].code == 655
        event_list.delete_at(old)
      end
    when 355
      next unless SCRIPT
      @all_text = @file.delete_at(0)
      command.parameters[0] = @all_text.delete_at(0)
      @all_text.reverse!
    end
  end
end
def save_map_event
  map_list = load_data("Data/MapInfos.rvdata2").keys
  map_list.each do |map_id|
    read_txt("地图#{map_id}")
    map = load_data(sprintf("Data/Map%03d.rvdata2",map_id))
    map.events.keys.each do |event_id|      
      map.events[event_id].pages.each do |page|
        save_event_list(page.list)
      end
    end
    save_data(map,sprintf("Data/Map%03d.rvdata2",map_id))
  end
end
def save_common_event
  read_txt("公共事件")
  file = load_data("Data/CommonEvents.rvdata2")
  file.each do |event|
    save_event_list(event.list) if event
  end
  save_data(file,"Data/CommonEvents.rvdata2")
end
def save_troop_event
  file = load_data("Data/Troops.rvdata2")
  file.each do |troop|
    next if !troop
    read_txt("敌群#{troop.id}")
    troop.pages.each do |page|
      save_event_list(page.list)
    end
  end
  save_data(file,"Data/Troops.rvdata2")
end
def load_event_list(event_list)
  @text_flag = false
  event_list.each do |command|
    case command.code
    when 101
      check_text_flag
      face = command.parameters[0]
      face_index = command.parameters[1]
      if face == ""
        @file_content += ("#{M5MARK}显示了一段文字:\n")
      else
        if NAMELIST[face] and NAMELIST[face][command.parameters[1]]
          @file_content += ("#{M5MARK}#{NAMELIST[face][face_index]}说:\n")
        else
          @file_content += ("#{M5MARK}#{face}(#{face_index})说:\n")
        end
      end
      open_text_flag
    when 401 ,405
      text_temp = command.parameters[0] == "" ? M5MARK2 : command.parameters[0]      
      @file_content += ("#{text_temp}\n")
    when 105
      check_text_flag
      @file_content += ("#{M5MARK}显示了滚动文字:\n")
      open_text_flag
    when 102
      check_text_flag
      @file_content += ("#{M5MARK}显示了选项:\n")
      number = command.parameters[0].size
      command.parameters[0].each_with_index do |cho,ind|                
        @file_content += ("#{cho}\n#{ind +1 != number ? "#{M5MARK}以及\n":""}")
      end
    when 355
      next unless SCRIPT
      check_text_flag      
      @file_content += ("#{M5MARK}运行了代码:\n")
      open_text_flag
      @file_content += ("#{command.parameters[0]}\n")
    when 655
      next unless SCRIPT
      @file_content += ("#{command.parameters[0]}\n")
    end
  end
  check_text_flag
  @file_content += ("\n")
end
def check_text_flag
  return if !@text_flag  
  @text_flag = false
  @file_content += ("#{M5MARK}#{M5MARK}\n")
end
def open_text_flag
  @text_flag = true
  @file_content += ("#{M5MARK}#{M5MARK}\n")
end
def load_map_event
  file = load_data("Data/MapInfos.rvdata2")
  file.keys.each do |map_id|
    map = load_data(sprintf("Data/Map%03d.rvdata2",map_id))
    @file_content = "#{M5MARK}《#{file[map_id].name}#{map.display_name != "" ? "(#{map.display_name})" : ""}》\n\n"
    event = map.events
    event.keys.each do |event_id|
      @file_content += ("#{M5MARK}#{event[event_id].name}(#{event_id}号事件):\n")
      event[event_id].pages.each_with_index do |event_page,index|
        @file_content += ("#{M5MARK}<事件页#{index + 1}>\n")
        load_event_list(event_page.list)
      end
    end
    save_text("地图#{map_id}",@file_content)
  end
end
def load_common_event
  file = load_data("Data/CommonEvents.rvdata2")
  @file_content = "#{M5MARK}《公共事件》\n\n"
  file.each do |event|
    next if !event    
    @file_content += ("#{M5MARK}#{event.name}(#{event.id}号公共事件):\n")    
    load_event_list(event.list)
  end
  save_text("公共事件",@file_content)
end
def load_troop_event
  file = load_data("Data/Troops.rvdata2")
  file.each do |troop|
    next if !troop
    @file_content = "#{M5MARK}《#{troop.name}(#{troop.id}号敌群)》\n\n"    
    troop.pages.each_with_index do |event_page,index|
      @file_content += ("#{M5MARK}<事件页#{index + 1}>\n")
      load_event_list(event_page.list)
    end
    save_text("敌群#{troop.id}",@file_content)
  end
end
def save_text(name,word)
  content = File.open("Event/#{name}.txt",'w')
  content.puts word
  content.close
end
if LOADMODE
  Dir.mkdir("Event") if !File.directory?("Event")
  load_map_event
  load_common_event if COMMON
  load_troop_event if TROOP
  msgbox "导出完毕!\n导出的游戏文本保存在游戏工程的Event目录下"
else
  save_map_event
  save_common_event if COMMON
  save_troop_event if TROOP
  msgbox "导入完毕!#{$TEST ? "\n请重新启动编辑器以查看效果" : ""}"
end
exit
1

鸡蛋
2

鲜花

刚表态过的朋友 (3 人)

发表评论 评论 (14 个评论)

回复 飛揚寒星 2014-3-16 17:26
经过测试发现一个bug……
如果有两层以上的“显示选项”,导入时会错位

另外,如果修改的文字比原文行数少,必须手动填上空白符○
如果能够由“●显示了一段文字”来判断对话显示的分割就好了……
回复 喵呜喵5 2014-3-16 17:35
飛揚寒星: 经过测试发现一个bug……
如果有两层以上的“显示选项”,导入时会错位

另外,如果修改的文字比原文行数少,必须手动填上空白符○
如果能够由“●显示了一段文 ...
前一个导入错位的问题我之后去看看,
VA默认的文字数据就是以行为单位进行记录的,某一行空缺的话替换的内容自然会错位,以显示文字这句话作为标志的话我得稍微想想看怎么实现(正则捕捉,批量插入,删除空白的对话指令...)........
回复 飛揚寒星 2014-3-16 18:57
我发现所有的“显示选项”都移位了,后面多了只有一格空格的一行。
用批量替换的功能去掉这些空格之后重新导入,错位的问题就解决了。
回复 飛揚寒星 2014-3-16 19:03
喵呜喵5: 前一个导入错位的问题我之后去看看,
VA默认的文字数据就是以行为单位进行记录的,某一行空缺的话替换的内容自然会错位,以显示文字这句话作为标志的话我得稍微 ...
嗯,其实手动填上空白符○也就是工程量稍微大了一点,其实还是可行的
如果以“●显示了一段文字”来分割的方法太过复杂的话也容易出bug……orz
其实也考虑过是不是能用外部程序来读取,不使用RM自带的Ruby脚本功能,不过这样还得破解RM VA地图的格式|||像目前2000、2003和XP都有人做出直接导入导出文本的工具(Dreamaker),不过可惜的是它不适用于VX和VA……
最后谢谢你的回复www
回复 飛揚寒星 2014-3-16 19:55
刚刚发现导入的时候,所有的“显示选项”的内容都还是原本的样子,并没有成功导入,不知道是怎么回事。
回复 喵呜喵5 2014-3-16 20:26
飛揚寒星: 刚刚发现导入的时候,所有的“显示选项”的内容都还是原本的样子,并没有成功导入,不知道是怎么回事。
我之后去看看
回复 喵呜喵5 2014-3-17 16:25
飛揚寒星: 刚刚发现导入的时候,所有的“显示选项”的内容都还是原本的样子,并没有成功导入,不知道是怎么回事。
显示选项部分的导入已经修复,你自己试试看还有没有什么问题,另外编辑器中会出现“显示选项XXX”和“如果选择XXX”的提示不符合的情况,实际运行游戏时会发现选项已经导入了,并没有什么大问题,我再去看看有没有办法刷新编辑器的提示……
回复 喵呜喵5 2014-3-17 17:50
飛揚寒星: 嗯,其实手动填上空白符○也就是工程量稍微大了一点,其实还是可行的
如果以“●显示了一段文字”来分割的方法太过复杂的话也容易出bug……orz
其实也考虑过是不 ...
现在可以自动判断对话的长短了
回复 飛揚寒星 2014-3-19 14:57
喵呜喵5: 现在可以自动判断对话的长短了
抱歉再次打扰。
刚刚试着用新的脚本导出,然后不改Event内容直接导入时,出现错误

脚本“”第 123 行:发生 NoMethodError 。

undefined method `reverse' for nil:NilClass
回复 喵呜喵5 2014-3-19 17:47
飛揚寒星: 抱歉再次打扰。
刚刚试着用新的脚本导出,然后不改Event内容直接导入时,出现错误

脚本“”第 123 行:发生 NoMethodError 。

undefined method `reverse' for ...
抱歉是我疏忽了,今天没网,明天我会更新修正这个问题并能够导出敌群以及公共事件的版本
回复 喵呜喵5 2014-3-20 12:16
飛揚寒星: 抱歉再次打扰。
刚刚试着用新的脚本导出,然后不改Event内容直接导入时,出现错误

脚本“”第 123 行:发生 NoMethodError 。

undefined method `reverse' for ...
脚本已更新,请试试看这个问题是否还存在
回复 飛揚寒星 2014-3-20 19:16
喵呜喵5: 脚本已更新,请试试看这个问题是否还存在
已经测试过,导入和导出都没问题了,谢谢喵呜喵5君!
回复 Wimeael 2020-2-18 12:05
请问发生"第136行:发生NoMethodError。undefined method 'delete_ _at' for " ":String“应该怎么办qwq?
回复 喵呜喵5 2020-2-18 14:08
Wimeael: 请问发生&quot;第136行:发生NoMethodError。undefined method 'delete_ _at' for &quot; &quot;:String“应该怎么办qwq?
有没有使用什么特殊的脚本改过事件?

facelist doodle 涂鸦笔

您需要登录后才可以评论 登录 | 注册会员

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-19 14:04

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

返回顶部