rvpacker-txt 1.5.2 → 1.7.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 +4 -4
- data/README.md +5 -4
- data/bin/rvpacker-txt +37 -33
- data/lib/classes.rb +63 -1
- data/lib/read.rb +312 -229
- data/lib/write.rb +347 -279
- data/rvpacker-txt.gemspec +1 -1
- metadata +2 -2
data/lib/write.rb
CHANGED
|
@@ -2,28 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
require 'zlib'
|
|
4
4
|
|
|
5
|
+
# @param [String] string A parsed scripts code string, containing raw Ruby code
|
|
6
|
+
# @return [[Array<String>, Array<Integer>]] Hash of parsed from code strings and their start indices
|
|
5
7
|
def self.extract_quoted_strings(string)
|
|
6
8
|
# Hash of string-index key-value pairs
|
|
7
|
-
|
|
9
|
+
strings_array = []
|
|
10
|
+
indices_array = []
|
|
8
11
|
|
|
9
12
|
skip_block = false
|
|
10
13
|
in_quotes = false
|
|
11
14
|
quote_type = nil
|
|
12
15
|
buffer = []
|
|
13
16
|
|
|
14
|
-
# I hope this calculates index correctly
|
|
15
17
|
current_string_index = 0
|
|
16
18
|
string.each_line do |line|
|
|
17
19
|
stripped = line.strip
|
|
18
20
|
|
|
19
21
|
if stripped[0] == '#' || stripped.start_with?(/(Win|Lose)|_Fanfare/)
|
|
22
|
+
current_string_index += line.length
|
|
20
23
|
next
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
skip_block = true if stripped.start_with?('=begin')
|
|
24
27
|
skip_block = false if stripped.start_with?('=end')
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
if skip_block
|
|
30
|
+
current_string_index += line.length
|
|
31
|
+
next
|
|
32
|
+
end
|
|
27
33
|
|
|
28
34
|
buffer.push('\#') if in_quotes
|
|
29
35
|
|
|
@@ -36,169 +42,110 @@ def self.extract_quoted_strings(string)
|
|
|
36
42
|
|
|
37
43
|
quote_type = char
|
|
38
44
|
in_quotes = !in_quotes
|
|
39
|
-
|
|
45
|
+
|
|
46
|
+
strings_array.push(buffer.join)
|
|
47
|
+
indices_array.push(current_string_index + index)
|
|
48
|
+
|
|
40
49
|
buffer.clear
|
|
41
50
|
next
|
|
42
51
|
end
|
|
43
52
|
|
|
44
|
-
if in_quotes
|
|
45
|
-
buffer.push(char)
|
|
46
|
-
end
|
|
53
|
+
buffer.push(char) if in_quotes
|
|
47
54
|
end
|
|
48
55
|
|
|
49
56
|
current_string_index += line.length
|
|
50
57
|
end
|
|
51
58
|
|
|
52
|
-
|
|
59
|
+
[strings_array, indices_array]
|
|
53
60
|
end
|
|
54
61
|
|
|
55
|
-
|
|
62
|
+
# @param [Array<String>] array
|
|
63
|
+
# @return [Array<String>]
|
|
64
|
+
def self.shuffle_words(array)
|
|
56
65
|
array.each do |string|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
string.gsub(
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def self.merge_seq(object_array)
|
|
64
|
-
first = nil
|
|
65
|
-
number = -1
|
|
66
|
-
in_sequence = false
|
|
67
|
-
string_array = []
|
|
68
|
-
|
|
69
|
-
i = 0
|
|
70
|
-
|
|
71
|
-
while i > object_array.length
|
|
72
|
-
object = object_array[i]
|
|
73
|
-
code = object.instance_variable_get(:@code)
|
|
74
|
-
|
|
75
|
-
if [401, 405].include?(code)
|
|
76
|
-
first = i if first.nil?
|
|
77
|
-
|
|
78
|
-
number += 1
|
|
79
|
-
string_array.push(object.instance_variable_get(:@parameters)[0])
|
|
80
|
-
in_sequence = true
|
|
81
|
-
elsif i.positive? && in_sequence && !first.nil? && !number.negative?
|
|
82
|
-
parameters = object_array[first].instance_variable_get(:@parameters)
|
|
83
|
-
parameters[0] = string_array.join("\n")
|
|
84
|
-
object_array[first].instance_variable_set(:@parameters, parameters)
|
|
85
|
-
|
|
86
|
-
start_index = first + 1
|
|
87
|
-
items_to_delete = start_index + number
|
|
88
|
-
object_array.slice(start_index, items_to_delete)
|
|
89
|
-
|
|
90
|
-
string_array.clear
|
|
91
|
-
i -= number
|
|
92
|
-
number = -1
|
|
93
|
-
first = nil
|
|
94
|
-
in_sequence = false
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
i += 1
|
|
66
|
+
select_words_re = /\S+/
|
|
67
|
+
words = string.scan(select_words_re).shuffle
|
|
68
|
+
string.gsub(select_words_re) { words.pop || '' }
|
|
98
69
|
end
|
|
99
|
-
|
|
100
|
-
object_array
|
|
101
70
|
end
|
|
102
71
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
72
|
+
# @param [Integer] code
|
|
73
|
+
# @param [String] parameter
|
|
74
|
+
# @param [Hash{String => String}] hashmap
|
|
75
|
+
# @param [String] game_type
|
|
76
|
+
def self.get_parameter_translated(code, parameter, hashmap, game_type)
|
|
77
|
+
unless game_type.nil?
|
|
78
|
+
lisa_start = nil
|
|
79
|
+
|
|
80
|
+
case code
|
|
81
|
+
when 401, 405
|
|
82
|
+
case game_type
|
|
83
|
+
when 'lisa'
|
|
84
|
+
match = parameter.scan(/^(\\et\[[0-9]+\]|\\nbt)/)
|
|
85
|
+
|
|
86
|
+
unless match.empty?
|
|
87
|
+
lisa_start = match[0]
|
|
88
|
+
parameter = parameter.slice((match[0].length)..)
|
|
89
|
+
end
|
|
90
|
+
else
|
|
91
|
+
nil
|
|
92
|
+
end
|
|
93
|
+
when 102, 402
|
|
94
|
+
# Implement some custom parsing
|
|
95
|
+
when 356
|
|
96
|
+
# Implement some custom parsing
|
|
97
|
+
else
|
|
98
|
+
nil
|
|
114
99
|
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
object
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def self.merge_other(object_array)
|
|
121
|
-
object_array.each do |object|
|
|
122
|
-
next if object.nil?
|
|
123
|
-
|
|
124
|
-
pages = object.instance_variable_get(:@pages)
|
|
125
|
-
|
|
126
|
-
if pages.is_a?(Array)
|
|
127
|
-
pages.each do |page|
|
|
128
|
-
list = page.instance_variable_get(:@list)
|
|
129
|
-
next unless list.is_a?(Array)
|
|
130
|
-
|
|
131
|
-
page.instance_variable_set(:@list, merge_seq(list))
|
|
132
|
-
end
|
|
133
100
|
|
|
134
|
-
|
|
135
|
-
else
|
|
136
|
-
list = object.instance_variable_get(:@list)
|
|
137
|
-
next unless list.is_a?(Array)
|
|
101
|
+
gotten = hashmap[parameter]
|
|
138
102
|
|
|
139
|
-
|
|
103
|
+
case game_type
|
|
104
|
+
when 'lisa'
|
|
105
|
+
gotten = lisa_start + gotten unless lisa_start.nil?
|
|
106
|
+
else
|
|
107
|
+
nil
|
|
140
108
|
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
object_array
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def self.get_parameter_translated(code, parameter, hashmap, game_type)
|
|
147
|
-
lisa_start = nil
|
|
148
|
-
|
|
149
|
-
case code
|
|
150
|
-
when 401, 405
|
|
151
|
-
case game_type
|
|
152
|
-
when 'lisa'
|
|
153
|
-
match = parameter.scan(/^(\\et\[[0-9]+\]|\\nbt)/)
|
|
154
|
-
lisa_start = match[0]
|
|
155
|
-
parameter = parameter.slice((match[0].length)..) unless match.nil?
|
|
156
|
-
else
|
|
157
|
-
nil
|
|
158
|
-
end
|
|
159
|
-
when 102, 402
|
|
160
|
-
# Implement some custom parsing
|
|
161
|
-
when 356
|
|
162
|
-
# Implement some custom parsing
|
|
163
|
-
else
|
|
164
|
-
nil
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
gotten = hashmap[parameter]
|
|
168
109
|
|
|
169
|
-
|
|
170
|
-
when 'lisa'
|
|
171
|
-
gotten = lisa_start + gotten unless lisa_start.nil?
|
|
172
|
-
else
|
|
173
|
-
nil
|
|
110
|
+
return gotten
|
|
174
111
|
end
|
|
175
112
|
|
|
176
|
-
|
|
113
|
+
hashmap[parameter]
|
|
177
114
|
end
|
|
178
115
|
|
|
116
|
+
# @param [String] variable
|
|
117
|
+
# @param [Hash{String => String}] hashmap
|
|
118
|
+
# @param [String] _game_type
|
|
119
|
+
# @return [String]
|
|
179
120
|
def self.get_variable_translated(variable, hashmap, _game_type)
|
|
180
121
|
hashmap[variable]
|
|
181
122
|
end
|
|
182
123
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
124
|
+
# @param [Array<String>] original_files_paths
|
|
125
|
+
# @param [String] maps_path
|
|
126
|
+
# @param [String] output_path
|
|
127
|
+
# @param [Integer] shuffle_level
|
|
128
|
+
# @param [Boolean] logging
|
|
129
|
+
# @param [String] game_type
|
|
130
|
+
def self.write_map(original_files_paths, maps_path, output_path, shuffle_level, logging, game_type)
|
|
131
|
+
maps_object_map = Hash[original_files_paths.map do |filename|
|
|
132
|
+
[File.basename(filename), Marshal.load(File.binread(filename))]
|
|
186
133
|
end]
|
|
187
134
|
|
|
188
|
-
maps_original_text =
|
|
189
|
-
line.gsub('\#', "\n")
|
|
190
|
-
end
|
|
135
|
+
maps_original_text = File.readlines(File.join(maps_path, 'maps.txt'), encoding: 'UTF-8', chomp: true).map do |line|
|
|
136
|
+
line.gsub('\#', "\n").strip
|
|
137
|
+
end.freeze
|
|
191
138
|
|
|
192
|
-
names_original_text =
|
|
193
|
-
line.gsub('\#', "\n")
|
|
194
|
-
end
|
|
139
|
+
names_original_text = File.readlines(File.join(maps_path, 'names.txt'), encoding: 'UTF-8', chomp: true).map do |line|
|
|
140
|
+
line.gsub('\#', "\n").strip
|
|
141
|
+
end.freeze
|
|
195
142
|
|
|
196
|
-
maps_translated_text = File.readlines(
|
|
197
|
-
line.gsub('\#', "\n")
|
|
143
|
+
maps_translated_text = File.readlines(File.join(maps_path, 'maps.txt'), encoding: 'UTF-8', chomp: true).map do |line|
|
|
144
|
+
line.gsub('\#', "\n").strip
|
|
198
145
|
end
|
|
199
146
|
|
|
200
|
-
names_translated_text = File.readlines(
|
|
201
|
-
line.gsub('\#', "\n")
|
|
147
|
+
names_translated_text = File.readlines(File.join(maps_path, 'names_trans.txt'), encoding: 'UTF-8', chomp: true).map do |line|
|
|
148
|
+
line.gsub('\#', "\n").strip
|
|
202
149
|
end
|
|
203
150
|
|
|
204
151
|
if shuffle_level.positive?
|
|
@@ -214,47 +161,95 @@ def self.write_map(original_files, maps_path, output_path, shuffle_level, loggin
|
|
|
214
161
|
maps_translation_map = Hash[maps_original_text.zip(maps_translated_text)].freeze
|
|
215
162
|
names_translation_map = Hash[names_original_text.zip(names_translated_text)].freeze
|
|
216
163
|
|
|
217
|
-
|
|
164
|
+
# 401 - dialogue lines
|
|
165
|
+
# 102 - dialogue choices array
|
|
166
|
+
# 402 - one of the dialogue choices from the array
|
|
167
|
+
# 356 - system lines/special texts (do they even exist before mv?)
|
|
168
|
+
allowed_codes = [401, 102, 402, 356].freeze
|
|
218
169
|
|
|
219
170
|
maps_object_map.each do |filename, object|
|
|
220
|
-
display_name = object.
|
|
171
|
+
display_name = object.display_name
|
|
221
172
|
display_name_gotten = names_translation_map[display_name]
|
|
222
|
-
object.
|
|
173
|
+
object.display_name = display_name_gotten unless display_name_gotten.nil?
|
|
223
174
|
|
|
224
|
-
events = object.
|
|
175
|
+
events = object.events
|
|
225
176
|
next if events.nil?
|
|
226
177
|
|
|
227
178
|
events.each_value do |event|
|
|
228
|
-
pages = event.
|
|
179
|
+
pages = event.pages
|
|
229
180
|
next if pages.nil?
|
|
230
181
|
|
|
231
182
|
pages.each do |page|
|
|
232
|
-
list = page.
|
|
183
|
+
list = page.list
|
|
233
184
|
next if list.nil?
|
|
234
185
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
186
|
+
in_sequence = false
|
|
187
|
+
line = []
|
|
188
|
+
item_indices = []
|
|
238
189
|
|
|
239
|
-
|
|
190
|
+
list.each_with_index do |item, it|
|
|
191
|
+
code = item.code
|
|
240
192
|
|
|
241
|
-
|
|
242
|
-
if
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
193
|
+
unless allowed_codes.include?(code)
|
|
194
|
+
if in_sequence
|
|
195
|
+
joined = line.join('\#').strip
|
|
196
|
+
translated = get_parameter_translated(401, joined, maps_translation_map, game_type)
|
|
197
|
+
|
|
198
|
+
unless translated.nil? || translated.empty?
|
|
199
|
+
split = translated.split('\#')
|
|
200
|
+
|
|
201
|
+
split_length = split.length
|
|
202
|
+
line_length = line.length
|
|
203
|
+
|
|
204
|
+
item_indices.each_with_index do |index, i|
|
|
205
|
+
list[index].parameters[0] = i < split_length ? split[i] : ''
|
|
252
206
|
end
|
|
207
|
+
|
|
208
|
+
list[item_indices.last].parameters[0] = split[line_length..].join("\n") if split_length > line_length
|
|
253
209
|
end
|
|
254
210
|
end
|
|
211
|
+
next
|
|
255
212
|
end
|
|
256
213
|
|
|
257
|
-
item.
|
|
214
|
+
parameters = item.parameters
|
|
215
|
+
|
|
216
|
+
if code == 401
|
|
217
|
+
next unless parameters[0].is_a?(String) && !parameters[0].empty?
|
|
218
|
+
|
|
219
|
+
in_sequence = true
|
|
220
|
+
line.push(parameters[0])
|
|
221
|
+
item_indices.push(it)
|
|
222
|
+
elsif code == 356
|
|
223
|
+
parameter = parameters[0]
|
|
224
|
+
next unless parameter.is_a?(String)
|
|
225
|
+
|
|
226
|
+
parameter = parameter.strip
|
|
227
|
+
next if parameter.empty?
|
|
228
|
+
|
|
229
|
+
translated = get_parameter_translated(code, parameter, maps_translation_map, game_type)
|
|
230
|
+
parameters[0] = translated unless translated.nil? || translated.empty?
|
|
231
|
+
elsif code == 402
|
|
232
|
+
parameter = parameters[1]
|
|
233
|
+
next unless parameter.is_a?(String)
|
|
234
|
+
|
|
235
|
+
parameter = parameter.strip
|
|
236
|
+
next if parameter.empty?
|
|
237
|
+
|
|
238
|
+
translated = get_parameter_translated(code, parameter, maps_translation_map, game_type)
|
|
239
|
+
parameters[1] = translated unless translated.nil? || translated.empty?
|
|
240
|
+
elsif code == 102 && parameters[0].is_a?(Array)
|
|
241
|
+
parameters[0].each_with_index do |subparameter, sp|
|
|
242
|
+
next unless subparameter.is_a?(String)
|
|
243
|
+
|
|
244
|
+
subparameter = subparameter.strip
|
|
245
|
+
next if subparameter.empty?
|
|
246
|
+
|
|
247
|
+
translated = get_parameter_translated(code, subparameter, maps_translation_map, game_type)
|
|
248
|
+
parameters[0][sp] = translated unless translated.nil? || translated.empty?
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
item.parameters = parameters
|
|
258
253
|
end
|
|
259
254
|
end
|
|
260
255
|
end
|
|
@@ -265,25 +260,35 @@ def self.write_map(original_files, maps_path, output_path, shuffle_level, loggin
|
|
|
265
260
|
end
|
|
266
261
|
end
|
|
267
262
|
|
|
268
|
-
|
|
269
|
-
|
|
263
|
+
# @param [Array<String>] original_files
|
|
264
|
+
# @param [String] other_path
|
|
265
|
+
# @param [String] output_path
|
|
266
|
+
# @param [Integer] shuffle_level
|
|
267
|
+
# @param [Boolean] logging
|
|
268
|
+
# @param [String] game_type
|
|
269
|
+
def self.write_other(original_files_paths, other_path, output_path, shuffle_level, logging, game_type)
|
|
270
|
+
other_object_array_map = Hash[original_files_paths.map do |filename|
|
|
270
271
|
basename = File.basename(filename)
|
|
271
272
|
object = Marshal.load(File.binread(filename))
|
|
272
|
-
object = merge_other(object).slice(1..) if basename.start_with?(/Common|Troops/)
|
|
273
273
|
|
|
274
274
|
[basename, object]
|
|
275
275
|
end]
|
|
276
276
|
|
|
277
|
-
|
|
277
|
+
# 401 - dialogue lines
|
|
278
|
+
# 405 - credits lines
|
|
279
|
+
# 102 - dialogue choices array
|
|
280
|
+
# 402 - one of the dialogue choices from the array
|
|
281
|
+
# 356 - system lines/special texts (do they even exist before mv?)
|
|
282
|
+
allowed_codes = [401, 405, 102, 402, 356].freeze
|
|
278
283
|
|
|
279
284
|
other_object_array_map.each do |filename, other_object_array|
|
|
280
285
|
other_filename = File.basename(filename, '.*').downcase
|
|
281
286
|
|
|
282
|
-
other_original_text = File.readlines(
|
|
283
|
-
.map { |line| line.gsub('\#', "\n") }
|
|
287
|
+
other_original_text = File.readlines(File.join(other_path, "#{other_filename}.txt"), encoding: 'UTF-8', chomp: true)
|
|
288
|
+
.map { |line| line.gsub('\#', "\n").strip }
|
|
284
289
|
|
|
285
|
-
other_translated_text = File.readlines(
|
|
286
|
-
.map { |line| line.gsub('\#', "\n") }
|
|
290
|
+
other_translated_text = File.readlines(File.join(other_path, "#{other_filename}_trans.txt"), encoding: 'UTF-8', chomp: true)
|
|
291
|
+
.map { |line| line.gsub('\#', "\n").strip }
|
|
287
292
|
|
|
288
293
|
if shuffle_level.positive?
|
|
289
294
|
other_translated_text.shuffle!
|
|
@@ -296,54 +301,110 @@ def self.write_other(original_files, other_path, output_path, shuffle_level, log
|
|
|
296
301
|
other_object_array.each do |object|
|
|
297
302
|
next if object.nil?
|
|
298
303
|
|
|
299
|
-
|
|
304
|
+
name = object.name
|
|
305
|
+
nickname = object.nickname
|
|
306
|
+
description = object.description
|
|
307
|
+
note = object.note
|
|
308
|
+
|
|
309
|
+
[name, nickname, description, note].each_with_index do |variable, i|
|
|
310
|
+
next unless variable.is_a?(String)
|
|
311
|
+
|
|
312
|
+
variable = variable.strip
|
|
313
|
+
next if variable.empty?
|
|
300
314
|
|
|
301
|
-
|
|
302
|
-
nickname = object.instance_variable_get(variables_symbols[1])
|
|
303
|
-
description = object.instance_variable_get(variables_symbols[2])
|
|
304
|
-
note = object.instance_variable_get(variables_symbols[3])
|
|
315
|
+
variable = variable.gsub(/\r\n/, "\n")
|
|
305
316
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
317
|
+
translated = get_variable_translated(variable, other_translation_map, game_type)
|
|
318
|
+
|
|
319
|
+
if i.zero?
|
|
320
|
+
object.name = translated unless translated.nil? || translated.empty?
|
|
321
|
+
elsif i == 1
|
|
322
|
+
object.nickname = translated unless translated.nil? || translated.empty?
|
|
323
|
+
elsif i == 2
|
|
324
|
+
object.description = translated unless translated.nil? || translated.empty?
|
|
325
|
+
else
|
|
326
|
+
object.note = translated unless translated.nil? || translated.empty?
|
|
313
327
|
end
|
|
314
328
|
end
|
|
315
329
|
end
|
|
316
330
|
else
|
|
317
331
|
other_object_array.each do |object|
|
|
318
|
-
|
|
332
|
+
next if object.nil?
|
|
333
|
+
|
|
334
|
+
pages = object.pages
|
|
319
335
|
pages_length = pages.nil? ? 1 : pages.length
|
|
320
336
|
|
|
321
|
-
(0..pages_length).each do |
|
|
322
|
-
list = pages.nil? ? object.
|
|
337
|
+
(0..pages_length).each do |pg|
|
|
338
|
+
list = pages.nil? ? object.list : pages[pg].instance_variable_get(:@list) # for some reason .list access doesn't work (wtf?)
|
|
323
339
|
next if list.nil?
|
|
324
340
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
341
|
+
in_sequence = false
|
|
342
|
+
line = []
|
|
343
|
+
item_indices = []
|
|
328
344
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
345
|
+
list.each_with_index do |item, it|
|
|
346
|
+
code = item.code
|
|
347
|
+
|
|
348
|
+
unless allowed_codes.include?(code)
|
|
349
|
+
if in_sequence
|
|
350
|
+
joined = line.join('\#').strip
|
|
351
|
+
translated = get_parameter_translated(401, joined, other_translation_map, game_type)
|
|
352
|
+
|
|
353
|
+
unless translated.nil? || translated.empty?
|
|
354
|
+
split = translated.split('\#')
|
|
355
|
+
|
|
356
|
+
split_length = split.length
|
|
357
|
+
line_length = line.length
|
|
358
|
+
|
|
359
|
+
item_indices.each_with_index do |index, i|
|
|
360
|
+
list[index].parameters[0] = i < split_length ? split[i] : ''
|
|
341
361
|
end
|
|
362
|
+
|
|
363
|
+
list[item_indices.last].parameters[0] = split[line_length..].join("\n") if split_length > line_length
|
|
342
364
|
end
|
|
343
365
|
end
|
|
366
|
+
next
|
|
344
367
|
end
|
|
345
368
|
|
|
346
|
-
item.
|
|
369
|
+
parameters = item.parameters
|
|
370
|
+
|
|
371
|
+
if [401, 405].include?(code)
|
|
372
|
+
next unless parameters[0].is_a?(String) && !parameters[0].empty?
|
|
373
|
+
|
|
374
|
+
in_sequence = true
|
|
375
|
+
line.push(parameters[0])
|
|
376
|
+
item_indices.push(it)
|
|
377
|
+
elsif code == 356
|
|
378
|
+
parameter = parameters[0]
|
|
379
|
+
next unless parameter.is_a?(String)
|
|
380
|
+
|
|
381
|
+
parameter = parameter.strip
|
|
382
|
+
next if parameter.empty?
|
|
383
|
+
|
|
384
|
+
translated = get_parameter_translated(code, parameter, other_translation_map, game_type)
|
|
385
|
+
parameters[0] = translated unless translated.nil? || translated.empty?
|
|
386
|
+
elsif code == 402
|
|
387
|
+
parameter = parameters[1]
|
|
388
|
+
next unless parameter.is_a?(String)
|
|
389
|
+
|
|
390
|
+
parameter = parameter.strip
|
|
391
|
+
next if parameter.empty?
|
|
392
|
+
|
|
393
|
+
translated = get_parameter_translated(code, parameter, other_translation_map, game_type)
|
|
394
|
+
parameters[1] = translated unless translated.nil? || translated.empty?
|
|
395
|
+
elsif code == 102 && parameters[0].is_a?(Array)
|
|
396
|
+
parameters[0].each_with_index do |subparameter, sp|
|
|
397
|
+
next unless subparameter.is_a?(String)
|
|
398
|
+
|
|
399
|
+
subparameter = subparameter.strip
|
|
400
|
+
next if subparameter.empty?
|
|
401
|
+
|
|
402
|
+
translated = get_parameter_translated(code, subparameter, other_translation_map, game_type)
|
|
403
|
+
parameters[0][sp] = translated unless translated.nil? || translated.empty?
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
item.parameters = parameters
|
|
347
408
|
end
|
|
348
409
|
end
|
|
349
410
|
end
|
|
@@ -355,24 +416,34 @@ def self.write_other(original_files, other_path, output_path, shuffle_level, log
|
|
|
355
416
|
end
|
|
356
417
|
end
|
|
357
418
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
file_lines[title_line_index] = translated
|
|
366
|
-
File.binwrite(ini_file_path, file_lines.join)
|
|
419
|
+
# @param [String] ini_file_path
|
|
420
|
+
# @param [String] translated
|
|
421
|
+
def self.write_ini_title(ini_file_path, translated)
|
|
422
|
+
file_lines = File.readlines(ini_file_path, chomp: true)
|
|
423
|
+
title_line_index = file_lines.each_with_index do |line, i|
|
|
424
|
+
break i if line.downcase.start_with?('title')
|
|
367
425
|
end
|
|
368
426
|
|
|
427
|
+
file_lines[title_line_index] = translated
|
|
428
|
+
File.binwrite(ini_file_path, file_lines.join("\n"))
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
# @param [String] system_file_path
|
|
432
|
+
# @param [String] ini_file_path
|
|
433
|
+
# @param [String] other_path
|
|
434
|
+
# @param [String] output_path
|
|
435
|
+
# @param [Integer] shuffle_level
|
|
436
|
+
# @param [Boolean] logging
|
|
437
|
+
def self.write_system(system_file_path, ini_file_path, other_path, output_path, shuffle_level, logging)
|
|
369
438
|
system_basename = File.basename(system_file_path)
|
|
370
439
|
system_object = Marshal.load(File.binread(system_file_path))
|
|
371
440
|
|
|
372
|
-
system_original_text = File.readlines(
|
|
441
|
+
system_original_text = File.readlines(File.join(other_path, 'system.txt'), encoding: 'UTF-8', chomp: true)
|
|
442
|
+
.map(&:strip)
|
|
373
443
|
.freeze
|
|
374
444
|
|
|
375
|
-
system_translated_text = File.readlines(
|
|
445
|
+
system_translated_text = File.readlines(File.join(other_path, 'system_trans.txt'), encoding: 'UTF-8', chomp: true)
|
|
446
|
+
.map(&:strip)
|
|
376
447
|
|
|
377
448
|
if shuffle_level.positive?
|
|
378
449
|
system_translated_text.shuffle!
|
|
@@ -381,123 +452,120 @@ def self.write_system(system_file_path, ini_file_path, other_path, output_path,
|
|
|
381
452
|
|
|
382
453
|
system_translation_map = Hash[system_original_text.zip(system_translated_text)].freeze
|
|
383
454
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
currency_unit = system_object.instance_variable_get(system_symbols[4])
|
|
391
|
-
terms = system_object.instance_variable_get(system_symbols[5]) || system_object.instance_variable_get(system_symbols[6])
|
|
455
|
+
elements = system_object.elements
|
|
456
|
+
skill_types = system_object.skill_types
|
|
457
|
+
weapon_types = system_object.weapon_types
|
|
458
|
+
armor_types = system_object.armor_types
|
|
459
|
+
currency_unit = system_object.currency_unit
|
|
460
|
+
terms = system_object.terms || system_object.words
|
|
392
461
|
|
|
393
462
|
[elements, skill_types, weapon_types, armor_types].each_with_index.each do |array, i|
|
|
394
463
|
next unless array.is_a?(Array)
|
|
395
464
|
|
|
396
|
-
array.map!
|
|
397
|
-
|
|
465
|
+
array.map! do |string|
|
|
466
|
+
stripped = string.strip
|
|
467
|
+
return string if stripped.empty?
|
|
468
|
+
|
|
469
|
+
translated = system_translation_map[stripped]
|
|
470
|
+
!translated.nil? && !translated.empty? ? translated : stripped
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
if i.zero?
|
|
474
|
+
system_object.elements = array
|
|
475
|
+
elsif i == 1
|
|
476
|
+
system_object.skill_types = array
|
|
477
|
+
elsif i == 2
|
|
478
|
+
system_object.weapon_types = array
|
|
479
|
+
else
|
|
480
|
+
system_object.armor_types = array
|
|
481
|
+
end
|
|
398
482
|
end
|
|
399
483
|
|
|
400
484
|
currency_unit_translated = system_translation_map[currency_unit]
|
|
401
|
-
system_object.
|
|
402
|
-
!currency_unit_translated.nil?
|
|
485
|
+
system_object.currency_unit = currency_unit_translated if currency_unit.is_a?(String) &&
|
|
486
|
+
(!currency_unit_translated.nil? && !currency_unit_translated.empty?)
|
|
403
487
|
|
|
404
488
|
terms.instance_variables.each do |variable|
|
|
405
489
|
value = terms.instance_variable_get(variable)
|
|
406
490
|
|
|
407
491
|
if value.is_a?(String)
|
|
408
|
-
|
|
409
|
-
|
|
492
|
+
stripped = value.strip
|
|
493
|
+
next if value.empty?
|
|
494
|
+
|
|
495
|
+
translated = system_translation_map[stripped]
|
|
496
|
+
value = !translated.nil? && !translated.empty? ? translated : value
|
|
410
497
|
elsif value.is_a?(Array)
|
|
411
|
-
value.map!
|
|
498
|
+
value.map! do |string|
|
|
499
|
+
stripped = string.strip
|
|
500
|
+
return string if stripped.empty?
|
|
501
|
+
|
|
502
|
+
translated = system_translation_map[stripped]
|
|
503
|
+
value = !translated.nil? && !translated.empty? ? translated : value
|
|
504
|
+
end
|
|
412
505
|
end
|
|
413
506
|
|
|
414
507
|
terms.instance_variable_set(variable, value)
|
|
415
508
|
end
|
|
416
509
|
|
|
417
|
-
system_object.
|
|
418
|
-
system_object.
|
|
419
|
-
system_object.
|
|
510
|
+
system_object.terms.nil? ?
|
|
511
|
+
system_object.words = terms :
|
|
512
|
+
system_object.terms = terms
|
|
420
513
|
|
|
421
514
|
game_title_translated = system_translated_text[-1]
|
|
422
|
-
system_object.
|
|
423
|
-
|
|
515
|
+
system_object.game_title = game_title_translated
|
|
424
516
|
write_ini_title(ini_file_path, game_title_translated)
|
|
425
517
|
|
|
426
518
|
puts "Written #{system_basename}" if logging
|
|
427
519
|
|
|
428
|
-
File.binwrite(
|
|
520
|
+
File.binwrite(File.join(output_path, system_basename), Marshal.dump(system_object))
|
|
429
521
|
end
|
|
430
522
|
|
|
523
|
+
# @param [String] scripts_file_path Path to Scripts.*data file
|
|
524
|
+
# @param [String] other_path Path to translation/other directory containing .txt files
|
|
525
|
+
# @param [String] output_path Path to the output directory
|
|
526
|
+
# @param [Boolean] logging Whether to log
|
|
431
527
|
def self.write_scripts(scripts_file_path, other_path, output_path, logging)
|
|
432
528
|
scripts_basename = File.basename(scripts_file_path)
|
|
433
529
|
script_entries = Marshal.load(File.binread(scripts_file_path))
|
|
434
530
|
|
|
435
|
-
|
|
531
|
+
scripts_original_text = File.readlines(File.join(other_path, 'scripts.txt'), encoding: 'UTF-8', chomp: true)
|
|
532
|
+
.map { |line| line.gsub('\#', "\r\n") }
|
|
533
|
+
scripts_translated_text = File.readlines(File.join(other_path, 'scripts_trans.txt'), encoding: 'UTF-8', chomp: true)
|
|
436
534
|
.map { |line| line.gsub('\#', "\r\n") }
|
|
437
535
|
|
|
536
|
+
scripts_translation_map = Hash[scripts_original_text.zip(scripts_translated_text)]
|
|
537
|
+
|
|
438
538
|
# Shuffle can possibly break the game in scripts, so no shuffling
|
|
539
|
+
codes = []
|
|
439
540
|
|
|
541
|
+
# This code was fun before `that` game used Windows-1252 degree symbol
|
|
440
542
|
script_entries.each do |script|
|
|
441
543
|
code = Zlib::Inflate.inflate(script[2]).force_encoding('UTF-8')
|
|
442
544
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
string.match?(/^[a-z\-()\/ +'&]*$/) ||
|
|
460
|
-
string.match?(/^[A-Za-z]+[+-]$/) ||
|
|
461
|
-
string.match?(/^[.()+-:;\[\]^~%&!*\/→×??x%▼|]$/) ||
|
|
462
|
-
string.match?(/^Tile.*[A-Z]$/) ||
|
|
463
|
-
string.match?(/^:?%.*[ds][:%]*?$/) ||
|
|
464
|
-
string.match?(/^[a-zA-Z]+([A-Z][a-z]*)+$/) ||
|
|
465
|
-
string.match?(/^Cancel Action$|^Invert$|^End$|^Individual$|^Missed File$|^Bitmap$|^Audio$/) ||
|
|
466
|
-
string.match?(/\.(mp3|ogg|jpg|png|ini)$/) ||
|
|
467
|
-
string.match?(/\/(\d.*)?$/) ||
|
|
468
|
-
string.match?(/FILE$/) ||
|
|
469
|
-
string.match?(/#\{/) ||
|
|
470
|
-
string.match?(/\\(?!#)/) ||
|
|
471
|
-
string.match?(/\+?=?=/) ||
|
|
472
|
-
string.match?(/[}{_<>]/) ||
|
|
473
|
-
string.match?(/r[vx]data/) ||
|
|
474
|
-
string.match?(/No such file or directory/) ||
|
|
475
|
-
string.match?(/level \*\*/) ||
|
|
476
|
-
string.match?(/Courier New/) ||
|
|
477
|
-
string.match?(/Comic Sans/) ||
|
|
478
|
-
string.match?(/Lucida/) ||
|
|
479
|
-
string.match?(/Verdana/) ||
|
|
480
|
-
string.match?(/Tahoma/) ||
|
|
481
|
-
string.match?(/Arial/) ||
|
|
482
|
-
string.match?(/Player start location/) ||
|
|
483
|
-
string.match?(/Common event call has exceeded/) ||
|
|
484
|
-
string.match?(/se-/) ||
|
|
485
|
-
string.match?(/Start Pos/) ||
|
|
486
|
-
string.match?(/An error has occurred/) ||
|
|
487
|
-
string.match?(/Define it first/) ||
|
|
488
|
-
string.match?(/Process Skill/) ||
|
|
489
|
-
string.match?(/Wpn Only/) ||
|
|
490
|
-
string.match?(/Don't Wait/) ||
|
|
491
|
-
string.match?(/Clear image/) ||
|
|
492
|
-
string.match?(/Can Collapse/)
|
|
493
|
-
|
|
494
|
-
code[string_index, string.length] = scripts_translated_text[i]
|
|
545
|
+
unless code.valid_encoding?
|
|
546
|
+
# who the fuck uses the degree symbol from FUCKING WINDOWS-1252 and NOT UTF-8
|
|
547
|
+
# also, String#encode does NOT FUCKING WORK and for some reason raises on the
|
|
548
|
+
# fucking degree symbol from windows-1252 when trying to encode
|
|
549
|
+
code.force_encoding('Windows-1252')
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
# this shit finally works and requires NO further changes
|
|
553
|
+
string_array, index_array = extract_quoted_strings(code)
|
|
554
|
+
|
|
555
|
+
string_array.zip(index_array).reverse_each do |string, index|
|
|
556
|
+
string = string.strip.delete(' ')
|
|
557
|
+
next if string.empty? || !scripts_translation_map.include?(string)
|
|
558
|
+
|
|
559
|
+
gotten = scripts_translation_map[string]
|
|
560
|
+
code[index - string.length, string.length] = gotten unless gotten.nil? || gotten.empty?
|
|
495
561
|
end
|
|
496
562
|
|
|
563
|
+
codes.push(code)
|
|
497
564
|
script[2] = Zlib::Deflate.deflate(code, Zlib::BEST_COMPRESSION)
|
|
498
565
|
end
|
|
499
566
|
|
|
500
567
|
puts "Written #{scripts_basename}" if logging
|
|
501
568
|
|
|
502
|
-
File.binwrite(
|
|
569
|
+
# File.binwrite(File.join(output_path, 'scripts_plain.txt'), codes.join("\n")) - debug line
|
|
570
|
+
File.binwrite(File.join(output_path, scripts_basename), Marshal.dump(script_entries))
|
|
503
571
|
end
|