1use crate::AudioFile;
2use crate::SystemTestBattler;
3use crate::SystemWords;
4use ruby_marshal::FromValue;
5use ruby_marshal::FromValueContext;
6use ruby_marshal::FromValueError;
7use ruby_marshal::IntoValue;
8use ruby_marshal::IntoValueError;
9use ruby_marshal::ObjectValue;
10use ruby_marshal::StringValue;
11use ruby_marshal::SymbolValue;
12use ruby_marshal::Value;
13use ruby_marshal::ValueArena;
14use ruby_marshal::ValueHandle;
15
16const OBJECT_NAME: &[u8] = b"RPG::System";
17
18const VARIABLES_FIELD: &[u8] = b"@variables";
19const CANCEL_SE_FIELD: &[u8] = b"@cancel_se";
20const MAGIC_NUMBER_FIELD: &[u8] = b"@magic_number";
21const ESCAPE_SE_FIELD: &[u8] = b"@escape_se";
22const BATTLE_END_ME_FIELD: &[u8] = b"@battle_end_me";
23const START_MAP_ID_FIELD: &[u8] = b"@start_map_id";
24const SHOP_SE_FIELD: &[u8] = b"@shop_se";
25const GAMEOVER_NAME_FIELD: &[u8] = b"@gameover_name";
26const WORDS_FIELD: &[u8] = b"@words";
27const SWITCHES_FIELD: &[u8] = b"@switches";
28const DECISION_SE_FIELD: &[u8] = b"@decision_se";
29const EDIT_MAP_ID_FIELD: &[u8] = b"@edit_map_id";
30const BATTLE_START_SE_FIELD: &[u8] = b"@battle_start_se";
31const BATTLE_BGM_FIELD: &[u8] = b"@battle_bgm";
32const TEST_TROOP_ID_FIELD: &[u8] = b"@test_troop_id";
33const EQUIP_SE_FIELD: &[u8] = b"@equip_se";
34const TITLE_NAME_FIELD: &[u8] = b"@title_name";
35const ENEMY_COLLAPSE_SE_FIELD: &[u8] = b"@enemy_collapse_se";
36const CURSOR_SE_FIELD: &[u8] = b"@cursor_se";
37const ELEMENTS_FIELD: &[u8] = b"@elements";
38const UNDERSCORE_FIELD: &[u8] = b"@_";
39const START_Y_FIELD: &[u8] = b"@start_y";
40const BATTLER_HUE_FIELD: &[u8] = b"@battler_hue";
41const LOAD_SE_FIELD: &[u8] = b"@load_se";
42const TITLE_BGM_FIELD: &[u8] = b"@title_bgm";
43const BUZZER_SE_FIELD: &[u8] = b"@buzzer_se";
44const WINDOWSKIN_NAME_FIELD: &[u8] = b"@windowskin_name";
45const TEST_BATTLERS_FIELD: &[u8] = b"@test_battlers";
46const BATTLEBACK_NAME_FIELD: &[u8] = b"@battleback_name";
47const PARTY_MEMBERS_FIELD: &[u8] = b"@party_members";
48const ACTOR_COLLAPSE_SE_FIELD: &[u8] = b"@actor_collapse_se";
49const GAMEOVER_ME_FIELD: &[u8] = b"@gameover_me";
50const BATTLER_NAME_FIELD: &[u8] = b"@battler_name";
51const SAVE_SE_FIELD: &[u8] = b"@save_se";
52const BATTLE_TRANSITION_FIELD: &[u8] = b"@battle_transition";
53const START_X_FIELD: &[u8] = b"@start_x";
54
55#[derive(Debug, serde::Serialize, serde::Deserialize)]
56pub struct System {
57 pub variables: Vec<Option<String>>,
58 pub cancel_se: AudioFile,
59 pub magic_number: i32,
60 pub escape_se: AudioFile,
61 pub battle_end_me: AudioFile,
62 pub start_map_id: i32,
63 pub shop_se: AudioFile,
64 pub gameover_name: String,
65 pub words: SystemWords,
66 pub switches: Vec<Option<String>>,
67 pub decision_se: AudioFile,
68 pub edit_map_id: i32,
69 pub battle_start_se: AudioFile,
70 pub battle_bgm: AudioFile,
71 pub test_troop_id: i32,
72 pub equip_se: AudioFile,
73 pub title_name: String,
74 pub enemy_collapse_se: AudioFile,
75 pub cursor_se: AudioFile,
76 pub elements: Vec<String>,
77 pub underscore: i32,
78 pub start_y: i32,
79 pub battler_hue: i32,
80 pub load_se: AudioFile,
81 pub title_bgm: AudioFile,
82 pub buzzer_se: AudioFile,
83 pub windowskin_name: String,
84 pub test_battlers: Vec<SystemTestBattler>,
85 pub battleback_name: String,
86 pub party_members: Vec<i32>,
87 pub actor_collapse_se: AudioFile,
88 pub gameover_me: AudioFile,
89 pub battler_name: String,
90 pub save_se: AudioFile,
91 pub battle_transition: String,
92 pub start_x: i32,
93}
94
95impl<'a> FromValue<'a> for System {
96 fn from_value(ctx: &FromValueContext<'a>, value: &Value) -> Result<Self, FromValueError> {
97 let object: &ObjectValue = FromValue::from_value(ctx, value)?;
98 let name = object.name();
99 let name: &SymbolValue = ctx.from_value(name.into())?;
100 let name = name.value();
101
102 if name != OBJECT_NAME {
103 return Err(FromValueError::UnexpectedObjectName { name: name.into() });
104 }
105
106 let instance_variables = object.instance_variables();
107
108 let mut variables_field = None;
109 let mut cancel_se_field = None;
110 let mut magic_number_field = None;
111 let mut escape_se_field = None;
112 let mut battle_end_me_field = None;
113 let mut start_map_id_field = None;
114 let mut shop_se_field = None;
115 let mut gameover_name_field = None;
116 let mut words_field = None;
117 let mut switches_field = None;
118 let mut decision_se_field = None;
119 let mut edit_map_id_field = None;
120 let mut battle_start_se_field = None;
121 let mut battle_bgm_field = None;
122 let mut test_troop_id_field = None;
123 let mut equip_se_field = None;
124 let mut title_name_field = None;
125 let mut enemy_collapse_se_field = None;
126 let mut cursor_se_field = None;
127 let mut elements_field = None;
128 let mut underscore_field = None;
129 let mut start_y_field = None;
130 let mut battler_hue_field = None;
131 let mut load_se_field = None;
132 let mut title_bgm_field = None;
133 let mut buzzer_se_field = None;
134 let mut windowskin_name_field = None;
135 let mut test_battlers_field = None;
136 let mut battleback_name_field = None;
137 let mut party_members_field = None;
138 let mut actor_collapse_se_field = None;
139 let mut gameover_me_field = None;
140 let mut battler_name_field = None;
141 let mut save_se_field = None;
142 let mut battle_transition_field = None;
143 let mut start_x_field = None;
144
145 for (key, value) in instance_variables.iter().copied() {
146 let key: &SymbolValue = ctx.from_value(key.into())?;
147 let key = key.value();
148
149 match key {
150 VARIABLES_FIELD => {
151 if variables_field.is_some() {
152 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
153 }
154
155 let variables: Vec<Option<&StringValue>> = ctx.from_value(value)?;
156 let variables = variables
157 .into_iter()
158 .map(|value| {
159 value
160 .map(|value| {
161 std::str::from_utf8(value.value())
162 .map(|value| value.to_string())
163 })
164 .transpose()
165 })
166 .collect::<Result<_, _>>()
167 .map_err(FromValueError::new_other)?;
168
169 variables_field = Some(variables);
170 }
171 CANCEL_SE_FIELD => {
172 if cancel_se_field.is_some() {
173 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
174 }
175
176 let cancel_se: AudioFile = ctx.from_value(value)?;
177 cancel_se_field = Some(cancel_se);
178 }
179 MAGIC_NUMBER_FIELD => {
180 if magic_number_field.is_some() {
181 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
182 }
183
184 let magic_number: i32 = ctx.from_value(value)?;
185 magic_number_field = Some(magic_number);
186 }
187 ESCAPE_SE_FIELD => {
188 if escape_se_field.is_some() {
189 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
190 }
191
192 let escape_se: AudioFile = ctx.from_value(value)?;
193 escape_se_field = Some(escape_se);
194 }
195 BATTLE_END_ME_FIELD => {
196 if battle_end_me_field.is_some() {
197 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
198 }
199
200 let battle_end_me: AudioFile = ctx.from_value(value)?;
201 battle_end_me_field = Some(battle_end_me);
202 }
203 START_MAP_ID_FIELD => {
204 if start_map_id_field.is_some() {
205 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
206 }
207
208 let start_map_id: i32 = ctx.from_value(value)?;
209 start_map_id_field = Some(start_map_id);
210 }
211 SHOP_SE_FIELD => {
212 if shop_se_field.is_some() {
213 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
214 }
215
216 let shop_se: AudioFile = ctx.from_value(value)?;
217 shop_se_field = Some(shop_se);
218 }
219 GAMEOVER_NAME_FIELD => {
220 if gameover_name_field.is_some() {
221 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
222 }
223
224 let gameover_name: &StringValue = ctx.from_value(value)?;
225 let gameover_name = std::str::from_utf8(gameover_name.value())
226 .map_err(FromValueError::new_other)?
227 .to_string();
228 gameover_name_field = Some(gameover_name);
229 }
230 WORDS_FIELD => {
231 if words_field.is_some() {
232 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
233 }
234
235 let words: SystemWords = ctx.from_value(value)?;
236 words_field = Some(words);
237 }
238 SWITCHES_FIELD => {
239 if switches_field.is_some() {
240 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
241 }
242
243 let switches: Vec<Option<&StringValue>> = ctx.from_value(value)?;
244 let switches = switches
245 .into_iter()
246 .map(|value| {
247 value
248 .map(|value| {
249 std::str::from_utf8(value.value())
250 .map(|value| value.to_string())
251 })
252 .transpose()
253 })
254 .collect::<Result<_, _>>()
255 .map_err(FromValueError::new_other)?;
256
257 switches_field = Some(switches);
258 }
259 DECISION_SE_FIELD => {
260 if decision_se_field.is_some() {
261 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
262 }
263
264 let decision_se: AudioFile = ctx.from_value(value)?;
265 decision_se_field = Some(decision_se);
266 }
267 EDIT_MAP_ID_FIELD => {
268 if edit_map_id_field.is_some() {
269 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
270 }
271
272 let edit_map_id: i32 = ctx.from_value(value)?;
273 edit_map_id_field = Some(edit_map_id);
274 }
275 BATTLE_START_SE_FIELD => {
276 if battle_start_se_field.is_some() {
277 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
278 }
279
280 let battle_start_se: AudioFile = ctx.from_value(value)?;
281 battle_start_se_field = Some(battle_start_se);
282 }
283 BATTLE_BGM_FIELD => {
284 if battle_bgm_field.is_some() {
285 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
286 }
287
288 let battle_bgm: AudioFile = ctx.from_value(value)?;
289 battle_bgm_field = Some(battle_bgm);
290 }
291 TEST_TROOP_ID_FIELD => {
292 if test_troop_id_field.is_some() {
293 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
294 }
295
296 let test_troop_id: i32 = ctx.from_value(value)?;
297 test_troop_id_field = Some(test_troop_id);
298 }
299 EQUIP_SE_FIELD => {
300 if equip_se_field.is_some() {
301 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
302 }
303
304 let equip_se: AudioFile = ctx.from_value(value)?;
305 equip_se_field = Some(equip_se);
306 }
307 TITLE_NAME_FIELD => {
308 if title_name_field.is_some() {
309 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
310 }
311
312 let title_name: &StringValue = ctx.from_value(value)?;
313 let title_name = std::str::from_utf8(title_name.value())
314 .map_err(FromValueError::new_other)?
315 .to_string();
316 title_name_field = Some(title_name);
317 }
318 ENEMY_COLLAPSE_SE_FIELD => {
319 if enemy_collapse_se_field.is_some() {
320 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
321 }
322
323 let enemy_collapse_se: AudioFile = ctx.from_value(value)?;
324 enemy_collapse_se_field = Some(enemy_collapse_se);
325 }
326 CURSOR_SE_FIELD => {
327 if cursor_se_field.is_some() {
328 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
329 }
330
331 let cursor_se: AudioFile = ctx.from_value(value)?;
332 cursor_se_field = Some(cursor_se);
333 }
334 ELEMENTS_FIELD => {
335 if elements_field.is_some() {
336 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
337 }
338
339 let elements: Vec<&StringValue> = ctx.from_value(value)?;
340 let elements = elements
341 .into_iter()
342 .map(|value| {
343 std::str::from_utf8(value.value()).map(|value| value.to_string())
344 })
345 .collect::<Result<_, _>>()
346 .map_err(FromValueError::new_other)?;
347
348 elements_field = Some(elements);
349 }
350 UNDERSCORE_FIELD => {
351 if underscore_field.is_some() {
352 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
353 }
354
355 let underscore: i32 = ctx.from_value(value)?;
356 underscore_field = Some(underscore);
357 }
358 START_Y_FIELD => {
359 if start_y_field.is_some() {
360 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
361 }
362
363 let start_y: i32 = ctx.from_value(value)?;
364 start_y_field = Some(start_y);
365 }
366 BATTLER_HUE_FIELD => {
367 if battler_hue_field.is_some() {
368 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
369 }
370
371 let battler_hue: i32 = ctx.from_value(value)?;
372 battler_hue_field = Some(battler_hue);
373 }
374 LOAD_SE_FIELD => {
375 if load_se_field.is_some() {
376 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
377 }
378
379 let load_se: AudioFile = ctx.from_value(value)?;
380 load_se_field = Some(load_se);
381 }
382 TITLE_BGM_FIELD => {
383 if title_bgm_field.is_some() {
384 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
385 }
386
387 let title_bgm: AudioFile = ctx.from_value(value)?;
388 title_bgm_field = Some(title_bgm);
389 }
390 BUZZER_SE_FIELD => {
391 if buzzer_se_field.is_some() {
392 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
393 }
394
395 let buzzer_se: AudioFile = ctx.from_value(value)?;
396 buzzer_se_field = Some(buzzer_se);
397 }
398 WINDOWSKIN_NAME_FIELD => {
399 if windowskin_name_field.is_some() {
400 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
401 }
402
403 let windowskin_name: &StringValue = ctx.from_value(value)?;
404 let windowskin_name = std::str::from_utf8(windowskin_name.value())
405 .map_err(FromValueError::new_other)?
406 .to_string();
407 windowskin_name_field = Some(windowskin_name);
408 }
409 TEST_BATTLERS_FIELD => {
410 if test_battlers_field.is_some() {
411 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
412 }
413
414 let test_battlers: Vec<SystemTestBattler> = ctx.from_value(value)?;
415 test_battlers_field = Some(test_battlers);
416 }
417 BATTLEBACK_NAME_FIELD => {
418 if battleback_name_field.is_some() {
419 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
420 }
421
422 let battleback_name: &StringValue = ctx.from_value(value)?;
423 let battleback_name = std::str::from_utf8(battleback_name.value())
424 .map_err(FromValueError::new_other)?
425 .to_string();
426 battleback_name_field = Some(battleback_name);
427 }
428 PARTY_MEMBERS_FIELD => {
429 if party_members_field.is_some() {
430 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
431 }
432
433 let party_members: Vec<i32> = ctx.from_value(value)?;
434 party_members_field = Some(party_members);
435 }
436 ACTOR_COLLAPSE_SE_FIELD => {
437 if actor_collapse_se_field.is_some() {
438 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
439 }
440
441 let actor_collapse_se: AudioFile = ctx.from_value(value)?;
442 actor_collapse_se_field = Some(actor_collapse_se);
443 }
444 GAMEOVER_ME_FIELD => {
445 if gameover_me_field.is_some() {
446 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
447 }
448
449 let gameover_me: AudioFile = ctx.from_value(value)?;
450 gameover_me_field = Some(gameover_me);
451 }
452 BATTLER_NAME_FIELD => {
453 if battler_name_field.is_some() {
454 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
455 }
456
457 let battler_name: &StringValue = ctx.from_value(value)?;
458 let battler_name = std::str::from_utf8(battler_name.value())
459 .map_err(FromValueError::new_other)?
460 .to_string();
461 battler_name_field = Some(battler_name);
462 }
463 SAVE_SE_FIELD => {
464 if save_se_field.is_some() {
465 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
466 }
467
468 let save_se: AudioFile = ctx.from_value(value)?;
469 save_se_field = Some(save_se);
470 }
471 BATTLE_TRANSITION_FIELD => {
472 if battle_transition_field.is_some() {
473 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
474 }
475
476 let battle_transition: &StringValue = ctx.from_value(value)?;
477 let battle_transition = std::str::from_utf8(battle_transition.value())
478 .map_err(FromValueError::new_other)?
479 .to_string();
480 battle_transition_field = Some(battle_transition);
481 }
482 START_X_FIELD => {
483 if start_x_field.is_some() {
484 return Err(FromValueError::DuplicateInstanceVariable { name: key.into() });
485 }
486
487 let start_x: i32 = ctx.from_value(value)?;
488 start_x_field = Some(start_x);
489 }
490 _ => {
491 return Err(FromValueError::UnknownInstanceVariable { name: key.into() });
492 }
493 }
494 }
495
496 let variables = variables_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
497 name: VARIABLES_FIELD.into(),
498 })?;
499 let cancel_se = cancel_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
500 name: CANCEL_SE_FIELD.into(),
501 })?;
502 let magic_number =
503 magic_number_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
504 name: MAGIC_NUMBER_FIELD.into(),
505 })?;
506 let escape_se = escape_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
507 name: ESCAPE_SE_FIELD.into(),
508 })?;
509 let battle_end_me =
510 battle_end_me_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
511 name: BATTLE_END_ME_FIELD.into(),
512 })?;
513 let start_map_id =
514 start_map_id_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
515 name: START_MAP_ID_FIELD.into(),
516 })?;
517 let shop_se = shop_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
518 name: SHOP_SE_FIELD.into(),
519 })?;
520 let gameover_name =
521 gameover_name_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
522 name: GAMEOVER_NAME_FIELD.into(),
523 })?;
524 let words = words_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
525 name: WORDS_FIELD.into(),
526 })?;
527 let switches = switches_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
528 name: SWITCHES_FIELD.into(),
529 })?;
530 let decision_se =
531 decision_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
532 name: DECISION_SE_FIELD.into(),
533 })?;
534 let edit_map_id =
535 edit_map_id_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
536 name: EDIT_MAP_ID_FIELD.into(),
537 })?;
538 let battle_start_se =
539 battle_start_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
540 name: BATTLE_START_SE_FIELD.into(),
541 })?;
542 let battle_bgm =
543 battle_bgm_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
544 name: BATTLE_BGM_FIELD.into(),
545 })?;
546 let test_troop_id =
547 test_troop_id_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
548 name: TEST_TROOP_ID_FIELD.into(),
549 })?;
550 let equip_se = equip_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
551 name: EQUIP_SE_FIELD.into(),
552 })?;
553 let title_name =
554 title_name_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
555 name: TITLE_NAME_FIELD.into(),
556 })?;
557 let enemy_collapse_se =
558 enemy_collapse_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
559 name: ENEMY_COLLAPSE_SE_FIELD.into(),
560 })?;
561 let cursor_se = cursor_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
562 name: CURSOR_SE_FIELD.into(),
563 })?;
564 let elements = elements_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
565 name: ELEMENTS_FIELD.into(),
566 })?;
567 let underscore =
568 underscore_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
569 name: UNDERSCORE_FIELD.into(),
570 })?;
571 let start_y = start_y_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
572 name: START_Y_FIELD.into(),
573 })?;
574 let battler_hue =
575 battler_hue_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
576 name: BATTLER_HUE_FIELD.into(),
577 })?;
578 let load_se = load_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
579 name: LOAD_SE_FIELD.into(),
580 })?;
581 let title_bgm = title_bgm_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
582 name: TITLE_BGM_FIELD.into(),
583 })?;
584 let buzzer_se = buzzer_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
585 name: BUZZER_SE_FIELD.into(),
586 })?;
587 let windowskin_name =
588 windowskin_name_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
589 name: WINDOWSKIN_NAME_FIELD.into(),
590 })?;
591 let test_battlers =
592 test_battlers_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
593 name: TEST_BATTLERS_FIELD.into(),
594 })?;
595 let battleback_name =
596 battleback_name_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
597 name: BATTLEBACK_NAME_FIELD.into(),
598 })?;
599 let party_members =
600 party_members_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
601 name: PARTY_MEMBERS_FIELD.into(),
602 })?;
603 let actor_collapse_se =
604 actor_collapse_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
605 name: ACTOR_COLLAPSE_SE_FIELD.into(),
606 })?;
607 let gameover_me =
608 gameover_me_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
609 name: GAMEOVER_ME_FIELD.into(),
610 })?;
611 let battler_name =
612 battler_name_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
613 name: BATTLER_NAME_FIELD.into(),
614 })?;
615 let save_se = save_se_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
616 name: SAVE_SE_FIELD.into(),
617 })?;
618 let battle_transition =
619 battle_transition_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
620 name: BATTLE_TRANSITION_FIELD.into(),
621 })?;
622 let start_x = start_x_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
623 name: START_X_FIELD.into(),
624 })?;
625
626 Ok(Self {
627 variables,
628 cancel_se,
629 magic_number,
630 escape_se,
631 battle_end_me,
632 start_map_id,
633 shop_se,
634 gameover_name,
635 words,
636 switches,
637 decision_se,
638 edit_map_id,
639 battle_start_se,
640 battle_bgm,
641 test_troop_id,
642 equip_se,
643 title_name,
644 enemy_collapse_se,
645 cursor_se,
646 elements,
647 underscore,
648 start_y,
649 battler_hue,
650 load_se,
651 title_bgm,
652 buzzer_se,
653 windowskin_name,
654 test_battlers,
655 battleback_name,
656 party_members,
657 actor_collapse_se,
658 gameover_me,
659 battler_name,
660 save_se,
661 battle_transition,
662 start_x,
663 })
664 }
665}
666
667impl IntoValue for System {
668 fn into_value(self, arena: &mut ValueArena) -> Result<ValueHandle, IntoValueError> {
669 let object_name = arena.create_symbol(OBJECT_NAME.into());
670
671 let variables_field_key = arena.create_symbol(VARIABLES_FIELD.into());
672 let cancel_se_field_key = arena.create_symbol(CANCEL_SE_FIELD.into());
673 let magic_number_field_key = arena.create_symbol(MAGIC_NUMBER_FIELD.into());
674 let escape_se_field_key = arena.create_symbol(ESCAPE_SE_FIELD.into());
675 let battle_end_me_field_key = arena.create_symbol(BATTLE_END_ME_FIELD.into());
676 let start_map_id_field_key = arena.create_symbol(START_MAP_ID_FIELD.into());
677 let shop_se_field_key = arena.create_symbol(SHOP_SE_FIELD.into());
678 let gameover_name_field_key = arena.create_symbol(GAMEOVER_NAME_FIELD.into());
679 let words_field_key = arena.create_symbol(WORDS_FIELD.into());
680 let switches_field_key = arena.create_symbol(SWITCHES_FIELD.into());
681 let decision_se_field_key = arena.create_symbol(DECISION_SE_FIELD.into());
682 let edit_map_id_field_key = arena.create_symbol(EDIT_MAP_ID_FIELD.into());
683 let battle_start_se_field_key = arena.create_symbol(BATTLE_START_SE_FIELD.into());
684 let battle_bgm_field_key = arena.create_symbol(BATTLE_BGM_FIELD.into());
685 let test_troop_id_field_key = arena.create_symbol(TEST_TROOP_ID_FIELD.into());
686 let equip_se_field_key = arena.create_symbol(EQUIP_SE_FIELD.into());
687 let title_name_field_key = arena.create_symbol(TITLE_NAME_FIELD.into());
688 let enemy_collapse_se_field_key = arena.create_symbol(ENEMY_COLLAPSE_SE_FIELD.into());
689 let cursor_se_field_key = arena.create_symbol(CURSOR_SE_FIELD.into());
690 let elements_field_key = arena.create_symbol(ELEMENTS_FIELD.into());
691 let underscore_field_key = arena.create_symbol(UNDERSCORE_FIELD.into());
692 let start_y_field_key = arena.create_symbol(START_Y_FIELD.into());
693 let battler_hue_field_key = arena.create_symbol(BATTLER_HUE_FIELD.into());
694 let load_se_field_key = arena.create_symbol(LOAD_SE_FIELD.into());
695 let title_bgm_field_key = arena.create_symbol(TITLE_BGM_FIELD.into());
696 let buzzer_se_field_key = arena.create_symbol(BUZZER_SE_FIELD.into());
697 let windowskin_name_field_key = arena.create_symbol(WINDOWSKIN_NAME_FIELD.into());
698 let test_battlers_field_key = arena.create_symbol(TEST_BATTLERS_FIELD.into());
699 let battleback_name_field_key = arena.create_symbol(BATTLEBACK_NAME_FIELD.into());
700 let party_members_field_key = arena.create_symbol(PARTY_MEMBERS_FIELD.into());
701 let actor_collapse_se_field_key = arena.create_symbol(ACTOR_COLLAPSE_SE_FIELD.into());
702 let gameover_me_field_key = arena.create_symbol(GAMEOVER_ME_FIELD.into());
703 let battler_name_field_key = arena.create_symbol(BATTLER_NAME_FIELD.into());
704 let save_se_field_key = arena.create_symbol(SAVE_SE_FIELD.into());
705 let battle_transition_field_key = arena.create_symbol(BATTLE_TRANSITION_FIELD.into());
706 let start_x_field_key = arena.create_symbol(START_X_FIELD.into());
707
708 let variables_field_value = {
709 let mut variables = Vec::with_capacity(self.variables.len());
710 for variable in self.variables {
711 let handle = match variable {
712 Some(variable) => arena.create_string(variable.into()).into(),
713 None => arena.create_nil().into(),
714 };
715 variables.push(handle);
716 }
717
718 arena.create_array(variables).into()
719 };
720 let cancel_se_field_value = self.cancel_se.into_value(arena)?;
721 let magic_number_field_value = self.magic_number.into_value(arena)?;
722 let escape_se_field_value = self.escape_se.into_value(arena)?;
723 let battle_end_me_field_value = self.battle_end_me.into_value(arena)?;
724 let start_map_id_field_value = self.start_map_id.into_value(arena)?;
725 let shop_se_field_value = self.shop_se.into_value(arena)?;
726 let gameover_name_field_value = arena.create_string(self.gameover_name.into()).into();
727 let words_field_value = self.words.into_value(arena)?;
728 let switches_field_value = {
729 let mut switches = Vec::with_capacity(self.switches.len());
730 for switch in self.switches {
731 let handle = match switch {
732 Some(switch) => arena.create_string(switch.into()).into(),
733 None => arena.create_nil().into(),
734 };
735 switches.push(handle);
736 }
737
738 arena.create_array(switches).into()
739 };
740 let decision_se_field_value = self.decision_se.into_value(arena)?;
741 let edit_map_id_field_value = self.edit_map_id.into_value(arena)?;
742 let battle_start_se_field_value = self.battle_start_se.into_value(arena)?;
743 let battle_bgm_field_value = self.battle_bgm.into_value(arena)?;
744 let test_troop_id_field_value = self.test_troop_id.into_value(arena)?;
745 let equip_se_field_value = self.equip_se.into_value(arena)?;
746 let title_name_field_value = arena.create_string(self.title_name.into()).into();
747 let enemy_collapse_se_field_value = self.enemy_collapse_se.into_value(arena)?;
748 let cursor_se_field_value = self.cursor_se.into_value(arena)?;
749 let elements_field_value = {
750 let mut elements = Vec::with_capacity(self.elements.len());
751 for element in self.elements {
752 let handle = arena.create_string(element.into()).into();
753 elements.push(handle);
754 }
755 arena.create_array(elements).into()
756 };
757 let underscore_field_value = self.underscore.into_value(arena)?;
758 let start_y_field_value = self.start_y.into_value(arena)?;
759 let battler_hue_field_value = self.battler_hue.into_value(arena)?;
760 let load_se_field_value = self.load_se.into_value(arena)?;
761 let title_bgm_field_value = self.title_bgm.into_value(arena)?;
762 let buzzer_se_field_value = self.buzzer_se.into_value(arena)?;
763 let windowskin_name_field_value = arena.create_string(self.windowskin_name.into()).into();
764 let test_battlers_field_value = self.test_battlers.into_value(arena)?;
765 let battleback_name_field_value = arena.create_string(self.battleback_name.into()).into();
766 let party_members_field_value = self.party_members.into_value(arena)?;
767 let actor_collapse_se_field_value = self.actor_collapse_se.into_value(arena)?;
768 let gameover_me_field_value = self.gameover_me.into_value(arena)?;
769 let battler_name_field_value = arena.create_string(self.battler_name.into()).into();
770 let save_se_field_value = self.save_se.into_value(arena)?;
771 let battle_transition_field_value =
772 arena.create_string(self.battle_transition.into()).into();
773 let start_x_field_value = self.start_x.into_value(arena)?;
774
775 let fields = vec![
776 (variables_field_key, variables_field_value),
777 (cancel_se_field_key, cancel_se_field_value),
778 (magic_number_field_key, magic_number_field_value),
779 (escape_se_field_key, escape_se_field_value),
780 (battle_end_me_field_key, battle_end_me_field_value),
781 (start_map_id_field_key, start_map_id_field_value),
782 (shop_se_field_key, shop_se_field_value),
783 (gameover_name_field_key, gameover_name_field_value),
784 (words_field_key, words_field_value),
785 (switches_field_key, switches_field_value),
786 (decision_se_field_key, decision_se_field_value),
787 (edit_map_id_field_key, edit_map_id_field_value),
788 (battle_start_se_field_key, battle_start_se_field_value),
789 (battle_bgm_field_key, battle_bgm_field_value),
790 (test_troop_id_field_key, test_troop_id_field_value),
791 (equip_se_field_key, equip_se_field_value),
792 (title_name_field_key, title_name_field_value),
793 (enemy_collapse_se_field_key, enemy_collapse_se_field_value),
794 (cursor_se_field_key, cursor_se_field_value),
795 (elements_field_key, elements_field_value),
796 (underscore_field_key, underscore_field_value),
797 (start_y_field_key, start_y_field_value),
798 (battler_hue_field_key, battler_hue_field_value),
799 (load_se_field_key, load_se_field_value),
800 (title_bgm_field_key, title_bgm_field_value),
801 (buzzer_se_field_key, buzzer_se_field_value),
802 (windowskin_name_field_key, windowskin_name_field_value),
803 (test_battlers_field_key, test_battlers_field_value),
804 (battleback_name_field_key, battleback_name_field_value),
805 (party_members_field_key, party_members_field_value),
806 (actor_collapse_se_field_key, actor_collapse_se_field_value),
807 (gameover_me_field_key, gameover_me_field_value),
808 (battler_name_field_key, battler_name_field_value),
809 (save_se_field_key, save_se_field_value),
810 (battle_transition_field_key, battle_transition_field_value),
811 (start_x_field_key, start_x_field_value),
812 ];
813
814 let object = arena.create_object(object_name, fields);
815
816 Ok(object.into())
817 }
818}