=begin CSV入出力テストforツクールXP (2010/07/19)         by 半生 http://www.tktkgame.com http://www11.atpages.jp/namahanka/ ・CsvOut.export_actors  アクターデータをCSVで出力 ・CsvOut.import_actors  CSVのアクターデータを"Data/Actors.rxdata"に取り込み =end module SimpleCSV module_function # ダブルクォーテーションのエスケープ他 def csv_escape(param, dq=true) param = param.to_s unless param.is_a?(String) if param.include?("\"") dq = true param = param.gsub("\"","\001").gsub("\001","\"\"") elsif param.include?(",") dq = true end if dq return "\"#{param}\"" else return "#{param}" end end # ダブルクォーテーションのアンエスケープ def csv_unescape(str) data = str.sub(/^\s*\"?/,"").sub(/\"?\s*$/,"") return data.gsub("\"\"","\001").gsub("\001","\"") end # 二次元配列をCSV文字列に変換 def ary2csv(lines, sep=",") text = "" lines.each do |line| text += line.map{|param| csv_escape(param)}.join(sep) text += "\n" end return text end # CSV一行を一次元配列に分解 def csv_split_line(str, sep=",") line_datas = [] tmp_datas = str.split(sep) tmp = "" tmp_datas.each do |item| tmp += item if tmp.count("\"") % 2 == 0 data = csv_unescape(tmp) line_datas.push(data) tmp = "" else tmp += sep end end if tmp != "" raise("CSVデータの解析に失敗しました。列分解") end return line_datas end # CSVの文字列を二次元配列に変換 def csv2ary(str) lines = [] datas = [] tmp_lines = str.split("\n") tmp_data = "" tmp_lines.each do |tmp_line| tmp_data += tmp_line if tmp_data.count("\"") % 2 == 0 lines.push(tmp_data) tmp_data = "" else tmp_data += "\n" end end if tmp_data != "" raise("CSVデータの解析に失敗しました。行分解") end lines.each do |line| datas.push(csv_split_line(line)) end return datas end end # 文字コード変換 module CConv CP_ACP = 0 CP_UTF8 = 65001 @m2w = Win32API.new('kernel32', 'MultiByteToWideChar', 'ilpipi', 'i') @w2m = Win32API.new('kernel32', 'WideCharToMultiByte', 'ilpipipp', 'i') module_function def s2u8(str) # Shift-Jis => UTF16 len = @m2w.call(CP_ACP, 0, str + "\000", -1, nil, 0); buf1 = "\000" * 2 * len @m2w.call(CP_ACP, 0, str, -1, buf1, len); # UTF16 => UTF8 len = @w2m.call(CP_UTF8, 0, buf1, -1, nil, 0, nil, nil); buf2 = "\000" * len @w2m.call(CP_UTF8, 0, buf1, -1, buf2, len, nil, nil); return buf2[0..-2] end def u82s(str) # UTF8 => UTF16 len = @m2w.call(CP_UTF8, 0, str + "\000", -1, nil, 0); buf1 = "\000" * 2 * len @m2w.call(CP_UTF8, 0, str, -1, buf1, len); # UTF16 => Shift-Jis len = @w2m.call(CP_ACP, 0, buf1, -1, nil, 0, nil, nil); buf2 = "\000" * len @w2m.call(CP_ACP, 0, buf1, -1, buf2, len, nil, nil); return buf2[0..-2] end end module CsvOut ACTOR_PARAMS = ["MaxHP","MaxSP","腕力","器用さ","素早さ","魔力"] LABEL_LEVEL = ["\# レベル"] + (1..99).to_a module_function def load_csv(filename) file = open(filename,"r") str = file.read file.close data = CConv::s2u8(str) return SimpleCSV::csv2ary(data) end def save_csv(filename, ary) text = SimpleCSV::ary2csv(ary) text = CConv::u82s(text) open(filename, "w") {|file| file.print(text) } end def export_actors actors = load_data("Data/Actors.rxdata") open("Actors.csv", "w") {|file| file.print(CConv.u82s("\"人数\",\"#{actors.size - 1}\"")) } actors.each do |actor| next if actor.nil? filename = sprintf("Actor%03d.csv", actor.id) save_csv(filename, get_actor_datas(actor)) end end def get_actor_datas(actor) lines = [] lines.push(["ID", actor.id]) lines.push(["名前", actor.name]) lines.push(["クラスID", actor.class_id]) lines.push(["初期レベル", actor.initial_level]) lines.push(["最終レベル", actor.final_level]) lines.push(["Exp基本値", actor.exp_basis]) lines.push(["Exp増加度", actor.exp_inflation]) lines.push(["キャラ画像", actor.character_name]) lines.push(["キャラ色相", actor.character_hue]) lines.push(["バトラー画像", actor.battler_name]) lines.push(["バトラー色相", actor.battler_hue]) lines.push(LABEL_LEVEL) for param_no in 0..5 params = [ACTOR_PARAMS[param_no]] for lv in 1..99 params.push(actor.parameters[param_no, lv]) end lines.push(params) end lines.push(["武器ID", actor.weapon_id]) lines.push(["盾ID", actor.armor1_id]) lines.push(["兜ID", actor.armor2_id]) lines.push(["鎧ID", actor.armor3_id]) lines.push(["装飾ID", actor.armor4_id]) lines.push(["武器固定フラグ", actor.weapon_fix]) lines.push(["盾固定フラグ", actor.armor1_fix]) lines.push(["兜固定フラグ", actor.armor2_fix]) lines.push(["鎧固定フラグ", actor.armor3_fix]) lines.push(["装飾固定フラグ", actor.armor4_fix]) end def set_actor_datas(lines, actor=RPG::Actor.new) lines.each do |line| case line.first when "ID" actor.id = line[1].to_i when "名前" actor.name = line[1] when "クラスID" actor.class_id = line[1].to_i when "初期レベル" actor.initial_level = line[1].to_i when "最終レベル" actor.final_level = line[1].to_i when "Exp基本値" actor.exp_basis = line[1].to_i when "Exp増加度" actor.exp_inflation = line[1].to_i when "キャラ画像" actor.character_name = line[1] when "キャラ色相" actor.character_hue = line[1].to_i when "バトラー画像" actor.battler_name = line[1] when "バトラー色相" actor.battler_hue = line[1].to_i when ACTOR_PARAMS[0] for level in 1..99 actor.parameters[0, level] = line[level + 1].to_i end when ACTOR_PARAMS[1] for level in 1..99 actor.parameters[1, level] = line[level + 1].to_i end when ACTOR_PARAMS[2] for level in 1..99 actor.parameters[2, level] = line[level + 1].to_i end when ACTOR_PARAMS[3] for level in 1..99 actor.parameters[3, level] = line[level + 1].to_i end when ACTOR_PARAMS[4] for level in 1..99 actor.parameters[4, level] = line[level + 1].to_i end when ACTOR_PARAMS[5] for level in 1..99 actor.parameters[5, level] = line[level + 1].to_i end when "武器ID" actor.weapon_id = line[1].to_i when "盾ID" actor.armor1_id = line[1].to_i when "兜ID" actor.armor2_id = line[1].to_i when "鎧ID" actor.armor3_id = line[1].to_i when "装飾ID" actor.armor4_id = line[1].to_i when "武器固定フラグ" actor.weapon_fix = (line[1].downcase == "true") when "盾固定フラグ" actor.armor1_fix = (line[1].downcase == "true") when "兜固定フラグ" actor.armor2_fix = (line[1].downcase == "true") when "鎧固定フラグ" actor.armor3_fix = (line[1].downcase == "true") when "装飾固定フラグ" actor.armor4_fix = (line[1].downcase == "true") end end return actor end def import_actors(filename="Actors.csv") unless FileTest.exist?(filename) p "CSVデータが見つかりませんでした。" return end actors = [nil] general = load_csv(filename) actor_size = general[0][1].to_i actor_size.times do |i| actor_id = i + 1 datas = load_csv(sprintf("Actor%03d.csv", actor_id)) actors.push(set_actor_datas(datas)) end save_data(actors, "Data/Actors.rxdata") end end