rmxp_extractor 1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d7b51a145563f360dc65d561c466e707c589d49a4263a28f736e91c3e0159ed6
4
+ data.tar.gz: 134a976c1dd75b55dd314d85af0b03c14a38135b5d12f0abf7704042039ddea4
5
+ SHA512:
6
+ metadata.gz: 21223fc5624bc66b467e6a4f7039c58e2831ce3b8b90a728798515b3725bb01bc7010f268ada2b573fc61333681978af3c4e27ff0f28c516dbfbd6835ba366a4
7
+ data.tar.gz: 30b67b3168a7d63789cddd215e022f94138a06c9de3c2eb3111a9b32b598b89b4deae31374dac051d2e47b24177cfb18b5e9f1f303febaf66570e39eafaac78b
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at matthew@nowaffles.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rmxp_extractor.gemspec
4
+ gemspec
5
+
6
+ gem "oj"
7
+ gem "ruby-progressbar"
8
+ gem "fileutils"
9
+ gem "pathname"
10
+ gem "json"
11
+ gem "zlib"
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rmxp_extractor (1.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ fileutils (1.5.0)
10
+ json (2.5.1)
11
+ oj (3.11.5)
12
+ pathname (0.1.0)
13
+ ruby-progressbar (1.11.0)
14
+ zlib (1.1.0)
15
+
16
+ PLATFORMS
17
+ x64-mingw32
18
+
19
+ DEPENDENCIES
20
+ fileutils
21
+ json
22
+ oj
23
+ pathname
24
+ rmxp_extractor!
25
+ ruby-progressbar
26
+ zlib
27
+
28
+ BUNDLED WITH
29
+ 2.1.4
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Speak2Erase
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # RMXP-Extractor
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rmxp_extractor`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'rmxp_extractor'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install rmxp_extractor
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rmxp_extractor. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/rmxp_extractor/blob/master/CODE_OF_CONDUCT.md).
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
41
+
42
+ ## Code of Conduct
43
+
44
+ Everyone interacting in the RMXP-Extractor project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/rmxp_extractor/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rmxp_extractor"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ RMXPExtractor.process ARGV
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,22 @@
1
+ module RMXPExtractor
2
+ require "rmxp_extractor/data_export"
3
+ require "rmxp_extractor/data_import"
4
+ require "rmxp_extractor/version"
5
+
6
+ def self.usage
7
+ STDERR.puts "usage: data-extractor.rb import|export"
8
+ exit 1
9
+ end
10
+
11
+ def self.process(type)
12
+ RMXPExtractor.usage if type.length < 1
13
+
14
+ if type[0] == "import"
15
+ RMXPExtractor.import
16
+ elsif type[0] == "export"
17
+ RMXPExtractor.export
18
+ else
19
+ RMXPExtractor.usage
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,1163 @@
1
+ class Color
2
+ attr_accessor :red, :green, :blue, :alpha
3
+
4
+ def initialize(hash)
5
+ @red = hash["red"]
6
+ @green = hash["green"]
7
+ @blue = hash["blue"]
8
+ @alpha = hash["alpha"]
9
+ end
10
+
11
+ def hash
12
+ dump = {
13
+ red: @red,
14
+ green: @green,
15
+ blue: @blue,
16
+ alpha: @alpha,
17
+ }
18
+ end
19
+
20
+ def _dump(limit)
21
+ [@red, @green, @blue, @alpha].pack("EEEE")
22
+ end
23
+
24
+ def self._load(obj)
25
+ data = *obj.unpack("EEEE")
26
+ s_hash = {
27
+ red: data[0],
28
+ green: data[1],
29
+ blue: data[2],
30
+ alpha: data[3],
31
+ }
32
+ hash = {}
33
+ s_hash.each do |key, value|
34
+ hash[key.to_s] = value
35
+ end
36
+ Color.new hash
37
+ end
38
+ end
39
+
40
+ class Table
41
+ def initialize(hash, resize = true)
42
+ @num_of_dimensions = hash["dimensions"]
43
+ @xsize = hash["width"]
44
+ @ysize = hash["height"]
45
+ @zsize = hash["depth"]
46
+ @num_of_elements = hash["size"]
47
+ @elements = []
48
+ if @num_of_dimensions > 1 && !resize
49
+ hash["elements"].each_with_index do |value, uindex|
50
+ @elements << []
51
+ value.each_with_index do |value, index|
52
+ @elements[uindex] << eval(value) #!Yep, you can do this to turn strings back into arrays
53
+ end
54
+ end
55
+ else
56
+ @elements = hash["elements"]
57
+ end
58
+
59
+ if resize
60
+ if @num_of_dimensions > 1
61
+ if @xsize > 1
62
+ @elements = @elements.each_slice(@xsize).to_a
63
+ else
64
+ @elements = @elements.map { |element| [element] }
65
+ end
66
+ end
67
+ if @num_of_dimensions > 2
68
+ if @ysize > 1
69
+ @elements = @elements.each_slice(@ysize).to_a
70
+ else
71
+ @elements = @elements.map { |element| [element] }
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ def hash
78
+ dump = {
79
+ dimensions: @num_of_dimensions,
80
+ width: @xsize,
81
+ height: @ysize,
82
+ depth: @zsize,
83
+ size: @num_of_elements,
84
+ elements: [],
85
+ } #.pack("VVVVVv*")
86
+
87
+ if @num_of_dimensions > 1
88
+ @elements.each_with_index do |value, uindex|
89
+ dump[:elements] << []
90
+ value.each_with_index do |value, index|
91
+ dump[:elements][uindex] << value.to_s
92
+ end
93
+ end
94
+ else
95
+ dump[:elements] = *@elements
96
+ end
97
+
98
+ dump
99
+ end
100
+
101
+ def _dump(limit)
102
+ [@num_of_dimensions, @xsize, @ysize, @zsize, @num_of_elements, *@elements.flatten].pack("VVVVVv*")
103
+ end
104
+
105
+ def self._load(obj)
106
+ data = obj.unpack("VVVVVv*")
107
+ @num_of_dimensions, @xsize, @ysize, @zsize, @num_of_elements, *@elements = *data
108
+ s_hash = {
109
+ dimensions: @num_of_dimensions,
110
+ width: @xsize,
111
+ height: @ysize,
112
+ depth: @zsize,
113
+ size: @num_of_elements,
114
+ elements: [],
115
+ }
116
+ hash = {}
117
+ s_hash.each do |key, value|
118
+ hash[key.to_s] = value
119
+ end
120
+ hash["elements"] = *@elements
121
+
122
+ Table.new(hash)
123
+ end
124
+ end
125
+
126
+ class Tone
127
+ attr_accessor :red, :green, :blue, :gray
128
+
129
+ def initialize(hash = {})
130
+ @red = hash["red"]
131
+ @green = hash["green"]
132
+ @blue = hash["blue"]
133
+ @gray = hash["gray"]
134
+ end
135
+
136
+ def hash
137
+ dump = {
138
+ red: @red,
139
+ green: @green,
140
+ blue: @blue,
141
+ gray: @gray,
142
+ }
143
+ end
144
+
145
+ def _dump(limit)
146
+ [@red, @green, @blue, @gray].pack("EEEE")
147
+ end
148
+
149
+ def self._load(obj)
150
+ data = *obj.unpack("EEEE")
151
+ s_hash = {
152
+ "red": data[0],
153
+ "green": data[1],
154
+ "blue": data[2],
155
+ "gray": data[3],
156
+ }
157
+ hash = {}
158
+ s_hash.each do |key, value|
159
+ hash[key.to_s] = value
160
+ end
161
+ Tone.new hash
162
+ end
163
+ end
164
+
165
+ module RPG
166
+ class Event
167
+ def initialize(hash)
168
+ @id = hash["id"]
169
+ @name = hash["name"]
170
+ @x = hash["x"]
171
+ @y = hash["y"]
172
+ @pages = []
173
+ hash["pages"].each_with_index do |value|
174
+ @pages << RPG::Event::Page.new(value)
175
+ end
176
+ end
177
+
178
+ def hash
179
+ dump = {
180
+ id: @id,
181
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
182
+ x: @x,
183
+ y: @y,
184
+ pages: [],
185
+ }
186
+ @pages.each_with_index do |value|
187
+ dump[:pages] << value.hash
188
+ end
189
+ dump
190
+ end
191
+
192
+ class Page
193
+ def initialize(hash)
194
+ @condition = RPG::Event::Page::Condition.new hash["condition"]
195
+ @graphic = RPG::Event::Page::Graphic.new hash["graphic"]
196
+ @move_type = hash["move_type"]
197
+ @move_speed = hash["move_speed"]
198
+ @move_frequency = hash["move_frequency"]
199
+ @move_route = RPG::MoveRoute.new hash["move_route"]
200
+ @walk_anime = hash["walk_anime"]
201
+ @step_anime = hash["step_anime"]
202
+ @direction_fix = hash["direction_fix"]
203
+ @through = hash["through"]
204
+ @always_on_top = hash["always_on_top"]
205
+ @trigger = hash["trigger"]
206
+ @list = []
207
+ hash["list"].each_with_index do |value|
208
+ @list << RPG::EventCommand.new(value)
209
+ end
210
+ end
211
+
212
+ def hash
213
+ dump = {
214
+ condition: "",
215
+ graphic: "",
216
+ move_type: @move_type,
217
+ move_speed: @move_speed,
218
+ move_frequency: @move_frequency,
219
+ move_route: "",
220
+ walk_anime: @walk_anime,
221
+ step_anime: @step_anime,
222
+ direction_fix: @direction_fix,
223
+ through: @through,
224
+ always_on_top: @always_on_top,
225
+ trigger: @trigger,
226
+ list: [],
227
+ }
228
+ @list.each_with_index do |value|
229
+ dump[:list] << value.hash
230
+ end
231
+ dump[:condition] = @condition.hash
232
+ dump[:graphic] = @graphic.hash
233
+ dump[:move_route] = @move_route.hash
234
+ dump
235
+ end
236
+
237
+ class Condition
238
+ def initialize(hash)
239
+ @switch1_valid = hash["switch1_valid"]
240
+ @switch2_valid = hash["switch2_valid"]
241
+ @variable_valid = hash["variable_valid"]
242
+ @self_switch_valid = hash["self_switch_valid"]
243
+ @switch1_id = hash["switch1_id"]
244
+ @switch2_id = hash["switch2_id"]
245
+ @variable_id = hash["variable_id"]
246
+ @variable_value = hash["variable_value"]
247
+ @self_switch_ch = hash["self_switch_ch"]
248
+ end
249
+
250
+ def hash
251
+ dump = {
252
+ switch1_valid: @switch1_valid,
253
+ switch2_valid: @switch2_valid,
254
+ variable_valid: @variable_valid,
255
+ self_switch_valid: @self_switch_valid,
256
+ switch1_id: @switch1_id,
257
+ switch2_id: @switch2_id,
258
+ variable_id: @variable_id,
259
+ variable_value: @variable_value,
260
+ self_switch_ch: @self_switch_ch,
261
+ }
262
+ end
263
+ end
264
+
265
+ class Graphic
266
+ def initialize(hash)
267
+ @tile_id = hash["tile_id"]
268
+ @character_name = hash["character_name"]
269
+ @character_hue = hash["character_hue"]
270
+ @direction = hash["direction"]
271
+ @pattern = hash["pattern"]
272
+ @opacity = hash["opacity"]
273
+ @blend_type = hash["blend_type"]
274
+ end
275
+
276
+ def hash
277
+ dump = {
278
+ tile_id: @tile_id,
279
+ character_name: @character_name,
280
+ character_hue: @character_hue,
281
+ direction: @direction,
282
+ pattern: @pattern,
283
+ opacity: @opacity,
284
+ blend_type: @blend_type,
285
+ }
286
+ end
287
+ end
288
+ end
289
+ end
290
+
291
+ class EventCommand
292
+ def initialize(hash)
293
+ @code = hash["code"]
294
+ @indent = hash["indent"]
295
+ @parameters = []
296
+ hash["parameters"].each_with_index do |value|
297
+ if value.is_a?(Hash)
298
+ if hash["code"] == 250 || hash["code"] == 249 || hash["code"] == 241 || hash["code"] == 242 || hash["code"] == 245
299
+ @parameters << RPG::AudioFile.new(value)
300
+ elsif hash["code"] == 223 || hash["code"] == 234 || hash["code"] == 205
301
+ @parameters << Tone.new(value)
302
+ elsif hash["code"] == 224
303
+ @parameters << Color.new(value)
304
+ elsif hash["code"] == 509
305
+ @parameters << RPG::MoveCommand.new(value)
306
+ elsif hash["code"] == 209
307
+ @parameters << RPG::MoveRoute.new(value)
308
+ end
309
+ else
310
+ @parameters << value
311
+ end
312
+ end
313
+ end
314
+
315
+ def hash
316
+ dump = {
317
+ code: @code,
318
+ indent: @indent,
319
+ parameters: [],
320
+ }
321
+ @parameters.each_with_index do |value|
322
+ if value.to_s.match(/#<RPG::/) || value.to_s.match(/#<Tone:/) || value.to_s.match(/#<Color:/) || value.to_s.match(/#<Table:/)
323
+ dump[:parameters] << value.hash
324
+ elsif value.is_a? String
325
+ if value.encoding.to_s != "UTF-8"
326
+ dump[:parameters] << value.force_encoding("iso-8859-1").encode("utf-8")
327
+ else
328
+ dump[:parameters] << value
329
+ end
330
+ else
331
+ dump[:parameters] << value
332
+ end
333
+ end
334
+ dump
335
+ end
336
+ end
337
+
338
+ class MoveRoute
339
+ def initialize(hash)
340
+ @repeat = hash["repeat"]
341
+ @skippable = hash["skippable"]
342
+ @list = []
343
+ hash["list"].each_with_index do |value|
344
+ @list << RPG::MoveCommand.new(value)
345
+ end
346
+ end
347
+
348
+ def hash
349
+ dump = {
350
+ repeat: @repeat,
351
+ skippable: @skippable,
352
+ list: [],
353
+ }
354
+ @list.each_with_index do |value|
355
+ dump[:list] << value.hash
356
+ end
357
+ dump
358
+ end
359
+ end
360
+
361
+ class MoveCommand
362
+ def initialize(hash)
363
+ @code = hash["code"]
364
+ @parameters = []
365
+ hash["parameters"].each_with_index do |value|
366
+ if value.to_s.match(/#<RPG::/)
367
+ @parameters << RPG::AudioFile.new(value)
368
+ elsif value.to_s.match(/#<Tone:/)
369
+ @parameters << Tone.new(value)
370
+ elsif value.to_s.match(/#<Color:/)
371
+ @parameters << Color.new(value)
372
+ elsif value.to_s.match(/#<Table:/)
373
+ @parameters << Table.new(value, false)
374
+ else
375
+ @parameters << value
376
+ end
377
+ end
378
+ end
379
+
380
+ def hash
381
+ dump = {
382
+ code: @code,
383
+ parameters: [],
384
+ }
385
+ @parameters.each_with_index do |value|
386
+ if value.to_s.match(/#<RPG::/) || value.to_s.match(/#<Tone:/) || value.to_s.match(/#<Color:/) || value.to_s.match(/#<Table:/)
387
+ dump[:parameters] << value.hash
388
+ elsif value.is_a? String
389
+ dump[:parameters] << value.force_encoding("iso-8859-1").encode("utf-8")
390
+ else
391
+ dump[:parameters] << value
392
+ end
393
+ end
394
+ dump
395
+ end
396
+ end
397
+
398
+ class Map
399
+ def initialize(hash)
400
+ @tileset_id = hash["tileset_id"]
401
+ @width = hash["width"]
402
+ @height = hash["height"]
403
+ @autoplay_bgm = hash["autoplay_bgm"]
404
+ @autoplay_bgs = hash["autoplay_bgs"]
405
+ @bgm = RPG::AudioFile.new hash["bgm"]
406
+ @bgs = RPG::AudioFile.new hash["bgs"]
407
+ @encounter_list = hash["encounter_list"]
408
+ @encounter_step = hash["encounter_step"]
409
+ @data = Table.new(hash["data"], false)
410
+ @events = {}
411
+ events = hash["events"].sort_by { |key| key }.to_h
412
+ events.each do |key, value|
413
+ @events[key.to_i] = RPG::Event.new value
414
+ end
415
+ end
416
+
417
+ def hash
418
+ dump = {
419
+ tileset_id: @tileset_id,
420
+ width: @width,
421
+ height: @height,
422
+ autoplay_bgm: @autoplay_bgm,
423
+ bgm: @bgm.hash,
424
+ autoplay_bgs: @autoplay_bgs,
425
+ bgs: @bgs.hash,
426
+ encounter_list: @encounter_list,
427
+ encounter_step: @encounter_step,
428
+ events: {},
429
+ data: @data.hash,
430
+ }
431
+ events = @events.sort_by { |key| key }.to_h
432
+ events.each do |key, value|
433
+ dump[:events][key] = value.hash
434
+ end
435
+ dump
436
+ end
437
+ end
438
+
439
+ class MapInfo
440
+ attr_accessor :order
441
+
442
+ def initialize(hash)
443
+ @name = hash["name"]
444
+ @parent_id = hash["parent_id"]
445
+ @order = hash["order"]
446
+ @expanded = hash["expanded"]
447
+ @scroll_x = hash["scroll_x"]
448
+ @scroll_y = hash["scroll_y"]
449
+ end
450
+
451
+ def hash
452
+ dump = {
453
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
454
+ parent_id: @parent_id,
455
+ order: @order,
456
+ expanded: @expanded,
457
+ scroll_x: @scroll_x,
458
+ scroll_y: @scroll_y,
459
+ }
460
+ end
461
+ end
462
+
463
+ class AudioFile
464
+ def initialize(hash)
465
+ @name = hash["name"]
466
+ @volume = hash["volume"]
467
+ @pitch = hash["pitch"]
468
+ end
469
+
470
+ def hash
471
+ dump = {
472
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
473
+ volume: @volume,
474
+ pitch: @pitch,
475
+ }
476
+ end
477
+ end
478
+
479
+ class System
480
+ def initialize(hash)
481
+ hash.each do |key, value|
482
+ if value.is_a?(Hash)
483
+ if value["volume"] != nil
484
+ eval("@#{key.to_s}=RPG::AudioFile.new(value)")
485
+ else
486
+ eval("@#{key.to_s}=RPG::System::Words.new(value)")
487
+ end
488
+ else
489
+ eval("@#{key.to_s}=value")
490
+ end
491
+ end
492
+ end
493
+
494
+ def hash
495
+ dump = {
496
+ magic_number: @magic_number,
497
+ party_members: @party_members,
498
+ elements: @elements,
499
+ switches: @switches,
500
+ variables: @variables,
501
+ windowskin_name: @windowskin_name,
502
+ title_name: @title_name,
503
+ gameover_name: @gameover_name,
504
+ battle_transition: @battle_transition,
505
+
506
+ title_bgm: @title_bgm.hash,
507
+ battle_bgm: @battle_bgm.hash,
508
+ battle_end_me: @battle_end_me.hash,
509
+ gameover_me: @gameover_me.hash,
510
+ cursor_se: @cursor_se.hash,
511
+ decision_se: @decision_se.hash,
512
+ cancel_se: @cancel_se.hash,
513
+ buzzer_se: @buzzer_se.hash,
514
+ equip_se: @equip_se.hash,
515
+ shop_se: @shop_se.hash,
516
+ save_se: @save_se.hash,
517
+ load_se: @load_se.hash,
518
+ battle_start_se: @battle_start_se.hash,
519
+ escape_se: @escape_se.hash,
520
+ actor_collapse_se: @actor_collapse_se.hash,
521
+ enemy_collapse_se: @enemy_collapse_se.hash,
522
+
523
+ words: @words.hash,
524
+ test_battlers: [],
525
+ test_troop_id: @test_troop_id,
526
+ start_map_id: @start_map_id,
527
+ start_x: @start_x,
528
+ start_y: @start_y,
529
+ battleback_name: @battleback_name,
530
+ battler_name: @battler_name,
531
+ battler_hue: @battler_hue,
532
+ edit_map_id: @edit_map_id,
533
+ }
534
+ @test_battlers.each_with_index do |value, index|
535
+ dump[:test_battlers] << value.hash
536
+ end
537
+ dump
538
+ end
539
+
540
+ class Words
541
+ def initialize(hash)
542
+ hash.each do |key, value|
543
+ eval("@#{key.to_s}=value")
544
+ end
545
+ end
546
+
547
+ def hash
548
+ dump = {
549
+ gold: @gold,
550
+ hp: @hp,
551
+ sp: @sp,
552
+ str: @str,
553
+ dex: @dex,
554
+ agi: @agi,
555
+ int: @int,
556
+ atk: @atk,
557
+ pdef: @pdef,
558
+ mdef: @mdef,
559
+ weapon: @weapon,
560
+ armor1: @armor1,
561
+ armor2: @armor2,
562
+ armor3: @armor3,
563
+ armor4: @armor4,
564
+ attack: @attack,
565
+ skill: @skill,
566
+ guard: @guard,
567
+ item: @item,
568
+ equip: @equip,
569
+ }
570
+ end
571
+ end
572
+
573
+ class TestBattler
574
+ def hash
575
+ dump = {
576
+ actor_id: @actor_id,
577
+ level: @level,
578
+ weapon_id: @weapon_id,
579
+ armor1_id: @armor1_id,
580
+ armor2_id: @armor2_id,
581
+ armor3_id: @armor3_id,
582
+ armor4_id: @armor4_id,
583
+ }
584
+ end
585
+ end
586
+ end
587
+
588
+ class CommonEvent
589
+ def initialize(hash)
590
+ @id = hash["id"]
591
+ @name = hash["name"]
592
+ @trigger = hash["trigger"]
593
+ @switch_id = hash["switch_id"]
594
+ @list = []
595
+ hash["list"].each_with_index do |value|
596
+ @list << RPG::EventCommand.new(value)
597
+ end
598
+ end
599
+
600
+ def hash
601
+ dump = {
602
+ id: @id,
603
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
604
+ trigger: @trigger,
605
+ switch_id: @switch_id,
606
+ list: [],
607
+ }
608
+ @list.each_with_index do |value|
609
+ dump[:list] << value.hash
610
+ end
611
+ dump
612
+ end
613
+ end
614
+
615
+ class Tileset
616
+ def initialize(hash)
617
+ hash.each do |key, value|
618
+ if value.is_a?(Hash)
619
+ eval("@#{key.to_s}=Table.new(value, false)")
620
+ else
621
+ eval("@#{key.to_s}=value")
622
+ end
623
+ end
624
+ end
625
+
626
+ def hash
627
+ dump = {
628
+ id: @id,
629
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
630
+ tileset_name: @tileset_name,
631
+ autotile_names: @autotile_names,
632
+ panorama_name: @panorama_name,
633
+ panorama_hue: @panorama_hue,
634
+ fog_name: @fog_name,
635
+ fog_hue: @fog_hue,
636
+ fog_opacity: @fog_opacity,
637
+ fog_blend_type: @fog_blend_type,
638
+ fog_zoom: @fog_zoom,
639
+ fog_sx: @fog_sx,
640
+ fog_sy: @fog_sy,
641
+ battleback_name: @battleback_name,
642
+ passages: @passages.hash,
643
+ priorities: @priorities.hash,
644
+ terrain_tags: @terrain_tags.hash,
645
+ }
646
+ dump
647
+ end
648
+ end
649
+
650
+ class State
651
+ def initialize(hash)
652
+ hash.each do |key, value|
653
+ eval("@#{key.to_s}=value")
654
+ end
655
+ end
656
+
657
+ def hash
658
+ dump = {
659
+ id: @id,
660
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
661
+ animation_id: @animation_id,
662
+ restriction: @restriction,
663
+ nonresistance: @nonresistance,
664
+ zero_hp: @zero_hp,
665
+ cant_get_exp: @cant_get_exp,
666
+ cant_evade: @cant_evade,
667
+ slip_damage: @slip_damage,
668
+ rating: @rating,
669
+ hit_rate: @hit_rate,
670
+ maxhp_rate: @maxhp_rate,
671
+ maxsp_rate: @maxsp_rate,
672
+ str_rate: @str_rate,
673
+ dex_rate: @dex_rate,
674
+ agi_rate: @agi_rate,
675
+ int_rate: @int_rate,
676
+ atk_rate: @atk_rate,
677
+ pdef_rate: @pdef_rate,
678
+ mdef_rate: @mdef_rate,
679
+ eva: @eva,
680
+ battle_only: @battle_only,
681
+ hold_turn: @hold_turn,
682
+ auto_release_prob: @auto_release_prob,
683
+ shock_release_prob: @shock_release_prob,
684
+ guard_element_set: @guard_element_set,
685
+ plus_state_set: @plus_state_set,
686
+ minus_state_set: @minus_state_set,
687
+ }
688
+ end
689
+ end
690
+
691
+ class Animation
692
+ class Frame
693
+ def initialize(hash)
694
+ @cell_max = hash["cell_max"]
695
+ @cell_data = Table.new hash["cell_data"], false
696
+ end
697
+
698
+ def hash
699
+ dump = {
700
+ cell_max: @cell_max,
701
+ cell_data: @cell_data.hash,
702
+ }
703
+ end
704
+ end
705
+
706
+ class Timing
707
+ def initialize(hash)
708
+ @frame = hash["frame"]
709
+ @se = RPG::AudioFile.new hash["se"]
710
+ @flash_scope = hash["flash_scope"]
711
+ @flash_color = Color.new hash["flash_color"]
712
+ @flash_duration = hash["flash_duration"]
713
+ @condition = hash["condition"]
714
+ end
715
+
716
+ def hash
717
+ dump = {
718
+ frame: @frame,
719
+ se: @se.hash,
720
+ flash_scope: @flash_scope,
721
+ flash_color: @flash_color.hash,
722
+ flash_duration: @flash_duration,
723
+ condition: @condition,
724
+ }
725
+ end
726
+ end
727
+
728
+ def initialize(hash)
729
+ @id = hash["id"]
730
+ @name = hash["name"]
731
+ @animation_name = hash["animation_name"]
732
+ @animation_hue = hash["animation_hue"]
733
+ @position = hash["position"]
734
+ @frame_max = hash["frame_max"]
735
+ @frames = []
736
+ @timings = []
737
+ hash["frames"].each_with_index do |value|
738
+ @frames << RPG::Animation::Frame.new(value)
739
+ end
740
+ hash["timings"].each_with_index do |value|
741
+ @timings << RPG::Animation::Timing.new(value)
742
+ end
743
+ end
744
+
745
+ def hash
746
+ dump = {
747
+ id: @id,
748
+ name: @name,
749
+ animation_name: @animation_name,
750
+ animation_hue: @animation_hue,
751
+ position: @position,
752
+ frame_max: @frame_max,
753
+ frames: [],
754
+ timings: [],
755
+ }
756
+ @frames.each_with_index do |value|
757
+ dump[:frames] << value.hash
758
+ end
759
+ @timings.each_with_index do |value|
760
+ dump[:timings] << value.hash
761
+ end
762
+ dump
763
+ end
764
+ end
765
+
766
+ class Class
767
+ def initialize(hash)
768
+ @id = hash["id"]
769
+ @name = hash["name"]
770
+ @position = hash["position"]
771
+ @weapon_set = hash["weapon_set"]
772
+ @armor_set = hash["armor_set"]
773
+ @element_ranks = Table.new hash["element_ranks"], false
774
+ @state_ranks = Table.new hash["state_ranks"], false
775
+ @learnings = []
776
+ hash["learnings"].each_with_index do |value|
777
+ @learnings << RPG::Class::Learning.new(value)
778
+ end
779
+ end
780
+
781
+ class Learning
782
+ def initialize(hash)
783
+ @level = hash["level"]
784
+ @skill_id = hash["skill_id"]
785
+ end
786
+
787
+ def hash
788
+ dump = {
789
+ level: @level,
790
+ skill_id: @skill_id,
791
+ }
792
+ end
793
+ end
794
+
795
+ def hash
796
+ dump = {
797
+ id: @id,
798
+ name: @name,
799
+ position: @position,
800
+ weapon_set: @weapon_set,
801
+ armor_set: @armor_set,
802
+ element_ranks: @element_ranks.hash,
803
+ state_ranks: @state_ranks.hash,
804
+ learnings: [],
805
+ }
806
+ @learnings.each_with_index do |value|
807
+ dump[:learnings] << value.hash
808
+ end
809
+ dump
810
+ end
811
+ end
812
+
813
+ class Actor
814
+ def initialize(hash)
815
+ hash.each do |key, value|
816
+ if value.is_a?(Hash)
817
+ eval("@#{key.to_s}=Table.new(value, false)") #! We know there is only one hash in here so this is fine
818
+ else
819
+ eval("@#{key.to_s}=value")
820
+ end
821
+ end
822
+ end
823
+
824
+ def hash
825
+ dump = {
826
+ id: @id,
827
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
828
+ class_id: @class_id,
829
+ initial_level: @initial_level,
830
+ final_level: @final_level,
831
+ exp_basis: @exp_basis,
832
+ exp_inflation: @exp_inflation,
833
+ character_name: @character_name,
834
+ character_hue: @character_hue,
835
+ battler_name: @battler_name,
836
+ battler_hue: @battler_hue,
837
+ parameters: @parameters.hash,
838
+ weapon_id: @weapon_id,
839
+ armor1_id: @armor1_id,
840
+ armor2_id: @armor2_id,
841
+ armor3_id: @armor3_id,
842
+ armor4_id: @armor4_id,
843
+ weapon_fix: @weapon_fix,
844
+ armor1_fix: @armor1_fix,
845
+ armor2_fix: @armor2_fix,
846
+ armor3_fix: @armor3_fix,
847
+ armor4_fix: @armor4_fix,
848
+ }
849
+ end
850
+ end
851
+
852
+ class Skill
853
+ def initialize(hash)
854
+ hash.each do |key, value|
855
+ if value.is_a?(Hash)
856
+ eval("@#{key.to_s}=RPG::AudioFile.new(value)") #! We know there is only one hash in here so this is fine
857
+ else
858
+ eval("@#{key.to_s}=value")
859
+ end
860
+ end
861
+ end
862
+
863
+ def hash
864
+ dump = {
865
+ id: @id,
866
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
867
+ icon_name: @icon_name,
868
+ description: @description.force_encoding("iso-8859-1").encode("utf-8"),
869
+ scope: @scope,
870
+ occasion: @occasion,
871
+ animation1_id: @animation1_id,
872
+ animation2_id: @animation2_id,
873
+ menu_se: @menu_se.hash,
874
+ common_event_id: @common_event_id,
875
+ sp_cost: @sp_cost,
876
+ power: @power,
877
+ atk_f: @atk_f,
878
+ eva_f: @eva_f,
879
+ str_f: @str_f,
880
+ dex_f: @dex_f,
881
+ agi_f: @agi_f,
882
+ int_f: @int_f,
883
+ hit: @hit,
884
+ pdef_f: @pdef_f,
885
+ mdef_f: @mdef_f,
886
+ variance: @variance,
887
+ element_set: @element_set,
888
+ plus_state_set: @plus_state_set,
889
+ minus_state_set: @minus_state_set,
890
+ }
891
+ dump
892
+ end
893
+ end
894
+
895
+ class Item
896
+ def initialize(hash)
897
+ hash.each do |key, value|
898
+ if value.is_a?(Hash)
899
+ eval("@#{key.to_s}=RPG::AudioFile.new(value)") #! We know there is only one hash in here so this is fine
900
+ else
901
+ eval("@#{key.to_s}=value")
902
+ end
903
+ end
904
+ end
905
+
906
+ def hash
907
+ dump = {
908
+ id: @id,
909
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
910
+ icon_name: @icon_name,
911
+ description: @description.force_encoding("iso-8859-1").encode("utf-8"),
912
+ scope: @scope,
913
+ occasion: @occasion,
914
+ animation1_id: @animation1_id,
915
+ animation2_id: @animation2_id,
916
+ menu_se: @menu_se.hash,
917
+ common_event_id: @common_event_id,
918
+ price: @price,
919
+ consumable: @consumable,
920
+ parameter_type: @parameter_type,
921
+ parameter_points: @parameter_points,
922
+ recover_hp_rate: @recover_hp_rate,
923
+ recover_hp: @recover_hp,
924
+ hit: @hit,
925
+ pdef_f: @pdef_f,
926
+ mdef_f: @mdef_f,
927
+ variance: @variance,
928
+ element_set: @element_set,
929
+ plus_state_set: @plus_state_set,
930
+ minus_state_set: @minus_state_set,
931
+ }
932
+ end
933
+ end
934
+
935
+ class Weapon
936
+ def initialize(hash)
937
+ hash.each do |key, value|
938
+ eval("@#{key.to_s}=value")
939
+ end
940
+ end
941
+
942
+ def hash
943
+ dump = {
944
+ id: @id,
945
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
946
+ icon_name: @icon_name,
947
+ description: @description.force_encoding("iso-8859-1").encode("utf-8"),
948
+ animation1_id: @animation1_id,
949
+ animation2_id: @animation2_id,
950
+ price: @price,
951
+ atk: @atk,
952
+ pdef: @pdef,
953
+ mdef: @mdef,
954
+ str_plus: @str_plus,
955
+ dex_plus: @dex_plus,
956
+ agi_plus: @agi_plus,
957
+ int_plus: @int_plus,
958
+ element_set: @element_set,
959
+ plus_state_set: @plus_state_set,
960
+ minus_state_set: @minus_state_set,
961
+ }
962
+ end
963
+ end
964
+
965
+ class Armor
966
+ def initialize(hash)
967
+ hash.each do |key, value|
968
+ eval("@#{key.to_s}=value")
969
+ end
970
+ end
971
+
972
+ def hash
973
+ dump = {
974
+ id: @id,
975
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
976
+ icon_name: @icon_name,
977
+ description: @description.force_encoding("iso-8859-1").encode("utf-8"),
978
+ kind: @kind,
979
+ price: @price,
980
+ pdef: @pdef,
981
+ mdef: @mdef,
982
+ eva: @eva,
983
+ str_plus: @str_plus,
984
+ dex_plus: @dex_plus,
985
+ agi_plus: @agi_plus,
986
+ int_plus: @int_plus,
987
+ guard_element_set: @guard_element_set,
988
+ guard_state_set: @guard_state_set,
989
+ }
990
+ end
991
+ end
992
+
993
+ class Enemy
994
+ class Action
995
+ def initialize(hash)
996
+ hash.each do |key, value|
997
+ eval("@#{key.to_s}=value")
998
+ end
999
+ end
1000
+
1001
+ def hash
1002
+ dump = {
1003
+ kind: @kind,
1004
+ basic: @basic,
1005
+ skill_id: @skill_id,
1006
+ condition_turn_a: @condition_turn_a,
1007
+ condition_turn_b: @condition_turn_b,
1008
+ condition_hp: @condition_hp,
1009
+ condition_level: @condition_level,
1010
+ condition_switch_id: @condition_switch_id,
1011
+ rating: @rating,
1012
+ }
1013
+ end
1014
+ end
1015
+
1016
+ def initialize(hash)
1017
+ hash.each do |key, value|
1018
+ if value.is_a?(Hash)
1019
+ eval("@#{key.to_s}=Table.new(value, false)")
1020
+ elsif value.is_a?(Array)
1021
+ @actions = []
1022
+ value.each_with_index do |value|
1023
+ @actions << RPG::Enemy::Action.new(value)
1024
+ end
1025
+ else
1026
+ eval("@#{key.to_s}=value")
1027
+ end
1028
+ end
1029
+ end
1030
+
1031
+ def hash
1032
+ dump = {
1033
+ id: @id,
1034
+ name: @name.force_encoding("iso-8859-1").encode("utf-8"),
1035
+ battler_name: @battler_name,
1036
+ battler_hue: @battler_hue,
1037
+ maxhp: @maxhp,
1038
+ maxsp: @maxsp,
1039
+ str: @str,
1040
+ dex: @dex,
1041
+ agi: @agi,
1042
+ int: @int,
1043
+ atk: @atk,
1044
+ pdef: @pdef,
1045
+ mdef: @mdef,
1046
+ eva: @eva,
1047
+ animation1_id: @animation1_id,
1048
+ animation2_id: @animation2_id,
1049
+ element_ranks: @element_ranks.hash,
1050
+ state_ranks: @state_ranks.hash,
1051
+ actions: [],
1052
+ exp: @exp,
1053
+ gold: @gold,
1054
+ item_id: @item_id,
1055
+ weapon_id: @weapon_id,
1056
+ armor_id: @armor_id,
1057
+ treasure_prob: @treasure_prob,
1058
+ }
1059
+ @actions.each_with_index do |value|
1060
+ dump[:actions] << value.hash
1061
+ end
1062
+ dump
1063
+ end
1064
+ end
1065
+
1066
+ class Troop
1067
+ class Member
1068
+ def initialize(hash)
1069
+ hash.each do |key, value|
1070
+ eval("@#{key.to_s}=value")
1071
+ end
1072
+ end
1073
+
1074
+ def hash
1075
+ dump = {
1076
+ enemy_id: @enemy_id,
1077
+ x: @x,
1078
+ y: @y,
1079
+ hidden: @hidden,
1080
+ immortal: @immortal,
1081
+ }
1082
+ end
1083
+ end
1084
+
1085
+ class Page
1086
+ class Condition
1087
+ def initialize(hash)
1088
+ hash.each do |key, value|
1089
+ eval("@#{key.to_s}=value")
1090
+ end
1091
+ end
1092
+
1093
+ def hash
1094
+ dump = {
1095
+ turn_valid: @turn_valid,
1096
+ enemy_valid: @enemy_valid,
1097
+ actor_valid: @actor_valid,
1098
+ switch_valid: @switch_valid,
1099
+ turn_a: @turn_a,
1100
+ turn_b: @turn_b,
1101
+ enemy_index: @enemy_index,
1102
+ enemy_hp: @enemy_hp,
1103
+ actor_id: @actor_id,
1104
+ actor_hp: @actor_hp,
1105
+ switch_id: @switch_id,
1106
+ }
1107
+ end
1108
+ end
1109
+
1110
+ def initialize(hash)
1111
+ @condition = RPG::Troop::Page::Condition.new hash["condition"]
1112
+ @span = hash["span"]
1113
+ @list = []
1114
+ hash["list"].each_with_index do |value|
1115
+ @list << RPG::EventCommand.new(value)
1116
+ end
1117
+ end
1118
+
1119
+ def hash
1120
+ dump = {
1121
+ condition: @condition.hash,
1122
+ span: @span,
1123
+ list: [],
1124
+ }
1125
+ @list.each_with_index do |value|
1126
+ dump[:list] << value.hash
1127
+ end
1128
+ dump
1129
+ end
1130
+ end
1131
+
1132
+ def initialize(hash)
1133
+ @id = hash["id"]
1134
+ @name = hash["name"]
1135
+ @members = []
1136
+ @pages = []
1137
+
1138
+ hash["members"].each_with_index do |value|
1139
+ @members << RPG::Troop::Member.new(value)
1140
+ end
1141
+
1142
+ hash["pages"].each_with_index do |value|
1143
+ @pages << RPG::Troop::Page.new(value)
1144
+ end
1145
+ end
1146
+
1147
+ def hash
1148
+ dump = {
1149
+ id: @id,
1150
+ name: @name,
1151
+ members: [],
1152
+ pages: [],
1153
+ }
1154
+ @members.each_with_index do |value|
1155
+ dump[:members] << value.hash
1156
+ end
1157
+ @pages.each_with_index do |value|
1158
+ dump[:pages] << value.hash
1159
+ end
1160
+ dump
1161
+ end
1162
+ end
1163
+ end