rvpacker-txt 1.2.0 → 1.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0504a1427ffcd718aedc6a6db70bce63331ef54046b9e5abe0037d60ffbb0445
4
- data.tar.gz: fa94b889274185fa2c6adfb1bd539ded6a8ecf7b1e05702bdf49a557376e9d7d
3
+ metadata.gz: 2b17d69aea817f8b41bc154daf4a4f6c6f4c2a0200427cefefadf593c8fae715
4
+ data.tar.gz: 79a5a1f73df2a44a7571df5fb47bb76c234ecf774946cbdeb51d6a23265a7e13
5
5
  SHA512:
6
- metadata.gz: 9d16fa9c8cecf327cbc947250fe8b9f84b4cf0656a80d12caded68d74c2037f7971a8630469389542b8548b5737ff110aa2cdd0936eb34b822d646e3bc661a21
7
- data.tar.gz: c0fb36404458b2fc15546c10782ca43841e9179d139e65ced2f12478345911e7d67ad2751e4f43ea7756490b032c43b34777493161f75187de51686fa7ee223d
6
+ metadata.gz: 5ef9f467c491d122c582f0af55ded8757de79e1bc41eb92b9fdb40617a83b8b06d0cb57dae3d8ae7fc5e397004977b308d303b4489446654022b19ba79279d91
7
+ data.tar.gz: 00fa12e46f27a7c225bf76179431f4e680d9e4da2c85c48ff0e2355b257254eab80c31d5e07e9be1681982c450d4bfbb3d8d48d41e9e1ab2343af9e7872bcb20
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in rvpacker-txt.gemspec
4
- gemspec
4
+ gemspec
5
+ gem 'rubocop', group: 'development', require: false
data/Rakefile CHANGED
@@ -1,2 +1 @@
1
- require "bundler/gem_tasks"
2
-
1
+ require 'bundler/gem_tasks'
data/bin/rvpacker-txt CHANGED
@@ -1,51 +1,55 @@
1
1
  #!/usr/bin/env ruby
2
- require 'RGSS'
2
+ require 'classes'
3
3
  require 'optparse'
4
4
 
5
5
  $logging = false
6
- $no = [true, true, true, true] # 0 is whether to process maps, 1 is other, 2 is system, 3 is scripts
6
+ $shuffle = 0
7
+ $no = [false, false, false, false] # 0 is whether to NOT process maps, 1 is other, 2 is system, 3 is scripts
7
8
 
8
- opts = {}
9
- OptionParser.new do |options|
10
- options.banner = "This tool allows to parse RPG Maker project to .txt files and back.\n\nUsage: rvpacker-txt COMMAND [options]\n\nCOMMANDS:\n read - Parses RPG Maker game files to .txt\n write - Writes parsed files back to their initial form\nOPTIONS:\n"
9
+ options = {}
10
+ OptionParser.new do |command|
11
+ command.banner = "This tool allows to parse RPG Maker project to .txt files and back.\n\nUsage: rvpacker-txt COMMAND [options]\n\nCOMMANDS:\n read - Parses RPG Maker game files to .txt\n write - Writes parsed files back to their initial form\nOPTIONS:\n"
11
12
 
12
- options.on('-d', '--input-dir DIRECTORY', 'Input directory of RPG Maker project.',
13
+ command.on('-d',
14
+ '--input-dir DIRECTORY',
15
+ 'Input directory of RPG Maker project.',
13
16
  'Must contain "Data" or "original" folder to read,',
14
- 'and additionally "translation" with "maps" and "other" subdirectories to write.') do |dir|
15
- opts[:input_dir] = dir
16
- end
17
+ 'and additionally "translation" with "maps" and "other" subdirectories to write.') { |dir| options[:input_dir] = dir }
17
18
 
18
- options.on('--no', "Don't process specified files.", 'Takes multiple values separated by a comma.', 'Allowed values: maps, other, system, plugins') do |files|
19
+ command.on('--no',
20
+ "Don't process specified files.",
21
+ 'Takes multiple values separated by a comma.',
22
+ 'Allowed values: maps, other, system, plugins') do |files|
19
23
  actual_files = files.split(',')
20
24
 
21
25
  actual_files.each do |file|
22
26
  case file
23
27
  when "maps"
24
- $no[0] = false
28
+ $no[0] = true
25
29
  when "other"
26
- $no[1] = false
30
+ $no[1] = true
27
31
  when "system"
28
- $no[2] = false
32
+ $no[2] = true
29
33
  when "scripts"
30
- $no[3] = false
34
+ $no[3] = true
31
35
  else
32
- nil
36
+ puts "Wrong value for no argument: #{file}.\nAllowed values: maps, other, system, plugins"
37
+ exit
33
38
  end
34
39
  end
35
40
  end
36
41
 
37
- options.on('-s', '--shuffle NUMBER', 'At value 1: Shuffles all lines in strings, at value 2: shuffles all lines and words in strings.') do |number|
38
- opts[:shuffle] = number
39
- end
42
+ command.on('-s',
43
+ '--shuffle NUMBER',
44
+ 'At value 1: Shuffles all lines in strings, at value 2: shuffles all lines and words in strings.') { |number| $shuffle = number }
40
45
 
41
- options.on('-l', '--log', 'Log information while processing.') do
42
- $logging = true
43
- end
44
-
45
- options.on_tail('-h', '--help', 'Show help message.') do
46
- puts options
47
- exit
48
- end
46
+ command.on('-l',
47
+ '--log',
48
+ 'Log information while processing.') { $logging = true }
49
+
50
+ command.on_tail('-h',
51
+ '--help',
52
+ 'Show help message.') { puts command; exit }
49
53
  end.parse!(ARGV)
50
54
 
51
55
  if ARGV.empty?
@@ -53,37 +57,27 @@ if ARGV.empty?
53
57
  exit
54
58
  end
55
59
 
56
- opts[:action] = ARGV.shift
60
+ options[:action] = ARGV.shift
57
61
 
58
- unless %w[read write].include?(opts[:action])
62
+ unless %w[read write].include?(options[:action])
59
63
  puts 'Invalid command. Allowed commands are: read, write.'
60
64
  exit
61
65
  end
62
66
 
63
- project_types = { 'vx' => :vx, 'ace' => :ace, 'xp' => :xp }
64
-
65
- directory = opts[:input_dir]
67
+ directory = options[:input_dir]
66
68
  raise "#{directory} not found" unless File.exist?(directory)
67
69
 
68
- original_directory = Dir.foreach(directory).find { |filename| filename.downcase == 'original' } ||
69
- Dir.foreach(directory).find { |filename| filename.downcase == 'data' }
70
+ original_directory = Dir.foreach(directory).find { |dirname| dirname.downcase == 'original' || dirname.downcase == 'data' }
70
71
  raise '"Data" or "original" directory not found within input directory.' if original_directory.nil?
71
72
 
72
- types = %w[vx ace xp]
73
-
74
- type = types.find do |type_|
75
- case type_
76
- when 'xp'
77
- break project_types[type_] if File.exist?(File.join(directory, original_directory, 'System.rxdata'))
78
- when 'vx'
79
- break project_types[type_] if File.exist?(File.join(directory, original_directory, 'System.rvdata'))
80
- when 'ace'
81
- break project_types[type_] if File.exist?(File.join(directory, original_directory, 'System.rvdata2'))
82
- else
83
- break nil
84
- end
85
- end
86
-
87
- raise 'Couldn\'t determine project engine.' if type.nil?
88
-
89
- RGSS.serialize(type, opts[:action], directory, original_directory)
73
+ engine = if File.exist?(File.join(directory, original_directory, 'System.rxdata'))
74
+ :xp
75
+ elsif File.exist?(File.join(directory, original_directory, 'System.rvdata'))
76
+ :vx
77
+ elsif File.exist?(File.join(directory, original_directory, 'System.rvdata2'))
78
+ :ace
79
+ else
80
+ raise "Couldn't determine project engine."
81
+ end
82
+
83
+ RGSS.serialize(engine, options[:action], directory, original_directory,)
@@ -78,48 +78,10 @@ class Rect
78
78
  end
79
79
  end
80
80
 
81
- module RGSS
82
- def self.remove_defined_method(scope, name)
83
- if scope.instance_methods(false).include?(name)
84
- scope.send(:remove_method, name)
85
- end
86
- end
87
-
88
- def self.reset_method(scope, name, method)
89
- remove_defined_method(scope, name)
90
- scope.send(:define_method, name, method)
91
- end
92
-
93
- def self.reset_const(scope, symbol, value)
94
- scope.send(:remove_const, symbol) if scope.const_defined?(symbol)
95
- scope.send(:const_set, symbol, value)
96
- end
97
-
98
- def self.array_to_hash(array, &block)
99
- hash = {}
100
-
101
- array.each_with_index do |value, index|
102
- r = block_given? ? block.call(value) : value
103
- hash[index] = r unless r.nil?
104
- end
105
-
106
- unless array.empty?
107
- last = array.length - 1
108
- hash[last] = nil unless hash.has_key?(last)
109
- end
110
-
111
- hash
112
- end
113
-
114
- def self.hash_to_array(hash)
115
- array = []
116
- hash.each { |key, value| array[key] = value }
117
- array
118
- end
119
-
120
- require 'RGSS/BasicCoder'
121
- require 'RPG'
81
+ module RPG
82
+ end
122
83
 
84
+ module RGSS
123
85
  # creates an empty class in a potentially nested scope
124
86
  def self.process(root, name, *args)
125
87
  if !args.empty?
@@ -156,6 +118,7 @@ module RGSS
156
118
  %i[RPG Event Page],
157
119
  %i[RPG Event Page Condition],
158
120
  %i[RPG Event Page Graphic],
121
+ %i[RPG EventCommand],
159
122
  %i[RPG Item],
160
123
  %i[RPG Map],
161
124
  %i[RPG Map Encounter],
@@ -166,6 +129,7 @@ module RGSS
166
129
  %i[RPG SE],
167
130
  %i[RPG Skill],
168
131
  %i[RPG State],
132
+ %i[RPG System],
169
133
  %i[RPG System Terms],
170
134
  %i[RPG System TestBattler],
171
135
  %i[RPG System Vehicle],
@@ -178,103 +142,8 @@ module RGSS
178
142
  %i[RPG UsableItem],
179
143
  %i[RPG UsableItem Damage],
180
144
  %i[RPG UsableItem Effect],
181
- %i[RPG Weapon],
182
- # Script classes serialized in save game files
183
- [:Game_ActionResult],
184
- [:Game_Actor],
185
- [:Game_Actors],
186
- [:Game_BaseItem],
187
- [:Game_BattleAction],
188
- [:Game_CommonEvent],
189
- [:Game_Enemy],
190
- [:Game_Event],
191
- [:Game_Follower],
192
- [:Game_Followers],
193
- [:Game_Interpreter],
194
- [:Game_Map],
195
- [:Game_Message],
196
- [:Game_Party],
197
- [:Game_Picture],
198
- [:Game_Pictures],
199
- [:Game_Player],
200
- [:Game_System],
201
- [:Game_Timer],
202
- [:Game_Troop],
203
- [:Game_Screen],
204
- [:Game_Vehicle],
205
- [:Interpreter]
145
+ %i[RPG Weapon]
206
146
  ].each { |symbol_array| process(Object, *symbol_array) }
207
-
208
- def self.setup_classes(version)
209
- # change version_id to fixed number
210
- reset_method(
211
- RPG::System,
212
- :reduce_string,
213
- ->(string) do
214
- return nil if string.nil?
215
-
216
- stripped = string.strip
217
- stripped.empty? ? nil : stripped
218
- end
219
- )
220
-
221
- # These magic numbers should be different. If they are the same, the saved version
222
- # of the map in save files will be used instead of any updated version of the map
223
- reset_method(
224
- RPG::System,
225
- :map_version,
226
- ->(_ignored) { 12_345_678 }
227
- )
228
-
229
- reset_method(
230
- Game_System,
231
- :map_version,
232
- ->(_ignored) { 87_654_321 }
233
- )
234
-
235
- # Game_Interpreter is marshalled differently in VX Ace
236
- if version == :ace
237
- reset_method(Game_Interpreter, :marshal_dump, -> { return @data })
238
- reset_method(
239
- Game_Interpreter,
240
- :marshal_load,
241
- ->(obj) { @data = obj }
242
- )
243
- else
244
- remove_defined_method(Game_Interpreter, :marshal_dump)
245
- remove_defined_method(Game_Interpreter, :marshal_load)
246
- end
247
-
248
- reset_method(
249
- RPG::EventCommand,
250
- :clean,
251
- -> { @parameters[0].rstrip! if @code == 401 }
252
- )
253
-
254
- reset_const(
255
- RPG::EventCommand,
256
- :MOVE_LIST_CODE,
257
- version == :xp ? 209 : 205
258
- )
259
-
260
- BasicCoder.ivars_methods_set(version)
261
- end
262
-
263
- class Game_Switches
264
- include RGSS::BasicCoder
265
- end
266
-
267
- class Game_Variables
268
- include RGSS::BasicCoder
269
- end
270
-
271
- class Game_SelfSwitches
272
- include RGSS::BasicCoder
273
- end
274
-
275
- class Game_System
276
- include RGSS::BasicCoder
277
- end
278
-
279
- require 'RGSS/serialize'
280
147
  end
148
+
149
+ require 'serialize'
@@ -65,8 +65,8 @@ module RGSS
65
65
 
66
66
  game_title.downcase!
67
67
 
68
- if game_title.include?("lisa")
69
- return "lisa"
68
+ if game_title.include?('lisa')
69
+ return 'lisa'
70
70
  end
71
71
 
72
72
  nil
@@ -76,9 +76,9 @@ module RGSS
76
76
  case code
77
77
  when 401, 405
78
78
  case $game_type
79
- when "lisa"
80
- match = parameter.scan(/^\\et\[[0-9]+\]|\\nbt/)
81
- parameter = parameter.slice(match[0].length) if match
79
+ when 'lisa'
80
+ match = parameter.scan(/^(\\et\[[0-9]+\]|\\nbt)/)
81
+ parameter = parameter.slice((match[0].length)..) if match
82
82
  else
83
83
  nil
84
84
  end
@@ -98,7 +98,7 @@ module RGSS
98
98
  variable = variable.gsub(/\r?\n/, '\#')
99
99
 
100
100
  case $game_type
101
- when "lisa"
101
+ when 'lisa'
102
102
  unless variable.split('\#').all? { |line| line.match?(/^<.*>\.?$/) || line.length.nil? }
103
103
  return nil
104
104
  end
@@ -119,7 +119,7 @@ module RGSS
119
119
 
120
120
  object_map.each do |filename, object|
121
121
  display_name = object.instance_variable_get(:@display_name)
122
- lines[1].add(display_name) unless display_name.nil? || display_name.empty?
122
+ lines[1].add(display_name) if display_name.is_a?(String) && !display_name.empty?
123
123
 
124
124
  events = object.instance_variable_get(:@events)
125
125
  next if events.nil?
@@ -174,14 +174,18 @@ module RGSS
174
174
  end
175
175
 
176
176
  File.write("#{output_path}/maps.txt", lines[0].join("\n"))
177
- File.write("#{output_path}/maps_trans.txt", "\n" * (!lines[0].empty? ? lines[0].length - 1 : 0))
177
+ File.write("#{output_path}/maps_trans.txt", "\n" * (lines[0].empty? ? 0 : lines[0].length - 1))
178
178
  File.write("#{output_path}/names.txt", lines[1].join("\n"))
179
- File.write("#{output_path}/names_trans.txt", "\n" * (!lines[1].empty? ? lines[1].length - 1 : 0))
179
+ File.write("#{output_path}/names_trans.txt", "\n" * (lines[1].empty? ? 0 : lines[1].length - 1))
180
180
  end
181
181
 
182
182
  def self.read_other(original_other_files, output_path)
183
183
  object_array_map = Hash[original_other_files.map do |filename|
184
- [File.basename(filename), Marshal.load(File.read(filename, mode: 'rb'))]
184
+ basename = File.basename(filename)
185
+ object = Marshal.load(File.read(filename, mode: 'rb'))
186
+ object = merge_other(object).slice(1..) if basename.start_with?(/Common|Troops/)
187
+
188
+ [basename, object]
185
189
  end]
186
190
 
187
191
  object_array_map.each do |filename, object_array|
@@ -252,7 +256,7 @@ module RGSS
252
256
  puts "Parsed #{filename}" if $logging
253
257
 
254
258
  File.write("#{output_path}/#{processed_filename}.txt", lines.join("\n"))
255
- File.write("#{output_path}/#{processed_filename}_trans.txt", "\n" * (!lines.empty? ? lines.length - 1 : 0))
259
+ File.write("#{output_path}/#{processed_filename}_trans.txt", "\n" * (lines.empty? ? 0 : lines.length - 1))
256
260
  end
257
261
  end
258
262
 
@@ -294,47 +298,58 @@ module RGSS
294
298
  puts "Parsed #{filename}" if $logging
295
299
 
296
300
  File.write("#{output_path}/#{basename}.txt", lines.join("\n"), mode: 'wb')
297
- File.write("#{output_path}/#{basename}_trans.txt", "\n" * (!lines.empty? ? lines.length - 1 : 0),
301
+ File.write("#{output_path}/#{basename}_trans.txt", "\n" * (lines.empty? ? 0 : lines.length - 1),
298
302
  mode: 'wb')
299
303
  end
300
304
 
301
- def self.extract_quoted_strings(input)
305
+ def self.shuffle_words(array)
306
+ array.map do |string|
307
+ re = /\S+/
308
+ words = string.scan(re)
309
+ words.shuffle
310
+
311
+ (0..(words.length)).each do |i|
312
+ string.sub!(string[i], words[i])
313
+ end
314
+
315
+ string
316
+ end
317
+ end
318
+
319
+ def self.extract_quoted_strings(string)
302
320
  result = []
321
+
322
+ skip_block = false
303
323
  in_quotes = false
304
324
  quote_type = nil
305
325
  buffer = []
306
326
 
307
- input.each_char.with_index do |char, index|
308
- if char == '#' && (index == 0 || input[index - 1] == "\n")
309
- index = input.index("\n", index) || input.length
310
- next
311
- end
327
+ string.each_line(chomp: true) do |line|
328
+ line.strip!
329
+ next if line[0] == '#' || line.start_with?(/(Win|Lose)|_Fanfare/)
312
330
 
313
- if char == '"' || char == "'"
314
- if in_quotes
315
- if char == quote_type
316
- result.push(buffer.join)
317
- buffer.clear
318
- in_quotes = false
319
- quote_type = nil
320
- else
321
- buffer.push(char)
322
- end
323
- else
324
- in_quotes = true
325
- quote_type = char
326
- end
331
+ skip_block = true if line.start_with?('=begin')
332
+ skip_block = false if line.start_with?('=end')
327
333
 
328
- next
329
- end
334
+ next if skip_block
335
+
336
+ buffer.push('\#') if in_quotes
330
337
 
331
- if in_quotes
332
- if char != "\r"
333
- if char == "\n"
334
- buffer.push('\#')
338
+ line.each_char do |char|
339
+ if char == "'" || char == '"'
340
+ unless quote_type.nil? || char == quote_type
341
+ buffer.push(char)
335
342
  next
336
343
  end
337
344
 
345
+ quote_type = char
346
+ in_quotes = !in_quotes
347
+ result.push(buffer.join)
348
+ buffer.clear
349
+ next
350
+ end
351
+
352
+ if in_quotes
338
353
  buffer.push(char)
339
354
  end
340
355
  end
@@ -346,22 +361,49 @@ module RGSS
346
361
  def self.read_scripts(scripts_file_path, output_path)
347
362
  script_entries = Marshal.load(File.read(scripts_file_path, mode: 'rb'))
348
363
  strings = IndexedSet.new
364
+ codes = []
349
365
 
350
366
  script_entries.each do |script|
351
367
  code = Zlib::Inflate.inflate(script[2]).force_encoding('UTF-8')
368
+ codes.push(code)
352
369
 
353
370
  extract_quoted_strings(code).each do |string|
354
- next if string.strip! || (string.empty? || string.delete('  ').empty?)
355
-
356
- next if string.start_with?(/(#|\!?\$|@|(Graphics|Data|Audio|CG|Movies)\/)/) ||
357
- string.match?(/^\d+$|^(.)\1{2,}$|^false|true$|^(wb|rb)$|^[A-Za-z0-9\-]+$|^[\.\(\)\+\-:;\|\[\]\^~%&!\*\/→×?\?x%▼]$|#\{|\\(?!#)|\+?=?=|\{|\}|_|r[vx]data|[<>]|\.split/) ||
358
-
359
- strings.add(string)
371
+ string.strip!
372
+
373
+ next if string.empty? || string.delete('  ').empty?
374
+
375
+ # Maybe this mess will remove something that mustn't be removed, but it needs to be tested
376
+ next if string.start_with?(/([#!?$@]|(\.\/)?(Graphics|Data|Audio|CG|Movies|Save)\/)/) ||
377
+ string.match?(/^\d+$/) ||
378
+ string.match?(/^(.)\1{2,}$/) ||
379
+ string.match?(/^(false|true)$/) ||
380
+ string.match?(/^[wr]b$/) ||
381
+ string.match?(/^(?=.*\d)[A-Za-z0-9\-]+$/) ||
382
+ string.match?(/^[A-Z\-()\/ +'&]*$/) ||
383
+ string.match?(/^[a-z\-()\/ +'&]*$/) ||
384
+ string.match?(/^[A-Za-z]+[+-]$/) ||
385
+ string.match?(/^[.()+-:;\[\]^~%&!*\/→×??x%▼|]$/) ||
386
+ string.match?(/^Tile.*[A-Z]$/) ||
387
+ string.match?(/^:?%.*[ds][:%]*?$/) ||
388
+ string.match?(/^[a-zA-Z]+([A-Z][a-z]*)+$/) ||
389
+ string.match?(/^Cancel Action$|^Invert$|^End$|^Individual$|^Missed File$|^Bitmap$|^Audio$/) ||
390
+ string.match?(/\.(mp3|ogg|jpg|png|ini)$/) ||
391
+ string.match?(/\/(\d.*)?$/) ||
392
+ string.match?(/FILE$/) ||
393
+ string.match?(/#\{/) ||
394
+ string.match?(/\\(?!#)/) ||
395
+ string.match?(/\+?=?=/) ||
396
+ string.match?(/[}{_<>]/) ||
397
+ string.match?(/r[vx]data/) ||
398
+ string.match?(/No such file or directory|level \*\*|Courier New|Comic Sans|Lucida|Verdana|Tahoma|Arial|Player start location|Common event call has exceeded|se-|Start Pos|An error has occurred|Define it first|Process Skill|Wpn Only|Don't Wait|Clear image|Can Collapse/)
399
+
400
+ strings.add(string)
360
401
  end
361
402
  end
362
403
 
404
+ File.write("#{output_path}/scripts_plain.txt", codes.join("\n"), mode: 'wb')
363
405
  File.write("#{output_path}/scripts.txt", strings.join("\n"), mode: 'wb')
364
- File.write("#{output_path}/scripts_trans.txt", "\n" * (!strings.empty? ? strings.length - 1 : 0), mode: 'wb')
406
+ File.write("#{output_path}/scripts_trans.txt", "\n" * (strings.empty? ? 0 : strings.length - 1), mode: 'wb')
365
407
  end
366
408
 
367
409
  def self.merge_seq(object_array)
@@ -385,7 +427,7 @@ module RGSS
385
427
  elsif i.positive? && in_sequence && !first.nil? && !number.negative?
386
428
  parameters = object_array[first].instance_variable_get(:@parameters)
387
429
  parameters[0] = string_array.join("\n")
388
- object_array[first].instance_variable_set(parameters)
430
+ object_array[first].instance_variable_set(:@parameters, parameters)
389
431
 
390
432
  start_index = first + 1
391
433
  items_to_delete = start_index + number
@@ -434,6 +476,8 @@ module RGSS
434
476
 
435
477
  page.instance_variable_set(:@list, merge_seq(list))
436
478
  end
479
+
480
+ object.instance_variable_set(:@pages, pages)
437
481
  else
438
482
  list = object.instance_variable_get(:@list)
439
483
  next unless list.is_a?(Array)
@@ -446,12 +490,15 @@ module RGSS
446
490
  end
447
491
 
448
492
  def self.get_translated(code, parameter, hashmap)
493
+ lisa_start = nil
494
+
449
495
  case code
450
496
  when 401, 356, 405
451
497
  case $game_type
452
- when "lisa"
453
- match = parameter.scan(/^\\et\[[0-9]+\]/) || parameter.scan(/^\\nbt/)
454
- parameter = parameter.slice(match[0].length) unless match.nil?
498
+ when 'lisa'
499
+ match = parameter.scan(/^(\\et\[[0-9]+\]|\\nbt)/)
500
+ lisa_start = match[0]
501
+ parameter = parameter.slice((match[0].length)..) unless match.nil?
455
502
  else
456
503
  nil
457
504
  end
@@ -461,7 +508,16 @@ module RGSS
461
508
  nil
462
509
  end
463
510
 
464
- return hashmap[parameter]
511
+ gotten = hashmap[parameter]
512
+
513
+ case $game_type
514
+ when 'lisa'
515
+ gotten = lisa_start + gotten unless lisa_start.nil?
516
+ else
517
+ nil
518
+ end
519
+
520
+ gotten
465
521
  end
466
522
 
467
523
  def self.get_variable_translated(variable, hashmap)
@@ -489,6 +545,16 @@ module RGSS
489
545
  line.gsub('\#', "\n")
490
546
  end
491
547
 
548
+ if $shuffle > 0
549
+ maps_translated_text.shuffle!
550
+ names_translated_text.shuffle!
551
+
552
+ if $shuffle == 2
553
+ maps_translated_text = shuffle_words(maps_translated_text)
554
+ names_translated_text = shuffle_words(names_translated_text)
555
+ end
556
+ end
557
+
492
558
  maps_translation_map = Hash[maps_original_text.zip(maps_translated_text)].freeze
493
559
  names_translation_map = Hash[names_original_text.zip(names_translated_text)].freeze
494
560
 
@@ -496,7 +562,8 @@ module RGSS
496
562
 
497
563
  object_map.each do |filename, object|
498
564
  display_name = object.instance_variable_get(:@display_name)
499
- object.instance_variable_set(:@display_name, names_translation_map[display_name]) if names_translation_map.key?(display_name)
565
+ display_name_gotten = names_translation_map[display_name]
566
+ object.instance_variable_set(:@display_name, display_name_gotten) unless display_name_gotten.nil?
500
567
 
501
568
  events = object.instance_variable_get(:@events)
502
569
  next if events.nil?
@@ -546,7 +613,7 @@ module RGSS
546
613
  object_array_map = Hash[original_files.map do |filename|
547
614
  basename = File.basename(filename)
548
615
  object = Marshal.load(File.read(filename, mode: 'rb'))
549
- object = merge_other(object)[1..] if basename.start_with?(/Common|Troops/)
616
+ object = merge_other(object).slice(1..) if basename.start_with?(/Common|Troops/)
550
617
 
551
618
  [basename, object]
552
619
  end]
@@ -556,29 +623,40 @@ module RGSS
556
623
  object_array_map.each do |filename, object_array|
557
624
  processed_filename = File.basename(filename, '.*').downcase
558
625
 
559
- other_original_text = File.read("#{File.join(other_path, processed_filename)}.txt").split("\n").map do
560
- |line|
561
- line.gsub('\#', "\n")
562
- end
626
+ other_original_text = File.read("#{File.join(other_path, processed_filename)}.txt")
627
+ .split("\n")
628
+ .map { |line| line.gsub('\#', "\n") }
629
+ .freeze
630
+
631
+ other_translated_text = File.read("#{File.join(other_path, processed_filename)}_trans.txt")
632
+ .split("\n")
633
+ .map { |line| line.gsub('\#', "\n") }
634
+
635
+ if $shuffle > 0
636
+ other_translated_text.shuffle!
563
637
 
564
- other_translated_text = File.read("#{File.join(other_path, processed_filename)}_trans.txt").split("\n")
565
- .map do
566
- |line|
567
- line.gsub('\#', "\n")
638
+ if $shuffle == 2
639
+ other_translated_text = shuffle_words(other_translated_text)
640
+ end
568
641
  end
569
642
 
570
- other_translation_map = Hash[other_original_text.zip(other_translated_text)]
643
+ other_translation_map = Hash[other_original_text.zip(other_translated_text)].freeze
571
644
 
572
645
  if !filename.start_with?(/Common|Troops/)
573
646
  object_array.each do |object|
574
647
  next if object.nil?
575
648
 
576
- name = object.instance_variable_get(:@name)
577
- nickname = object.instance_variable_get(:@nickname)
578
- description = object.instance_variable_get(:@description)
579
- note = object.instance_variable_get(:@note)
649
+ variables_symbols = %i[@name @nickname @description @note].freeze
580
650
 
581
- [[:@name, name], [:@nickname, nickname], [:@description, description], [:@note, note]].each do |symbol, variable|
651
+ name = object.instance_variable_get(variables_symbols[0])
652
+ nickname = object.instance_variable_get(variables_symbols[1])
653
+ description = object.instance_variable_get(variables_symbols[2])
654
+ note = object.instance_variable_get(variables_symbols[3])
655
+
656
+ [[variables_symbols[0], name],
657
+ [variables_symbols[1], nickname],
658
+ [variables_symbols[2], description],
659
+ [variables_symbols[3], note]].each do |symbol, variable|
582
660
  if variable.is_a?(String) && !variable.empty?
583
661
  translated = get_variable_translated(variable, other_translation_map)
584
662
  object.instance_variable_set(symbol, variable) unless translated.nil?
@@ -606,7 +684,7 @@ module RGSS
606
684
  parameters[i] = translated unless translated.nil?
607
685
  end
608
686
  elsif parameter.is_a?(Array)
609
- parameter.each_with_index.map do |subparameter, j|
687
+ parameter.each_with_index do |subparameter, j|
610
688
  if subparameter.is_a?(String) && !subparameter.empty?
611
689
  translated = get_translated(code, subparameter, other_translation_map)
612
690
  parameters[i][j] = translated unless translated.nil?
@@ -631,33 +709,42 @@ module RGSS
631
709
  basename = File.basename(system_file_path)
632
710
  object = Marshal.load(File.read(system_file_path, mode: 'rb'))
633
711
 
634
- system_original_text = File.read("#{other_path}/system.txt").split("\n")
635
- system_translated_text = File.read("#{other_path}/system_trans.txt").split("\n")
712
+ system_original_text = File.read("#{other_path}/system.txt")
713
+ .split("\n")
714
+ .freeze
715
+ system_translated_text = File.read("#{other_path}/system_trans.txt")
716
+ .split("\n")
636
717
 
637
- system_translation_map = Hash[system_original_text.zip(system_translated_text)]
718
+ if $shuffle > 0
719
+ system_translated_text.shuffle!
638
720
 
639
- symbols = %i[@elements @skill_types @weapon_types @armor_types]
640
- elements = object.instance_variable_get(:@elements)
641
- skill_types = object.instance_variable_get(:@skill_types)
642
- weapon_types = object.instance_variable_get(:@weapon_types)
643
- armor_types = object.instance_variable_get(:@armor_types)
644
- currency_unit = object.instance_variable_get(:@currency_unit)
645
- terms = object.instance_variable_get(:@terms) || object.instance_variable_get(:@words)
646
- game_title = object.instance_variable_get(:@game_title)
721
+ if $shuffle == 2
722
+ system_translated_text = shuffle_words(system_translated_text)
723
+ end
724
+ end
647
725
 
648
- [elements, skill_types, weapon_types, armor_types].each_with_index.each do |array, i|
649
- next if array.nil?
726
+ system_translation_map = Hash[system_original_text.zip(system_translated_text)].freeze
650
727
 
651
- array.each_with_index do |string, j|
652
- translated = system_translation_map[string]
653
- array[j] = translated unless translated.nil?
654
- end
728
+ symbols = %i[@elements @skill_types @weapon_types @armor_types @currency_unit @terms @words @game_title].freeze
729
+
730
+ elements = object.instance_variable_get(symbols[0])
731
+ skill_types = object.instance_variable_get(symbols[1])
732
+ weapon_types = object.instance_variable_get(symbols[2])
733
+ armor_types = object.instance_variable_get(symbols[3])
734
+ currency_unit = object.instance_variable_get(symbols[4])
735
+ terms = object.instance_variable_get(symbols[5]) || object.instance_variable_get(symbols[6])
736
+ game_title = object.instance_variable_get(symbols[7])
737
+
738
+ [elements, skill_types, weapon_types, armor_types].each_with_index.each do |array, i|
739
+ next unless array.is_a?(Array)
655
740
 
741
+ array.map! { |string| system_translation_map[string] || string }
656
742
  object.instance_variable_set(symbols[i], array)
657
743
  end
658
744
 
659
- instance_variable_set(:@currency_unit, system_translation_map[currency_unit]) if !currency_unit.nil? &&
660
- system_translation_map.key?(currency_unit)
745
+ currency_unit_translated = system_translation_map[currency_unit]
746
+ object.instance_variable_set(symbols[4], currency_unit_translated) if currency_unit.is_a?(String) &&
747
+ !currency_unit_translated.nil?
661
748
 
662
749
  terms.instance_variables.each do |variable|
663
750
  value = terms.instance_variable_get(variable)
@@ -666,37 +753,48 @@ module RGSS
666
753
  translated = system_translation_map[value]
667
754
  value = translated unless translated.nil?
668
755
  elsif value.is_a?(Array)
669
- value.each_with_index do |string, i|
670
- translated = system_translation_map[string]
671
- value[i] = translated unless translated.nil?
672
- end
756
+ value.map! { |string| system_translation_map[string] || string }
673
757
  end
674
758
 
675
759
  terms.instance_variable_set(variable, value)
676
760
  end
677
761
 
678
- object.instance_variable_defined?(:@terms) ? object.instance_variable_set(:@terms, terms) : object
679
- .instance_variable_set(:@words, terms)
762
+ object.instance_variable_defined?(symbols[5]) ?
763
+ object.instance_variable_set(symbols[5], terms) :
764
+ object.instance_variable_set(symbols[6], terms)
680
765
 
681
- object.instance_variable_set(:@game_title, system_translation_map[game_title]) if !currency_unit.nil? &&
682
- system_translation_map
683
- .key?(game_title)
766
+ game_title_translated = system_translation_map[game_title]
767
+ object.instance_variable_set(symbols[7], game_title_translated) if currency_unit.is_a?(String) && !game_title_translated.nil?
684
768
 
685
769
  puts "Written #{basename}" if $logging
686
770
 
687
- File.write("#{output_path}/#{basename}", Marshal.dump(object), mode: 'wb')
771
+ File.write("#{output_path}/ #{basename}", Marshal.dump(object), mode: 'wb')
688
772
  end
689
773
 
690
774
  def self.write_scripts(scripts_file, other_path, output_path)
691
775
  script_entries = Marshal.load(File.read(scripts_file, mode: 'rb'))
692
- strings_original = File.read("#{other_path}/scripts.txt", mode: 'rb').split("\n").map { |line| line.gsub('\#', "\r\n") }
693
- strings = File.read("#{other_path}/scripts_trans.txt", mode: 'rb').split("\n").map { |line| line.gsub('\#', "\r\n") }
694
776
 
695
- scripts_translation_map = Hash[strings_original.zip(strings)]
777
+ scripts_original_text = File.read("#{other_path}/scripts.txt", mode: 'rb')
778
+ .force_encoding('UTF-8')
779
+ .split("\n")
780
+ .map { |line| line.gsub('\#', "\r\n") }
781
+ .freeze
782
+
783
+ scripts_translated_text = File.read("#{other_path}/scripts_trans.txt", mode: 'rb')
784
+ .force_encoding('UTF-8')
785
+ .split("\n")
786
+ .map { |line| line.gsub('\#', "\r\n") }
787
+ .freeze
696
788
 
697
- script_entries.each_with_index do |script, i|
789
+ # Shuffle can possibly break the game in scripts, so no shuffling
790
+
791
+ script_entries.each do |script|
698
792
  code = Zlib::Inflate.inflate(script[2]).force_encoding('UTF-8')
699
- code.gsub(/".*"/, scripts_translation_map[strings[i]]) if scripts_translation_map.key?(strings[i])
793
+
794
+ scripts_original_text.zip(scripts_translated_text).each do |original, translated|
795
+ code.gsub!(original, translated) unless translated.nil?
796
+ end
797
+
700
798
  script[2] = Zlib::Deflate.deflate(code, Zlib::BEST_COMPRESSION)
701
799
  end
702
800
 
@@ -706,9 +804,7 @@ module RGSS
706
804
  def self.serialize(engine, action, directory, original_directory)
707
805
  start_time = Time.now
708
806
 
709
- setup_classes(engine)
710
-
711
- absolute_path = File.realpath(directory)
807
+ absolute_path = File.realpath(directory).freeze
712
808
 
713
809
  paths = {
714
810
  original_path: File.join(absolute_path, original_directory),
@@ -720,21 +816,19 @@ module RGSS
720
816
 
721
817
  paths.each_value { |path| FileUtils.mkdir_p(path) }
722
818
 
723
- extensions = { ace: '.rvdata2', vx: '.rvdata', xp: '.rxdata' }
819
+ extensions = { ace: '.rvdata2', vx: '.rvdata', xp: '.rxdata' }.freeze
724
820
 
725
- files = (
726
- Dir
727
- .children(paths[:original_path])
728
- .select { |filename| File.extname(filename) == extensions[engine] }
729
- .map { |filename| "#{paths[:original_path]}/#{filename}" }
730
- )
821
+ files = Dir.children(paths[:original_path])
822
+ .select { |filename| File.extname(filename) == extensions[engine] }
823
+ .map { |filename| "#{paths[:original_path]}/#{filename}" }
824
+ .freeze
731
825
 
732
826
  maps_files = []
733
827
  other_files = []
734
- system_file = "#{paths[:original_path]}/System#{extensions[engine]}"
735
- scripts_file = "#{paths[:original_path]}/Scripts#{extensions[engine]}"
828
+ system_file = "#{paths[:original_path]}/System#{extensions[engine]}".freeze
829
+ scripts_file = "#{paths[:original_path]}/Scripts#{extensions[engine]}".freeze
736
830
 
737
- $game_type = get_game_type(system_file)
831
+ $game_type = get_game_type(system_file).freeze
738
832
 
739
833
  files.each do |file|
740
834
  basename = File.basename(file)
@@ -758,6 +852,6 @@ module RGSS
758
852
  write_scripts(scripts_file, paths[:other_path], paths[:output_path]) unless $no[3]
759
853
  end
760
854
 
761
- puts "Done in #{(Time.now - start_time)}"
855
+ puts "Done in #{Time.now - start_time}"
762
856
  end
763
857
  end
data/rvpacker-txt.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'rvpacker-txt'
3
- spec.version = '1.2.0'
3
+ spec.version = '1.3.0'
4
4
  spec.authors = ['Howard Jeng', 'Andrew Kesterson', 'Solistra', 'Darkness9724', 'savannstm']
5
5
  spec.email = ['savannstm@gmail.com']
6
6
  spec.summary = 'Reads or writes RPG Maker XP/VX/VXAce game text to .txt files'
@@ -8,11 +8,12 @@ Gem::Specification.new do |spec|
8
8
  spec.license = 'MIT'
9
9
  spec.required_ruby_version = Gem::Requirement.new('>= 3.0.0')
10
10
 
11
+ spec.metadata = { 'homepage_uri' => 'https://github.com/savannstm/rvpacker-txt' }
12
+
11
13
  spec.files = `git ls-files -z`.split("\x0")
12
14
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
13
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
14
15
  spec.require_paths = ['lib']
15
16
 
16
- spec.add_development_dependency 'bundler', '>= 2.5.14'
17
- spec.add_development_dependency 'rake', '>= 13.0.6'
17
+ spec.add_development_dependency 'bundler', '~> 2.5'
18
+ spec.add_development_dependency 'rake', '~> 13.0'
18
19
  end
@@ -0,0 +1,4 @@
1
+ $logging: bool
2
+ $shuffle: Integer
3
+ $no: Array[bool]
4
+ $game_type: String | nil
data/sig/rgss.rbs CHANGED
@@ -1,14 +1,18 @@
1
1
  module RGSS
2
+ def self.extract_quoted_strings: (String) -> Array[String]
3
+
2
4
  def self.get_game_type: (String) -> (String | nil)
3
5
 
4
6
  def self.get_translated: (Integer, String, Hash[String, String]) -> (String | nil)
5
7
 
6
- def self.get_variable_translated: (String) -> (String | nil)
8
+ def self.get_variable_translated: (String, Hash[String, String]) -> (String | nil)
7
9
 
8
10
  def self.merge_map: (Object) -> Object
9
11
 
10
12
  def self.merge_other: (Array[Object]) -> Array[Object]
11
13
 
14
+ def self.merge_seq: (Array[Object]) -> Array[Object]
15
+
12
16
  def self.parse_parameter: (Integer, String) -> (String | nil)
13
17
 
14
18
  def self.parse_variable: (String) -> (String | nil)
@@ -23,6 +27,8 @@ module RGSS
23
27
 
24
28
  def self.serialize: (Symbol, String, String, String) -> void
25
29
 
30
+ def self.shuffle_words: (Array[String]) -> Array[String]
31
+
26
32
  def self.write_map: (Array[String], String, String) -> void
27
33
 
28
34
  def self.write_other: (Array[String], String, String) -> void
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rvpacker-txt
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Howard Jeng
@@ -12,36 +12,36 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2024-07-03 00:00:00.000000000 Z
15
+ date: 2024-07-05 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bundler
19
19
  requirement: !ruby/object:Gem::Requirement
20
20
  requirements:
21
- - - ">="
21
+ - - "~>"
22
22
  - !ruby/object:Gem::Version
23
- version: 2.5.14
23
+ version: '2.5'
24
24
  type: :development
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - ">="
28
+ - - "~>"
29
29
  - !ruby/object:Gem::Version
30
- version: 2.5.14
30
+ version: '2.5'
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: rake
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  requirements:
35
- - - ">="
35
+ - - "~>"
36
36
  - !ruby/object:Gem::Version
37
- version: 13.0.6
37
+ version: '13.0'
38
38
  type: :development
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
- - - ">="
42
+ - - "~>"
43
43
  - !ruby/object:Gem::Version
44
- version: 13.0.6
44
+ version: '13.0'
45
45
  description:
46
46
  email:
47
47
  - savannstm@gmail.com
@@ -55,16 +55,16 @@ files:
55
55
  - README.md
56
56
  - Rakefile
57
57
  - bin/rvpacker-txt
58
- - lib/RGSS.rb
59
- - lib/RGSS/BasicCoder.rb
60
- - lib/RGSS/serialize.rb
61
- - lib/RPG.rb
58
+ - lib/classes.rb
59
+ - lib/serialize.rb
62
60
  - rvpacker-txt.gemspec
61
+ - sig/global_variables.rbs
63
62
  - sig/rgss.rbs
64
63
  homepage: https://github.com/savannstm/rvpacker-txt
65
64
  licenses:
66
65
  - MIT
67
- metadata: {}
66
+ metadata:
67
+ homepage_uri: https://github.com/savannstm/rvpacker-txt
68
68
  post_install_message:
69
69
  rdoc_options: []
70
70
  require_paths:
@@ -1,31 +0,0 @@
1
- module RGSS
2
- module BasicCoder
3
- def ivars
4
- instance_variables
5
- end
6
-
7
- INCLUDED_CLASSES = []
8
-
9
- def self.included(module_)
10
- INCLUDED_CLASSES.push(module_)
11
- end
12
-
13
- def self.ivars_methods_set(version)
14
- INCLUDED_CLASSES.each do |class_|
15
- if version == :ace
16
- RGSS.reset_method(
17
- class_,
18
- :ivars,
19
- -> { instance_variables }
20
- )
21
- else
22
- RGSS.reset_method(
23
- class_,
24
- :ivars,
25
- -> { instance_variables.sort }
26
- )
27
- end
28
- end
29
- end
30
- end
31
- end
data/lib/RPG.rb DELETED
@@ -1,9 +0,0 @@
1
- require 'RGSS'
2
- module RPG
3
- class System
4
- include RGSS::BasicCoder
5
- end
6
-
7
- class EventCommand
8
- end
9
- end