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.
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
- result = {}
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
- next if skip_block
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
- result[buffer.join] = current_string_index + index
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
- result
59
+ [strings_array, indices_array]
53
60
  end
54
61
 
55
- def shuffle_words(array)
62
+ # @param [Array<String>] array
63
+ # @return [Array<String>]
64
+ def self.shuffle_words(array)
56
65
  array.each do |string|
57
- words = string.scan(/\S+/)
58
- shuffled_words = words.shuffle
59
- string.gsub(/\S+/) { shuffled_words.pop || "" }
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
- def self.merge_map(object)
104
- events = object.instance_variable_get(:@events)
105
- return object if events.nil?
106
-
107
- events.each_value do |event|
108
- pages = event.instance_variable_get(:@pages)
109
- next if pages.nil?
110
-
111
- pages.each do |page|
112
- list = page.instance_variable_get(:@list)
113
- page.instance_variable_set(:@list, merge_seq(list))
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
- object.instance_variable_set(:@pages, pages)
135
- else
136
- list = object.instance_variable_get(:@list)
137
- next unless list.is_a?(Array)
101
+ gotten = hashmap[parameter]
138
102
 
139
- object.instance_variable_set(:@list, merge_seq(list))
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
- case game_type
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
- gotten
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
- def self.write_map(original_files, maps_path, output_path, shuffle_level, logging, game_type)
184
- maps_object_map = Hash[original_files.map do |filename|
185
- [File.basename(filename), merge_map(Marshal.load(File.binread(filename)))]
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 = (File.readlines("#{maps_path}/maps.txt", encoding: 'UTF-8', chomp: true).map do |line|
189
- line.gsub('\#', "\n")
190
- end).freeze
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 = (File.readlines("#{maps_path}/names.txt", encoding: 'UTF-8', chomp: true).map do |line|
193
- line.gsub('\#', "\n")
194
- end).freeze
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("#{maps_path}/maps_trans.txt", encoding: 'UTF-8', chomp: true).map do |line|
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("#{maps_path}/names_trans.txt", encoding: 'UTF-8', chomp: true).map do |line|
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
- allowed_codes = [401, 402, 356, 102].freeze
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.instance_variable_get(:@display_name)
171
+ display_name = object.display_name
221
172
  display_name_gotten = names_translation_map[display_name]
222
- object.instance_variable_set(:@display_name, display_name_gotten) unless display_name_gotten.nil?
173
+ object.display_name = display_name_gotten unless display_name_gotten.nil?
223
174
 
224
- events = object.instance_variable_get(:@events)
175
+ events = object.events
225
176
  next if events.nil?
226
177
 
227
178
  events.each_value do |event|
228
- pages = event.instance_variable_get(:@pages)
179
+ pages = event.pages
229
180
  next if pages.nil?
230
181
 
231
182
  pages.each do |page|
232
- list = page.instance_variable_get(:@list)
183
+ list = page.list
233
184
  next if list.nil?
234
185
 
235
- list.each do |item|
236
- code = item.instance_variable_get(:@code)
237
- next unless allowed_codes.include?(code)
186
+ in_sequence = false
187
+ line = []
188
+ item_indices = []
238
189
 
239
- parameters = item.instance_variable_get(:@parameters)
190
+ list.each_with_index do |item, it|
191
+ code = item.code
240
192
 
241
- parameters.each_with_index do |parameter, i|
242
- if [401, 402, 356].include?(code)
243
- if parameter.is_a?(String) && !parameter.empty?
244
- translated = get_parameter_translated(code, parameter, maps_translation_map, game_type)
245
- parameters[i] = translated unless translated.nil?
246
- end
247
- elsif parameter.is_a?(Array)
248
- parameter.each_with_index do |subparameter, j|
249
- if subparameter.is_a?(String) && !subparameter.empty?
250
- translated = get_parameter_translated(code, subparameter, maps_translation_map, game_type)
251
- parameters[i][j] = translated unless translated.nil?
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.instance_variable_set(:@parameters, parameters)
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
- def self.write_other(original_files, other_path, output_path, shuffle_level, logging, game_type)
269
- other_object_array_map = Hash[original_files.map do |filename|
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
- allowed_codes = [401, 402, 405, 356, 102].freeze
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("#{File.join(other_path, other_filename)}.txt", encoding: 'UTF-8', chomp: true)
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("#{File.join(other_path, other_filename)}_trans.txt", encoding: 'UTF-8', chomp: true)
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
- variables_symbols = %i[@name @nickname @description @note].freeze
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
- name = object.instance_variable_get(variables_symbols[0])
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
- [[variables_symbols[0], name],
307
- [variables_symbols[1], nickname],
308
- [variables_symbols[2], description],
309
- [variables_symbols[3], note]].each do |symbol, variable|
310
- if variable.is_a?(String) && !variable.empty?
311
- translated = get_variable_translated(variable, other_translation_map, game_type)
312
- object.instance_variable_set(symbol, variable) unless translated.nil?
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
- pages = object.instance_variable_get(:@pages)
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 |i|
322
- list = pages.nil? ? object.instance_variable_get(:@list) : pages[i].instance_variable_get(:@list)
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
- list.each do |item|
326
- code = item.instance_variable_get(:@code)
327
- next unless allowed_codes.include?(code)
341
+ in_sequence = false
342
+ line = []
343
+ item_indices = []
328
344
 
329
- parameters = item.instance_variable_get(:@parameters)
330
- parameters.each do |parameter|
331
- if [401, 402, 356, 405].include?(code)
332
- if parameter.is_a?(String) && !parameter.empty?
333
- translated = get_parameter_translated(code, parameter, other_translation_map, game_type)
334
- parameters[i] = translated unless translated.nil?
335
- end
336
- elsif parameter.is_a?(Array)
337
- parameter.each_with_index do |subparameter, j|
338
- if subparameter.is_a?(String) && !subparameter.empty?
339
- translated = get_parameter_translated(code, subparameter, other_translation_map, game_type)
340
- parameters[i][j] = translated unless translated.nil?
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.instance_variable_set(:@parameters, parameters)
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
- def self.write_system(system_file_path, ini_file_path, other_path, output_path, shuffle_level, logging)
359
- def self.write_ini_title(ini_file_path, translated)
360
- file_lines = File.readlines(ini_file_path, chomp: true)
361
- title_line_index = file_lines.each_with_index do |line, i|
362
- break i if line.start_with?('title')
363
- end
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("#{other_path}/system.txt", encoding: 'UTF-8', chomp: true)
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("#{other_path}/system_trans.txt", encoding: 'UTF-8', chomp: true)
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
- system_symbols = %i[@elements @skill_types @weapon_types @armor_types @currency_unit @terms @words @game_title].freeze
385
-
386
- elements = system_object.instance_variable_get(system_symbols[0])
387
- skill_types = system_object.instance_variable_get(system_symbols[1])
388
- weapon_types = system_object.instance_variable_get(system_symbols[2])
389
- armor_types = system_object.instance_variable_get(system_symbols[3])
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! { |string| system_translation_map[string] || string }
397
- system_object.instance_variable_set(system_symbols[i], array)
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.instance_variable_set(system_symbols[4], currency_unit_translated) if currency_unit.is_a?(String) &&
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
- translated = system_translation_map[value]
409
- value = translated unless translated.nil?
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! { |string| system_translation_map[string] || string }
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.instance_variable_defined?(system_symbols[5]) ?
418
- system_object.instance_variable_set(system_symbols[5], terms) :
419
- system_object.instance_variable_set(system_symbols[6], terms)
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.instance_variable_set(system_symbols[7], game_title_translated) if currency_unit.is_a?(String) && !game_title_translated.nil?
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("#{output_path}/#{system_basename}", Marshal.dump(system_object))
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
- scripts_translated_text = File.readlines("#{other_path}/scripts_trans.txt", encoding: 'UTF-8', chomp: true)
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
- (extract_quoted_strings(code)).each_with_index do |string_data, i|
444
- string, string_index = string_data
445
-
446
- string.strip!
447
-
448
- # Removes the U+3000 Japanese typographical space to check if string, when stripped, is truly empty
449
- next if string.empty? || string.gsub(' ', '').empty?
450
-
451
- # Maybe this mess will remove something that mustn't be removed, but it needs to be tested
452
- next if string.start_with?(/([#!?$@]|(\.\/)?(Graphics|Data|Audio|CG|Movies|Save)\/)/) ||
453
- string.match?(/^\d+$/) ||
454
- string.match?(/^(.)\1{2,}$/) ||
455
- string.match?(/^(false|true)$/) ||
456
- string.match?(/^[wr]b$/) ||
457
- string.match?(/^(?=.*\d)[A-Za-z0-9\-]+$/) ||
458
- string.match?(/^[A-Z\-()\/ +'&]*$/) ||
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("#{output_path}/#{scripts_basename}", Marshal.dump(script_entries))
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