Last active
September 6, 2024 14:45
-
-
Save UserUnknownFactor/4e700940079109f2430078534f163504 to your computer and use it in GitHub Desktop.
Unpacker/repacker for RPG Maker XP, VX [Ace] games
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
require 'zlib' | |
# Some data structures that are common to both VX and VX Ace. | |
class Rect | |
def initialize(x, y, width, height) | |
@x = x | |
@y = y | |
@width = width | |
@height = height | |
end | |
class << self | |
def _load(s) | |
end | |
end | |
end | |
class Tone | |
def initialize(red, green, blue, gray = 0.0) | |
@red = red | |
@green = green | |
@blue = blue | |
@gray = gray | |
end | |
def _dump(d = 0) | |
[@red].pack('d') + [@green].pack('d') + [@blue].pack('d') + [@gray].pack('d') | |
end | |
class << self | |
def _load(s) | |
red = s[0,8].unpack('d')[0] | |
blue = s[8,8].unpack('d')[0] | |
green = s[16,8].unpack('d')[0] | |
gray = s[24,8].unpack('d')[0] | |
Tone.new(red, blue, green, gray) | |
end | |
end | |
end | |
class Color | |
def initialize(red, green, blue, alpha = 255.0) | |
@red = red | |
@green = green | |
@blue = blue | |
@alpha = alpha | |
end | |
def _dump(d = 0) | |
[@red].pack('d') + [@green].pack('d') + [@blue].pack('d') + [@alpha].pack('d') | |
end | |
class << self | |
def _load(s) | |
red = s[0,8].unpack('d')[0] | |
blue = s[8,8].unpack('d')[0] | |
green = s[16,8].unpack('d')[0] | |
alpha = s[24,8].unpack('d')[0] | |
Color.new(red, blue, green, alpha) | |
end | |
end | |
end | |
class Table | |
def initialize(x, y = nil, z = nil) | |
@dims = 1 + (y.nil?() ? 0:1) + (z.nil?() ? 0:1) | |
@xsize = x | |
@ysize = y.nil?() ? 1:y | |
@zsize = z.nil?() ? 1:z | |
@data=Array.new(@xsize*@ysize*@zsize, 0) | |
end | |
def [](x, y = 0, z = 0) | |
@data[x + y*@xsize + z*@xsize*@ysize] | |
end | |
def []=(*args) | |
x = args[0] | |
y = args.size>2 ? args[1]:0 | |
z = args.size>3 ? args[2]:0 | |
v = args.pop | |
@data[x + y*@xsize + z*@xsize*@ysize]=v | |
end | |
def _dump(d = 0) | |
s = [@dims].pack('L') | |
s += [@xsize].pack('L') + [@ysize].pack('L') + [@zsize].pack('L') | |
s += [@xsize*@ysize*@zsize].pack('L') | |
for z in 0...@zsize | |
for y in 0...@ysize | |
for x in 0...@xsize | |
s += [@data[x + y*@xsize + z*@xsize*@ysize]].pack('S')[0,2] | |
end | |
end | |
end | |
s | |
end | |
attr_reader(:xsize,:ysize,:zsize,:data) | |
class << self | |
def _load(s) | |
dims = s[0,4].unpack('L')[0] | |
nx = s[4,4].unpack('L')[0] | |
ny = s[8,4].unpack('L')[0] | |
nz = s[12,4].unpack('L')[0] | |
data = [] | |
for i in 10...(s.size/2) | |
data.push(s[i*2, 2].unpack('S')[0]) | |
end | |
t = Table.new(nx, (dims >= 2 ? ny:nil), (dims >= 3 ? nz:nil)) | |
n = 0 | |
for z in 0...nz | |
for y in 0...ny | |
for x in 0...nx | |
t[x, y, z] = data[n] | |
n += 1 | |
end | |
end | |
end | |
t | |
end | |
end | |
end | |
# Not actually an RPG Maker class, just for convenience. | |
class Script | |
def initialize(index, name, text, scripts_path, script_idx) | |
@index = index | |
@name = name | |
@text = Zlib::Inflate.inflate(text).force_encoding('UTF-8') | |
script_name = "Script" + script_idx.to_s.rjust(3, "0") | |
@file = scripts_path.join(script_name).sub_ext(".rb") | |
end | |
def to_json(*a) | |
File.binwrite(@file, @text) | |
File.binwrite(@file.sub_ext('_tran.rb'), @text) | |
{ | |
'json_class' => self.class.name, | |
'filename' => @file, | |
'name' => dump_string(@name), | |
}.to_json(*a) | |
end | |
def self.data_is_script?(data) | |
data.instance_of?(Array) and data[0].instance_of?(Array) and data[0].length == 3 | |
end | |
end |
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
require_relative 'common_db' | |
# This file contains all the RPG data structures for RPG Maker VX. | |
module RPG | |
class Actor | |
def initialize | |
@id = 0 | |
@name = "" | |
@class_id = 1 | |
@initial_level = 1 | |
@exp_basis = 25 | |
@exp_inflation = 35 | |
@character_name = "" | |
@character_index = 0 | |
@face_name = "" | |
@face_index = 0 | |
@parameters = Table.new(6, 100) | |
for i in 1..99 | |
@parameters[0,i] = 400+i*50 | |
@parameters[1,i] = 80+i*10 | |
@parameters[2,i] = 15+i*5/4 | |
@parameters[3,i] = 15+i*5/4 | |
@parameters[4,i] = 20+i*5/2 | |
@parameters[5,i] = 20+i*5/2 | |
end | |
@weapon_id = 0 | |
@armor1_id = 0 | |
@armor2_id = 0 | |
@armor3_id = 0 | |
@armor4_id = 0 | |
@two_swords_style = false | |
@fix_equipment = false | |
@auto_battle = false | |
@super_guard = false | |
@pharmacology = false | |
@critical_bonus = false | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
end | |
class Class | |
def initialize | |
@id = 0 | |
@name = "" | |
@position = 0 | |
@weapon_set = [] | |
@armor_set = [] | |
@element_ranks = Table.new(1) | |
@state_ranks = Table.new(1) | |
@learnings = [] | |
@skill_name_valid = false | |
@skill_name = "" | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
class Learning | |
def initialize | |
@level = 1 | |
@skill_id = 1 | |
end | |
end | |
end | |
class Map | |
def initialize(width, height) | |
@width = width | |
@height = height | |
@scroll_type = 0 | |
@autoplay_bgm = false | |
@bgm = RPG::AudioFile.new | |
@autoplay_bgs = false | |
@bgs = RPG::AudioFile.new("", 80) | |
@disable_dashing = false | |
@encounter_list = [] | |
@encounter_step = 30 | |
@parallax_name = "" | |
@parallax_loop_x = false | |
@parallax_loop_y = false | |
@parallax_sx = 0 | |
@parallax_sy = 0 | |
@parallax_show = false | |
@data = Table.new(width, height, 3) | |
@events = {} | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'events' => dump_array(@events.sort) | |
}.to_json(*a) | |
end | |
end | |
class MapInfo | |
def initialize | |
@name = "" | |
@parent_id = 0 | |
@order = 0 | |
@expanded = false | |
@scroll_x = 0 | |
@scroll_y = 0 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
end | |
class Area | |
def initialize | |
@id = 0 | |
@name = "" | |
@map_id = 0 | |
@rect = Rect.new(0,0,0,0) | |
@encounter_list = [] | |
@order = 0 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
end | |
class Event | |
def initialize(x, y) | |
@id = 0 | |
@name = "" | |
@x = x | |
@y = y | |
@pages = [RPG::Event::Page.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'pages' => @pages | |
}.to_json(*a) | |
end | |
class Page | |
def initialize | |
@condition = RPG::Event::Page::Condition.new | |
@graphic = RPG::Event::Page::Graphic.new | |
@move_type = 0 | |
@move_speed = 3 | |
@move_frequency = 3 | |
@move_route = RPG::MoveRoute.new | |
@walk_anime = true | |
@step_anime = false | |
@direction_fix = false | |
@through = false | |
@priority_type = 0 | |
@trigger = 0 | |
@list = [RPG::EventCommand.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'commands' => merge_event_commands(@list) | |
}.to_json(*a) | |
end | |
class Condition | |
def initialize | |
@switch1_valid = false | |
@switch2_valid = false | |
@variable_valid = false | |
@self_switch_valid = false | |
@item_valid = false | |
@actor_valid = false | |
@switch1_id = 1 | |
@switch2_id = 1 | |
@variable_id = 1 | |
@variable_value = 0 | |
@self_switch_ch = "A" | |
@item_id = 1 | |
@actor_id = 1 | |
end | |
end | |
class Graphic | |
def initialize | |
@tile_id = 0 | |
@character_name = "" | |
@character_index = 0 | |
@direction = 2 | |
@pattern = 0 | |
end | |
end | |
end | |
end | |
class EventCommand | |
def initialize(code = 0, indent = 0, parameters = []) | |
@code = code | |
@indent = indent | |
@parameters = parameters | |
end | |
attr_accessor :code | |
attr_accessor :indent | |
attr_accessor :parameters | |
def to_json(*a) | |
obj = {} | |
obj['json_class'] = self.class.name | |
(type, is_text) = get_event_type(@code) | |
obj['type'] = type | |
if is_text then | |
obj['parameters'] = dump_parameters(@parameters) | |
end | |
obj.to_json(*a) | |
end | |
end | |
class MoveRoute | |
def initialize | |
@repeat = true | |
@skippable = false | |
@wait = false | |
@list = [RPG::MoveCommand.new] | |
end | |
end | |
class MoveCommand | |
def initialize(code = 0, parameters = []) | |
@code = code | |
@parameters = parameters | |
end | |
end | |
class BaseItem | |
def initialize | |
@id = 0 | |
@name = "" | |
@icon_index = 0 | |
@description = "" | |
@note = "" | |
end | |
def base_to_json(clsname) | |
{ | |
'json_class' => clsname, | |
'name' => dump_string(@name), | |
'description' => dump_string(@description), | |
'note' => dump_string(@note) | |
} | |
end | |
def base_translate(tran, info) | |
@name = translate_string("name", @name, tran, info) | |
@description = translate_string("description", @description, tran, info) | |
@note = translate_string("note", @note, tran, info) | |
end | |
def base_update(tran, info) | |
tran = update_string("name", @name, tran, info) | |
tran = update_string("description", @description, tran, info) | |
update_string("note", @note, tran, info) | |
end | |
end | |
class UsableItem < BaseItem | |
def initialize | |
super | |
@scope = 0 | |
@occasion = 0 | |
@speed = 0 | |
@animation_id = 0 | |
@common_event_id = 0 | |
@base_damage = 0 | |
@variance = 20 | |
@atk_f = 0 | |
@spi_f = 0 | |
@physical_attack = false | |
@damage_to_mp = false | |
@absorb_damage = false | |
@ignore_defense = false | |
@element_set = [] | |
@plus_state_set = [] | |
@minus_state_set = [] | |
end | |
def for_opponent? | |
return [1, 2, 3, 4, 5, 6].include?(@scope) | |
end | |
def for_friend? | |
return [7, 8, 9, 10, 11].include?(@scope) | |
end | |
def for_dead_friend? | |
return [9, 10].include?(@scope) | |
end | |
def for_user? | |
return [11].include?(@scope) | |
end | |
def for_one? | |
return [1, 3, 4, 7, 9, 11].include?(@scope) | |
end | |
def for_two? | |
return [5].include?(@scope) | |
end | |
def for_three? | |
return [6].include?(@scope) | |
end | |
def for_random? | |
return [4, 5, 6].include?(@scope) | |
end | |
def for_all? | |
return [2, 8, 10].include?(@scope) | |
end | |
def dual? | |
return [3].include?(@scope) | |
end | |
def need_selection? | |
return [1, 3, 7, 9].include?(@scope) | |
end | |
def battle_ok? | |
return [0, 1].include?(@occasion) | |
end | |
def menu_ok? | |
return [0, 2].include?(@occasion) | |
end | |
end | |
class Skill < UsableItem | |
def initialize | |
super | |
@scope = 1 | |
@mp_cost = 0 | |
@hit = 100 | |
@message1 = "" | |
@message2 = "" | |
end | |
def to_json(*a) | |
data = base_to_json(self.class.name) | |
data['message1'] = dump_string(@message1) | |
data['message2'] = dump_string(@message2) | |
data.to_json(*a) | |
end | |
end | |
class Item < UsableItem | |
def initialize | |
super | |
@scope = 7 | |
@price = 0 | |
@consumable = true | |
@hp_recovery_rate = 0 | |
@hp_recovery = 0 | |
@mp_recovery_rate = 0 | |
@mp_recovery = 0 | |
@parameter_type = 0 | |
@parameter_points = 0 | |
end | |
def to_json(*a) | |
base_to_json(self.class.name).to_json(*a) | |
end | |
end | |
class Weapon < BaseItem | |
def initialize | |
super | |
@animation_id = 0 | |
@price = 0 | |
@hit = 95 | |
@atk = 0 | |
@def = 0 | |
@spi = 0 | |
@agi = 0 | |
@two_handed = false | |
@fast_attack = false | |
@dual_attack = false | |
@critical_bonus = false | |
@element_set = [] | |
@state_set = [] | |
end | |
def to_json(*a) | |
base_to_json(self.class.name).to_json(*a) | |
end | |
end | |
class Armor < BaseItem | |
def initialize | |
super | |
@kind = 0 | |
@price = 0 | |
@eva = 0 | |
@atk = 0 | |
@def = 0 | |
@spi = 0 | |
@agi = 0 | |
@prevent_critical = false | |
@half_mp_cost = false | |
@double_exp_gain = false | |
@auto_hp_recover = false | |
@element_set = [] | |
@state_set = [] | |
end | |
def to_json(*a) | |
base_to_json(self.class.name).to_json(*a) | |
end | |
end | |
class Enemy | |
def initialize | |
@id = 0 | |
@name = "" | |
@battler_name = "" | |
@battler_hue = 0 | |
@maxhp = 10 | |
@maxmp = 10 | |
@atk = 10 | |
@def = 10 | |
@spi = 10 | |
@agi = 10 | |
@hit = 95 | |
@eva = 5 | |
@exp = 0 | |
@gold = 0 | |
@drop_item1 = RPG::Enemy::DropItem.new | |
@drop_item2 = RPG::Enemy::DropItem.new | |
@levitate = false | |
@has_critical = false | |
@element_ranks = Table.new(1) | |
@state_ranks = Table.new(1) | |
@actions = [RPG::Enemy::Action.new] | |
@note = "" | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'note' => dump_string(@note) | |
}.to_json(*a) | |
end | |
class DropItem | |
def initialize | |
@kind = 0 | |
@item_id = 1 | |
@weapon_id = 1 | |
@armor_id = 1 | |
@denominator = 1 | |
end | |
end | |
class Action | |
def initialize | |
@kind = 0 | |
@basic = 0 | |
@skill_id = 1 | |
@condition_type = 0 | |
@condition_param1 = 0 | |
@condition_param2 = 0 | |
@rating = 5 | |
end | |
def skill? | |
return @kind == 1 | |
end | |
end | |
end | |
class Troop | |
def initialize | |
@id = 0 | |
@name = "" | |
@members = [] | |
@pages = [RPG::BattleEventPage.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'pages' => @pages | |
}.to_json(*a) | |
end | |
class Member | |
def initialize | |
@enemy_id = 1 | |
@x = 0 | |
@y = 0 | |
@hidden = false | |
@immortal = false | |
end | |
end | |
class Page | |
def initialize | |
@condition = RPG::Troop::Page::Condition.new | |
@span = 0 | |
@list = [RPG::EventCommand.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'commands' => merge_event_commands(@list) | |
}.to_json(*a) | |
end | |
class Condition | |
def initialize | |
@turn_ending = false | |
@turn_valid = false | |
@enemy_valid = false | |
@actor_valid = false | |
@switch_valid = false | |
@turn_a = 0 | |
@turn_b = 0 | |
@enemy_index = 0 | |
@enemy_hp = 50 | |
@actor_id = 1 | |
@actor_hp = 50 | |
@switch_id = 1 | |
end | |
end | |
end | |
end | |
class State | |
def initialize | |
@id = 0 | |
@name = "" | |
@icon_index = 0 | |
@restriction = 0 | |
@priority = 5 | |
@atk_rate = 100 | |
@def_rate = 100 | |
@spi_rate = 100 | |
@agi_rate = 100 | |
@nonresistance = false | |
@offset_by_opposite = false | |
@slip_damage = false | |
@reduce_hit_ratio = false | |
@battle_only = true | |
@release_by_damage = false | |
@hold_turn = 0 | |
@auto_release_prob = 0 | |
@message1 = "" | |
@message2 = "" | |
@message3 = "" | |
@message4 = "" | |
@element_set = [] | |
@state_set = [] | |
@note = "" | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'message1' => dump_string(@message1), | |
'message2' => dump_string(@message2), | |
'message3' => dump_string(@message3), | |
'message4' => dump_string(@message4), | |
'note' => dump_string(@note) | |
}.to_json(*a) | |
end | |
end | |
class Animation | |
def initialize | |
@id = 0 | |
@name = "" | |
@animation1_name = "" | |
@animation1_hue = 0 | |
@animation2_name = "" | |
@animation2_hue = 0 | |
@position = 1 | |
@frame_max = 1 | |
@frames = [RPG::Animation::Frame.new] | |
@timings = [] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
class Frame | |
def initialize | |
@cell_max = 0 | |
@cell_data = Table.new(0, 0) | |
end | |
end | |
class Timing | |
def initialize | |
@frame = 0 | |
@se = RPG::AudioFile.new("", 80) | |
@flash_scope = 0 | |
@flash_color = Color.new(255,255,255,255) | |
@flash_duration = 5 | |
end | |
end | |
end | |
class CommonEvent | |
def initialize | |
@id = 0 | |
@name = "" | |
@trigger = 0 | |
@switch_id = 1 | |
@list = [RPG::EventCommand.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'commands' => merge_event_commands(@list) | |
}.to_json(*a) | |
end | |
end | |
class System | |
def initialize | |
@game_title = "" | |
@version_id = 0 | |
@party_members = [1] | |
@elements = [nil, ""] | |
@switches = [nil, ""] | |
@variables = [nil, ""] | |
@passages = Table.new(8192) | |
@boat = RPG::System::Vehicle.new | |
@ship = RPG::System::Vehicle.new | |
@airship = RPG::System::Vehicle.new | |
@title_bgm = RPG::BGM.new | |
@battle_bgm = RPG::BGM.new | |
@battle_end_me = RPG::ME.new | |
@gameover_me = RPG::ME.new | |
@sounds = [] | |
20.times { @sounds.push(RPG::AudioFile.new) } | |
@test_battlers = [] | |
@test_troop_id = 1 | |
@start_map_id = 1 | |
@start_x = 0 | |
@start_y = 0 | |
@terms = RPG::System::Terms.new | |
@battler_name = "" | |
@battler_hue = 0 | |
@edit_map_id = 1 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'game_title' => dump_string(@game_title), | |
'terms' => @terms, | |
'elements' => dump_array(@elements), | |
'switches' => dump_array(@switches), | |
'variables' => dump_array(@variables) | |
}.to_json(*a) | |
end | |
class Vehicle | |
def initialize | |
@character_name = "" | |
@character_index = 0 | |
@bgm = RPG::AudioFile.new | |
@start_map_id = 0 | |
@start_x = 0 | |
@start_y = 0 | |
end | |
end | |
class Terms | |
def initialize | |
@level = "" | |
@level_a = "" | |
@hp = "" | |
@hp_a = "" | |
@mp = "" | |
@mp_a = "" | |
@atk = "" | |
@def = "" | |
@spi = "" | |
@agi = "" | |
@weapon = "" | |
@armor1 = "" | |
@armor2 = "" | |
@armor3 = "" | |
@armor4 = "" | |
@weapon1 = "" | |
@weapon2 = "" | |
@attack = "" | |
@skill = "" | |
@guard = "" | |
@item = "" | |
@equip = "" | |
@status = "" | |
@save = "" | |
@game_end = "" | |
@fight = "" | |
@escape = "" | |
@new_game = "" | |
@continue = "" | |
@shutdown = "" | |
@to_title = "" | |
@cancel = "" | |
@gold = "" | |
end | |
def to_json(*a) | |
{ | |
'level' => dump_string(@level), | |
'level_a' => dump_string(@level_a), | |
'hp' => dump_string(@hp), | |
'hp_a' => dump_string(@hp_a), | |
'mp' => dump_string(@mp), | |
'mp_a' => dump_string(@mp_a), | |
'atk' => dump_string(@atk), | |
'def' => dump_string(@def), | |
'spi' => dump_string(@spi), | |
'agi' => dump_string(@agi), | |
'weapon' => dump_string(@weapon), | |
'armor1' => dump_string(@armor1), | |
'armor2' => dump_string(@armor2), | |
'armor3' => dump_string(@armor3), | |
'armor4' => dump_string(@armor4), | |
'weapon1' => dump_string(@weapon1), | |
'weapon2' => dump_string(@weapon2), | |
'attack' => dump_string(@attack), | |
'skill' => dump_string(@skill), | |
'guard' => dump_string(@guard), | |
'item' => dump_string(@item), | |
'equip' => dump_string(@equip), | |
'status' => dump_string(@status), | |
'save' => dump_string(@save), | |
'game_end' => dump_string(@game_end), | |
'fight' => dump_string(@fight), | |
'escape' => dump_string(@escape), | |
'new_game' => dump_string(@new_game), | |
'continue' => dump_string(@continue), | |
'shutdown' => dump_string(@shutdown), | |
'to_title' => dump_string(@to_title), | |
'cancel' => dump_string(@cancel), | |
'gold' => dump_string(@gold) | |
}.to_json(*a) | |
end | |
end | |
class TestBattler | |
def initialize | |
@actor_id = 1 | |
@level = 1 | |
@weapon_id = 0 | |
@armor1_id = 0 | |
@armor2_id = 0 | |
@armor3_id = 0 | |
@armor4_id = 0 | |
end | |
end | |
end | |
class AudioFile | |
def initialize(name = "", volume = 100, pitch = 100) | |
@name = name | |
@pitch = pitch | |
@volume = volume | |
end | |
end | |
class BGM < AudioFile | |
@@last = BGM.new | |
def play | |
if @name.empty? | |
Audio.bgm_stop | |
@@last = BGM.new | |
else | |
Audio.bgm_play("Audio/BGM/" + @name, @volume, @pitch) | |
@@last = self | |
end | |
end | |
def self.stop | |
Audio.bgm_stop | |
@@last = BGM.new | |
end | |
def self.fade(time) | |
Audio.bgm_fade(time) | |
@@last = BGM.new | |
end | |
def self.last | |
@@last | |
end | |
end | |
class BGS < AudioFile | |
@@last = BGS.new | |
def play | |
if @name.empty? | |
Audio.bgs_stop | |
@@last = BGS.new | |
else | |
Audio.bgs_play("Audio/BGS/" + @name, @volume, @pitch) | |
@@last = self | |
end | |
end | |
def self.stop | |
Audio.bgs_stop | |
@@last = BGS.new | |
end | |
def self.fade(time) | |
Audio.bgs_fade(time) | |
@@last = BGS.new | |
end | |
def self.last | |
@@last | |
end | |
end | |
class ME < AudioFile | |
def play | |
if @name.empty? | |
Audio.me_stop | |
else | |
Audio.me_play("Audio/ME/" + @name, @volume, @pitch) | |
end | |
end | |
def self.stop | |
Audio.me_stop | |
end | |
def self.fade(time) | |
Audio.me_fade(time) | |
end | |
end | |
class SE < AudioFile | |
def play | |
unless @name.empty? | |
Audio.se_play("Audio/SE/" + @name, @volume, @pitch) | |
end | |
end | |
def self.stop | |
Audio.se_stop | |
end | |
end | |
end | |
# Table of what type of event command the event codes corresponds to. | |
EVENT_COMMAND_CODES = { | |
0 => ["Empty", false], | |
101 => ["Show Text Attributes", false], | |
102 => ["Show Choices", true], | |
103 => ["Input Number", false], | |
108 => ["Comment", true], | |
111 => ["Conditional Branch", false], | |
112 => ["Loop", false], | |
113 => ["Break Loop", false], | |
115 => ["Exit Event Processing"], | |
117 => ["Call Common Event", false], | |
118 => ["Label", false], | |
119 => ["Jump to Label", false], | |
121 => ["Control Switches", false], | |
122 => ["Control Variables", false], | |
123 => ["Control Self Switch", false], | |
124 => ["Control Timer", false], | |
125 => ["Change Gold", false], | |
126 => ["Change Items", false], | |
127 => ["Change Weapons", false], | |
128 => ["Change Armor", false], | |
129 => ["Change Party Member", false], | |
132 => ["Change Battle BGM", false], | |
133 => ["Change Battle End ME", false], | |
134 => ["Change Save Access", false], | |
135 => ["Change Menu Access", false], | |
136 => ["Change Encounter", false], | |
201 => ["Transfer Player", false], | |
202 => ["Set Vehicle Location", false], | |
203 => ["Set Event Location", false], | |
204 => ["Scroll Map", false], | |
205 => ["Set Move Route", false], | |
206 => ["Get on/off Vehicle", false], | |
211 => ["Change Transparency", false], | |
212 => ["Show Animation", false], | |
213 => ["Shot Balloon Icon", false], | |
214 => ["Erase Event", false], | |
221 => ["Fadeout Screen", false], | |
222 => ["Fadein Screen", false], | |
223 => ["Tint Screen", false], | |
224 => ["Flash Screen", false], | |
225 => ["Shake Screen", false], | |
230 => ["Wait", false], | |
231 => ["Show Picture", false], | |
232 => ["Move Picture", false], | |
233 => ["Rotate Picture", false], | |
234 => ["Tint Picture", false], | |
235 => ["Erase Picture", false], | |
236 => ["Set Weather Effects", false], | |
241 => ["Play BGM", false], | |
242 => ["Fadeout BGM", false], | |
245 => ["Play BGS", false], | |
246 => ["Fadeout BGS", false], | |
249 => ["Play ME", false], | |
250 => ["Play SE", false], | |
251 => ["Stop SE", false], | |
301 => ["Battle Processing", false], | |
302 => ["Shop Processing", false], | |
303 => ["Name Input Processing", false], | |
311 => ["Change HP", false], | |
312 => ["Change MP", false], | |
313 => ["Change State", false], | |
314 => ["Recover All", false], | |
315 => ["Change EXP", false], | |
316 => ["Change Level", false], | |
317 => ["Change Parameters", false], | |
318 => ["Change Skills", false], | |
319 => ["Change Equipment", false], | |
320 => ["Change Actor Name", true], | |
321 => ["Change Actor Class", false], | |
322 => ["Change Actor Graphic", false], | |
323 => ["Change Vehicle Graphic", false], | |
331 => ["Change Enemy HP", false], | |
332 => ["Change Enemy MP", false], | |
333 => ["Change Enemy State", false], | |
334 => ["Enemy Recover All", false], | |
335 => ["Enemy Appear", false], | |
336 => ["Enemy Transform", false], | |
337 => ["Show Battle Animation", false], | |
339 => ["Force Action", false], | |
340 => ["Abort Battle", false], | |
351 => ["Open Menu Screen", false], | |
352 => ["Open Save Screen", false], | |
353 => ["Game Over", false], | |
354 => ["Return to Title Screen", false], | |
355 => ["Script", true], | |
401 => ["Show Text", true], | |
402 => ["When", false], | |
403 => ["When Cancel", false], | |
404 => ["Choices End", false], | |
408 => ["Comment More", true], | |
411 => ["Else", false], | |
412 => ["Branch End", false], | |
413 => ["Repeat Above", false], | |
505 => ["Move Command", false], | |
601 => ["If Win", false], | |
602 => ["If Escape", false], | |
603 => ["If Lose", false], | |
604 => ["Battle Processing End", false], | |
605 => ["Shop Item", false], | |
655 => ["Script More", true] | |
} | |
# Given an event code, returns the type of the event and whether it can contain | |
# something translatable. | |
def get_event_type(code) | |
type = EVENT_COMMAND_CODES[code] | |
type.nil? ? [code, false] : type | |
end | |
def merge_event_commands(commands) | |
merged_cmds = [] | |
i = 0 | |
while i < commands.length | |
cmd = commands[i] | |
match_code = case cmd.code | |
when 401 then 401 # Show Text | |
when 108 then 408 # Comment | |
when 355 then 655 # Script | |
else 0 | |
end | |
if match_code != 0 and commands[i+1].code == match_code | |
params = cmd.parameters | |
while commands[i+1].code == match_code | |
i += 1 | |
params.concat commands[i].parameters | |
end | |
cmd = RPG::EventCommand.new(cmd.code, cmd.indent, params) | |
end | |
merged_cmds.push cmd | |
i += 1 | |
end | |
merged_cmds | |
end | |
def split_event_commands(commands) | |
split_cmds = [] | |
commands.each do |cmd| | |
match_code = case cmd.code | |
when 401 then 401 | |
when 108 then 408 | |
when 355 then 655 | |
else 0 | |
end | |
if match_code != 0 and cmd.parameters.length > 1 | |
code = cmd.code | |
cmd.parameters.each do |p| | |
split_cmds.push RPG::EventCommand.new(code, cmd.indent, [p]) | |
code = match_code | |
end | |
else | |
split_cmds.push cmd | |
end | |
end | |
split_cmds | |
end |
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
require_relative 'common_db' | |
# This file contains all the RPG data structures for RPG Maker VX Ace. | |
module RPG | |
class BaseItem | |
def initialize | |
@id = 0 | |
@name = '' | |
@icon_index = 0 | |
@description = '' | |
@features = [] | |
@note = '' | |
end | |
class Feature | |
def initialize(code = 0, data_id = 0, value = 0) | |
@code = code | |
@data_id = data_id | |
@value = value | |
end | |
end | |
end | |
class Actor < BaseItem | |
def initialize | |
super | |
@nickname = '' | |
@class_id = 1 | |
@initial_level = 1 | |
@max_level = 99 | |
@character_name = '' | |
@character_index = 0 | |
@face_name = '' | |
@face_index = 0 | |
@equips = [0,0,0,0,0] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'nickname' => dump_string(@nickname), | |
'description' => dump_string(@description), | |
'note' => dump_string(@note) | |
}.to_json(*a) | |
end | |
end | |
class Class < BaseItem | |
def initialize | |
super | |
@exp_params = [30,20,30,30] | |
@params = Table.new(8,100) | |
(1..99).each do |i| | |
@params[0,i] = 400+i*50 | |
@params[1,i] = 80+i*10 | |
(2..5).each {|j| @params[j,i] = 15+i*5/4 } | |
(6..7).each {|j| @params[j,i] = 30+i*5/2 } | |
end | |
@learnings = [] | |
@features.push(RPG::BaseItem::Feature.new(23, 0, 1)) | |
@features.push(RPG::BaseItem::Feature.new(22, 0, 0.95)) | |
@features.push(RPG::BaseItem::Feature.new(22, 1, 0.05)) | |
@features.push(RPG::BaseItem::Feature.new(22, 2, 0.04)) | |
@features.push(RPG::BaseItem::Feature.new(41, 1)) | |
@features.push(RPG::BaseItem::Feature.new(51, 1)) | |
@features.push(RPG::BaseItem::Feature.new(52, 1)) | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'description' => dump_string(@description), | |
'note' => dump_string(@note), | |
'learnings' => @learnings | |
}.to_json(*a) | |
end | |
class Learning | |
def initialize | |
@level = 1 | |
@skill_id = 1 | |
@note = '' | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'note' => dump_string(@note) | |
}.to_json(*a) | |
end | |
end | |
end | |
class UsableItem < BaseItem | |
def initialize | |
super | |
@scope = 0 | |
@occasion = 0 | |
@speed = 0 | |
@success_rate = 100 | |
@repeats = 1 | |
@tp_gain = 0 | |
@hit_type = 0 | |
@animation_id = 0 | |
@damage = RPG::UsableItem::Damage.new | |
@effects = [] | |
end | |
class Damage | |
def initialize | |
@type = 0 | |
@element_id = 0 | |
@formula = '0' | |
@variance = 20 | |
@critical = false | |
end | |
end | |
class Effect | |
def initialize(code = 0, data_id = 0, value1 = 0, value2 = 0) | |
@code = code | |
@data_id = data_id | |
@value1 = value1 | |
@value2 = value2 | |
end | |
end | |
end | |
class Skill < UsableItem | |
def initialize | |
super | |
@scope = 1 | |
@stype_id = 1 | |
@mp_cost = 0 | |
@tp_cost = 0 | |
@message1 = '' | |
@message2 = '' | |
@required_wtype_id1 = 0 | |
@required_wtype_id2 = 0 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'description' => dump_string(@description), | |
'message1' => dump_string(@message1), | |
'message2' => dump_string(@message2), | |
'note' => dump_string(@note) | |
}.to_json(*a) | |
end | |
end | |
class Item < UsableItem | |
def initialize | |
super | |
@scope = 7 | |
@itype_id = 1 | |
@price = 0 | |
@consumable = true | |
end | |
def key_item? | |
@itype_id == 2 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'description' => dump_string(@description), | |
'note' => dump_string(@note) | |
}.to_json(*a) | |
end | |
end | |
class EquipItem < BaseItem | |
def initialize | |
super | |
@price = 0 | |
@etype_id = 0 | |
@params = [0] * 8 | |
end | |
end | |
class Weapon < EquipItem | |
def initialize | |
super | |
@wtype_id = 0 | |
@animation_id = 0 | |
@features.push(RPG::BaseItem::Feature.new(31, 1, 0)) | |
@features.push(RPG::BaseItem::Feature.new(22, 0, 0)) | |
end | |
def performance | |
params[2] + params[4] + params.inject(0) {|r, v| r += v } | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'description' => dump_string(@description), | |
'note' => dump_string(@note) | |
}.to_json(*a) | |
end | |
end | |
class Armor < EquipItem | |
def initialize | |
super | |
@atype_id = 0 | |
@etype_id = 1 | |
@features.push(RPG::BaseItem::Feature.new(22, 1, 0)) | |
end | |
def performance | |
params[3] + params[5] + params.inject(0) {|r, v| r += v } | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'description' => dump_string(@description), | |
'note' => dump_string(@note) | |
}.to_json(*a) | |
end | |
end | |
class Enemy < BaseItem | |
def initialize | |
super | |
@battler_name = '' | |
@battler_hue = 0 | |
@params = [100,0,10,10,10,10,10,10] | |
@exp = 0 | |
@gold = 0 | |
@drop_items = Array.new(3) { RPG::Enemy::DropItem.new } | |
@actions = [RPG::Enemy::Action.new] | |
@features.push(RPG::BaseItem::Feature.new(22, 0, 0.95)) | |
@features.push(RPG::BaseItem::Feature.new(22, 1, 0.05)) | |
@features.push(RPG::BaseItem::Feature.new(31, 1, 0)) | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'description' => dump_string(@description), | |
'note' => dump_string(@note) | |
}.to_json(*a) | |
end | |
class DropItem | |
def initialize | |
@kind = 0 | |
@data_id = 1 | |
@denominator = 1 | |
end | |
end | |
class Action | |
def initialize | |
@skill_id = 1 | |
@condition_type = 0 | |
@condition_param1 = 0 | |
@condition_param2 = 0 | |
@rating = 5 | |
end | |
end | |
end | |
class State < BaseItem | |
def initialize | |
super | |
@restriction = 0 | |
@priority = 50 | |
@remove_at_battle_end = false | |
@remove_by_restriction = false | |
@auto_removal_timing = 0 | |
@min_turns = 1 | |
@max_turns = 1 | |
@remove_by_damage = false | |
@chance_by_damage = 100 | |
@remove_by_walking = false | |
@steps_to_remove = 100 | |
@message1 = '' | |
@message2 = '' | |
@message3 = '' | |
@message4 = '' | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'message1' => dump_string(@message1), | |
'message2' => dump_string(@message2), | |
'message3' => dump_string(@message3), | |
'message4' => dump_string(@message4), | |
'note' => dump_string(@note) | |
}.to_json(*a) | |
end | |
end | |
class Map | |
def initialize(width, height) | |
@display_name = '' | |
@tileset_id = 1 | |
@width = width | |
@height = height | |
@scroll_type = 0 | |
@specify_battleback = false | |
@battleback_floor_name = '' | |
@battleback_wall_name = '' | |
@autoplay_bgm = false | |
@bgm = RPG::BGM.new | |
@autoplay_bgs = false | |
@bgs = RPG::BGS.new('', 80) | |
@disable_dashing = false | |
@encounter_list = [] | |
@encounter_step = 30 | |
@parallax_name = '' | |
@parallax_loop_x = false | |
@parallax_loop_y = false | |
@parallax_sx = 0 | |
@parallax_sy = 0 | |
@parallax_show = false | |
@note = '' | |
@data = Table.new(width, height, 4) | |
@events = {} | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'display_name' => dump_string(@display_name), | |
'note' => dump_string(@note), | |
'events' => dump_array(@events.sort), | |
}.to_json(*a) | |
end | |
class Encounter | |
def initialize | |
@troop_id = 1 | |
@weight = 10 | |
@region_set = [] | |
end | |
end | |
end | |
class MapInfo | |
def initialize | |
@name = '' | |
@parent_id = 0 | |
@order = 0 | |
@expanded = false | |
@scroll_x = 0 | |
@scroll_y = 0 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
end | |
class Event | |
def initialize(x, y) | |
@id = 0 | |
@name = '' | |
@x = x | |
@y = y | |
@pages = [RPG::Event::Page.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'pages' => @pages | |
}.to_json(*a) | |
end | |
class Page | |
def initialize | |
@condition = RPG::Event::Page::Condition.new | |
@graphic = RPG::Event::Page::Graphic.new | |
@move_type = 0 | |
@move_speed = 3 | |
@move_frequency = 3 | |
@move_route = RPG::MoveRoute.new | |
@walk_anime = true | |
@step_anime = false | |
@direction_fix = false | |
@through = false | |
@priority_type = 0 | |
@trigger = 0 | |
@list = [RPG::EventCommand.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'commands' => merge_event_commands(@list) | |
}.to_json(*a) | |
end | |
class Condition | |
def initialize | |
@switch1_valid = false | |
@switch2_valid = false | |
@variable_valid = false | |
@self_switch_valid = false | |
@item_valid = false | |
@actor_valid = false | |
@switch1_id = 1 | |
@switch2_id = 1 | |
@variable_id = 1 | |
@variable_value = 0 | |
@self_switch_ch = 'A' | |
@item_id = 1 | |
@actor_id = 1 | |
end | |
end | |
class Condition | |
def initialize | |
@switch1_valid = false | |
@switch2_valid = false | |
@variable_valid = false | |
@self_switch_valid = false | |
@item_valid = false | |
@actor_valid = false | |
@switch1_id = 1 | |
@switch2_id = 1 | |
@variable_id = 1 | |
@variable_value = 0 | |
@self_switch_ch = 'A' | |
@item_id = 1 | |
@actor_id = 1 | |
end | |
end | |
class RPG::Event::Page::Graphic | |
def initialize | |
@tile_id = 0 | |
@character_name = '' | |
@character_index = 0 | |
@direction = 2 | |
@pattern = 0 | |
end | |
end | |
end | |
end | |
class EventCommand | |
def initialize(code = 0, indent = 0, parameters = []) | |
@code = code | |
@indent = indent | |
@parameters = parameters | |
end | |
attr_accessor :code | |
attr_accessor :indent | |
attr_accessor :parameters | |
def to_json(*a) | |
obj = {} | |
obj['json_class'] = self.class.name | |
(type, is_text) = get_event_type(@code, @parameters) | |
obj['type'] = type | |
if is_text then | |
obj['parameters'] = dump_parameters(@parameters) | |
end | |
obj.to_json(*a) | |
end | |
end | |
class MoveRoute | |
def initialize | |
@repeat = true | |
@skippable = false | |
@wait = false | |
@list = [RPG::MoveCommand.new] | |
end | |
end | |
class MoveCommand | |
def initialize(code = 0, parameters = []) | |
@code = code | |
@parameters = parameters | |
end | |
end | |
class Troop | |
def initialize | |
@id = 0 | |
@name = '' | |
@members = [] | |
@pages = [RPG::Troop::Page.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'pages' => @pages | |
}.to_json(*a) | |
end | |
class Member | |
def initialize | |
@enemy_id = 1 | |
@x = 0 | |
@y = 0 | |
@hidden = false | |
end | |
end | |
class Page | |
def initialize | |
@condition = RPG::Troop::Page::Condition.new | |
@span = 0 | |
@list = [RPG::EventCommand.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'commands' => merge_event_commands(@list) | |
}.to_json(*a) | |
end | |
class Condition | |
def initialize | |
@turn_ending = false | |
@turn_valid = false | |
@enemy_valid = false | |
@actor_valid = false | |
@switch_valid = false | |
@turn_a = 0 | |
@turn_b = 0 | |
@enemy_index = 0 | |
@enemy_hp = 50 | |
@actor_id = 1 | |
@actor_hp = 50 | |
@switch_id = 1 | |
end | |
end | |
end | |
end | |
class Animation | |
def initialize | |
@id = 0 | |
@name = '' | |
@animation1_name = '' | |
@animation1_hue = 0 | |
@animation2_name = '' | |
@animation2_hue = 0 | |
@position = 1 | |
@frame_max = 1 | |
@frames = [RPG::Animation::Frame.new] | |
@timings = [] | |
end | |
def to_screen? | |
@position == 3 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
class Frame | |
def initialize | |
@cell_max = 0 | |
@cell_data = Table.new(0, 0) | |
end | |
end | |
class Timing | |
def initialize | |
@frame = 0 | |
@se = RPG::SE.new('', 80) | |
@flash_scope = 0 | |
@flash_color = Color.new(255,255,255,255) | |
@flash_duration = 5 | |
end | |
end | |
end | |
class Tileset | |
def initialize | |
@id = 0 | |
@mode = 1 | |
@name = '' | |
@tileset_names = Array.new(9).collect{''} | |
@flags = Table.new(8192) | |
@flags[0] = 0x0010 | |
(2048..2815).each {|i| @flags[i] = 0x000F} | |
(4352..8191).each {|i| @flags[i] = 0x000F} | |
@note = '' | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
end | |
class CommonEvent | |
def initialize | |
@id = 0 | |
@name = '' | |
@trigger = 0 | |
@switch_id = 1 | |
@list = [RPG::EventCommand.new] | |
end | |
def autorun? | |
@trigger == 1 | |
end | |
def parallel? | |
@trigger == 2 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'commands' => merge_event_commands(@list) | |
}.to_json(*a) | |
end | |
end | |
class System | |
def initialize | |
@game_title = '' | |
@version_id = 0 | |
@japanese = true | |
@party_members = [1] | |
@currency_unit = '' | |
@elements = [nil, ''] | |
@skill_types = [nil, ''] | |
@weapon_types = [nil, ''] | |
@armor_types = [nil, ''] | |
@switches = [nil, ''] | |
@variables = [nil, ''] | |
@boat = RPG::System::Vehicle.new | |
@ship = RPG::System::Vehicle.new | |
@airship = RPG::System::Vehicle.new | |
@title1_name = '' | |
@title2_name = '' | |
@opt_draw_title = true | |
@opt_use_midi = false | |
@opt_transparent = false | |
@opt_followers = true | |
@opt_slip_death = false | |
@opt_floor_death = false | |
@opt_display_tp = true | |
@opt_extra_exp = false | |
@window_tone = Tone.new(0,0,0) | |
@title_bgm = RPG::BGM.new | |
@battle_bgm = RPG::BGM.new | |
@battle_end_me = RPG::ME.new | |
@gameover_me = RPG::ME.new | |
@sounds = Array.new(24) { RPG::SE.new } | |
@test_battlers = [] | |
@test_troop_id = 1 | |
@start_map_id = 1 | |
@start_x = 0 | |
@start_y = 0 | |
@terms = RPG::System::Terms.new | |
@battleback1_name = '' | |
@battleback2_name = '' | |
@battler_name = '' | |
@battler_hue = 0 | |
@edit_map_id = 1 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'game_title' => dump_string(@game_title), | |
'currency_unit' => dump_string(@currency_unit), | |
'elements' => dump_array(@elements), | |
'skill_types' => dump_array(@skill_types), | |
'weapon_types' => dump_array(@weapon_types), | |
'armor_types' => dump_array(@armor_types), | |
'terms' => @terms | |
}.to_json(*a) | |
end | |
class Vehicle | |
def initialize | |
@character_name = '' | |
@character_index = 0 | |
@bgm = RPG::BGM.new | |
@start_map_id = 0 | |
@start_x = 0 | |
@start_y = 0 | |
end | |
end | |
class Terms | |
def initialize | |
@basic = Array.new(8) {''} | |
@params = Array.new(8) {''} | |
@etypes = Array.new(5) {''} | |
@commands = Array.new(23) {''} | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'basic' => dump_array(@basic), | |
'parameters' => dump_array(@params), | |
'equipment types' => dump_array(@etypes), | |
'commands' => dump_array(@commands) | |
}.to_json(*a) | |
end | |
end | |
class TestBattler | |
def initialize | |
@actor_id = 1 | |
@level = 1 | |
@equips = [0,0,0,0,0] | |
end | |
end | |
end | |
class AudioFile | |
def initialize(name = '', volume = 100, pitch = 100) | |
@name = name | |
@volume = volume | |
@pitch = pitch | |
end | |
end | |
class BGM < AudioFile | |
@@last = BGM.new | |
def play(pos = 0) | |
if @name.empty? | |
Audio.bgm_stop | |
@@last = BGM.new | |
else | |
Audio.bgm_play('Audio/BGM/' + @name, @volume, @pitch, pos) | |
@@last = self.clone | |
end | |
end | |
def replay | |
play(@pos) | |
end | |
def self.stop | |
Audio.bgm_stop | |
@@last = BGM.new | |
end | |
def self.fade(time) | |
Audio.bgm_fade(time) | |
@@last = BGM.new | |
end | |
def self.last | |
@@last.pos = Audio.bgm_pos | |
@@last | |
end | |
end | |
class BGS < AudioFile | |
@@last = BGS.new | |
def play(pos = 0) | |
if @name.empty? | |
Audio.bgs_stop | |
@@last = BGS.new | |
else | |
Audio.bgs_play('Audio/BGS/' + @name, @volume, @pitch, pos) | |
@@last = self.clone | |
end | |
end | |
def replay | |
play(@pos) | |
end | |
def self.stop | |
Audio.bgs_stop | |
@@last = BGS.new | |
end | |
def self.fade(time) | |
Audio.bgs_fade(time) | |
@@last = BGS.new | |
end | |
def self.last | |
@@last.pos = Audio.bgs_pos | |
@@last | |
end | |
end | |
class ME < AudioFile | |
def play | |
if @name.empty? | |
Audio.me_stop | |
else | |
Audio.me_play('Audio/ME/' + @name, @volume, @pitch) | |
end | |
end | |
def self.stop | |
Audio.me_stop | |
end | |
def self.fade(time) | |
Audio.me_fade(time) | |
end | |
end | |
class SE < AudioFile | |
def play | |
unless @name.empty? | |
Audio.se_play('Audio/SE/' + @name, @volume, @pitch) | |
end | |
end | |
def self.stop | |
Audio.se_stop | |
end | |
end | |
end | |
# Table of what type of event command the event codes corresponds to. | |
EVENT_COMMAND_CODES = { | |
0 => ["Empty", false], | |
101 => ["Show Text Attributes", false], | |
102 => ["Show Choices", true], | |
103 => ["Input Number", false], | |
104 => ["Select Key Item", false], | |
105 => ["Show Scrolling Text Attributes", false], | |
108 => ["Comment", true], | |
111 => ["Conditional Branch", false], | |
112 => ["Loop", false], | |
113 => ["Break Loop", false], | |
115 => ["Exit Event Processing", false], | |
117 => ["Call Common Event", false], | |
118 => ["Label", false], | |
119 => ["Jump to Label", false], | |
121 => ["Control Switches", false], | |
122 => ["Control Variables", false], | |
123 => ["Control Self Switch", false], | |
124 => ["Control Timer", false], | |
125 => ["Change Gold", false], | |
126 => ["Change Items", false], | |
127 => ["Change Weapons", false], | |
128 => ["Change Armor", false], | |
129 => ["Change Party Member", false], | |
132 => ["Change Battle BGM", false], | |
133 => ["Change Battle End ME", false], | |
134 => ["Change Save Access", false], | |
135 => ["Change Menu Access", false], | |
136 => ["Change Encounter", false], | |
137 => ["Change Formation Access", false], | |
138 => ["Change Window Color", false], | |
201 => ["Transfer Player", false], | |
202 => ["Set Vehicle Location", false], | |
203 => ["Set Event Location", false], | |
204 => ["Scroll Map", false], | |
205 => ["Set Move Route", false], | |
206 => ["Get on/off Vehicle", false], | |
211 => ["Change Transparency", false], | |
212 => ["Show Animation", false], | |
213 => ["Shot Balloon Icon", false], | |
214 => ["Erase Event", false], | |
216 => ["Change Player Followers", false], | |
217 => ["Gather Followers", false], | |
221 => ["Fadeout Screen", false], | |
222 => ["Fadein Screen", false], | |
223 => ["Tint Screen", false], | |
224 => ["Flash Screen", false], | |
225 => ["Shake Screen", false], | |
230 => ["Wait", false], | |
231 => ["Show Picture", false], | |
232 => ["Move Picture", false], | |
233 => ["Rotate Picture", false], | |
234 => ["Tint Picture", false], | |
235 => ["Erase Picture", false], | |
236 => ["Set Weather Effects", false], | |
241 => ["Play BGM", false], | |
242 => ["Fadeout BGM", false], | |
243 => ["Save BGM", false], | |
244 => ["Replay BGM", false], | |
245 => ["Play BGS", false], | |
246 => ["Fadeout BGS", false], | |
249 => ["Play ME", false], | |
250 => ["Play SE", false], | |
251 => ["Stop SE", false], | |
261 => ["Play Movie", false], | |
281 => ["Change Map Display", false], | |
282 => ["Change Tileset", false], | |
283 => ["Change Battle Back", false], | |
284 => ["Change Parallax Back", false], | |
285 => ["Get Location Info", false], | |
301 => ["Battle Processing", false], | |
302 => ["Shop Processing", false], | |
303 => ["Name Input Processing", false], | |
311 => ["Change HP", false], | |
312 => ["Change MP", false], | |
313 => ["Change State", false], | |
314 => ["Recover All", false], | |
315 => ["Change EXP", false], | |
316 => ["Change Level", false], | |
317 => ["Change Parameters", false], | |
318 => ["Change Skills", false], | |
319 => ["Change Equipment", false], | |
320 => ["Change Actor Name", true], | |
321 => ["Change Actor Class", false], | |
322 => ["Change Actor Graphic", false], | |
323 => ["Change Vehicle Graphic", false], | |
324 => ["Change Actor Nickname", true], | |
331 => ["Change Enemy HP", false], | |
332 => ["Change Enemy MP", false], | |
333 => ["Change Enemy State", false], | |
334 => ["Enemy Recover All", false], | |
335 => ["Enemy Appear", false], | |
336 => ["Enemy Transform", false], | |
337 => ["Show Battle Animation", false], | |
339 => ["Force Action", false], | |
340 => ["Abort Battle", false], | |
351 => ["Open Menu Screen", false], | |
352 => ["Open Save Screen", false], | |
353 => ["Game Over", false], | |
354 => ["Return to Title Screen", false], | |
355 => ["Script", true], | |
401 => ["Show Text", true], | |
402 => ["When", false], | |
403 => ["When Cancel", false], | |
404 => ["Choices End", false], | |
405 => ["Show Scrolling Text", true], | |
408 => ["Comment More", true], | |
411 => ["Else", false], | |
412 => ["Branch End", false], | |
413 => ["Repeat Above", false], | |
601 => ["If Win", false], | |
602 => ["If Escape", false], | |
603 => ["If Lose", false], | |
604 => ["Battle Processing End", false], | |
605 => ["Shop Item", false], | |
655 => ["Script More", true] | |
} | |
# Given an event code, returns the type of the event and whether it can contain | |
# something translatable. | |
def get_event_type(code, params) | |
type = EVENT_COMMAND_CODES[code] | |
# Control variables can be assigned scripts: | |
if code == 122 and params[3] == 4 then | |
type[1] = true | |
end | |
type.nil? ? [code, false] : type | |
end | |
def merge_event_commands(commands) | |
merged_cmds = [] | |
i = 0 | |
while i < commands.length | |
cmd = commands[i] | |
match_code = case cmd.code | |
when 401 then 401 # Show Text | |
when 108 then 408 # Comment | |
when 355 then 655 # Script | |
else 0 | |
end | |
if match_code != 0 and commands[i+1].code == match_code | |
params = cmd.parameters | |
while commands[i+1].code == match_code | |
i += 1 | |
params.concat commands[i].parameters | |
end | |
cmd = RPG::EventCommand.new(cmd.code, cmd.indent, params) | |
end | |
merged_cmds.push cmd | |
i += 1 | |
end | |
merged_cmds | |
end | |
def split_event_commands(commands) | |
split_cmds = [] | |
commands.each do |cmd| | |
match_code = case cmd.code | |
when 401 then 401 | |
when 108 then 408 | |
when 355 then 655 | |
else 0 | |
end | |
if match_code != 0 and cmd.parameters.length > 1 | |
code = cmd.code | |
cmd.parameters.each do |p| | |
split_cmds.push RPG::EventCommand.new(code, cmd.indent, [p]) | |
code = match_code | |
end | |
else | |
split_cmds.push cmd | |
end | |
end | |
split_cmds | |
end |
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
require_relative 'common_db' | |
# This file contains all the RPG data structures for RPG Maker XP | |
module RPG | |
class Actor | |
def initialize | |
@id = 0 | |
@name = "" | |
@class_id = 1 | |
@initial_level = 1 | |
@final_level = 99 | |
@exp_basis = 30 | |
@exp_inflation = 30 | |
@character_name = "" | |
@character_hue = 0 | |
@battler_name = "" | |
@battler_hue = 0 | |
@parameters = Table.new(6,100) | |
for i in 1..99 | |
@parameters[0,i] = 500+i*50 | |
@parameters[1,i] = 500+i*50 | |
@parameters[2,i] = 50+i*5 | |
@parameters[3,i] = 50+i*5 | |
@parameters[4,i] = 50+i*5 | |
@parameters[5,i] = 50+i*5 | |
end | |
@weapon_id = 0 | |
@armor1_id = 0 | |
@armor2_id = 0 | |
@armor3_id = 0 | |
@armor4_id = 0 | |
@weapon_fix = false | |
@armor1_fix = false | |
@armor2_fix = false | |
@armor3_fix = false | |
@armor4_fix = false | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
end | |
class Class | |
def initialize | |
@id = 0 | |
@name = "" | |
@position = 0 | |
@weapon_set = [] | |
@armor_set = [] | |
@element_ranks = Table.new(1) | |
@state_ranks = Table.new(1) | |
@learnings = [] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
class Learning | |
def initialize | |
@level = 1 | |
@skill_id = 1 | |
end | |
end | |
end | |
class Skill | |
def initialize | |
@id = 0 | |
@name = "" | |
@icon_name = "" | |
@description = "" | |
@scope = 0 | |
@occasion = 1 | |
@animation1_id = 0 | |
@animation2_id = 0 | |
@menu_se = RPG::AudioFile.new("", 80) | |
@common_event_id = 0 | |
@sp_cost = 0 | |
@power = 0 | |
@atk_f = 0 | |
@eva_f = 0 | |
@str_f = 0 | |
@dex_f = 0 | |
@agi_f = 0 | |
@int_f = 100 | |
@hit = 100 | |
@pdef_f = 0 | |
@mdef_f = 100 | |
@variance = 15 | |
@element_set = [] | |
@plus_state_set = [] | |
@minus_state_set = [] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'description' => dump_string(@description) | |
}.to_json(*a) | |
end | |
end | |
class Item | |
def initialize | |
@id = 0 | |
@name = "" | |
@icon_name = "" | |
@description = "" | |
@scope = 0 | |
@occasion = 0 | |
@animation1_id = 0 | |
@animation2_id = 0 | |
@menu_se = RPG::AudioFile.new("", 80) | |
@common_event_id = 0 | |
@price = 0 | |
@consumable = true | |
@parameter_type = 0 | |
@parameter_points = 0 | |
@recover_hp_rate = 0 | |
@recover_hp = 0 | |
@recover_sp_rate = 0 | |
@recover_sp = 0 | |
@hit = 100 | |
@pdef_f = 0 | |
@mdef_f = 0 | |
@variance = 0 | |
@element_set = [] | |
@plus_state_set = [] | |
@minus_state_set = [] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'description' => dump_string(@description) | |
}.to_json(*a) | |
end | |
end | |
class Weapon | |
def initialize | |
@id = 0 | |
@name = "" | |
@icon_name = "" | |
@description = "" | |
@animation1_id = 0 | |
@animation2_id = 0 | |
@price = 0 | |
@atk = 0 | |
@pdef = 0 | |
@mdef = 0 | |
@str_plus = 0 | |
@dex_plus = 0 | |
@agi_plus = 0 | |
@int_plus = 0 | |
@element_set = [] | |
@plus_state_set = [] | |
@minus_state_set = [] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'description' => dump_string(@description) | |
}.to_json(*a) | |
end | |
end | |
class Armor | |
def initialize | |
@id = 0 | |
@name = "" | |
@icon_name = "" | |
@description = "" | |
@kind = 0 | |
@auto_state_id = 0 | |
@price = 0 | |
@pdef = 0 | |
@mdef = 0 | |
@eva = 0 | |
@str_plus = 0 | |
@dex_plus = 0 | |
@agi_plus = 0 | |
@int_plus = 0 | |
@guard_element_set = [] | |
@guard_state_set = [] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'description' => dump_string(@description) | |
}.to_json(*a) | |
end | |
end | |
class Enemy | |
def initialize | |
@id = 0 | |
@name = "" | |
@battler_name = "" | |
@battler_hue = 0 | |
@maxhp = 500 | |
@maxsp = 500 | |
@str = 50 | |
@dex = 50 | |
@agi = 50 | |
@int = 50 | |
@atk = 100 | |
@pdef = 100 | |
@mdef = 100 | |
@eva = 0 | |
@animation1_id = 0 | |
@animation2_id = 0 | |
@element_ranks = Table.new(1) | |
@state_ranks = Table.new(1) | |
@actions = [RPG::Enemy::Action.new] | |
@exp = 0 | |
@gold = 0 | |
@item_id = 0 | |
@weapon_id = 0 | |
@armor_id = 0 | |
@treasure_prob = 100 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
class Action | |
def initialize | |
@kind = 0 | |
@basic = 0 | |
@skill_id = 1 | |
@condition_turn_a = 0 | |
@condition_turn_b = 1 | |
@condition_hp = 100 | |
@condition_level = 1 | |
@condition_switch_id = 0 | |
@rating = 5 | |
end | |
end | |
end | |
class Troop | |
def initialize | |
@id = 0 | |
@name = "" | |
@members = [] | |
@pages = [RPG::BattleEventPage.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'pages' => @pages | |
}.to_json(*a) | |
end | |
class Member | |
def initialize | |
@enemy_id = 1 | |
@x = 0 | |
@y = 0 | |
@hidden = false | |
@immortal = false | |
end | |
end | |
class Page | |
def initialize | |
@condition = RPG::Troop::Page::Condition.new | |
@span = 0 | |
@list = [RPG::EventCommand.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'commands' => merge_event_commands(@list) | |
}.to_json(*a) | |
end | |
class Condition | |
def initialize | |
@turn_valid = false | |
@enemy_valid = false | |
@actor_valid = false | |
@switch_valid = false | |
@turn_a = 0 | |
@turn_b = 0 | |
@enemy_index = 0 | |
@enemy_hp = 50 | |
@actor_id = 1 | |
@actor_hp = 50 | |
@switch_id = 1 | |
end | |
end | |
end | |
end | |
class State | |
def initialize | |
@id = 0 | |
@name = "" | |
@animation_id = 0 | |
@restriction = 0 | |
@nonresistance = false | |
@zero_hp = false | |
@cant_get_exp = false | |
@cant_evade = false | |
@slip_damage = false | |
@rating = 5 | |
@hit_rate = 100 | |
@maxhp_rate = 100 | |
@maxsp_rate = 100 | |
@str_rate = 100 | |
@dex_rate = 100 | |
@agi_rate = 100 | |
@int_rate = 100 | |
@atk_rate = 100 | |
@pdef_rate = 100 | |
@mdef_rate = 100 | |
@eva = 0 | |
@battle_only = true | |
@hold_turn = 0 | |
@auto_release_prob = 0 | |
@shock_release_prob = 0 | |
@guard_element_set = [] | |
@plus_state_set = [] | |
@minus_state_set = [] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
end | |
class Event | |
def initialize(x, y) | |
@id = 0 | |
@name = "" | |
@x = x | |
@y = y | |
@pages = [RPG::Event::Page.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'pages' => @pages | |
}.to_json(*a) | |
end | |
class Page | |
def initialize | |
@condition = RPG::Event::Page::Condition.new | |
@graphic = RPG::Event::Page::Graphic.new | |
@move_type = 0 | |
@move_speed = 3 | |
@move_frequency = 3 | |
@move_route = RPG::MoveRoute.new | |
@walk_anime = true | |
@step_anime = false | |
@direction_fix = false | |
@through = false | |
@always_on_top = false | |
@trigger = 0 | |
@list = [RPG::EventCommand.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'commands' => merge_event_commands(@list) | |
}.to_json(*a) | |
end | |
class Condition | |
def initialize | |
@switch1_valid = false | |
@switch2_valid = false | |
@variable_valid = false | |
@self_switch_valid = false | |
@switch1_id = 1 | |
@switch2_id = 1 | |
@variable_id = 1 | |
@variable_value = 0 | |
@self_switch_ch = "A" | |
end | |
end | |
class Graphic | |
def initialize | |
@tile_id = 0 | |
@character_name = "" | |
@character_hue = 0 | |
@direction = 2 | |
@pattern = 0 | |
@opacity = 255 | |
@blend_type = 0 | |
end | |
end | |
end | |
end | |
class EventCommand | |
def initialize(code = 0, indent = 0, parameters = []) | |
@code = code | |
@indent = indent | |
@parameters = parameters | |
end | |
attr_accessor :code | |
attr_accessor :indent | |
attr_accessor :parameters | |
def to_json(*a) | |
obj = {} | |
obj['json_class'] = self.class.name | |
(type, is_text) = get_event_type(@code) | |
obj['type'] = type | |
if is_text then | |
obj['parameters'] = dump_parameters(@parameters) | |
end | |
obj.to_json(*a) | |
end | |
end | |
class MapInfo | |
def initialize | |
@name = "" | |
@parent_id = 0 | |
@order = 0 | |
@expanded = false | |
@scroll_x = 0 | |
@scroll_y = 0 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
end | |
class Map | |
def initialize(width, height) | |
@tileset_id = 1 | |
@width = width | |
@height = height | |
@autoplay_bgm = false | |
@bgm = RPG::AudioFile.new | |
@autoplay_bgs = false | |
@bgs = RPG::AudioFile.new("", 80) | |
@encounter_list = [] | |
@encounter_step = 30 | |
@data = Table.new(width, height, 3) | |
@events = {} | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'events' => dump_array(@events.sort) | |
}.to_json(*a) | |
end | |
end | |
class MoveRoute | |
def initialize | |
@repeat = true | |
@skippable = false | |
@list = [RPG::MoveCommand.new] | |
end | |
end | |
class MoveCommand | |
def initialize(code = 0, parameters = []) | |
@code = code | |
@parameters = parameters | |
end | |
end | |
class Animation | |
def initialize | |
@id = 0 | |
@name = "" | |
@animation_name = "" | |
@animation_hue = 0 | |
@position = 1 | |
@frame_max = 1 | |
@frames = [RPG::Animation::Frame.new] | |
@timings = [] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
class Frame | |
def initialize | |
@cell_max = 0 | |
@cell_data = Table.new(0, 0) | |
end | |
end | |
class Timing | |
def initialize | |
@frame = 0 | |
@se = RPG::AudioFile.new("", 80) | |
@flash_scope = 0 | |
@flash_color = Color.new(255,255,255,255) | |
@flash_duration = 5 | |
@condition = 0 | |
end | |
end | |
end | |
class Tileset | |
def initialize | |
@id = 0 | |
@name = "" | |
@tileset_name = "" | |
@autotile_names = [""]*7 | |
@panorama_name = "" | |
@panorama_hue = 0 | |
@fog_name = "" | |
@fog_hue = 0 | |
@fog_opacity = 64 | |
@fog_blend_type = 0 | |
@fog_zoom = 200 | |
@fog_sx = 0 | |
@fog_sy = 0 | |
@battleback_name = "" | |
@passages = Table.new(384) | |
@priorities = Table.new(384) | |
@priorities[0] = 5 | |
@terrain_tags = Table.new(384) | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name) | |
}.to_json(*a) | |
end | |
end | |
class CommonEvent | |
def initialize | |
@id = 0 | |
@name = "" | |
@trigger = 0 | |
@switch_id = 1 | |
@list = [RPG::EventCommand.new] | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'name' => dump_string(@name), | |
'commands' => merge_event_commands(@list) | |
}.to_json(*a) | |
end | |
end | |
class System | |
def initialize | |
@magic_number = 0 | |
@party_members = [1] | |
@elements = [nil, ""] | |
@switches = [nil, ""] | |
@variables = [nil, ""] | |
@windowskin_name = "" | |
@title_name = "" | |
@gameover_name = "" | |
@battle_transition = "" | |
@title_bgm = RPG::AudioFile.new | |
@battle_bgm = RPG::AudioFile.new | |
@battle_end_me = RPG::AudioFile.new | |
@gameover_me = RPG::AudioFile.new | |
@cursor_se = RPG::AudioFile.new("", 80) | |
@decision_se = RPG::AudioFile.new("", 80) | |
@cancel_se = RPG::AudioFile.new("", 80) | |
@buzzer_se = RPG::AudioFile.new("", 80) | |
@equip_se = RPG::AudioFile.new("", 80) | |
@shop_se = RPG::AudioFile.new("", 80) | |
@save_se = RPG::AudioFile.new("", 80) | |
@load_se = RPG::AudioFile.new("", 80) | |
@battle_start_se = RPG::AudioFile.new("", 80) | |
@escape_se = RPG::AudioFile.new("", 80) | |
@actor_collapse_se = RPG::AudioFile.new("", 80) | |
@enemy_collapse_se = RPG::AudioFile.new("", 80) | |
@words = RPG::System::Words.new | |
@test_battlers = [] | |
@test_troop_id = 1 | |
@start_map_id = 1 | |
@start_x = 0 | |
@start_y = 0 | |
@battleback_name = "" | |
@battler_name = "" | |
@battler_hue = 0 | |
@edit_map_id = 1 | |
end | |
def to_json(*a) | |
{ | |
'json_class' => self.class.name, | |
'elements' => dump_array(@elements), | |
'switches' => dump_array(@switches), | |
'variables' => dump_array(@variables), | |
'words' => @words | |
}.to_json(*a) | |
end | |
class Words | |
def initialize | |
@gold = "" | |
@hp = "" | |
@sp = "" | |
@str = "" | |
@dex = "" | |
@agi = "" | |
@int = "" | |
@atk = "" | |
@pdef = "" | |
@mdef = "" | |
@weapon = "" | |
@armor1 = "" | |
@armor2 = "" | |
@armor3 = "" | |
@armor4 = "" | |
@attack = "" | |
@skill = "" | |
@guard = "" | |
@item = "" | |
@equip = "" | |
end | |
def to_json(*a) | |
{ | |
'gold' => dump_string(@gold), | |
'hp' => dump_string(@hp), | |
'sp' => dump_string(@sp), | |
'str' => dump_string(@str), | |
'dex' => dump_string(@dex), | |
'agi' => dump_string(@agi), | |
'int' => dump_string(@int), | |
'atk' => dump_string(@atk), | |
'pdef' => dump_string(@pdef), | |
'mdef' => dump_string(@mdef), | |
'weapon' => dump_string(@weapon), | |
'armor1' => dump_string(@armor1), | |
'armor2' => dump_string(@armor2), | |
'armor3' => dump_string(@armor3), | |
'armor4' => dump_string(@armor4), | |
'attack' => dump_string(@attack), | |
'skill' => dump_string(@skill), | |
'guard' => dump_string(@guard), | |
'item' => dump_string(@item), | |
'equip' => dump_string(@equip) | |
}.to_json(*a) | |
end | |
end | |
class TestBattler | |
def initialize | |
@actor_id = 1 | |
@level = 1 | |
@weapon_id = 0 | |
@armor1_id = 0 | |
@armor2_id = 0 | |
@armor3_id = 0 | |
@armor4_id = 0 | |
end | |
end | |
end | |
class AudioFile | |
def initialize(name = "", volume = 100, pitch = 100) | |
@name = name | |
@volume = volume | |
@pitch = pitch | |
end | |
end | |
end | |
# Table of what type of event command the event codes corresponds to. | |
EVENT_COMMAND_CODES = { | |
0 => ["Empty", false], | |
101 => ["Show Text", true], | |
102 => ["Show Choices", true], | |
103 => ["Input Number", false], | |
104 => ["Change Text Options", false], | |
105 => ["Button Input Processing", false], | |
106 => ["Wait", false], | |
108 => ["Comment", true], | |
111 => ["Conditional Branch", false], | |
112 => ["Loop", false], | |
113 => ["Break Loop", false], | |
115 => ["Exit Event Processing"], | |
116 => ["Erase Event"], | |
117 => ["Call Common Event", false], | |
118 => ["Label", false], | |
119 => ["Jump to Label", false], | |
121 => ["Control Switches", false], | |
122 => ["Control Variables", false], | |
123 => ["Control Self Switch", false], | |
124 => ["Control Timer", false], | |
125 => ["Change Gold", false], | |
126 => ["Change Items", false], | |
127 => ["Change Weapons", false], | |
128 => ["Change Armor", false], | |
129 => ["Change Party Member", false], | |
131 => ["Change Windowskin", false], | |
132 => ["Change Battle BGM", false], | |
133 => ["Change Battle End ME", false], | |
134 => ["Change Save Access", false], | |
135 => ["Change Menu Access", false], | |
136 => ["Change Encounter", false], | |
201 => ["Transfer Player", false], | |
202 => ["Set Event Location", false], | |
203 => ["Scroll Map", false], | |
204 => ["Change Map Settings", false], | |
205 => ["Change Fog Color Tone", false], | |
206 => ["Change Fog Opacity", false], | |
207 => ["Show Animation", false], | |
208 => ["Change Transparent Flag", false], | |
209 => ["Set Move Route", false], | |
210 => ["Wait for Move's Completion", false], | |
221 => ["Prepare for Transition", false], | |
222 => ["Execute Transition", false], | |
223 => ["Change Screen Color Tone", false], | |
224 => ["Screen Flash", false], | |
225 => ["Screen Shake", false], | |
231 => ["Show Picture", false], | |
232 => ["Move Picture", false], | |
233 => ["Rotate Picture", false], | |
234 => ["Change Picture Color Tone", false], | |
235 => ["Erase Picture", false], | |
236 => ["Set Weather Effects", false], | |
241 => ["Play BGM", false], | |
242 => ["Fade Out BGM", false], | |
245 => ["Play BGS", false], | |
246 => ["Fade Out BGS", false], | |
247 => ["Memorize BGM/BGS", false], | |
248 => ["Restore BGM/BGS", false], | |
249 => ["Play ME", false], | |
250 => ["Play SE", false], | |
251 => ["Stop SE", false], | |
301 => ["Battle Processing", false], | |
302 => ["Shop Processing", false], | |
303 => ["Name Input Processing", false], | |
311 => ["Change HP", false], | |
312 => ["Change SP", false], | |
313 => ["Change State", false], | |
314 => ["Recover All", false], | |
315 => ["Change EXP", false], | |
316 => ["Change Level", false], | |
317 => ["Change Parameters", false], | |
318 => ["Change Skills", false], | |
319 => ["Change Equipment", false], | |
320 => ["Change Actor Name", true], | |
321 => ["Change Actor Class", false], | |
322 => ["Change Actor Graphic", false], | |
331 => ["Change Enemy HP", false], | |
332 => ["Change Enemy SP", false], | |
333 => ["Change Enemy State", false], | |
334 => ["Enemy Recover All", false], | |
335 => ["Enemy Appearance", false], | |
336 => ["Enemy Transform", false], | |
337 => ["Show Battle Animation", false], | |
338 => ["Deal Damage", false], | |
339 => ["Force Action", false], | |
340 => ["Abort Battle", false], | |
351 => ["Call Menu Screen", false], | |
352 => ["Call Save Screen", false], | |
353 => ["Game Over", false], | |
354 => ["Return to Title Screen", false], | |
355 => ["Script", true], | |
401 => ["Show Text More", true], | |
402 => ["When", false], | |
403 => ["When Cancel", false], | |
404 => ["Choices End", false], | |
408 => ["Comment More", true], | |
411 => ["Else", false], | |
412 => ["Branch End", false], | |
413 => ["Repeat Above", false], | |
509 => ["Move Command", false], | |
601 => ["If Win", false], | |
602 => ["If Escape", false], | |
603 => ["If Lose", false], | |
604 => ["Battle Processing End", false], | |
605 => ["Shop Item", false], | |
655 => ["Script More", true] | |
} | |
# Given an event code, returns the type of the event and whether it can contain | |
# something translatable. | |
def get_event_type(code) | |
type = EVENT_COMMAND_CODES[code] | |
type.nil? ? [code, false] : type | |
end | |
def merge_event_commands(commands) | |
merged_cmds = [] | |
i = 0 | |
while i < commands.length | |
cmd = commands[i] | |
match_code = case cmd.code | |
when 101 then 401 # Show Text | |
when 108 then 408 # Comment | |
when 355 then 655 # Script | |
else 0 | |
end | |
if match_code != 0 and commands[i+1].code == match_code | |
params = cmd.parameters | |
while commands[i+1].code == match_code | |
i += 1 | |
params.concat commands[i].parameters | |
end | |
cmd = RPG::EventCommand.new(cmd.code, cmd.indent, params) | |
end | |
merged_cmds.push cmd | |
i += 1 | |
end | |
merged_cmds | |
end | |
def split_event_commands(commands) | |
split_cmds = [] | |
commands.each do |cmd| | |
match_code = case cmd.code | |
when 101 then 401 | |
when 108 then 408 | |
when 355 then 655 | |
else 0 | |
end | |
if match_code != 0 and cmd.parameters.length > 1 | |
code = cmd.code | |
cmd.parameters.each do |p| | |
split_cmds.push RPG::EventCommand.new(code, cmd.indent, [p]) | |
code = match_code | |
end | |
else | |
split_cmds.push cmd | |
end | |
end | |
split_cmds | |
end |
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
#!/usr/bin/env ruby | |
# coding: utf-8 | |
require 'yaml' | |
require 'zlib' | |
require_relative 'rmvxace_db' | |
if not File.exists?('translation_out') | |
Dir.mkdir('translation_out') | |
end | |
if not File.exists?('translation_out/Data') | |
Dir.mkdir('translation_out/Data') | |
end | |
[ | |
'translation_out/Data/Actors.yml', | |
'translation_out/Data/Animations.yml', | |
'translation_out/Data/Armors.yml', | |
'translation_out/Data/Classes.yml', | |
'translation_out/Data/CommonEvents.yml', | |
'translation_out/Data/Enemies.yml', | |
'translation_out/Data/Items.yml', | |
*Dir.glob('translation_out/Data/Map[0-9][0-9][0-9].yml'), | |
'translation_out/Data/MapInfos.yml', | |
'translation_out/Data/Skills.yml', | |
'translation_out/Data/States.yml', | |
'translation_out/Data/System.yml', | |
'translation_out/Data/Tilesets.yml', | |
'translation_out/Data/Troops.yml', | |
'translation_out/Data/Weapons.yml' | |
].each do |yml| | |
if not File.exists?(yml); next end | |
data = '' | |
data = YAML.load_file(yml) | |
out_file = 'translation_out/Data/'+File.basename(yml,'.yml')+'.rvdata2' | |
if not File.exists?(out_file) | |
puts "Packaging... #{out_file}" | |
File.open(out_file, 'wb') do |file| | |
file.write(Marshal.dump(data)) | |
end | |
end | |
end | |
if not File.exists?('Data/Scripts'); exit end | |
puts "Packaging... translation_out/Data/Scripts.rvdata2" | |
data_old = Marshal.load(File.open('Data/Scripts.rvdata2', 'rb')) | |
class Array | |
def row_index(item, column) | |
self.each_with_index{|raw, i| return i if raw[column] == item} | |
return | |
end | |
end | |
Dir.glob('Data/Scripts/*.rb') do |rb| | |
name = File.basename(rb, '.rb') | |
File.open(rb, 'rb') do |file| | |
script = file.read | |
if script.length < 100; next end | |
index_ = data_old.row_index(name, 1) | |
if index_ | |
oldname = data_old[index_][1] | |
if not Zlib::Inflate.inflate(data_old[index_][2]).eql? script | |
puts " Replacing... #{name}" | |
data_old[index_][2] = Zlib::Deflate.deflate(script) | |
end | |
end | |
end | |
end | |
File.open('translation_out/Data/Scripts.rvdata2', 'wb') do |file| | |
file.write(Marshal.dump(data_old)) | |
end |
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
#!/usr/bin/env ruby | |
# coding: cp932 | |
require 'yaml' | |
require 'zlib' | |
require_relative 'rmxp_db' | |
if not File.exists?('translation_out') | |
Dir.mkdir('translation_out') | |
end | |
if not File.exists?('translation_out/Data') | |
Dir.mkdir('translation_out/Data') | |
end | |
[ | |
'translation_out/Data/Actors.yml', | |
'translation_out/Data/Animations.yml', | |
'translation_out/Data/Armors.yml', | |
'translation_out/Data/Classes.yml', | |
'translation_out/Data/CommonEvents.yml', | |
'translation_out/Data/Enemies.yml', | |
'translation_out/Data/Items.yml', | |
*Dir.glob('translation_out/Data/Map[0-9][0-9][0-9].yml'), | |
'translation_out/Data/MapInfos.yml', | |
'translation_out/Data/Skills.yml', | |
'translation_out/Data/States.yml', | |
'translation_out/Data/System.yml', | |
'translation_out/Data/Troops.yml', | |
'translation_out/Data/Weapons.yml' | |
].each do |yml| | |
if not File.exists?(yml); next end | |
data = '' | |
data = YAML.load_file(yml) | |
out_file = 'translation_out/Data/'+File.basename(yml,'.yml')+'.rxdata' | |
if not File.exists?(out_file) | |
puts "Packaging... #{out_file}" | |
File.open(out_file, 'wb') do |file| | |
file.write(Marshal.dump(data)) | |
end | |
end | |
end | |
if not File.exists?('Data/Scripts'); exit end | |
puts "Packaging... translation_out/Data/Scripts.rxdata" | |
data_old = Marshal.load(File.open('Data/Scripts.rxdata', 'rb')) | |
class Array | |
def row_index(item, column) | |
self.each_with_index{|raw, i| return i if raw[column] == item} | |
return | |
end | |
end | |
Dir.glob('Data/Scripts/*.rb') do |rb| | |
name = File.basename(rb, '.rb') | |
File.open(rb, 'rb') do |file| | |
script = file.read | |
if script.length < 100; next end | |
index_ = data_old.row_index(name, 1) | |
if index_ | |
oldname = data_old[index_][1] | |
if not Zlib::Inflate.inflate(data_old[index_][2]).eql? script | |
puts " Replacing... #{name}" | |
data_old[index_][2] = Zlib::Deflate.deflate(script) | |
end | |
end | |
end | |
end | |
File.open('translation_out/Data/Scripts.rxdata', 'wb') do |file| | |
file.write(Marshal.dump(data_old)) | |
end |
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
#!/usr/bin/env ruby | |
# coding: utf-8 | |
require 'zlib' | |
require 'psych' | |
require 'yaml' | |
require_relative 'rmvxace_db' | |
module PsychIntegerParsingPatch | |
def parse_int string | |
Integer(string.gsub(/[,_]+/, '')) | |
end | |
end | |
Psych::ScalarScanner.prepend(PsychIntegerParsingPatch) | |
def load_rvdata2(file) | |
Marshal.load(File.open(file, 'rb')) | |
end | |
def save_yaml(file, data) | |
File.open(file, 'w') do |f| | |
f.write(YAML.dump(data)) | |
end | |
end | |
DATA_NAMES = %w{ | |
Actors Animations Armors | |
Classes CommonEvents Enemies | |
Items MapInfos Skills | |
States System Tilesets | |
Troops Weapons | |
} | |
DATA_NAMES.each do |name| | |
rvdata_filename = 'Data/' + name + '.rvdata2' | |
yaml_filename = 'Data/' + name + '.yml' | |
puts "Unpacking... #{name}" | |
data = load_rvdata2(rvdata_filename) | |
save_yaml(yaml_filename, data) | |
end | |
# Map | |
Dir.glob('Data/Map[0-9][0-9][0-9].rvdata2').each do |rvdata_filename| | |
yaml_filename = 'Data/' + File.basename(rvdata_filename, ".*") + '.yml' | |
puts "Unpacking... #{rvdata_filename}" | |
data = load_rvdata2(rvdata_filename) | |
save_yaml(yaml_filename, data) | |
end | |
def cleanup_scripts_rb | |
if File.exists?('Data/Scripts') | |
Dir.glob('Data/Scripts/*.rb') do |file| | |
File::delete(file) | |
end | |
else | |
Dir.mkdir('Data/Scripts') | |
end | |
end | |
# Scripts | |
def unpack_scripts | |
data = load_rvdata2('Data/Scripts.rvdata2') | |
indexes = [] | |
data.each do |id, name, script| | |
if name.empty? | |
next | |
end | |
#puts "Unpacking... Scripts/#{name}" | |
indexes << id | |
File.open('Data/Scripts/'+name+'.rb', 'wb') do |f| | |
#f.write "# -*- id: #{id} -*-\n" | |
f.write Zlib::Inflate.inflate(script) | |
#f.write "\n# -*- END_OF_SCRIPT -*-\n\n" | |
end | |
end | |
File.open('Data/Scripts.yml', 'wb') do |file| | |
file.write(YAML.dump(indexes)) | |
end | |
end | |
puts "Unpacking... Scripts" | |
cleanup_scripts_rb | |
unpack_scripts |
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
#!/usr/bin/env ruby | |
# coding: cp932 | |
require 'zlib' | |
require 'psych' | |
require 'zaml' | |
require_relative 'rmxp_db' | |
module PsychIntegerParsingPatch | |
def parse_int string | |
Integer(string.gsub(/[,_]+/, '')) | |
end | |
end | |
Psych::ScalarScanner.prepend(PsychIntegerParsingPatch) | |
def load_rvdata2(file) | |
Marshal.load(File.open(file, 'rb')) | |
end | |
def save_yaml(file, data) | |
File.open(file, 'w:cp932') do |f| | |
f.write(ZAML.dump(data)) | |
end | |
end | |
DATA_NAMES = %w{ | |
Actors Animations Armors | |
Classes CommonEvents Enemies | |
Items MapInfos Skills | |
States System | |
Troops Weapons | |
} | |
DATA_NAMES.each do |name| | |
rvdata_filename = 'Data/' + name + '.rxdata' | |
yaml_filename = 'Data/' + name + '.yml' | |
puts "Unpacking... #{name}" | |
data = load_rvdata2(rvdata_filename) | |
save_yaml(yaml_filename, data) | |
end | |
# Map | |
Dir.glob('Data/Map[0-9][0-9][0-9].rxdata').each do |rvdata_filename| | |
yaml_filename = 'Data/' + File.basename(rvdata_filename, ".*") + '.yml' | |
puts "Unpacking... #{rvdata_filename}" | |
data = load_rvdata2(rvdata_filename) | |
save_yaml(yaml_filename, data) | |
end | |
def cleanup_scripts_rb | |
if File.exists?('Data/Scripts') | |
Dir.glob('Data/Scripts/*.rb') do |file| | |
File::delete(file) | |
end | |
else | |
Dir.mkdir('Data/Scripts') | |
end | |
end | |
# Scripts | |
def unpack_scripts | |
data = load_rvdata2('Data/Scripts.rxdata') | |
indexes = [] | |
data.each do |id, name, script| | |
if name.empty? | |
next | |
end | |
#puts "Unpacking... Scripts/#{name}" | |
indexes << id | |
File.open('Data/Scripts/'+name+'.rb', 'wb') do |f| | |
#f.write "# -*- id: #{id} -*-\n" | |
f.write Zlib::Inflate.inflate(script) | |
#f.write "\n# -*- END_OF_SCRIPT -*-\n\n" | |
end | |
end | |
File.open('Data/Scripts.yml', 'wb') do |file| | |
file.write(ZAML.dump(indexes)) | |
end | |
end | |
puts "Unpacking... Scripts" | |
cleanup_scripts_rb | |
unpack_scripts |
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
#!/bin/env ruby | |
# encoding: utf-8 | |
# | |
# ZAML -- A partial replacement for YAML, writen with speed and code clarity | |
# in mind. ZAML fixes one YAML bug (loading Exceptions) and provides | |
# a replacement for YAML.dump() unimaginatively called ZAML.dump(), | |
# which is faster on all known cases and an order of magnitude faster | |
# with complex structures. | |
# | |
# http://github.com/hallettj/zaml | |
# | |
# Authors: Markus Roberts, Jesse Hallett, Ian McIntosh, Igal Koshevoy, Simon Chiang | |
# | |
require 'yaml' | |
class ZAML | |
VERSION = "0.1.3" | |
# | |
# Class Methods | |
# | |
def self.dump(stuff, where='') | |
z = new | |
stuff.to_zaml(z) | |
where << z.to_s | |
end | |
# | |
# Instance Methods | |
# | |
def initialize | |
@result = [] | |
@indent = nil | |
@structured_key_prefix = nil | |
Label.counter_reset | |
emit('--- ') | |
end | |
def nested(tail=' ') | |
old_indent = @indent | |
@indent = "#{@indent || "\n"}#{tail}" | |
yield | |
@indent = old_indent | |
end | |
class Label | |
# | |
# YAML only wants objects in the datastream once; if the same object | |
# occurs more than once, we need to emit a label ("&idxxx") on the | |
# first occurrence and then emit a back reference (*idxxx") on any | |
# subsequent occurrence(s). | |
# | |
# To accomplish this we keeps a hash (by object id) of the labels of | |
# the things we serialize as we begin to serialize them. The labels | |
# initially serialize as an empty string (since most objects are only | |
# going to be be encountered once), but can be changed to a valid | |
# (by assigning it a number) the first time it is subsequently used, | |
# if it ever is. Note that we need to do the label setup BEFORE we | |
# start to serialize the object so that circular structures (in | |
# which we will encounter a reference to the object as we serialize | |
# it can be handled). | |
# | |
def self.counter_reset | |
@@previously_emitted_object = {} | |
@@next_free_label_number = 0 | |
end | |
def initialize(obj,indent) | |
@indent = indent | |
@this_label_number = nil | |
@@previously_emitted_object[obj.object_id] = self | |
end | |
def to_s | |
@this_label_number ? ('&id%03d%s' % [@this_label_number, @indent]) : '' | |
end | |
def reference | |
@this_label_number ||= (@@next_free_label_number += 1) | |
@reference ||= '*id%03d' % @this_label_number | |
end | |
def self.for(obj) | |
@@previously_emitted_object[obj.object_id] | |
end | |
end | |
def new_label_for(obj) | |
Label.new(obj,(Hash === obj || Array === obj) ? "#{@indent || "\n"} " : ' ') | |
end | |
def first_time_only(obj) | |
if label = Label.for(obj) | |
emit(label.reference) | |
else | |
if @structured_key_prefix and not obj.is_a? String | |
emit(@structured_key_prefix) | |
@structured_key_prefix = nil | |
end | |
emit(new_label_for(obj)) | |
yield | |
end | |
end | |
def emit(s) | |
@result << s | |
@recent_nl = false unless s.kind_of?(Label) | |
end | |
def nl(s='') | |
emit(@indent || "\n") unless @recent_nl | |
emit(s) | |
@recent_nl = true | |
end | |
def to_s | |
@result.join | |
end | |
def prefix_structured_keys(x) | |
@structured_key_prefix = x | |
yield | |
nl unless @structured_key_prefix | |
@structured_key_prefix = nil | |
end | |
end | |
################################################################ | |
# | |
# Behavior for custom classes | |
# | |
################################################################ | |
class Object | |
def to_yaml_properties | |
instance_variables.sort # Default YAML behavior | |
end | |
def zamlized_class_name(root) | |
"!ruby/#{root.name.downcase}#{self.class == root ? '' : ":#{self.class.name}"}" | |
end | |
def to_zaml(z) | |
z.first_time_only(self) { | |
z.emit(zamlized_class_name(Object)) | |
z.nested { | |
instance_variables = to_yaml_properties | |
if instance_variables.empty? | |
z.emit(" {}") | |
else | |
instance_variables.each { |v| | |
z.nl | |
v[1..-1].to_zaml(z) # Remove leading '@' | |
z.emit(': ') | |
instance_variable_get(v).to_zaml(z) | |
} | |
end | |
} | |
} | |
end | |
end | |
################################################################ | |
# | |
# Behavior for built-in classes | |
# | |
################################################################ | |
class NilClass | |
def to_zaml(z) | |
z.emit('') # NOTE: blank turns into nil in YAML.load | |
end | |
end | |
class Symbol | |
def to_zaml(z) | |
z.emit(self.inspect) | |
end | |
end | |
class TrueClass | |
def to_zaml(z) | |
z.emit('true') | |
end | |
end | |
class FalseClass | |
def to_zaml(z) | |
z.emit('false') | |
end | |
end | |
class Numeric | |
def to_zaml(z) | |
z.emit(self) | |
end | |
end | |
class Regexp | |
def to_zaml(z) | |
z.first_time_only(self) { z.emit("#{zamlized_class_name(Regexp)} #{inspect}") } | |
end | |
end | |
class Exception | |
def to_zaml(z) | |
z.emit(zamlized_class_name(Exception)) | |
z.nested { | |
z.nl("message: ") | |
message.to_zaml(z) | |
} | |
end | |
# | |
# Monkey patch for buggy Exception restore in YAML | |
# | |
# This makes it work for now but is not very future-proof; if things | |
# change we'll most likely want to remove this. To mitigate the risks | |
# as much as possible, we test for the bug before appling the patch. | |
# | |
if respond_to? :yaml_new and yaml_new(self, :tag, "message" => "blurp").message != "blurp" | |
def self.yaml_new( klass, tag, val ) | |
o = YAML.object_maker( klass, {} ).exception(val.delete( 'message')) | |
val.each_pair do |k,v| | |
o.instance_variable_set("@#{k}", v) | |
end | |
o | |
end | |
end | |
end | |
class String | |
ZAML_ESCAPES = %w{\x00 \x01 \x02 \x03 \x04 \x05 \x06 \a \x08 \t \n \v \f \r \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \e \x1c \x1d \x1e \x1f } | |
def escaped_for_zaml | |
gsub( /\x5C/, "\\\\\\" ). # Demi-kludge for Maglev/rubinius; the regexp should be /\\/ but parsetree chokes on that. | |
gsub( /"/, "\\\"" ) | |
end | |
def to_zaml(z) | |
z.first_time_only(self) { | |
num = '[-+]?(0x)?\d+\.?\d*' | |
case | |
when self == '' | |
self.force_encoding('cp932') | |
z.emit('""') | |
when ( | |
(self =~ /\A(true|false|yes|no|on|null|off|#{num}(:#{num})*|!|=|~)$/i) or | |
(self =~ /\A\n* /) or | |
(self =~ /[\s:]/) or | |
(self =~ /^[>|][-+\d]*\s/i) or | |
(self[-1..-1] =~ /\s/) or | |
(self =~ /[,\[\]\{\}\r\t]|:\s|\s#/) or | |
(self =~ /\A([-:?!#&*'"]|<<|%.+:.)/) | |
) | |
z.emit("\"#{escaped_for_zaml.force_encoding('cp932')}\"") | |
when self =~ /\n/ | |
self.force_encoding('cp932') | |
if self[-1..-1] == "\n" then z.emit('|+') else z.emit('|-') end | |
z.nested { split("\n",-1).each { |line| z.nl; z.emit(line.chomp("\n")) } } | |
z.nl | |
else | |
self.force_encoding('cp932') | |
z.emit(self) | |
end | |
} | |
end | |
end | |
class Hash | |
def to_zaml(z) | |
z.first_time_only(self) { | |
z.nested { | |
if empty? | |
z.emit('{}') | |
else | |
each_pair { |k, v| | |
z.nl | |
z.prefix_structured_keys('? ') { k.to_zaml(z) } | |
z.emit(': ') | |
v.to_zaml(z) | |
} | |
end | |
} | |
} | |
end | |
end | |
class Array | |
def to_zaml(z) | |
z.first_time_only(self) { | |
z.nested { | |
if empty? | |
z.emit('[]') | |
else | |
each { |v| z.nl('- '); v.to_zaml(z) } | |
end | |
} | |
} | |
end | |
end | |
class Time | |
def to_zaml(z) | |
# 2008-12-06 10:06:51.373758 -07:00 | |
ms = ("%0.6f" % (usec * 1e-6)).sub(/^\d+\./,'') | |
offset = "%+0.2i:%0.2i" % [utc_offset / 3600, (utc_offset / 60) % 60] | |
z.emit(self.strftime("%Y-%m-%d %H:%M:%S.#{ms} #{offset}")) | |
end | |
end | |
class Date | |
def to_zaml(z) | |
z.emit(strftime('%Y-%m-%d')) | |
end | |
end | |
class Range | |
def to_zaml(z) | |
z.first_time_only(self) { | |
z.emit(zamlized_class_name(Range)) | |
z.nested { | |
z.nl | |
z.emit('begin: ') | |
z.emit(first) | |
z.nl | |
z.emit('end: ') | |
z.emit(last) | |
z.nl | |
z.emit('excl: ') | |
z.emit(exclude_end?) | |
} | |
} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment