rvpacker-txt 1.1.0 → 1.2.1
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 +4 -4
- data/README.md +8 -3
- data/bin/rvpacker-txt +34 -12
- data/lib/RGSS/serialize.rb +195 -39
- data/lib/RGSS.rb +2 -1
- data/rvpacker-txt.gemspec +1 -1
- data/sig/rgss.rbs +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 366c510ab91e885534a8dd5d3c7421b3b6c68f03beaad2bcc7e5e160ba05bbf8
|
|
4
|
+
data.tar.gz: 6d93ab447d98bd285d738b0e5183ffadd8c59bb0e078a8b2a42db8fc3c463153
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ba4567fab07d8d079b9a5b60663c9a45ed006edba0006c48dfebf7d4bef70ad5fa5f338f7bd6ed8211530c8f69861c309d14d8f07a59b747e65d21d5227b2f12
|
|
7
|
+
data.tar.gz: cb0d9fe0cab421d58c0d6d867b6602974d5b94191b0fa421171ccf0d87ea5a93ef821838ece9f4d6990dd50542ccd0d82d566f184c2e5b66d180f6462e3f6e0a
|
data/README.md
CHANGED
|
@@ -20,6 +20,8 @@ Usage
|
|
|
20
20
|
|
|
21
21
|
```
|
|
22
22
|
$ rvpacker-txt -h
|
|
23
|
+
This tool allows to parse RPG Maker project to .txt files and back.
|
|
24
|
+
|
|
23
25
|
Usage: rvpacker-txt COMMAND [options]
|
|
24
26
|
|
|
25
27
|
COMMANDS:
|
|
@@ -29,15 +31,18 @@ OPTIONS:
|
|
|
29
31
|
-d, --input-dir DIRECTORY Input directory of RPG Maker project.
|
|
30
32
|
Must contain "Data" or "original" folder to read,
|
|
31
33
|
and additionally "translation" with "maps" and "other" subdirectories to write.
|
|
32
|
-
|
|
34
|
+
--no Don't process specified files.
|
|
35
|
+
Takes multiple values separated by a comma.
|
|
36
|
+
Allowed values: maps, other, system, plugins
|
|
33
37
|
-s, --shuffle NUMBER At value 1: Shuffles all lines in strings, at value 2: shuffles all lines and words in strings.
|
|
38
|
+
-l, --log Log information while processing.
|
|
34
39
|
-h, --help Show help message.
|
|
35
40
|
```
|
|
36
41
|
|
|
37
42
|
For example, to read a RPG Maker VX Ace project in E:/Documents/RPGMakerGame to .txt files:
|
|
38
43
|
|
|
39
44
|
```
|
|
40
|
-
$ rvpacker read --input-dir E:/Documents/RPGMakerGame
|
|
45
|
+
$ rvpacker-txt read --input-dir E:/Documents/RPGMakerGame
|
|
41
46
|
```
|
|
42
47
|
|
|
43
48
|
Program determines game engine automatically.
|
|
@@ -49,7 +54,7 @@ Lines from Scripts file will be parsed into translation/other/scripts.txt file a
|
|
|
49
54
|
To write previously parsed project back to its initial form:
|
|
50
55
|
|
|
51
56
|
```
|
|
52
|
-
$ rvpacker write --input-dir E:/Documents/RPGMakerGame
|
|
57
|
+
$ rvpacker-txt write --input-dir E:/Documents/RPGMakerGame
|
|
53
58
|
```
|
|
54
59
|
|
|
55
60
|
This will take all of translation lines from _trans files from the translation subdirectories and repack all of them
|
data/bin/rvpacker-txt
CHANGED
|
@@ -3,6 +3,9 @@ require 'RGSS'
|
|
|
3
3
|
require 'optparse'
|
|
4
4
|
|
|
5
5
|
$logging = false
|
|
6
|
+
$shuffle = 0
|
|
7
|
+
$no = [true, true, true, true] # 0 is whether to process maps, 1 is other, 2 is system, 3 is scripts
|
|
8
|
+
|
|
6
9
|
opts = {}
|
|
7
10
|
OptionParser.new do |options|
|
|
8
11
|
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"
|
|
@@ -13,12 +16,31 @@ OptionParser.new do |options|
|
|
|
13
16
|
opts[:input_dir] = dir
|
|
14
17
|
end
|
|
15
18
|
|
|
16
|
-
options.on('
|
|
17
|
-
|
|
19
|
+
options.on('--no', "Don't process specified files.", 'Takes multiple values separated by a comma.', 'Allowed values: maps, other, system, plugins') do |files|
|
|
20
|
+
actual_files = files.split(',')
|
|
21
|
+
|
|
22
|
+
actual_files.each do |file|
|
|
23
|
+
case file
|
|
24
|
+
when "maps"
|
|
25
|
+
$no[0] = false
|
|
26
|
+
when "other"
|
|
27
|
+
$no[1] = false
|
|
28
|
+
when "system"
|
|
29
|
+
$no[2] = false
|
|
30
|
+
when "scripts"
|
|
31
|
+
$no[3] = false
|
|
32
|
+
else
|
|
33
|
+
nil
|
|
34
|
+
end
|
|
35
|
+
end
|
|
18
36
|
end
|
|
19
37
|
|
|
20
38
|
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|
|
|
21
|
-
|
|
39
|
+
$shuffle = number
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
options.on('-l', '--log', 'Log information while processing.') do
|
|
43
|
+
$logging = true
|
|
22
44
|
end
|
|
23
45
|
|
|
24
46
|
options.on_tail('-h', '--help', 'Show help message.') do
|
|
@@ -44,20 +66,20 @@ project_types = { 'vx' => :vx, 'ace' => :ace, 'xp' => :xp }
|
|
|
44
66
|
directory = opts[:input_dir]
|
|
45
67
|
raise "#{directory} not found" unless File.exist?(directory)
|
|
46
68
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
raise '"Data" or "original" directory not found within input directory.' if
|
|
69
|
+
original_directory = Dir.foreach(directory).find { |filename| filename.downcase == 'original' } ||
|
|
70
|
+
Dir.foreach(directory).find { |filename| filename.downcase == 'data' }
|
|
71
|
+
raise '"Data" or "original" directory not found within input directory.' if original_directory.nil?
|
|
50
72
|
|
|
51
73
|
types = %w[vx ace xp]
|
|
52
74
|
|
|
53
|
-
type = types.find do |
|
|
54
|
-
case
|
|
75
|
+
type = types.find do |type_|
|
|
76
|
+
case type_
|
|
55
77
|
when 'xp'
|
|
56
|
-
break project_types[
|
|
78
|
+
break project_types[type_] if File.exist?(File.join(directory, original_directory, 'System.rxdata'))
|
|
57
79
|
when 'vx'
|
|
58
|
-
break project_types[
|
|
80
|
+
break project_types[type_] if File.exist?(File.join(directory, original_directory, 'System.rvdata'))
|
|
59
81
|
when 'ace'
|
|
60
|
-
break project_types[
|
|
82
|
+
break project_types[type_] if File.exist?(File.join(directory, original_directory, 'System.rvdata2'))
|
|
61
83
|
else
|
|
62
84
|
break nil
|
|
63
85
|
end
|
|
@@ -65,4 +87,4 @@ end
|
|
|
65
87
|
|
|
66
88
|
raise 'Couldn\'t determine project engine.' if type.nil?
|
|
67
89
|
|
|
68
|
-
RGSS.serialize(type, opts[:action], directory)
|
|
90
|
+
RGSS.serialize(type, opts[:action], directory, original_directory)
|
data/lib/RGSS/serialize.rb
CHANGED
|
@@ -50,6 +50,10 @@ class IndexedSet
|
|
|
50
50
|
def length
|
|
51
51
|
@index.length
|
|
52
52
|
end
|
|
53
|
+
|
|
54
|
+
def empty?
|
|
55
|
+
@index.empty?
|
|
56
|
+
end
|
|
53
57
|
end
|
|
54
58
|
|
|
55
59
|
module RGSS
|
|
@@ -74,7 +78,7 @@ module RGSS
|
|
|
74
78
|
case $game_type
|
|
75
79
|
when "lisa"
|
|
76
80
|
match = parameter.scan(/^\\et\[[0-9]+\]|\\nbt/)
|
|
77
|
-
parameter = parameter.slice(match[0].length) if match
|
|
81
|
+
parameter = parameter.slice((match[0].length)..) if match
|
|
78
82
|
else
|
|
79
83
|
nil
|
|
80
84
|
end
|
|
@@ -156,11 +160,9 @@ module RGSS
|
|
|
156
160
|
lines[0].add(parsed) unless parsed.nil?
|
|
157
161
|
end
|
|
158
162
|
end
|
|
159
|
-
elsif code == 356
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
lines[0].add(parsed.gsub(/\r?\n/, '\#')) unless parsed.nil?
|
|
163
|
-
end
|
|
163
|
+
elsif code == 356 && parameter.is_a?(String) && !parameter.empty?
|
|
164
|
+
parsed = parse_parameter(code, parameter)
|
|
165
|
+
lines[0].add(parsed.gsub(/\r?\n/, '\#')) unless parsed.nil?
|
|
164
166
|
end
|
|
165
167
|
end
|
|
166
168
|
end
|
|
@@ -172,14 +174,18 @@ module RGSS
|
|
|
172
174
|
end
|
|
173
175
|
|
|
174
176
|
File.write("#{output_path}/maps.txt", lines[0].join("\n"))
|
|
175
|
-
File.write("#{output_path}/maps_trans.txt", "\n" * (lines[0].
|
|
177
|
+
File.write("#{output_path}/maps_trans.txt", "\n" * (!lines[0].empty? ? lines[0].length - 1 : 0))
|
|
176
178
|
File.write("#{output_path}/names.txt", lines[1].join("\n"))
|
|
177
|
-
File.write("#{output_path}/names_trans.txt", "\n" * (lines[1].
|
|
179
|
+
File.write("#{output_path}/names_trans.txt", "\n" * (!lines[1].empty? ? lines[1].length - 1 : 0))
|
|
178
180
|
end
|
|
179
181
|
|
|
180
182
|
def self.read_other(original_other_files, output_path)
|
|
181
183
|
object_array_map = Hash[original_other_files.map do |filename|
|
|
182
|
-
|
|
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]
|
|
183
189
|
end]
|
|
184
190
|
|
|
185
191
|
object_array_map.each do |filename, object_array|
|
|
@@ -250,7 +256,7 @@ module RGSS
|
|
|
250
256
|
puts "Parsed #{filename}" if $logging
|
|
251
257
|
|
|
252
258
|
File.write("#{output_path}/#{processed_filename}.txt", lines.join("\n"))
|
|
253
|
-
File.write("#{output_path}/#{processed_filename}_trans.txt", "\n" * (lines.
|
|
259
|
+
File.write("#{output_path}/#{processed_filename}_trans.txt", "\n" * (!lines.empty? ? lines.length - 1 : 0))
|
|
254
260
|
end
|
|
255
261
|
end
|
|
256
262
|
|
|
@@ -292,21 +298,113 @@ module RGSS
|
|
|
292
298
|
puts "Parsed #{filename}" if $logging
|
|
293
299
|
|
|
294
300
|
File.write("#{output_path}/#{basename}.txt", lines.join("\n"), mode: 'wb')
|
|
295
|
-
File.write("#{output_path}/#{basename}_trans.txt", "\n" * (lines.
|
|
301
|
+
File.write("#{output_path}/#{basename}_trans.txt", "\n" * (!lines.empty? ? lines.length - 1 : 0),
|
|
296
302
|
mode: 'wb')
|
|
297
303
|
end
|
|
298
304
|
|
|
305
|
+
def self.shuffle_words(array)
|
|
306
|
+
array.map do |string|
|
|
307
|
+
re = /\S+/
|
|
308
|
+
words = string.scan(re)
|
|
309
|
+
words.shuffle
|
|
310
|
+
|
|
311
|
+
result = nil
|
|
312
|
+
|
|
313
|
+
(0..(words.length)).each do |i|
|
|
314
|
+
result = string.sub(string[i], words[i])
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
result
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def self.extract_quoted_strings(input)
|
|
322
|
+
result = []
|
|
323
|
+
|
|
324
|
+
skip_block = false
|
|
325
|
+
in_quotes = false
|
|
326
|
+
quote_type = nil
|
|
327
|
+
buffer = []
|
|
328
|
+
|
|
329
|
+
input.each_line(chomp: true) do |line|
|
|
330
|
+
line.strip!
|
|
331
|
+
next if line[0] == '#' || line.start_with?(/(Win|Lose)|_Fanfare/)
|
|
332
|
+
|
|
333
|
+
skip_block = true if line.start_with?("=begin")
|
|
334
|
+
skip_block = false if line.start_with?("=end")
|
|
335
|
+
|
|
336
|
+
next if skip_block
|
|
337
|
+
|
|
338
|
+
buffer.push('\#') if in_quotes
|
|
339
|
+
|
|
340
|
+
line.each_char do |char|
|
|
341
|
+
if char == "'" || char == '"'
|
|
342
|
+
if !quote_type.nil? && char != quote_type
|
|
343
|
+
buffer.push(char)
|
|
344
|
+
next
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
quote_type = char
|
|
348
|
+
in_quotes = !in_quotes
|
|
349
|
+
result.push(buffer.join)
|
|
350
|
+
buffer.clear
|
|
351
|
+
next
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
if in_quotes
|
|
355
|
+
buffer.push(char)
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
result
|
|
361
|
+
end
|
|
362
|
+
|
|
299
363
|
def self.read_scripts(scripts_file_path, output_path)
|
|
300
364
|
script_entries = Marshal.load(File.read(scripts_file_path, mode: 'rb'))
|
|
301
|
-
strings =
|
|
365
|
+
strings = IndexedSet.new
|
|
366
|
+
codes = []
|
|
302
367
|
|
|
303
368
|
script_entries.each do |script|
|
|
304
369
|
code = Zlib::Inflate.inflate(script[2]).force_encoding('UTF-8')
|
|
305
|
-
|
|
370
|
+
codes.push(code)
|
|
371
|
+
|
|
372
|
+
extract_quoted_strings(code).each do |string|
|
|
373
|
+
string.strip!
|
|
374
|
+
|
|
375
|
+
next if string.empty? || string.delete(' ').empty?
|
|
376
|
+
|
|
377
|
+
# Maybe this mess will remove something that mustn't be removed, but it needs to be tested
|
|
378
|
+
next if string.start_with?(/(#|!?\$|@|(\.\/)?(Graphics|Data|Audio|CG|Movies|Save)\/)/) ||
|
|
379
|
+
string.match?(/^\d+$/) ||
|
|
380
|
+
string.match?(/^(.)\1{2,}$/) ||
|
|
381
|
+
string.match?(/^(false|true)$/) ||
|
|
382
|
+
string.match?(/^(wb|rb)$/) ||
|
|
383
|
+
string.match?(/^(?=.*\d)[A-Za-z0-9\-]+$/) ||
|
|
384
|
+
string.match?(/^[A-Z\-()\/ +'&]*$/) ||
|
|
385
|
+
string.match?(/^[a-z\-()\/ +'&]*$/) ||
|
|
386
|
+
string.match?(/^[A-Za-z]+[+-]$/) ||
|
|
387
|
+
string.match?(/^[.()+-:;\[\]^~%&!*\/→×??x%▼|]$/) ||
|
|
388
|
+
string.match?(/^Tile.*[A-Z]$/) ||
|
|
389
|
+
string.match?(/^:?%.*[ds][:%]*?$/) ||
|
|
390
|
+
string.match?(/^[a-zA-Z]+([A-Z][a-z]*)+$/) ||
|
|
391
|
+
string.match?(/\.(mp3|ogg|jpg|png|ini)$/) ||
|
|
392
|
+
string.match?(/#\{/) ||
|
|
393
|
+
string.match?(/\\(?!#)/) ||
|
|
394
|
+
string.match?(/\+?=?=/) ||
|
|
395
|
+
string.match?(/[}{_<>]/) ||
|
|
396
|
+
string.match?(/r[vx]data/) ||
|
|
397
|
+
string.match?(/\/(\d.*)?$/) ||
|
|
398
|
+
string.match?(/FILE$/) ||
|
|
399
|
+
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|^Cancel Action$|^Invert$|^End$|^Individual$|^Missed File$|^Bitmap$|^Audio$/)
|
|
400
|
+
|
|
401
|
+
strings.add(string)
|
|
402
|
+
end
|
|
306
403
|
end
|
|
307
404
|
|
|
405
|
+
File.write("#{output_path}/scripts_plain.txt", codes.join("\n"), mode: 'wb')
|
|
308
406
|
File.write("#{output_path}/scripts.txt", strings.join("\n"), mode: 'wb')
|
|
309
|
-
File.write("#{output_path}/scripts_trans.txt", "\n" * (strings.
|
|
407
|
+
File.write("#{output_path}/scripts_trans.txt", "\n" * (!strings.empty? ? strings.length - 1 : 0), mode: 'wb')
|
|
310
408
|
end
|
|
311
409
|
|
|
312
410
|
def self.merge_seq(object_array)
|
|
@@ -363,7 +461,7 @@ module RGSS
|
|
|
363
461
|
end
|
|
364
462
|
end
|
|
365
463
|
|
|
366
|
-
|
|
464
|
+
object
|
|
367
465
|
end
|
|
368
466
|
|
|
369
467
|
def self.merge_other(object_array)
|
|
@@ -379,6 +477,8 @@ module RGSS
|
|
|
379
477
|
|
|
380
478
|
page.instance_variable_set(:@list, merge_seq(list))
|
|
381
479
|
end
|
|
480
|
+
|
|
481
|
+
object.instance_variable_set(:@pages, pages)
|
|
382
482
|
else
|
|
383
483
|
list = object.instance_variable_get(:@list)
|
|
384
484
|
next unless list.is_a?(Array)
|
|
@@ -386,15 +486,20 @@ module RGSS
|
|
|
386
486
|
object.instance_variable_set(:@list, merge_seq(list))
|
|
387
487
|
end
|
|
388
488
|
end
|
|
489
|
+
|
|
490
|
+
object_array
|
|
389
491
|
end
|
|
390
492
|
|
|
391
493
|
def self.get_translated(code, parameter, hashmap)
|
|
494
|
+
lisa_start = nil
|
|
495
|
+
|
|
392
496
|
case code
|
|
393
497
|
when 401, 356, 405
|
|
394
498
|
case $game_type
|
|
395
499
|
when "lisa"
|
|
396
500
|
match = parameter.scan(/^\\et\[[0-9]+\]/) || parameter.scan(/^\\nbt/)
|
|
397
|
-
|
|
501
|
+
lisa_start = match[0]
|
|
502
|
+
parameter = parameter.slice((match[0].length)..) unless match.nil?
|
|
398
503
|
else
|
|
399
504
|
nil
|
|
400
505
|
end
|
|
@@ -404,7 +509,16 @@ module RGSS
|
|
|
404
509
|
nil
|
|
405
510
|
end
|
|
406
511
|
|
|
407
|
-
|
|
512
|
+
gotten = hashmap[parameter]
|
|
513
|
+
|
|
514
|
+
case $game_type
|
|
515
|
+
when "lisa"
|
|
516
|
+
gotten = lisa_start + gotten unless lisa_start.nil?
|
|
517
|
+
else
|
|
518
|
+
nil
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
gotten
|
|
408
522
|
end
|
|
409
523
|
|
|
410
524
|
def self.get_variable_translated(variable, hashmap)
|
|
@@ -432,6 +546,16 @@ module RGSS
|
|
|
432
546
|
line.gsub('\#', "\n")
|
|
433
547
|
end
|
|
434
548
|
|
|
549
|
+
if $shuffle > 0
|
|
550
|
+
maps_translated_text.shuffle!
|
|
551
|
+
names_translated_text.shuffle!
|
|
552
|
+
|
|
553
|
+
if $shuffle == 2
|
|
554
|
+
maps_translated_text = shuffle_words(maps_translated_text)
|
|
555
|
+
names_translated_text = shuffle_words(names_translated_text)
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
|
|
435
559
|
maps_translation_map = Hash[maps_original_text.zip(maps_translated_text)].freeze
|
|
436
560
|
names_translation_map = Hash[names_original_text.zip(names_translated_text)].freeze
|
|
437
561
|
|
|
@@ -489,7 +613,7 @@ module RGSS
|
|
|
489
613
|
object_array_map = Hash[original_files.map do |filename|
|
|
490
614
|
basename = File.basename(filename)
|
|
491
615
|
object = Marshal.load(File.read(filename, mode: 'rb'))
|
|
492
|
-
object = merge_other(object)
|
|
616
|
+
object = merge_other(object).slice(1..) if basename.start_with?(/Common|Troops/)
|
|
493
617
|
|
|
494
618
|
[basename, object]
|
|
495
619
|
end]
|
|
@@ -510,18 +634,31 @@ module RGSS
|
|
|
510
634
|
line.gsub('\#', "\n")
|
|
511
635
|
end
|
|
512
636
|
|
|
637
|
+
if $shuffle > 0
|
|
638
|
+
other_translated_text.shuffle!
|
|
639
|
+
|
|
640
|
+
if $shuffle == 2
|
|
641
|
+
other_translated_text = shuffle_words(other_translated_text)
|
|
642
|
+
end
|
|
643
|
+
end
|
|
644
|
+
|
|
513
645
|
other_translation_map = Hash[other_original_text.zip(other_translated_text)]
|
|
514
646
|
|
|
515
647
|
if !filename.start_with?(/Common|Troops/)
|
|
516
648
|
object_array.each do |object|
|
|
517
649
|
next if object.nil?
|
|
518
650
|
|
|
519
|
-
|
|
520
|
-
nickname = object.instance_variable_get(:@nickname)
|
|
521
|
-
description = object.instance_variable_get(:@description)
|
|
522
|
-
note = object.instance_variable_get(:@note)
|
|
651
|
+
variables_symbols = %i[@name @nickname @description @note]
|
|
523
652
|
|
|
524
|
-
|
|
653
|
+
name = object.instance_variable_get(variables_symbols[0])
|
|
654
|
+
nickname = object.instance_variable_get(variables_symbols[1])
|
|
655
|
+
description = object.instance_variable_get(variables_symbols[2])
|
|
656
|
+
note = object.instance_variable_get(variables_symbols[3])
|
|
657
|
+
|
|
658
|
+
[[variables_symbols[0], name],
|
|
659
|
+
[variables_symbols[1], nickname],
|
|
660
|
+
[variables_symbols[2], description],
|
|
661
|
+
[variables_symbols[3], note]].each do |symbol, variable|
|
|
525
662
|
if variable.is_a?(String) && !variable.empty?
|
|
526
663
|
translated = get_variable_translated(variable, other_translation_map)
|
|
527
664
|
object.instance_variable_set(symbol, variable) unless translated.nil?
|
|
@@ -577,6 +714,14 @@ module RGSS
|
|
|
577
714
|
system_original_text = File.read("#{other_path}/system.txt").split("\n")
|
|
578
715
|
system_translated_text = File.read("#{other_path}/system_trans.txt").split("\n")
|
|
579
716
|
|
|
717
|
+
if $shuffle > 0
|
|
718
|
+
system_translated_text.shuffle!
|
|
719
|
+
|
|
720
|
+
if $shuffle == 2
|
|
721
|
+
system_translated_text = shuffle_words(system_translated_text)
|
|
722
|
+
end
|
|
723
|
+
end
|
|
724
|
+
|
|
580
725
|
system_translation_map = Hash[system_original_text.zip(system_translated_text)]
|
|
581
726
|
|
|
582
727
|
symbols = %i[@elements @skill_types @weapon_types @armor_types]
|
|
@@ -627,26 +772,37 @@ module RGSS
|
|
|
627
772
|
|
|
628
773
|
puts "Written #{basename}" if $logging
|
|
629
774
|
|
|
630
|
-
File.write("#{output_path}
|
|
775
|
+
File.write("#{output_path}/ #{basename}", Marshal.dump(object), mode: 'wb')
|
|
631
776
|
end
|
|
632
777
|
|
|
633
778
|
def self.write_scripts(scripts_file, other_path, output_path)
|
|
634
779
|
script_entries = Marshal.load(File.read(scripts_file, mode: 'rb'))
|
|
635
|
-
|
|
636
|
-
|
|
780
|
+
original_strings = File.read("#{other_path}/scripts.txt", mode: 'rb')
|
|
781
|
+
.force_encoding('UTF-8')
|
|
782
|
+
.split("\n")
|
|
783
|
+
.map { |line| line.gsub('\#', "\r\n") }
|
|
784
|
+
|
|
785
|
+
translation_strings = File.read("#{other_path}/scripts_trans.txt", mode: 'rb')
|
|
786
|
+
.force_encoding('UTF-8')
|
|
787
|
+
.split("\n")
|
|
788
|
+
.map { |line| line.gsub('\#', "\r\n") }
|
|
637
789
|
|
|
638
|
-
|
|
790
|
+
# Shuffle can possibly break the game in scripts, so no shuffling
|
|
639
791
|
|
|
640
|
-
script_entries.
|
|
792
|
+
script_entries.each do |script|
|
|
641
793
|
code = Zlib::Inflate.inflate(script[2]).force_encoding('UTF-8')
|
|
642
|
-
|
|
794
|
+
|
|
795
|
+
original_strings.zip(translation_strings).each do |original, translated|
|
|
796
|
+
code.gsub!(original, translated) unless translated.nil?
|
|
797
|
+
end
|
|
798
|
+
|
|
643
799
|
script[2] = Zlib::Deflate.deflate(code, Zlib::BEST_COMPRESSION)
|
|
644
800
|
end
|
|
645
801
|
|
|
646
802
|
File.write("#{output_path}/#{File.basename(scripts_file)}", Marshal.dump(script_entries), mode: 'wb')
|
|
647
803
|
end
|
|
648
804
|
|
|
649
|
-
def self.serialize(engine, action, directory)
|
|
805
|
+
def self.serialize(engine, action, directory, original_directory)
|
|
650
806
|
start_time = Time.now
|
|
651
807
|
|
|
652
808
|
setup_classes(engine)
|
|
@@ -654,7 +810,7 @@ module RGSS
|
|
|
654
810
|
absolute_path = File.realpath(directory)
|
|
655
811
|
|
|
656
812
|
paths = {
|
|
657
|
-
original_path: File.join(absolute_path,
|
|
813
|
+
original_path: File.join(absolute_path, original_directory),
|
|
658
814
|
translation_path: File.join(absolute_path, 'translation'),
|
|
659
815
|
maps_path: File.join(absolute_path, 'translation/maps'),
|
|
660
816
|
other_path: File.join(absolute_path, 'translation/other'),
|
|
@@ -690,15 +846,15 @@ module RGSS
|
|
|
690
846
|
end
|
|
691
847
|
|
|
692
848
|
if action == 'read'
|
|
693
|
-
read_map(maps_files, paths[:maps_path])
|
|
694
|
-
read_other(other_files, paths[:other_path])
|
|
695
|
-
read_system(system_file, paths[:other_path])
|
|
696
|
-
read_scripts(scripts_file, paths[:other_path])
|
|
849
|
+
read_map(maps_files, paths[:maps_path]) if $no[0]
|
|
850
|
+
read_other(other_files, paths[:other_path]) if $no[1]
|
|
851
|
+
read_system(system_file, paths[:other_path]) if $no[2]
|
|
852
|
+
read_scripts(scripts_file, paths[:other_path]) if $no[3]
|
|
697
853
|
else
|
|
698
|
-
write_map(maps_files, paths[:maps_path], paths[:output_path])
|
|
699
|
-
write_other(other_files, paths[:other_path], paths[:output_path])
|
|
700
|
-
write_system(system_file, paths[:other_path], paths[:output_path])
|
|
701
|
-
write_scripts(scripts_file, paths[:other_path], paths[:output_path])
|
|
854
|
+
write_map(maps_files, paths[:maps_path], paths[:output_path]) if $no[0]
|
|
855
|
+
write_other(other_files, paths[:other_path], paths[:output_path]) if $no[1]
|
|
856
|
+
write_system(system_file, paths[:other_path], paths[:output_path]) if $no[2]
|
|
857
|
+
write_scripts(scripts_file, paths[:other_path], paths[:output_path]) if $no[3]
|
|
702
858
|
end
|
|
703
859
|
|
|
704
860
|
puts "Done in #{(Time.now - start_time)}"
|
data/lib/RGSS.rb
CHANGED
|
@@ -17,6 +17,7 @@ FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TOR
|
|
|
17
17
|
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
18
18
|
DEALINGS IN THE SOFTWARE.
|
|
19
19
|
=end
|
|
20
|
+
|
|
20
21
|
class Table
|
|
21
22
|
def initialize(bytes)
|
|
22
23
|
@dim, @x, @y, @z, items, *@data = bytes.unpack('L5 S*')
|
|
@@ -233,7 +234,7 @@ module RGSS
|
|
|
233
234
|
|
|
234
235
|
# Game_Interpreter is marshalled differently in VX Ace
|
|
235
236
|
if version == :ace
|
|
236
|
-
reset_method(Game_Interpreter, :marshal_dump, -> {
|
|
237
|
+
reset_method(Game_Interpreter, :marshal_dump, -> { @data })
|
|
237
238
|
reset_method(
|
|
238
239
|
Game_Interpreter,
|
|
239
240
|
:marshal_load,
|
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.1
|
|
3
|
+
spec.version = '1.2.1'
|
|
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'
|
data/sig/rgss.rbs
CHANGED
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.1
|
|
4
|
+
version: 1.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Howard Jeng
|
|
@@ -12,7 +12,7 @@ authors:
|
|
|
12
12
|
autorequire:
|
|
13
13
|
bindir: bin
|
|
14
14
|
cert_chain: []
|
|
15
|
-
date: 2024-07-
|
|
15
|
+
date: 2024-07-04 00:00:00.000000000 Z
|
|
16
16
|
dependencies:
|
|
17
17
|
- !ruby/object:Gem::Dependency
|
|
18
18
|
name: bundler
|