Skip to content

Instantly share code, notes, and snippets.

@pota-gon
Last active April 18, 2024 00:11
Show Gist options
  • Save pota-gon/a7192741484fe05c77e53b913ba89468 to your computer and use it in GitHub Desktop.
Save pota-gon/a7192741484fe05c77e53b913ba89468 to your computer and use it in GitHub Desktop.
RGSS3: MVプロジェクトデータ変換
# MVプロジェクトデータ変換 Ver0.5.1
# 概要
=begin
MVのプロジェクトデータをVXAceのrvdata2形式に変換します。
=end
# ◆ スクリプト利用規約
=begin
プロジェクトデータ変換後は、スクリプトを削除するため、
ゲームに組み込んで配布することはないと思いますが、
プロジェクトに組み込みたいという場合もあるかもしれないので、
MITライセンスでの配布とします。
Copyright (c) 2023 ポテトードラゴン
Released under the MIT License.
https://opensource.org/licenses/mit-license.php
=end
# ◆ TODO(正式版までに必要な作業)
=begin
・MZでアニメーションを出力しないようにする。
・イベントコマンドの動作チェック
=end
# ◆ 注意事項
=begin
このスクリプトは、VXAceのプロジェクトデータを書き換えます。
必ずVXAceのプロジェクトをバックアップしてください。
テストが不十分なため、エラーが発生する可能性があります。
=end
# ◆ 免責事項
=begin
プロジェクトが壊れた等のトラブルが発生しても、作者はいかなる責任を負いません。
=end
# ◆ 使い方
=begin
1. ▼ 設定項目 を必要に応じて変更します。
2. MVのプロジェクトをVXAceのプロジェクト(Game.exe と同じフォルダ)に配置する。
3. 必要に応じて、Audio や Graphics の画像を差し替えてください。
4. テストプレイを実施します。
=> このタイミングで、
設定項目の EXPORT_FOLDER のフォルダ(デフォルトは rvdata2) に
MVのプロジェクトデータをコンバートした *.rvdata2 が作成されます。
5. テストプレイを終了します。
6. プロジェクトを終了します。
7. 作成されたフォルダの *.rvdata2 を
VXAceのプロジェクトの Data フォルダに移動します。
8. プロジェクトを起動します。
=> このタイミングで、MVのデータに切り替わります。
後述しますが、MVとVXAceでは、データの仕様が異なる場合があるため、
必要に応じてデータを修正してください。
9. このスクリプトを削除します。
10. MVのプロジェクトを削除します。
=> この手順実施で、移行完了です。
=end
# ◆ バックアップについて
=begin
設定項目の BACKUP_FOLDER のフォルダ(デフォルトは backup) に
日付_時間 のフォルダ内に rvdata2 のバックアップが作成されます。
VXAceのプロジェクトデータが破損した場合は、バックアップフォルダ内の
rvdata2 を Data フォルダに配置して復旧してください。
トラブル防止のため、バックアップをOFFにする設定項目は用意していません。
=end
# ◆ Graphics ファイルについて
=begin
MVの画像とVXAceの画像は素材規格が異なります。
規格が異なるものは、画像変換ソフト等で、サイズを変換してください。
=end
# ◆ Audio ファイルについて
=begin
Audio 内のファイルが存在しない場合、以下のようなメッセージが出力されます。
メッセージの位置にファイルを配置して、再度テストプレイを実施してください。
ファイルが見つかりません:
Audio/BGM/Theme6
=end
# ◆ マップについて
=begin
VXAceのレイヤーは、MV のレイヤーより、1つ少ないため、
マップが崩れる場合があります。
イベントに変更するなどで対応できる場合があるため、
適宜、マップを修正してください。
=end
# ◆ 更新情報
=begin
Ver0.5.1 2023年 08月 15日(火)
スキルの計算式で、()を含む計算式が使えない場合があるバグ修正
Ver0.5.0 2023年 08月 13日(日)
開発版公開
=end
# 共通モジュール
module Potadra
# MVプロジェクトデータ変換用モジュール
module MVtoAce
#==============================================================================
# ▼ 設定項目 重要度:☆>◎>○>△ ×:設定を変えないほうがいいもの。
#==============================================================================
# ○ trueで、起動時にMVプロジェクトデータ変換を呼び出す。false:呼び出さない。
CALL = true
# △ MVプロジェクトデータ変換後、ゲームを続ける。
# 本サイトのスクリプトを複数導入する場合、trueにすること。
GAME_PLAY = true # true:ゲームを続ける。 false:ゲーム終了
# △ MVプロジェクトデータ変換にかかった時間の表示設定。
TIME_PRINT = true # true:実行時間表示 false:表示しない
#--------------------------------------------------------------------------
# ☆ 基本設定: MVプロジェクトデータ変換の基本設定をします。
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
# ○ バックアップフォルダ: バックアップを生成するフォルダ名を決めます。
#--------------------------------------------------------------------------
BACKUP_FOLDER = 'backup'
#--------------------------------------------------------------------------
# ○ 出力するフォルダ: rvdata2を出力するフォルダを設定します。
#--------------------------------------------------------------------------
EXPORT_FOLDER = 'rvdata2'
#==============================================================================
# ▲ 設定終了 以降は trueをfalse に変えたり、文字列を変更する必要はありません
#==============================================================================
# ○ フォルダ作成
# ・引数
# name : 作成するフォルダ名(デフォルト => "新しいフォルダ")
# path : 作成するフォルダのパス(デフォルト => "./")
# separator : 返値の後ろの区切り文字(デフォルト => "")
# ・返値
# 作成したフォルダのパス(ファイル名を含む) : フォルダの作成に成功したとき
# raise : フォルダの作成に失敗したとき
def create_folder(name = "新しいフォルダ", path = "./", separator = "")
# フォルダのパスを作成
folder = File.join(path, name)
# ファイルのパスを作成
file = folder.sub(/\/$/, "")
# フォルダと同名のファイルが存在する場合は、削除する。
File.delete(file) if File.file?(file)
# フォルダが存在していない場合、フォルダを作成する。
Dir.mkdir(folder) unless File.exist?(folder)
return file + separator
rescue
p "フォルダの作成に失敗しました。"
raise
end
end
end
#==============================================================================
# □ PotadraMVtoAce
#------------------------------------------------------------------------------
#  MVプロジェクトデータ変換クラスです。
#==============================================================================
class PotadraMVtoAce
# ライブラリ
include Potadra
include MVtoAce
# 正規表現
INT_REGEXP = /^-?\d+/
FLOAT_REGEXP = /^-?\d+?\.\d+/
U_SCORE_REGEXP = /(.*)([A-Z].*)/
UNDERSCORE_REGEXP = /(.*)([A-Z].*).*([A-Z].*)/
HASH_REGEXP = /\{(.+)\}/m
ARRAY_REGEXP = /\[(.+)\]/m
KEY_VALUE_REGEXP = /(.+?):(.+)/m
# nil として扱う文字列
NIL_STR = 'null'
# Aceのプロジェクト内にあるフォルダの一覧
ACE_DIRS = %w[Audio Data Graphics Movies System]
# MVのデータフォルダの名称
DATA_DIR = 'data'
# そのまま登録するカラム
ACTOR_COLUMNS = %w[
id name note
nickname class_id initial_level max_level character_name character_index
face_name face_index equips
]
CLASS_COLUMNS = %w[id name note exp_params]
SKILL_COLUMNS = %w[
id name icon_index description note
stype_id mp_cost tp_cost
message1 message2 required_wtype_id1 required_wtype_id2
scope occasion speed success_rate repeats tp_gain hit_type animation_id
]
ITEM_COLUMNS = %w[
id name icon_index description note
itype_id price consumable
scope occasion speed success_rate repeats tp_gain hit_type animation_id
]
WEAPON_COLUMNS = %w[
id name icon_index description note
wtype_id animation_id params price
]
ARMOR_COLUMNS = %w[
id name icon_index description note
atype_id params price
]
ENEMY_COLUMNS = %w[id name note battler_name battler_hue params exp gold]
TROOP_COLUMNS = %w[id name]
STATE_COLUMNS = %w[
id name icon_index note
restriction priority remove_at_battle_end remove_by_restriction
auto_removal_timing min_turns max_turns remove_by_damage chance_by_damage
remove_by_walking steps_to_remove message1 message2 message3 message4
]
ANIME_COLUMNS = %w[
id name animation1_name animation1_hue
animation2_name animation2_hue position
]
TILESET_COLUMNS = %w[id name mode tileset_names note]
COMMON_COLUMNS = %w[id name trigger switch_id]
SYSTEM_COLUMNS = %w[
game_title version_id party_members currency_unit elements skill_types
weapon_types armor_types switches variables title1_name title2_name
opt_draw_title opt_transparent opt_followers opt_slip_death opt_floor_death
opt_display_tp opt_extra_exp start_map_id start_x start_y test_troop_id
battleback1_name battleback2_name battler_name battler_hue edit_map_id
]
MAP_INFO_COLUMNS = %w[name parent_id order expanded scroll_x scroll_y]
MAP_COLUMNS = %w[
display_name tileset_id scroll_type specify_battleback
battleback1_name battleback2_name autoplay_bgm autoplay_bgs
disable_dashing encounter_step parallax_name parallax_loop_x
parallax_loop_y parallax_sx parallax_sy parallax_show note
]
# 共通
FEATURE_COLUMNS = %w[code data_id value] # 特徴
DAMAGE_COLUMNS = %w[type element_id formula variance critical] # ダメージ
EFFECT_COLUMNS = %w[code data_id value1 value2] # 使用効果リスト
# 職業
LEARNING_COLUMNS = %w[level skill_id note] # 習得するスキル
# 敵キャラ
DROP_ITEM_COLUMNS = %w[kind data_id denominator] # ドロップアイテム
ACTION_COLUMNS = %w[
skill_id condition_type condition_param1 condition_param2 rating
] # 行動パターン
# 敵グループ
MEMBER_COLUMNS = %w[enemy_id x y hidden] # 敵グループメンバー
CONDITION_COLUMNS = %w[
turn_ending turn_valid enemy_valid actor_valid switch_valid turn_a turn_b
enemy_index enemy_hp actor_id actor_hp switch_id
] # バトルイベントの [条件]
# アニメーション: SE とフラッシュのタイミング
TIMING_COLUMNS = %w[frame flash_scope flash_duration]
# システム
TEST_BATTLER_COLUMNS = %w[actor_id level equips] # 戦闘テスト
TERMS_COLUMNS = %w[basic params] # 用語
VEHICLE_COLUMNS = %w[
character_name character_index start_map_id start_x start_y
] # 乗り物
# マップ
ENCOUNTER_COLUMNS = %w[troop_id weight region_set] # エンカウント設定
# イベント
EVENT_COLUMNS = %w[id name x y] # イベント
EVENT_COMMAND_COLUMNS = %w[code indent] # イベントコマンド
PAGE_COLUMNS = %w[
move_type move_speed move_frequency walk_anime step_anime direction_fix
through priority_type trigger
] # イベントページ
PAGE_CONDITION_COLUMNS = %w[
switch1_valid switch2_valid variable_valid self_switch_valid item_valid
actor_valid switch1_id switch2_id variable_id variable_value
self_switch_ch item_id actor_id
] # イベントページの [条件]
PAGE_GRAPHIC_COLUMNS = %w[
tile_id character_name character_index direction pattern
] # イベントページの [グラフィック]
MOVE_ROUTE_COLUMNS = %w[repeat skippable wait] # 移動ルート
# その他
AUDIO_COLUMNS = %w[name volume pitch] # Audio
#--------------------------------------------------------------------------
# ○ メイン処理
#--------------------------------------------------------------------------
def main
# 時間計測開始
start = Time.new
# ● 通常のデータベースをロード
DataManager.load_normal_database
# ○ バックアップフォルダ作成処理
path = create_folder(BACKUP_FOLDER)
backup_path = create_folder(start.strftime('%Y%m%d_%H%M%S'), path)
# ○ バックアップ
backup(backup_path)
# ○ プロジェクトを探す
@project_path, @data_path = find_project
# ○ フォルダ作成
create_folder(EXPORT_FOLDER)
# アクター
create_data('Actors', RPG::Actor, ACTOR_COLUMNS, true) do |datum, c_datum|
datum.description = c_datum['profile']
end
# 職業
create_data('Classes', RPG::Class, CLASS_COLUMNS, true) do |datum, c_datum|
datum.learnings = create_learnings(c_datum['learnings'])
datum.params = create_params(c_datum)
end
# スキル
create_data('Skills', RPG::Skill, SKILL_COLUMNS) do |datum, c_datum|
datum.damage = create_damage(c_datum['damage'])
datum.effects = create_effects(c_datum['effects'])
end
# アイテム
create_data('Items', RPG::Item, ITEM_COLUMNS) do |datum, c_datum|
datum.damage = create_damage(c_datum['damage'])
datum.effects = create_effects(c_datum['effects'])
end
# 武器
create_data('Weapons', RPG::Weapon, WEAPON_COLUMNS, true)
# 防具
create_data('Armors', RPG::Armor, ARMOR_COLUMNS, true) do |datum, c_datum|
datum.etype_id = c_datum['etype_id'] - 1
end
# 敵キャラ
create_data('Enemies', RPG::Enemy, ENEMY_COLUMNS, true) do |datum, c_datum|
datum.drop_items = create_drop_items(c_datum['drop_items'])
datum.actions = create_actions(c_datum['actions'])
end
# 敵グループ
create_data('Troops', RPG::Troop, TROOP_COLUMNS) do |datum, c_datum|
datum.members = create_members(c_datum['members'])
datum.pages = create_troop_pages(c_datum)
end
# ステート
create_data('States', RPG::State, STATE_COLUMNS, true)
# アニメーション
create_data('Animations', RPG::Animation, ANIME_COLUMNS) do |datum, c_datum|
next if c_datum['frames'].nil? # MZ の場合は、アニメーションをスキップ
datum.frame_max = c_datum['frames'].size
datum.frames = create_frames(c_datum)
datum.timings = create_timings(c_datum)
end
# タイルセット
create_data('Tilesets', RPG::Tileset, TILESET_COLUMNS) do |datum, c_datum|
datum.flags = create_tables(c_datum['flags'], 8192)
end
# コモンイベント
create_data('CommonEvents', RPG::CommonEvent,
COMMON_COLUMNS) do |datum, c_datum|
datum.list = create_pages(c_datum)
end
# システム
if pre_create_hash('System')
@datum = RPG::System.new
# VXAceのみの設定はそのままにする
@datum.opt_use_midi = $data_system.opt_use_midi
@datum.battle_end_me = $data_system.battle_end_me
create_hash(SYSTEM_COLUMNS) do |key, value|
@datum.japanese = (value == 'ja_JP') if key == 'locale'
@datum.window_tone = Tone.new(*value) if key == 'window_tone'
@datum.boat = create_vehicle(value) if key == 'boat'
@datum.ship = create_vehicle(value) if key == 'ship'
@datum.airship = create_vehicle(value) if key == 'airship'
@datum.title_bgm = create_bgm(value) if key == 'title_bgm'
@datum.battle_bgm = create_bgm(value) if key == 'battle_bgm'
@datum.gameover_me = create_me(value) if key == 'gameover_me'
@datum.sounds = create_sounds(value) if key == 'sounds'
# 用語
create_terms(value) if key == 'terms'
# 戦闘テストのパーティ設定
create_test_battlers(value) if key == 'test_battlers'
end
end
# ○ マップ情報
create_map_infos
# マップ
Dir.glob(File.join(@data_path, 'Map*')) do |map|
base_name = File.basename(map, '.json')
next if base_name == 'MapInfos' || !pre_create_hash(base_name)
w = @c_data['width']
h = @c_data['height']
@datum = RPG::Map.new(w, h)
create_hash(MAP_COLUMNS) do |key, value|
@datum.bgm = create_bgm(value) if key == 'bgm'
@datum.bgs = create_bgs(value) if key == 'bgs'
create_encounter_list(value) if key == 'encounter_list'
create_map_data(value, w, h) if key == 'data'
create_events(value) if key == 'events'
end
end
# 実行時間表示
p "MVプロジェクトデータ変換:#{Time.now - start}秒" if TIME_PRINT
# 終了処理
exit unless GAME_PLAY
end
#--------------------------------------------------------------------------
# ○ プロジェクトを探す
#--------------------------------------------------------------------------
def find_project
project_path = nil
data_path = nil
Dir.glob('*').each do |path|
next if ACE_DIRS.include?(path) || File.file?(path)
data_path = File.join(path, DATA_DIR)
if File.exist?(data_path)
project_path = path
break
end
end
if project_path.nil?
msgbox("VXAceプロジェクトにMVのプロジェクトがありません。\r\n" \
'変換したいプロジェクトを1つ配置してください。')
exit
end
[project_path, data_path]
end
#--------------------------------------------------------------------------
# ○ バックアップ
#--------------------------------------------------------------------------
def backup(path)
save_data($data_actors, File.join(path, 'Actors.rvdata2'))
save_data($data_classes, File.join(path, 'Classes.rvdata2'))
save_data($data_skills, File.join(path, 'Skills.rvdata2'))
save_data($data_items, File.join(path, 'Items.rvdata2'))
save_data($data_weapons, File.join(path, 'Weapons.rvdata2'))
save_data($data_armors, File.join(path, 'Armors.rvdata2'))
save_data($data_enemies, File.join(path, 'Enemies.rvdata2'))
save_data($data_troops, File.join(path, 'Troops.rvdata2'))
save_data($data_states, File.join(path, 'States.rvdata2'))
save_data($data_animations, File.join(path, 'Animations.rvdata2'))
save_data($data_tilesets, File.join(path, 'Tilesets.rvdata2'))
save_data($data_common_events, File.join(path, 'CommonEvents.rvdata2'))
save_data($data_system, File.join(path, 'System.rvdata2'))
save_data($data_mapinfos, File.join(path, 'MapInfos.rvdata2'))
# ○ マップバックアップ処理
map_backup(path)
rescue
p 'バックアップに失敗しました。'
raise
end
#--------------------------------------------------------------------------
# ○ マップバックアップ処理
#--------------------------------------------------------------------------
def map_backup(path)
return true if $data_mapinfos.empty?
$data_mapinfos.keys.each do |id|
# マップを00Xになるように設定
name = format('%03d', id)
# マップの読み込み・バックアップ
$data_map = load_data("Data/Map#{name}.rvdata2")
save_data($data_map, File.join(path, "Map#{name}.rvdata2"))
end
end
#--------------------------------------------------------------------------
# ○ マップ情報
#--------------------------------------------------------------------------
def create_map_infos
return false unless pre_create_hash('MapInfos')
datum = {}
@c_data.each_with_index do |c_datum, id|
next if c_datum.nil?
datum[id] = create_hash_datum(c_datum, RPG::MapInfo, MAP_INFO_COLUMNS)
end
save_data(datum, File.join(EXPORT_FOLDER, "#{@type}.rvdata2"))
end
#--------------------------------------------------------------------------
# ○ 配列データ作成
#--------------------------------------------------------------------------
def create_data(type, rpg_class, columns, feature = false)
start_str = read_file(type)
return false unless start_str
create_message(type)
c_data = format_data(start_str)
data = []
c_data.each do |c_datum|
if c_datum.nil?
data << nil
next
end
datum = rpg_class.new
columns.each do |column|
datum.send("#{column}=", c_datum[column])
end
# 特徴
if feature
datum.features = create_hash_data(
c_datum['traits'], RPG::BaseItem::Feature, FEATURE_COLUMNS
)
end
yield(datum, c_datum) if block_given?
data.push(datum)
end
return false if data.empty? || (data.size == 1 && data[0].nil?)
save_data(data, File.join(EXPORT_FOLDER, "#{type}.rvdata2"))
end
#--------------------------------------------------------------------------
# ○ ハッシュデータ作成準備
#--------------------------------------------------------------------------
def pre_create_hash(type)
@type = type
start_str = read_file(type)
return false unless start_str
@c_data = format_data(start_str)
true
end
#--------------------------------------------------------------------------
# ○ ハッシュデータ作成
#--------------------------------------------------------------------------
def create_hash(columns)
create_message(@type)
@c_data.each do |key, value|
@datum.send("#{key}=", value) if columns.include?(key)
yield(key, value)
end
save_data(@datum, File.join(EXPORT_FOLDER, "#{@type}.rvdata2"))
end
#--------------------------------------------------------------------------
# ○ ファイル読み込み
#--------------------------------------------------------------------------
def read_file(type)
path = File.join(@data_path, "#{type}.json")
unless File.exist?(path)
p "#{path} が存在しないため、#{type}のコンバートをスキップします。"
return false
end
File.read(path)
end
#--------------------------------------------------------------------------
# ○ 複数データの整形
#--------------------------------------------------------------------------
def format_data(start_str)
format_hash = false
return [] if start_str == '[]'
return {} if start_str == '{}'
case start_str[0]
when '{'
start_str =~ HASH_REGEXP
format_hash = true
when '['
start_str =~ ARRAY_REGEXP
else
return start_str if start_str.include?(':')
return cast(escape_value(start_str))
end
str = $1
tmp_str = ''
c_data = []
array_count = 0
hash_count = 0
quote_mode = false
before_char = ''
str.each_char do |c|
tmp_str << c
if before_char != '\\' && c == '"'
quote_mode ^= true
before_char = c
next
end
before_char = c
next if quote_mode
case c
when '{'
next unless array_count == 0
hash_count += 1
when '}'
next unless array_count == 0
hash_count -= 1
when '['
next unless hash_count == 0
array_count += 1
when ']'
next unless hash_count == 0
array_count -= 1
when ','
next unless array_count == 0
next unless hash_count == 0
unless tmp_str.empty?
c_data << tmp_str.chop.strip
tmp_str = ''
end
end
end
c_data << tmp_str.strip
data = []
c_data.each do |c_datum|
if c_datum == NIL_STR
data << nil
else
data << format_data(c_datum)
end
end
data = format_datum(data) if format_hash
data
end
#--------------------------------------------------------------------------
# ○ データの整形
#--------------------------------------------------------------------------
def format_datum(c_data)
datum = {}
c_data.each do |c_datum|
c_datum =~ /(.+?):(.+)/m
key = $1
value = $2
case value[0]
when '{', '['
value = format_data(value)
end
datum[underscore(escape_key(key))] = cast(escape_value(value))
end
datum
end
#--------------------------------------------------------------------------
# ○ keyエスケープ
#--------------------------------------------------------------------------
def escape_key(key)
key.gsub('"', '')
end
#--------------------------------------------------------------------------
# ○ valueエスケープ
#--------------------------------------------------------------------------
def escape_value(value)
if value.is_a?(String)
value =~ /\"(.+)\"/
$1 ? $1.gsub('\n', "\r\n") : value.gsub('\n', "\r\n")
else
value
end
end
#--------------------------------------------------------------------------
# ○ スネークケース: MV(json) => VXAce(rvdata2)
#--------------------------------------------------------------------------
def underscore(key)
case key
when UNDERSCORE_REGEXP
"#{$1}_#{$2.downcase}_#{$3.downcase}"
when U_SCORE_REGEXP
"#{$1}_#{$2.downcase}"
else
key
end
end
#--------------------------------------------------------------------------
# ○ 文字列キャスト
#--------------------------------------------------------------------------
def cast(value)
case value
when '""'
''
when 'true'
true
when 'false'
false
when FLOAT_REGEXP
value.to_f
when INT_REGEXP
if value.to_i.to_s == value
value.to_i
else
value
end
else
value
end
end
#--------------------------------------------------------------------------
# ○ 共通: rvdata2 の出力中のメッセージ
#--------------------------------------------------------------------------
def create_message(type)
p "#{type}.rvdata2 を出力中..."
end
#--------------------------------------------------------------------------
# ○ 共通: 複数ハッシュデータ作成
#--------------------------------------------------------------------------
def create_hash_data(c_data, rpg_class, columns)
data = []
c_data.each do |d|
data << create_hash_datum(d, rpg_class, columns)
end
data
end
#--------------------------------------------------------------------------
# ○ 共通: ハッシュデータ作成
#--------------------------------------------------------------------------
def create_hash_datum(c_datum, rpg_class, columns)
datum = rpg_class.new
columns.each do |column|
datum.send("#{column}=", c_datum[column])
end
datum
end
#--------------------------------------------------------------------------
# ○ 共通: Table作成
#--------------------------------------------------------------------------
def create_tables(c_data, number)
tables = Table.new(number)
c_data.each_with_index do |table, i|
tables[i] = table
end
tables
end
#--------------------------------------------------------------------------
# ○ 共通: BGM
#--------------------------------------------------------------------------
def create_bgm(value)
create_hash_datum(value, RPG::BGM, AUDIO_COLUMNS)
end
#--------------------------------------------------------------------------
# ○ 共通: BGS
#--------------------------------------------------------------------------
def create_bgs(value)
create_hash_datum(value, RPG::BGS, AUDIO_COLUMNS)
end
#--------------------------------------------------------------------------
# ○ 共通: ME
#--------------------------------------------------------------------------
def create_me(value)
create_hash_datum(value, RPG::ME, AUDIO_COLUMNS)
end
#--------------------------------------------------------------------------
# ○ 共通: SE
#--------------------------------------------------------------------------
def create_se(value)
create_hash_datum(value, RPG::SE, AUDIO_COLUMNS)
end
#--------------------------------------------------------------------------
# ○ 職業: 習得するスキル
#--------------------------------------------------------------------------
def create_learnings(learnings)
create_hash_data(learnings, RPG::Class::Learning, LEARNING_COLUMNS)
end
#--------------------------------------------------------------------------
# ○ 職業: 能力値成長曲線
#--------------------------------------------------------------------------
def create_params(c_datum)
params = Table.new(8, 100)
(0..7).each do |i|
(1..99).each do |j|
if c_datum['params'][i][j]
params[i, j] = c_datum['params'][i][j]
end
end
end
params
end
#--------------------------------------------------------------------------
# ○ スキル・アイテム: ダメージ
#--------------------------------------------------------------------------
def create_damage(damage)
create_hash_datum(damage, RPG::UsableItem::Damage, DAMAGE_COLUMNS)
end
#--------------------------------------------------------------------------
# ○ スキル・アイテム: 使用効果
#--------------------------------------------------------------------------
def create_effects(effects)
create_hash_data(effects, RPG::UsableItem::Effect, EFFECT_COLUMNS)
end
#--------------------------------------------------------------------------
# ○ 敵キャラ: ドロップアイテム
#--------------------------------------------------------------------------
def create_drop_items(drop_items)
create_hash_data(drop_items, RPG::Enemy::DropItem, DROP_ITEM_COLUMNS)
end
#--------------------------------------------------------------------------
# ○ 敵キャラ: 行動パターン
#--------------------------------------------------------------------------
def create_actions(actions)
create_hash_data(actions, RPG::Enemy::Action, ACTION_COLUMNS)
end
#--------------------------------------------------------------------------
# ○ 敵グループ: メンバー
#--------------------------------------------------------------------------
def create_members(members)
create_hash_data(members, RPG::Troop::Member, MEMBER_COLUMNS)
end
#--------------------------------------------------------------------------
# ○ 敵グループ: バトルイベント (ページ)
#--------------------------------------------------------------------------
def create_troop_pages(c_datum)
pages = []
c_datum['pages'].each do |c_page|
page = RPG::Troop::Page.new
# condition
page.condition = create_hash_datum(
c_page['conditions'], RPG::Troop::Page::Condition, CONDITION_COLUMNS
)
# span
page.span = c_page['span']
# list
page.list = create_pages(c_page)
pages << page
end
pages
end
#--------------------------------------------------------------------------
# ○ アニメーション: フレーム
#--------------------------------------------------------------------------
def create_frames(c_datum)
frames = []
c_datum['frames'].each do |c_frames|
frame = RPG::Animation::Frame.new
# cell_max
cell_max = c_frames.size
frame.cell_max = cell_max
# cell_data
frame.cell_data = Table.new(cell_max)
c_frames.each do |c_cells|
c_cells.each_with_index do |cell, i|
frame.cell_data[i] = cell
end
end
frames << frame
end
frames
end
#--------------------------------------------------------------------------
# ○ アニメーション: SE とフラッシュのタイミング
#--------------------------------------------------------------------------
def create_timings(c_datum)
timings = []
c_datum['timings'].each do |c_timing|
timing = create_hash_datum(
c_timing, RPG::Animation::Timing, TIMING_COLUMNS
)
timing.se = create_se(c_timing['se'])
timing.flash_color = Color.new(*c_timing['flash_color'])
timings << timing
end
timings
end
#--------------------------------------------------------------------------
# ○ システム: 乗り物
#--------------------------------------------------------------------------
def create_vehicle(value)
vehicle = create_hash_datum(value, RPG::System::Vehicle, VEHICLE_COLUMNS)
vehicle.bgm = create_bgm(value['bgm'])
vehicle
end
#--------------------------------------------------------------------------
# ○ システム: 効果音
#--------------------------------------------------------------------------
def create_sounds(value)
create_hash_data(value, RPG::SE, AUDIO_COLUMNS)
end
#--------------------------------------------------------------------------
# ○ システム: 用語
#--------------------------------------------------------------------------
def create_terms(value)
@datum.terms = create_hash_datum(
value, RPG::System::Terms, TERMS_COLUMNS
)
# equip_types
etypes = []
@c_data['equip_types'].each_with_index do |etype, i|
next if i == 0
etypes << etype
break if i == 4
end
@datum.terms.etypes = etypes
# commands
commands = @datum.terms.commands
@c_data['terms']['commands'].each_with_index do |command, i|
if i == 20 # シャットダウンはそのまま
commands[i] = $data_system.terms.commands[20]
else
commands[i] = command
end
end
@datum.terms.commands = commands
end
#--------------------------------------------------------------------------
# ○ システム: 戦闘テストのパーティ設定
#--------------------------------------------------------------------------
def create_test_battlers(value)
@datum.test_battlers = create_hash_data(
value, RPG::System::TestBattler, TEST_BATTLER_COLUMNS
)
end
#--------------------------------------------------------------------------
# ○ マップ: エンカウント設定
#--------------------------------------------------------------------------
def create_encounter_list(value)
@datum.encounter_list = create_hash_data(
value, RPG::Map::Encounter, ENCOUNTER_COLUMNS
)
end
#--------------------------------------------------------------------------
# ○ マップ: マップデータ
#--------------------------------------------------------------------------
def create_map_data(value, w, h)
@datum.data = Table.new(w, h, 4)
(0..w).each do |x|
(0..h).each do |y|
# 下層
(0..1).each do |z|
@datum.data[x, y, z] = get_tile_id(value, x, y, z, h, w)
end
# 上層
tile_id = get_tile_id(value, x, y, 2, h, w)
@datum.data[x, y, 2] = tile_id
@datum.data[x, y, 2] = get_tile_id(value, x, y, 3, h, w) if tile_id == 0
# 影ペン・リージョン
shadow = get_tile_id(value, x, y, 4, h, w)
region = get_tile_id(value, x, y, 5, h, w)
if region && region != 0
@datum.data[x, y, 3] = shadow + ((region) << 8)
else
@datum.data[x, y, 3] = shadow
end
end
end
end
#--------------------------------------------------------------------------
# ○ マップ: タイルID取得
#--------------------------------------------------------------------------
def get_tile_id(value, x, y, z, h, w)
v = value[x + ( y + z * h ) * w]
v.nil? ? 0 : v # nil(null) だとエラーが発生するため 0 を返す
end
#--------------------------------------------------------------------------
# ○ マップ: イベント
#--------------------------------------------------------------------------
def create_events(value)
events = {}
value.each do |c_event|
next if c_event.nil? || c_event.empty?
x = c_event['x']
y = c_event['y']
event = RPG::Event.new(x, y)
EVENT_COLUMNS.each do |column|
event.send("#{column}=", c_event[column])
end
# pages
pages = []
c_event['pages'].each do |c_page|
page = create_hash_datum(c_page, RPG::Event::Page, PAGE_COLUMNS)
# condition
page.condition = create_condition(c_page['conditions'])
# graphic
page.graphic = create_graphic(c_page['image'])
# move_route
page.move_route = create_move_route(c_page['move_route'])
# list
page.list = create_pages(c_page)
pages << page
end
event.pages = pages
events[c_event['id']] = event
end
@datum.events = events
end
#--------------------------------------------------------------------------
# ○ マップ: イベントページの [条件]
#--------------------------------------------------------------------------
def create_condition(conditions)
create_hash_datum(
conditions, RPG::Event::Page::Condition, PAGE_CONDITION_COLUMNS
)
end
#--------------------------------------------------------------------------
# ○ マップ: イベントページの [グラフィック]
#--------------------------------------------------------------------------
def create_graphic(image)
create_hash_datum(
image, RPG::Event::Page::Graphic, PAGE_GRAPHIC_COLUMNS
)
end
#--------------------------------------------------------------------------
# ○ イベント共通: イベント (ページ)
#--------------------------------------------------------------------------
def create_pages(c_page)
data = []
c_page['list'].each do |c_datum|
datum = RPG::EventCommand.new
EVENT_COMMAND_COLUMNS.each do |column|
datum.send("#{column}=", c_datum[column])
end
# TODO : コマンドのパラメータごとにクラスにする。
datum.parameters = convert_event(c_datum['code'], c_datum['parameters'])
data << datum
end
data
end
#--------------------------------------------------------------------------
# ○ イベント共通: イベント (コンバート)
#--------------------------------------------------------------------------
def convert_event(code, parameters)
params = parameters
case code
when 132, 241 # BGM
params[0] = create_bgm(parameters[0])
when 245 # BGS
params[0] = create_bgs(parameters[0])
when 133, 249 # ME
params[0] = create_me(parameters[0])
when 250 # SE
params[0] = create_se(parameters[0])
when 205 # 移動ルート
params[1] = create_move_route(parameters[1])
when 505 # 移動ルートの表示用(移動コマンド)?
params[0] = create_move_command(parameters[0])
end
params
end
#--------------------------------------------------------------------------
# ○ イベント共通: 移動ルート
#--------------------------------------------------------------------------
def create_move_route(c_move_route)
move_route = create_hash_datum(
c_move_route, RPG::MoveRoute, MOVE_ROUTE_COLUMNS
)
list = []
c_move_route['list'].each do |c_datum|
datum = RPG::MoveCommand.new
datum.code = c_datum['code']
if c_datum['parameters']
datum.parameters = convert_route(c_datum['code'], c_datum['parameters'])
end
list << datum
end
move_route.list = list
move_route
end
#--------------------------------------------------------------------------
# ○ イベント共通: 移動ルート (コンバート)
#--------------------------------------------------------------------------
def convert_route(code, parameters)
params = parameters
case code
when 44 # SE
params[0] = create_se(parameters[0])
end
params
end
#--------------------------------------------------------------------------
# ○ イベント共通: 移動ルートの表示用(移動コマンド)?
#--------------------------------------------------------------------------
def create_move_command(c_datum)
datum = RPG::MoveCommand.new
datum.code = c_datum['code']
if c_datum['parameters']
datum.parameters = convert_route(c_datum['code'], c_datum['parameters'])
end
datum
end
end
# メイン関数呼び出し
PotadraMVtoAce.new.main if Potadra::MVtoAce::CALL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment