Last active
April 18, 2024 00:11
-
-
Save pota-gon/a7192741484fe05c77e53b913ba89468 to your computer and use it in GitHub Desktop.
RGSS3: MVプロジェクトデータ変換
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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