rgss_db 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/COPYING.md +674 -0
  4. data/README.md +347 -0
  5. data/bin/rgss-db +4 -0
  6. data/bin/rgssdb +4 -0
  7. data/lib/rgss_db/app.rb +928 -0
  8. data/lib/rgss_db/controller/data_manager.rb +557 -0
  9. data/lib/rgss_db/model/data_file.rb +516 -0
  10. data/lib/rgss_db/model/data_file_factory.rb +94 -0
  11. data/lib/rgss_db/model/debug.rb +199 -0
  12. data/lib/rgss_db/model/errors.rb +17 -0
  13. data/lib/rgss_db/model/mixins/jsonable.rb +35 -0
  14. data/lib/rgss_db/model/mixins/jsonable_constructor.rb +40 -0
  15. data/lib/rgss_db/model/rpg_maker_data/vx/rgss/color.rb +72 -0
  16. data/lib/rgss_db/model/rpg_maker_data/vx/rgss/rect.rb +70 -0
  17. data/lib/rgss_db/model/rpg_maker_data/vx/rgss/table.rb +99 -0
  18. data/lib/rgss_db/model/rpg_maker_data/vx/rgss/tone.rb +72 -0
  19. data/lib/rgss_db/model/rpg_maker_data/vx/rgss.rb +11 -0
  20. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/actor.rb +44 -0
  21. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/animation.rb +31 -0
  22. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/animation_frame.rb +20 -0
  23. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/animation_timing.rb +23 -0
  24. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/area.rb +26 -0
  25. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/armor.rb +31 -0
  26. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/audio_file.rb +23 -0
  27. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/base_item.rb +25 -0
  28. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/bgm.rb +36 -0
  29. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/bgs.rb +36 -0
  30. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/class.rb +31 -0
  31. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/class_learning.rb +20 -0
  32. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/common_event.rb +25 -0
  33. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/enemy.rb +44 -0
  34. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/enemy_action.rb +29 -0
  35. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/enemy_drop_item.rb +23 -0
  36. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/event.rb +36 -0
  37. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/event_command.rb +19 -0
  38. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/event_page.rb +32 -0
  39. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/event_page_condition.rb +34 -0
  40. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/event_page_graphic.rb +25 -0
  41. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/item.rb +27 -0
  42. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/map.rb +47 -0
  43. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/map_info.rb +26 -0
  44. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/me.rb +27 -0
  45. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/move_command.rb +18 -0
  46. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/move_route.rb +20 -0
  47. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/se.rb +21 -0
  48. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/skill.rb +22 -0
  49. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/state.rb +47 -0
  50. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/system.rb +43 -0
  51. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/system_terms.rb +53 -0
  52. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/system_test_battler.rb +25 -0
  53. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/system_vehicle.rb +24 -0
  54. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/troop.rb +24 -0
  55. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/troop_member.rb +23 -0
  56. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/troop_page.rb +21 -0
  57. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/troop_page_condition.rb +33 -0
  58. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/usable_item.rb +87 -0
  59. data/lib/rgss_db/model/rpg_maker_data/vx/rpg/weapon.rb +31 -0
  60. data/lib/rgss_db/model/rpg_maker_data/vx/rpg.rb +59 -0
  61. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rgss/color.rb +72 -0
  62. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rgss/rect.rb +70 -0
  63. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rgss/table.rb +99 -0
  64. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rgss/tone.rb +72 -0
  65. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rgss.rb +11 -0
  66. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/actor.rb +27 -0
  67. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/animation.rb +31 -0
  68. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/animation_frame.rb +23 -0
  69. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/animation_timing.rb +26 -0
  70. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/armor.rb +20 -0
  71. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/audio_file.rb +23 -0
  72. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/base_item.rb +31 -0
  73. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/base_item_feature.rb +29 -0
  74. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/bgm.rb +43 -0
  75. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/bgs.rb +43 -0
  76. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/class.rb +37 -0
  77. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/class_learning.rb +24 -0
  78. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/common_event.rb +33 -0
  79. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/enemy.rb +27 -0
  80. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/enemy_action.rb +26 -0
  81. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/enemy_drop_item.rb +24 -0
  82. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/equip_item.rb +19 -0
  83. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/event.rb +36 -0
  84. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/event_command.rb +19 -0
  85. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/event_page.rb +35 -0
  86. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/event_page_condition.rb +40 -0
  87. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/event_page_graphic.rb +31 -0
  88. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/item.rb +25 -0
  89. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/map.rb +58 -0
  90. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/map_encounter.rb +23 -0
  91. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/map_info.rb +26 -0
  92. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/me.rb +27 -0
  93. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/move_command.rb +17 -0
  94. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/move_route.rb +19 -0
  95. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/se.rb +21 -0
  96. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/skill.rb +25 -0
  97. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/state.rb +34 -0
  98. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/system.rb +62 -0
  99. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/system_terms.rb +25 -0
  100. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/system_test_battler.rb +24 -0
  101. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/system_vehicle.rb +27 -0
  102. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/tileset.rb +26 -0
  103. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/troop.rb +24 -0
  104. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/troop_member.rb +25 -0
  105. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/troop_page.rb +24 -0
  106. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/troop_page_condition.rb +39 -0
  107. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/usable_item.rb +84 -0
  108. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/usable_item_damage.rb +56 -0
  109. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/usable_item_effect.rb +25 -0
  110. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/weapon.rb +25 -0
  111. data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg.rb +66 -0
  112. data/lib/rgss_db/model/rpg_maker_data/xp/rgss/color.rb +72 -0
  113. data/lib/rgss_db/model/rpg_maker_data/xp/rgss/rect.rb +70 -0
  114. data/lib/rgss_db/model/rpg_maker_data/xp/rgss/table.rb +99 -0
  115. data/lib/rgss_db/model/rpg_maker_data/xp/rgss/tone.rb +72 -0
  116. data/lib/rgss_db/model/rpg_maker_data/xp/rgss.rb +11 -0
  117. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/actor.rb +44 -0
  118. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/animation.rb +28 -0
  119. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/animation_frame.rb +20 -0
  120. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/animation_timing.rb +24 -0
  121. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/armor.rb +37 -0
  122. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/audio_file.rb +23 -0
  123. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/class.rb +28 -0
  124. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/class_learning.rb +20 -0
  125. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/common_event.rb +25 -0
  126. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/enemy.rb +47 -0
  127. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/enemy_action.rb +28 -0
  128. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/event.rb +36 -0
  129. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/event_command.rb +19 -0
  130. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/event_page.rb +32 -0
  131. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/event_page_condition.rb +30 -0
  132. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/event_page_graphic.rb +27 -0
  133. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/item.rb +48 -0
  134. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/map.rb +39 -0
  135. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/map_info.rb +26 -0
  136. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/move_command.rb +18 -0
  137. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/move_route.rb +19 -0
  138. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/skill.rb +47 -0
  139. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/state.rb +51 -0
  140. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/system.rb +56 -0
  141. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/system_test_battler.rb +25 -0
  142. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/system_words.rb +39 -0
  143. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/tileset.rb +39 -0
  144. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/troop.rb +24 -0
  145. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/troop_member.rb +23 -0
  146. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/troop_page.rb +21 -0
  147. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/troop_page_condition.rb +32 -0
  148. data/lib/rgss_db/model/rpg_maker_data/xp/rpg/weapon.rb +38 -0
  149. data/lib/rgss_db/model/rpg_maker_data/xp/rpg.rb +52 -0
  150. data/lib/rgss_db/model/strings.rb +607 -0
  151. data/lib/rgss_db/model/utilities.rb +90 -0
  152. data/lib/rgss_db/version.rb +7 -0
  153. data/lib/rgss_db/view/app_cli.rb +449 -0
  154. data/lib/rgss_db.rb +41 -0
  155. data/sig/rgss_db.rbs +5221 -0
  156. metadata +496 -0
@@ -0,0 +1,516 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgssDb
4
+ # Label used for data files that allows objects selection
5
+ # @return [String]
6
+ DATA_FILE_CUSTOM_LABEL = "_custom"
7
+
8
+ # RPG Maker actors data file (glob pattern)
9
+ # @return [String]
10
+ DATA_FILE_ACTORS = "Actors"
11
+
12
+ # RPG Maker animations data file (glob pattern)
13
+ # @return [String]
14
+ DATA_FILE_ANIMATIONS = "Animations"
15
+
16
+ # RPG Maker areas data file (glob pattern)
17
+ # @return [String]
18
+ DATA_FILE_AREAS = "Areas"
19
+
20
+ # RPG Maker armors data file (glob pattern)
21
+ # @return [String]
22
+ DATA_FILE_ARMORS = "Armors"
23
+
24
+ # RPG Maker classes data file (glob pattern)
25
+ # @return [String]
26
+ DATA_FILE_CLASSES = "Classes"
27
+
28
+ # RPG Maker common events data file (glob pattern)
29
+ # @return [String]
30
+ DATA_FILE_COMMON_EVENTS = "CommonEvents"
31
+
32
+ # RPG Maker enemies data file (glob pattern)
33
+ # @return [String]
34
+ DATA_FILE_ENEMIES = "Enemies"
35
+
36
+ # RPG Maker items data file (glob pattern)
37
+ # @return [String]
38
+ DATA_FILE_ITEMS = "Items"
39
+
40
+ # RPG Maker maps data file (glob pattern)
41
+ # @return [String]
42
+ DATA_FILE_MAPS = "Map[0-9][0-9][1-9]"
43
+
44
+ # RPG Maker map infos data file (glob pattern)
45
+ # @return [String]
46
+ DATA_FILE_MAP_INFOS = "MapInfos"
47
+
48
+ # RPG Maker skills data file (glob pattern)
49
+ # @return [String]
50
+ DATA_FILE_SKILLS = "Skills"
51
+
52
+ # RPG Maker states data file (glob pattern)
53
+ # @return [String]
54
+ DATA_FILE_STATES = "States"
55
+
56
+ # RPG Maker system data file (glob pattern)
57
+ # @return [String]
58
+ DATA_FILE_SYSTEM = "System"
59
+
60
+ # RPG Maker tilesets data file (glob pattern)
61
+ # @return [String]
62
+ DATA_FILE_TILESETS = "Tilesets"
63
+
64
+ # RPG Maker troops data file (glob pattern)
65
+ # @return [String]
66
+ DATA_FILE_TROOPS = "Troops"
67
+
68
+ # RPG Maker weapons data file (glob pattern)
69
+ # @return [String]
70
+ DATA_FILE_WEAPONS = "Weapons"
71
+
72
+ #
73
+ # RPG Maker base data file
74
+ #
75
+ # This class saves the object as is, without any treatment
76
+ #
77
+ class DataFile
78
+ include Comparable
79
+
80
+ # Data file type
81
+ # @return [String]
82
+ attr_reader :type
83
+
84
+ # Data file path
85
+ # @return [String]
86
+ attr_reader :file_path
87
+
88
+ # Data file object IDs list
89
+ # @return [Array<Integer>]
90
+ attr_reader :object_ids
91
+
92
+ # Data file object (not processed)
93
+ # @return [Object]
94
+ attr_reader :object
95
+
96
+ #
97
+ # Constructor
98
+ #
99
+ # @param type [String] Data file type
100
+ # @param file_path [String] Data file path
101
+ # @param object [Object] Data file object
102
+ #
103
+ def initialize(type, file_path, object)
104
+ @type = type
105
+ @file_path = file_path
106
+ @object = object
107
+ @object_ids = []
108
+ end
109
+
110
+ #
111
+ # Checks if the given file matches this data file path
112
+ #
113
+ # The check is case insensitive
114
+ #
115
+ # @param [String] file File path
116
+ #
117
+ # @return [Boolean]
118
+ #
119
+ def file_path?(file)
120
+ @file_path.casecmp?(file)
121
+ end
122
+
123
+ #
124
+ # Checks if the given file base name matches this data file base name
125
+ #
126
+ # The check is case insensitive
127
+ #
128
+ # @param file [String] File path
129
+ #
130
+ # @return [Boolean]
131
+ #
132
+ def file?(file)
133
+ File.basename(@file_path).casecmp?(File.basename(file))
134
+ end
135
+
136
+ #
137
+ # Checks if the given data type matches this data file type
138
+ #
139
+ # The check is case insensitive
140
+ #
141
+ # @param [String] data_type
142
+ #
143
+ # @return [Boolean]
144
+ #
145
+ def type?(data_type)
146
+ File.fnmatch(@type, data_type, File::FNM_CASEFOLD)
147
+ end
148
+
149
+ #
150
+ # Checks whether this data file instance supports object selection or not
151
+ #
152
+ # @return [Boolean]
153
+ #
154
+ def customizable?
155
+ !to_list.nil?
156
+ end
157
+
158
+ #
159
+ # Checks whether this data file instance is mergeable or not
160
+ #
161
+ # @return [Boolean]
162
+ #
163
+ def mergeable?
164
+ !to_merge.nil?
165
+ end
166
+
167
+ #
168
+ # Checks whether all objects are included in the serialization process
169
+ #
170
+ # @return [Boolean]
171
+ #
172
+ def all_objects?
173
+ true
174
+ end
175
+
176
+ #
177
+ # Updates the list of object IDs for this data file
178
+ #
179
+ # Any duped ID is auto. removed from the list
180
+ #
181
+ # @param object_ids [Array<Integer>]
182
+ #
183
+ def object_ids_update(*object_ids)
184
+ @object_ids = object_ids.flatten.uniq
185
+ end
186
+
187
+ #
188
+ # Clears the current list of object IDs
189
+ #
190
+ def object_ids_clear
191
+ @object_ids.clear
192
+ end
193
+
194
+ #
195
+ # Gets the data file name
196
+ #
197
+ # @return [String]
198
+ #
199
+ def file
200
+ File.basename(@file_path)
201
+ end
202
+
203
+ #
204
+ # Process the data file's file name for serialization
205
+ #
206
+ # The extension is automatically removed
207
+ #
208
+ # @return [String]
209
+ #
210
+ def serialize_file_name
211
+ base_name = File.basename(@file_path, ".*")
212
+ if all_objects?
213
+ base_name
214
+ else
215
+ base_name.concat(DATA_FILE_CUSTOM_LABEL)
216
+ end
217
+ end
218
+
219
+ #
220
+ # Merges the given data file contents with this data file
221
+ #
222
+ # @param [DataFile] data_file
223
+ #
224
+ # @raise [StandardError] Data file cannot be merged
225
+ #
226
+ def merge(data_file)
227
+ raise "cannot merge data file: '#{data_file}' because it is not supported!"
228
+ end
229
+
230
+ #
231
+ # Serializes the data file's object
232
+ #
233
+ # This method performs the necessary logic to the object for serialization
234
+ #
235
+ # By default, it returns the object as is
236
+ #
237
+ # @return [Object]
238
+ #
239
+ def serialize
240
+ @object
241
+ end
242
+
243
+ #
244
+ # Converts the given object list to object IDs for this data file
245
+ #
246
+ # The given list must be instances of this data file's contents
247
+ #
248
+ # By default it returns an empty array
249
+ #
250
+ # @param list [Array] List of objects
251
+ #
252
+ # @return [Array<Integer>]
253
+ #
254
+ def convert_list_to_ids(list)
255
+ []
256
+ end
257
+
258
+ #
259
+ # Gets a list of objects prepared to be merged
260
+ #
261
+ # Returns ``nil`` by default
262
+ #
263
+ # @return [Array<Object>]
264
+ #
265
+ def to_merge
266
+ nil
267
+ end
268
+
269
+ #
270
+ # Gets a list of objects to perform a selection
271
+ #
272
+ # If the data file does not allow this behavior it returns ``nil``
273
+ #
274
+ # Returns ``nil`` by default
275
+ #
276
+ # @return [Array<Object>]
277
+ #
278
+ def to_list
279
+ nil
280
+ end
281
+
282
+ #
283
+ # Converts this instance to a string
284
+ #
285
+ # @return [String]
286
+ #
287
+ def to_s
288
+ File.basename(@file_path)
289
+ end
290
+
291
+ #
292
+ # Comparable operator (case insensitive)
293
+ #
294
+ # @param [Object] other Other
295
+ #
296
+ # @return [Integer]
297
+ #
298
+ def <=>(other)
299
+ return @file_path.downcase <=> other.file_path.downcase if other.is_a?(DataFile)
300
+
301
+ @file_path.downcase <=> other.downcase if other.is_a?(String)
302
+ end
303
+ end
304
+
305
+ #
306
+ # RPG Maker array data file
307
+ #
308
+ # This class expects the object to be an array
309
+ #
310
+ class DataFileArray < DataFile
311
+ # Data file object (not processed)
312
+ # @return [Array]
313
+ attr_reader :object
314
+
315
+ #
316
+ # Checks whether all objects are included in the serialization process
317
+ #
318
+ # @return [Boolean]
319
+ #
320
+ def all_objects?
321
+ object_ids.empty? || object_ids.size == object.compact.size
322
+ end
323
+
324
+ #
325
+ # Merges the given data file contents with this data file
326
+ #
327
+ # @param [DataFile] data_file
328
+ #
329
+ # @raise [StandardError] Data file cannot be merged
330
+ #
331
+ def merge(data_file)
332
+ raise "cannot merge data file: '#{data_file}' because it is not supported!" unless data_file.is_a?(DataFileArray)
333
+
334
+ object.push(*data_file.to_merge)
335
+ end
336
+
337
+ #
338
+ # Serializes the data file's object
339
+ #
340
+ # This method prepares the object as an array
341
+ #
342
+ # The first element is always ``nil`` (required for RPG Maker)
343
+ #
344
+ # Object IDs list is used to filter the selected items on the data file
345
+ #
346
+ # @return [Array<Object>]
347
+ #
348
+ def serialize
349
+ # Applies the selected object IDs (if any)
350
+ processed_object = all_objects? ? object.dup : object.dup.values_at(*object_ids)
351
+
352
+ # Returns the formatted object (with a safe-check)
353
+ processed_object.first.nil? ? processed_object : processed_object.unshift(nil)
354
+ end
355
+
356
+ #
357
+ # Converts the given object list to object IDs for this data file
358
+ #
359
+ # The given list must be instances of this data file's array
360
+ #
361
+ # @param list [Array] List of objects
362
+ #
363
+ # @return [Array<Integer>]
364
+ #
365
+ def convert_list_to_ids(list)
366
+ list.map { |i| object.index(i) }
367
+ end
368
+
369
+ #
370
+ # Gets a list of objects prepared to be merged
371
+ #
372
+ # @return [Array<Object>]
373
+ #
374
+ def to_merge
375
+ object.compact
376
+ end
377
+
378
+ #
379
+ # Gets a list of objects to perform a selection
380
+ #
381
+ # @return [Array<Object>]
382
+ #
383
+ def to_list
384
+ # Data files needs to be compacted because TTY does not allow to create zero index based lists
385
+ # for some data files, the first element is nil because they are created in RPG Maker database starting at 1
386
+ # If this array is not compacted, it will cause an index mismatch later when selecting objects
387
+ object.compact
388
+ end
389
+ end
390
+
391
+ #
392
+ # RPG Maker hash data file
393
+ #
394
+ # This class expects the object to be a hash
395
+ #
396
+ class DataFileHash < DataFile
397
+ # Data file object (not processed)
398
+ # @return [Hash]
399
+ attr_reader :object
400
+
401
+ #
402
+ # Checks whether all objects are included in the serialization process
403
+ #
404
+ # @return [Boolean]
405
+ #
406
+ def all_objects?
407
+ object_ids.empty? || object.all? { |key, value| object_ids.include?(key) }
408
+ end
409
+
410
+ #
411
+ # Merges the given data file contents with this data file
412
+ #
413
+ # @param [DataFile] data_file
414
+ #
415
+ # @raise [StandardError] Data file cannot be merged
416
+ #
417
+ def merge(data_file)
418
+ raise "cannot merge data file: '#{data_file}' because it is not supported!" unless data_file.is_a?(DataFileHash)
419
+
420
+ data_file.to_merge.each_pair do |key, value|
421
+ object.store(key, value)
422
+ end
423
+ end
424
+
425
+ #
426
+ # Serializes the data file's object
427
+ #
428
+ # This method prepares the object as a hash
429
+ #
430
+ # Object IDs list is used to filter the correct
431
+ #
432
+ # @return [Hash]
433
+ #
434
+ def serialize
435
+ # Dups the original object
436
+ processed_object = object.dup
437
+
438
+ # Applies the selected object IDs (if any)
439
+ processed_object = processed_object.filter { |key, value| object_ids.include?(key) } unless all_objects?
440
+
441
+ # Returns the formatted object
442
+ processed_object
443
+ end
444
+
445
+ #
446
+ # Converts the given list to object IDs for this data file
447
+ #
448
+ # The list must be an array of this data file hash values or keys
449
+ #
450
+ # @param list [Array] List of objects
451
+ #
452
+ # @return [Array<Object>]
453
+ #
454
+ def convert_list_to_ids(list)
455
+ list.map { |i| object.key?(i) ? i : object.key(i) }
456
+ end
457
+
458
+ #
459
+ # Gets a list of objects prepared to be merged
460
+ #
461
+ # @return [Hash]
462
+ #
463
+ def to_merge
464
+ object
465
+ end
466
+
467
+ #
468
+ # Gets a list of objects to perform a selection
469
+ #
470
+ # @return [Array<Object>]
471
+ #
472
+ def to_list
473
+ # Data files needs to be compacted because TTY does not allow to create zero index based lists
474
+ # for some data files, the first element is nil because they are created in RPG Maker database starting at 1
475
+ # If this array is not compacted, it will cause an index mismatch later when auto-selecting objects
476
+ object.values
477
+ end
478
+ end
479
+
480
+ #
481
+ # RPG Maker numbered hash data file
482
+ #
483
+ # This class expects the object to be a hash
484
+ #
485
+ # This class forces hash keys to be a number for the data files:
486
+ # - Areas
487
+ # - MapInfos
488
+ #
489
+ # **Reason: Creating a DataFileHash instance from a MapInfos/Areas JSON file provokes undesired behavior.**
490
+ #
491
+ # JSON only allows key names to be strings, so all keys of the hash will be converted to string.
492
+ #
493
+ # This is undesired behavior because RPG Maker editor requires the MapInfos and Areas hash keys to be numbers.
494
+ #
495
+ # So we need to convert all keys read from the JSON file to integers when importing the JSON file into the
496
+ # RPG Maker database, hence the inclusion of this class specification from DataFileHash.
497
+ #
498
+ # Otherwise the RPG Maker editor will fail to show the maps and areas even though data still exists.
499
+ #
500
+ class DataFileHashNumber < DataFileHash
501
+ #
502
+ # Serializes the data file's object
503
+ #
504
+ # This method prepares the object as a hash
505
+ #
506
+ # Object IDs list is used to filter the correct
507
+ #
508
+ # @return [Hash]
509
+ #
510
+ def serialize
511
+ super.transform_keys do |key|
512
+ key.to_s.to_i
513
+ end
514
+ end
515
+ end
516
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./data_file"
4
+
5
+ module RgssDb
6
+ #
7
+ # Data file factory module
8
+ #
9
+ module DataFileFactory
10
+ # List of all data files types
11
+ # @return [Array<String>]
12
+ FACTORY_ALL_TYPES = [
13
+ DATA_FILE_ACTORS,
14
+ DATA_FILE_ANIMATIONS,
15
+ DATA_FILE_AREAS,
16
+ DATA_FILE_ARMORS,
17
+ DATA_FILE_CLASSES,
18
+ DATA_FILE_COMMON_EVENTS,
19
+ DATA_FILE_ENEMIES,
20
+ DATA_FILE_ITEMS,
21
+ DATA_FILE_MAP_INFOS,
22
+ DATA_FILE_MAPS,
23
+ DATA_FILE_SKILLS,
24
+ DATA_FILE_STATES,
25
+ DATA_FILE_SYSTEM,
26
+ DATA_FILE_TILESETS,
27
+ DATA_FILE_TROOPS,
28
+ DATA_FILE_WEAPONS
29
+ ].freeze
30
+
31
+ # List of data files handled using an array
32
+ #
33
+ # Some RPG Maker database files are saved as arrays (Actors, Weapons, Items...)
34
+ # @return [Array<String>]
35
+ FACTORY_ARRAY = [
36
+ DATA_FILE_ACTORS, DATA_FILE_ANIMATIONS,
37
+ DATA_FILE_ARMORS, DATA_FILE_CLASSES, DATA_FILE_COMMON_EVENTS,
38
+ DATA_FILE_ENEMIES, DATA_FILE_ITEMS, DATA_FILE_SKILLS,
39
+ DATA_FILE_STATES, DATA_FILE_TILESETS, DATA_FILE_TROOPS,
40
+ DATA_FILE_WEAPONS
41
+ ].freeze
42
+
43
+ # List of data files handled using a hash
44
+ # @return [Array<String>]
45
+ FACTORY_HASH = [].freeze
46
+
47
+ # List of data files handled using a number hash
48
+ # @return [Array<String>]
49
+ FACTORY_HASH_NUMBER = [
50
+ DATA_FILE_AREAS,
51
+ DATA_FILE_MAP_INFOS
52
+ ].freeze
53
+
54
+ #
55
+ # Creates a data file instance based on the given file entry
56
+ #
57
+ # The database file type is auto. determined using the ``data_file`` path
58
+ #
59
+ # @param data_file [String] Data file entry
60
+ # @param object [Object] Deserialized data file object
61
+ #
62
+ # @return [DataFile]
63
+ #
64
+ # @raise [StandardError] No type found
65
+ #
66
+ def self.create_data_file(data_file, object)
67
+ type = determine_data_file_type(data_file)
68
+ raise "could not find a valid data file type for the file: '#{data_file}'" if type.nil?
69
+
70
+ # Checks for a specific data file usage (bulk-check)
71
+ return DataFileArray.new(type, data_file, object) if FACTORY_ARRAY.any? { |f| f.casecmp?(type) }
72
+ return DataFileHash.new(type, data_file, object) if FACTORY_HASH.any? { |f| f.casecmp?(type) }
73
+ return DataFileHashNumber.new(type, data_file, object) if FACTORY_HASH_NUMBER.any? { |f| f.casecmp?(type) }
74
+
75
+ # Assume a base data file (map data files will use this)
76
+ DataFile.new(type, data_file, object)
77
+ end
78
+
79
+ #
80
+ # Determines the type of the data file
81
+ #
82
+ # Returns ``nil`` if a valid type cannot be found
83
+ #
84
+ # @param [String] data_file Data file entry
85
+ #
86
+ # @return [String]
87
+ #
88
+ def self.determine_data_file_type(data_file)
89
+ # Gets the data file name without extensions (and custom label, if any)
90
+ data_file_name = File.basename(data_file, ".*").gsub(DATA_FILE_CUSTOM_LABEL, "")
91
+ FACTORY_ALL_TYPES.find { |type| File.fnmatch(type, data_file_name, File::FNM_CASEFOLD) }
92
+ end
93
+ end
94
+ end