1use serde_json::{Value, Number};
2
3pub fn build_version() -> String { String::from(env!("BUILD_VERSION")) }
4
5pub fn engine_version() -> u64 { 15 }
6
7pub fn engine_version_json() -> Value {
8 Value::Number(Number::from(engine_version()))
9}
10
11fn get_engine_version(object: &Value) -> u64 {
12 if let &Value::Object (ref object) = object {
13 if let Some (engine_version) = object.get("engine_version") {
14 if let Some (value) = engine_version.as_u64() {
15 return value
16 }
17 }
18 }
19 engine_version()
20}
21
22fn upgrade_engine_version(meta: &mut Value) {
23 if let &mut Value::Object (ref mut object) = meta {
24 object.insert(String::from("engine_version"), engine_version_json());
25 }
26}
27
28pub(crate) fn upgrade_to_latest_fighter(fighter: &mut Value, file_name: &str) {
29 let fighter_engine_version = get_engine_version(fighter);
30 if fighter_engine_version > engine_version() {
31 println!("Fighter: {} is newer than this version of PF Sandbox. Please upgrade to the latest version.", file_name);
32 }
34 else if fighter_engine_version < engine_version() {
35 for upgrade_from in fighter_engine_version..engine_version() {
36 match upgrade_from {
37 14 => { upgrade_fighter14(fighter) }
38 13 => { upgrade_fighter13(fighter) }
39 12 => { upgrade_fighter12(fighter) }
40 11 => { upgrade_fighter11(fighter) }
41 10 => { upgrade_fighter10(fighter) }
42 9 => { upgrade_fighter9(fighter) }
43 8 => { upgrade_fighter8(fighter) }
44 7 => { upgrade_fighter7(fighter) }
45 6 => { upgrade_fighter6(fighter) }
46 5 => { upgrade_fighter5(fighter) }
47 4 => { upgrade_fighter4(fighter) }
48 3 => { upgrade_fighter3(fighter) }
49 2 => { upgrade_fighter2(fighter) }
50 1 => { upgrade_fighter1(fighter) }
51 0 => { upgrade_fighter0(fighter) }
52 _ => { }
53 }
54 }
55 upgrade_engine_version(fighter);
56 }
57}
58
59pub(crate) fn upgrade_to_latest_stage(stage: &mut Value, file_name: &str) {
60 let stage_engine_version = get_engine_version(stage);
61 if stage_engine_version > engine_version() {
62 println!("Stage: {} is newer than this version of PF Sandbox. Please upgrade to the latest version.", file_name);
63 }
65 else if stage_engine_version < engine_version() {
66 upgrade_engine_version(stage);
68 }
69}
70
71pub(crate) fn upgrade_to_latest_rules(rules: &mut Value) {
72 let rules_engine_version = get_engine_version(rules);
73 if rules_engine_version > engine_version() {
74 println!("rules.json is newer than this version of PF Sandbox. Please upgrade to the latest version.");
75 }
77 else if rules_engine_version < engine_version() {
78 upgrade_engine_version(rules);
80 }
81}
82
83pub(crate) fn upgrade_to_latest_meta(meta: &mut Value) {
84 let meta_engine_version = get_engine_version(meta);
85 if meta_engine_version > engine_version() {
86 println!("meta.json is newer than this version of PF Sandbox. Please upgrade to the latest version.");
87 }
89 else if meta_engine_version < engine_version() {
90 upgrade_engine_version(meta);
92 }
93}
94
95fn get_vec<'a>(parent: &'a mut Value, member: &str) -> Option<&'a mut Vec<Value>> {
96 if let &mut Value::Object (ref mut object) = parent {
97 if let Some (array) = object.get_mut(member) {
98 if let &mut Value::Array (ref mut vector) = array {
99 return Some (vector);
100 }
101 }
102 }
103 return None;
104}
105
106fn upgrade_fighter14(fighter: &mut Value) {
111 if let Some (actions) = get_vec(fighter, "actions") {
112 for action in actions {
113 if let Some (frames) = get_vec(action, "frames") {
114 for frame in frames {
115 if let &mut Value::Object (ref mut frame) = frame {
116 frame.remove(&String::from("set_x_vel"));
117 frame.remove(&String::from("set_y_vel"));
118 frame.insert(String::from("x_vel_modify"), json!("None"));
119 frame.insert(String::from("y_vel_modify"), json!("None"));
120 frame.insert(String::from("x_vel_temp"), json!("0.0"));
121 frame.insert(String::from("y_vel_temp"), json!("0.0"));
122 }
123 }
124 }
125 }
126 }
127}
128
129fn upgrade_fighter13(fighter: &mut Value) {
131 let action = json!({
132 "frames": [
133 {
134 "ecb": {
135 "top": 16.0,
136 "left": -4.0,
137 "right": 4.0,
138 "bottom": 0.0
139 },
140 "colboxes": [],
141 "colbox_links": [],
142 "render_order": [],
143 "effects": [],
144 "item_hold_x": 4.0,
145 "item_hold_y": 11.0,
146 "grab_hold_x": 4.0,
147 "grab_hold_y": 11.0,
148 "pass_through": true,
149 "ledge_cancel": false,
150 "use_platform_angle": false,
151 "ledge_grab_box": null,
152 "force_hitlist_reset": false
153 }
154 ],
155 "iasa": 0
156 });
157
158 if let Some (actions) = get_vec(fighter, "actions") {
159 actions.insert(0, action.clone());
160 }
161}
162
163fn upgrade_fighter12(fighter: &mut Value) {
165 if let Some (actions) = get_vec(fighter, "actions") {
166 for action in actions {
167 if let Some (frames) = get_vec(action, "frames") {
168 for frame in frames {
169 if let Some (colboxes) = get_vec(frame, "colboxes") {
170 for colbox in colboxes {
171 if let &mut Value::Object (ref mut colbox) = colbox {
172 if let Some (role) = colbox.get_mut("role") {
173 if let &mut Value::Object (ref mut role) = role {
174 if let Some (hitbox) = role.get_mut("Hit") {
175 if let &mut Value::Object (ref mut hitbox) = hitbox {
176 hitbox.insert(String::from("enable_reverse_hit"), Value::Bool(true));
177 }
178 }
179 }
180 }
181 }
182 }
183 }
184 }
185 }
186 }
187 }
188}
189
190fn upgrade_fighter11(fighter: &mut Value) {
192 let ecb = json!({
193 "top": 16.0,
194 "left": -4.0,
195 "right": 4.0,
196 "bottom": 0.0
197 });
198
199 if let Some (actions) = get_vec(fighter, "actions") {
200 for action in actions {
201 if let Some (frames) = get_vec(action, "frames") {
202 for frame in frames {
203 if let &mut Value::Object (ref mut frame) = frame {
204 frame.insert(String::from("ecb"), ecb.clone());
205 }
206 }
207 }
208 }
209 }
210}
211
212fn upgrade_fighter10(fighter: &mut Value) {
214 if let &mut Value::Object (ref mut fighter) = fighter {
215 fighter.insert(String::from("css_action"), Value::Number(Number::from(2)));
216 fighter.insert(String::from("css_scale"), Value::Number(Number::from(1)));
217 }
218}
219
220fn upgrade_fighter9(fighter: &mut Value) {
222 if let &mut Value::Object (ref mut fighter) = fighter {
223 fighter.insert(String::from("run_turn_flip_dir_frame"), Value::Number(Number::from(30)));
224 fighter.insert(String::from("tilt_turn_flip_dir_frame"), Value::Number(Number::from(5)));
225 fighter.insert(String::from("tilt_turn_into_dash_iasa"), Value::Number(Number::from(5)));
226 }
227}
228
229fn upgrade_fighter8(fighter: &mut Value) {
231 if let Some (actions) = get_vec(fighter, "actions") {
232 for action in actions {
233 if let Some (frames) = get_vec(action, "frames") {
234 for frame in frames {
235 if let &mut Value::Object (ref mut frame) = frame {
236 frame.insert(String::from("use_platform_angle"), Value::Bool(false));
237 }
238 }
239 }
240 }
241 }
242}
243
244fn upgrade_fighter7(fighter: &mut Value) {
246 let action_indexes: Vec<usize> = vec!(7, 46, 47, 48, 54, 69);
247 let action = json!({
248 "frames": [
249 {
250 "ecb": {
251 "top_x": 0.0,
252 "top_y": 16.0,
253 "left_x": -4.0,
254 "left_y": 11.0,
255 "right_x": 4.0,
256 "right_y": 11.0,
257 "bot_x": 0.0,
258 "bot_y": 0.0
259 },
260 "colboxes": [],
261 "colbox_links": [],
262 "render_order": [],
263 "effects": [],
264 "item_hold_x": 4.0,
265 "item_hold_y": 11.0,
266 "grab_hold_x": 4.0,
267 "grab_hold_y": 11.0,
268 "pass_through": true,
269 "ledge_cancel": false,
270 "ledge_grab_box": null,
271 "force_hitlist_reset": false
272 }
273 ],
274 "iasa": 0
275 });
276
277 if let Some (actions) = get_vec(fighter, "actions") {
278 for action_index in &action_indexes {
279 actions.insert(*action_index, action.clone());
280 }
281 }
282}
283
284fn upgrade_fighter6(fighter: &mut Value) {
286 let action_indexes: Vec<usize> = vec!(31, 47, 48, 49);
287 let action = json!({
288 "frames": [
289 {
290 "ecb": {
291 "top_x": 0.0,
292 "top_y": 16.0,
293 "left_x": -4.0,
294 "left_y": 11.0,
295 "right_x": 4.0,
296 "right_y": 11.0,
297 "bot_x": 0.0,
298 "bot_y": 0.0
299 },
300 "colboxes": [],
301 "colbox_links": [],
302 "render_order": [],
303 "effects": [],
304 "item_hold_x": 4.0,
305 "item_hold_y": 11.0,
306 "grab_hold_x": 4.0,
307 "grab_hold_y": 11.0,
308 "pass_through": true,
309 "ledge_cancel": false,
310 "ledge_grab_box": null,
311 "force_hitlist_reset": false
312 }
313 ],
314 "iasa": 0
315 });
316
317 if let Some (actions) = get_vec(fighter, "actions") {
318 for action_index in &action_indexes {
319 actions.insert(*action_index, action.clone());
320 }
321 }
322}
323
324fn upgrade_fighter5(fighter: &mut Value) {
326 if let Some (actions) = get_vec(fighter, "actions") {
328 for action in actions {
329 if let Some (frames) = get_vec(action, "frames") {
330 for frame in frames {
331 if let &mut Value::Object (ref mut frame) = frame {
332 frame.insert(String::from("ledge_cancel"), Value::Bool(true));
333 }
334 }
335 }
336 }
337 }
338
339 let action_indexes: Vec<usize> = vec!(5, 6, 36);
341 let action = json!({
342 "frames": [
343 {
344 "ecb": {
345 "top_x": 0.0,
346 "top_y": 16.0,
347 "left_x": -4.0,
348 "left_y": 11.0,
349 "right_x": 4.0,
350 "right_y": 11.0,
351 "bot_x": 0.0,
352 "bot_y": 0.0
353 },
354 "colboxes": [],
355 "colbox_links": [],
356 "render_order": [],
357 "effects": [],
358 "item_hold_x": 4.0,
359 "item_hold_y": 11.0,
360 "grab_hold_x": 4.0,
361 "grab_hold_y": 11.0,
362 "pass_through": true,
363 "ledge_cancel": false,
364 "ledge_grab_box": null,
365 "force_hitlist_reset": false
366 }
367 ],
368 "iasa": 0
369 });
370
371 if let Some (actions) = get_vec(fighter, "actions") {
372 for action_index in &action_indexes {
373 actions.insert(*action_index, action.clone());
374 }
375 }
376}
377
378fn upgrade_fighter4(fighter: &mut Value) {
380 let action_indexes: Vec<usize> = vec!(4, 24, 25, 26, 27, 28, 41, 42, 55, 56);
381 let action = json!({
382 "frames": [
383 {
384 "ecb": {
385 "top_x": 0.0,
386 "top_y": 16.0,
387 "left_x": -4.0,
388 "left_y": 11.0,
389 "right_x": 4.0,
390 "right_y": 11.0,
391 "bot_x": 0.0,
392 "bot_y": 0.0
393 },
394 "colboxes": [],
395 "colbox_links": [],
396 "render_order": [],
397 "effects": [],
398 "item_hold_x": 4.0,
399 "item_hold_y": 11.0,
400 "grab_hold_x": 4.0,
401 "grab_hold_y": 11.0,
402 "pass_through": true,
403 "ledge_grab_box": null,
404 "force_hitlist_reset": false
405 }
406 ],
407 "iasa": 0
408 });
409
410 if let Some (actions) = get_vec(fighter, "actions") {
411 for action_index in &action_indexes {
412 actions.insert(*action_index, action.clone());
413 }
414 }
415}
416
417fn upgrade_fighter3(fighter: &mut Value) {
419 if let Some (actions) = get_vec(fighter, "actions") {
420 for action in actions {
421 if let Some (frames) = get_vec(action, "frames") {
422 for frame in frames {
423 if let &mut Value::Object (ref mut frame) = frame {
424 frame.insert(String::from("pass_through"), Value::Bool(true));
425 }
426 }
427 }
428 }
429 }
430}
431
432fn upgrade_fighter2(fighter: &mut Value) {
434 if let Some (actions) = get_vec(fighter, "actions") {
435 for action in actions {
436 if let Some (frames) = get_vec(action, "frames") {
437 for frame in frames {
438 if let &mut Value::Object (ref mut frame) = frame {
439 frame.insert(String::from("force_hitlist_reset"), Value::Bool(false));
440 }
441 }
442 }
443 }
444 }
445}
446
447fn upgrade_fighter1(fighter: &mut Value) {
449 if let Some (actions) = get_vec(fighter, "actions") {
450 for action in actions {
451 if let Some (frames) = get_vec(action, "frames") {
452 for frame in frames {
453 if let Some (colboxes) = get_vec(frame, "colboxes") {
454 for colbox in colboxes {
455 if let &mut Value::Object (ref mut colbox) = colbox {
456 if let Some (role) = colbox.get_mut("role") {
457 if let &mut Value::Object (ref mut role) = role {
458 if let Some (hitbox) = role.get_mut("Hit") {
459 if let &mut Value::Object (ref mut hitbox) = hitbox {
460 let hitstun = json!({"FramesTimesKnockback": 0.5});
461 hitbox.insert(String::from("hitstun"), hitstun);
462 }
463 }
464 }
465 }
466 }
467 }
468 }
469 }
470 }
471 }
472 }
473}
474
475fn upgrade_fighter0(fighter: &mut Value) {
478 if let Some (actions) = get_vec(fighter, "actions") {
479 for action in actions {
480 if let Some (frames) = get_vec(action, "frames") {
481 for frame in frames {
482 if let &mut Value::Object (ref mut frame) = frame {
483 frame.insert(String::from("render_order"), Value::Array(vec!()));
484 }
485
486 if let Some (colbox_links) = get_vec(frame, "colbox_links") {
487 for colbox_link in colbox_links {
488 if let &mut Value::Object (ref mut colbox_link) = colbox_link {
489 let mut old_value = false;
490 if let Some (link_type) = colbox_link.get_mut("link_type") {
491 if let &mut Value::String (ref mut link_type_string) = link_type {
492 if link_type_string.as_str() == "Meld" {
493 old_value = true;
494 }
495 }
496 }
497 if old_value {
498 colbox_link.insert(String::from("link_type"), Value::String(String::from("MeldFirst")));
499 }
500 }
501 }
502 }
503 }
504 }
505 }
506 }
507}