1use super::{
2 function_call::FunctionCall,
3 novascript::{action::Action, nova_value::NovaValue},
4};
5use crate::{error::Error, Read, ReadContext, Write};
6
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
9pub enum ActionType {
10 Repeat {
11 actions: Vec<Action>,
12 count: NovaValue,
13 },
14 RepeatWhile {
15 actions: Vec<Action>,
16 condition: NovaValue,
17 },
18 ConditionBlock {
19 if_actions: Vec<Action>,
20 else_actions: Vec<Action>,
21 condition: NovaValue,
22 },
23 Wait {
24 duration: NovaValue,
25 },
26 WaitFrames {
27 frames: NovaValue,
28 },
29 Move {
30 target_objects: NovaValue,
31 position: NovaValue,
32 global: NovaValue,
33 duration: NovaValue,
34 easing: NovaValue,
35 },
36 Scale {
37 target_objects: NovaValue,
38 scale: NovaValue,
39 duration: NovaValue,
40 easing: NovaValue,
41 },
42 Rotate {
43 target_objects: NovaValue,
44 rotation: NovaValue,
45 shortest_path: NovaValue,
46 global: NovaValue,
47 duration: NovaValue,
48 easing: NovaValue,
49 },
50 RotateAround {
51 target_objects: NovaValue,
52 pivot: NovaValue,
53 rotation: NovaValue,
54 rotate_target: NovaValue,
55 duration: NovaValue,
56 easing: NovaValue,
57 },
58 SetVariable {
59 variable: i32,
60 value: Option<NovaValue>,
61 },
62 ResetVariable {
63 variable: i32,
64 },
65 ResetObject {
66 target_objects: NovaValue,
67 },
68 SetColor {
69 target_objects: NovaValue,
70 color: NovaValue,
71 channel: NovaValue,
72 duration: NovaValue,
73 easing: NovaValue,
74 },
75 SetTransparency {
76 target_objects: NovaValue,
77 transparency: NovaValue,
78 channel: NovaValue,
79 duration: NovaValue,
80 easing: NovaValue,
81 },
82 SetSecondaryColor {
83 target_objects: NovaValue,
84 color: NovaValue,
85 duration: NovaValue,
86 easing: NovaValue,
87 },
88 SetSecondaryTransparency {
89 target_objects: NovaValue,
90 transparency: NovaValue,
91 duration: NovaValue,
92 easing: NovaValue,
93 },
94 SetBorderColor {
95 target_objects: NovaValue,
96 color: NovaValue,
97 duration: NovaValue,
98 easing: NovaValue,
99 },
100 SetBorderTransparency {
101 target_objects: NovaValue,
102 transparency: NovaValue,
103 duration: NovaValue,
104 easing: NovaValue,
105 },
106 SetSprite {
107 target_objects: NovaValue,
108 sprite: NovaValue,
109 },
110 SetText {
111 target_objects: NovaValue,
112 text: NovaValue,
113 },
114 SetEnabled {
115 target_objects: NovaValue,
116 enabled: NovaValue,
117 },
118 Activate {
119 target_objects: NovaValue,
120 },
121 Deactivate {
122 target_objects: NovaValue,
123 },
124 Damage {
125 target_objects: NovaValue,
126 damage: NovaValue,
127 },
128 Kill {
129 target_objects: NovaValue,
130 },
131 GameFinish,
132 CameraPan {
133 position: NovaValue,
134 duration: NovaValue,
135 easing: NovaValue,
136 },
137 CameraFollowPlayer,
138 CameraZoom {
139 viewport_size: NovaValue,
140 duration: NovaValue,
141 easing: NovaValue,
142 },
143 CameraZoomReset {
144 duration: NovaValue,
145 easing: NovaValue,
146 },
147 CameraOffset {
148 offset: NovaValue,
149 duration: NovaValue,
150 easing: NovaValue,
151 },
152 CameraOffsetReset {
153 duration: NovaValue,
154 easing: NovaValue,
155 },
156 CameraShake {
157 strength: NovaValue,
158 roughness: NovaValue,
159 fade_in: NovaValue,
160 fade_out: NovaValue,
161 duration: NovaValue,
162 },
163 PlaySound {
164 sound: NovaValue,
165 volume: NovaValue,
166 pitch: NovaValue,
167 },
168 PlayMusic {
169 music: NovaValue,
170 volume: NovaValue,
171 pitch: NovaValue,
172 },
173 SetDirection {
174 target_objects: NovaValue,
175 direction: NovaValue,
176 },
177 SetGravity {
178 target_objects: NovaValue,
179 gravity: NovaValue,
180 },
181 SetVelocity {
182 target_objects: NovaValue,
183 velocity: NovaValue,
184 },
185 SetCinematic {
186 enabled: NovaValue,
187 },
188 SetInputEnabled {
189 enabled: NovaValue,
190 },
191 SetTimerEnabled {
192 enabled: NovaValue,
193 },
194 GameTextShow {
195 text: NovaValue,
196 duration: NovaValue,
197 },
198 DialogueShow {
199 text: NovaValue,
200 position: NovaValue,
201 reverse_direction: NovaValue,
202 },
203 StopScript {
204 script: NovaValue,
205 },
206 TransitionIn {
207 type_: NovaValue,
208 color: NovaValue,
209 duration: NovaValue,
210 easing: NovaValue,
211 },
212 TransitionOut {
213 type_: NovaValue,
214 color: NovaValue,
215 duration: NovaValue,
216 easing: NovaValue,
217 },
218 TimeScale {
219 time_scale: NovaValue,
220 duration: NovaValue,
221 easing: NovaValue,
222 },
223 RunFunction {
224 function: FunctionCall,
225 },
226 SetVariableOverTime {
227 variable: i32,
228 value: Option<NovaValue>,
229 duration: NovaValue,
230 easing: NovaValue,
231 },
232 RepeatForEachObject {
233 target_objects: NovaValue,
234 actions: Vec<Action>,
235 },
236 StopSound {
237 sound_instance: NovaValue,
238 fade_out: NovaValue,
239 },
240 PlayParticleSystem {
241 target_objects: NovaValue,
242 },
243 StopParticleSystem {
244 target_objects: NovaValue,
245 clear: NovaValue,
246 },
247}
248
249impl From<&ActionType> for i32 {
250 fn from(action_type: &ActionType) -> Self {
251 match action_type {
252 ActionType::Repeat { .. } => 0,
253 ActionType::RepeatWhile { .. } => 1,
254 ActionType::ConditionBlock { .. } => 2,
255 ActionType::Wait { .. } => 3,
256 ActionType::WaitFrames { .. } => 4,
257 ActionType::Move { .. } => 5,
258 ActionType::Scale { .. } => 6,
259 ActionType::Rotate { .. } => 7,
260 ActionType::RotateAround { .. } => 8,
261 ActionType::SetVariable { .. } => 9,
262 ActionType::ResetVariable { .. } => 10,
263 ActionType::ResetObject { .. } => 11,
264 ActionType::SetColor { .. } => 12,
265 ActionType::SetTransparency { .. } => 13,
266 ActionType::SetSecondaryColor { .. } => 14,
267 ActionType::SetSecondaryTransparency { .. } => 15,
268 ActionType::SetBorderColor { .. } => 16,
269 ActionType::SetBorderTransparency { .. } => 17,
270 ActionType::SetSprite { .. } => 18,
271 ActionType::SetText { .. } => 19,
272 ActionType::SetEnabled { .. } => 20,
273 ActionType::Activate { .. } => 21,
274 ActionType::Deactivate { .. } => 22,
275 ActionType::Damage { .. } => 23,
276 ActionType::Kill { .. } => 24,
277 ActionType::GameFinish => 25,
278 ActionType::CameraPan { .. } => 26,
279 ActionType::CameraFollowPlayer => 27,
280 ActionType::CameraZoom { .. } => 28,
281 ActionType::CameraZoomReset { .. } => 29,
282 ActionType::CameraOffset { .. } => 30,
283 ActionType::CameraOffsetReset { .. } => 31,
284 ActionType::CameraShake { .. } => 32,
285 ActionType::PlaySound { .. } => 33,
286 ActionType::PlayMusic { .. } => 34,
287 ActionType::SetDirection { .. } => 35,
288 ActionType::SetGravity { .. } => 36,
289 ActionType::SetVelocity { .. } => 37,
290 ActionType::SetCinematic { .. } => 38,
291 ActionType::SetInputEnabled { .. } => 39,
292 ActionType::SetTimerEnabled { .. } => 40,
293 ActionType::GameTextShow { .. } => 41,
294 ActionType::DialogueShow { .. } => 42,
295 ActionType::StopScript { .. } => 43,
296 ActionType::TransitionIn { .. } => 44,
297 ActionType::TransitionOut { .. } => 45,
298 ActionType::TimeScale { .. } => 46,
299 ActionType::RunFunction { .. } => 47,
300 ActionType::SetVariableOverTime { .. } => 48,
301 ActionType::RepeatForEachObject { .. } => 49,
302 ActionType::StopSound { .. } => 50,
303 ActionType::PlayParticleSystem { .. } => 51,
304 ActionType::StopParticleSystem { .. } => 52,
305 }
306 }
307}
308
309impl ReadContext for ActionType {
310 type Context = i32;
311
312 #[allow(clippy::too_many_lines)]
313 fn read_ctx(input: &mut impl std::io::Read, with: Self::Context) -> Result<Self, Error> {
314 Ok(match with {
315 0 => Self::Repeat {
316 actions: Read::read(input)?,
317 count: Read::read(input)?,
318 },
319 1 => Self::RepeatWhile {
320 actions: Read::read(input)?,
321 condition: Read::read(input)?,
322 },
323 2 => Self::ConditionBlock {
324 if_actions: Read::read(input)?,
325 else_actions: Read::read(input)?,
326 condition: Read::read(input)?,
327 },
328 3 => Self::Wait {
329 duration: Read::read(input)?,
330 },
331 4 => Self::WaitFrames {
332 frames: Read::read(input)?,
333 },
334 5 => Self::Move {
335 target_objects: Read::read(input)?,
336 position: Read::read(input)?,
337 global: Read::read(input)?,
338 duration: Read::read(input)?,
339 easing: Read::read(input)?,
340 },
341 6 => Self::Scale {
342 target_objects: Read::read(input)?,
343 scale: Read::read(input)?,
344 duration: Read::read(input)?,
345 easing: Read::read(input)?,
346 },
347 7 => Self::Rotate {
348 target_objects: Read::read(input)?,
349 rotation: Read::read(input)?,
350 shortest_path: Read::read(input)?,
351 global: Read::read(input)?,
352 duration: Read::read(input)?,
353 easing: Read::read(input)?,
354 },
355 8 => Self::RotateAround {
356 target_objects: Read::read(input)?,
357 pivot: Read::read(input)?,
358 rotation: Read::read(input)?,
359 rotate_target: Read::read(input)?,
360 duration: Read::read(input)?,
361 easing: Read::read(input)?,
362 },
363 9 => Self::SetVariable {
364 variable: Read::read(input)?,
365 value: Read::read(input)?,
366 },
367 10 => Self::ResetVariable {
368 variable: Read::read(input)?,
369 },
370 11 => Self::ResetObject {
371 target_objects: Read::read(input)?,
372 },
373 12 => Self::SetColor {
374 target_objects: Read::read(input)?,
375 color: Read::read(input)?,
376 channel: Read::read(input)?,
377 duration: Read::read(input)?,
378 easing: Read::read(input)?,
379 },
380 13 => Self::SetTransparency {
381 target_objects: Read::read(input)?,
382 transparency: Read::read(input)?,
383 channel: Read::read(input)?,
384 duration: Read::read(input)?,
385 easing: Read::read(input)?,
386 },
387 14 => Self::SetSecondaryColor {
388 target_objects: Read::read(input)?,
389 color: Read::read(input)?,
390 duration: Read::read(input)?,
391 easing: Read::read(input)?,
392 },
393 15 => Self::SetSecondaryTransparency {
394 target_objects: Read::read(input)?,
395 transparency: Read::read(input)?,
396 duration: Read::read(input)?,
397 easing: Read::read(input)?,
398 },
399 16 => Self::SetBorderColor {
400 target_objects: Read::read(input)?,
401 color: Read::read(input)?,
402 duration: Read::read(input)?,
403 easing: Read::read(input)?,
404 },
405 17 => Self::SetBorderTransparency {
406 target_objects: Read::read(input)?,
407 transparency: Read::read(input)?,
408 duration: Read::read(input)?,
409 easing: Read::read(input)?,
410 },
411 18 => Self::SetSprite {
412 target_objects: Read::read(input)?,
413 sprite: Read::read(input)?,
414 },
415 19 => Self::SetText {
416 target_objects: Read::read(input)?,
417 text: Read::read(input)?,
418 },
419 20 => Self::SetEnabled {
420 target_objects: Read::read(input)?,
421 enabled: Read::read(input)?,
422 },
423 21 => Self::Activate {
424 target_objects: Read::read(input)?,
425 },
426 22 => Self::Deactivate {
427 target_objects: Read::read(input)?,
428 },
429 23 => Self::Damage {
430 target_objects: Read::read(input)?,
431 damage: Read::read(input)?,
432 },
433 24 => Self::Kill {
434 target_objects: Read::read(input)?,
435 },
436 25 => Self::GameFinish,
437 26 => Self::CameraPan {
438 position: Read::read(input)?,
439 duration: Read::read(input)?,
440 easing: Read::read(input)?,
441 },
442 27 => Self::CameraFollowPlayer,
443 28 => Self::CameraZoom {
444 viewport_size: Read::read(input)?,
445 duration: Read::read(input)?,
446 easing: Read::read(input)?,
447 },
448 29 => Self::CameraZoomReset {
449 duration: Read::read(input)?,
450 easing: Read::read(input)?,
451 },
452 30 => Self::CameraOffset {
453 offset: Read::read(input)?,
454 duration: Read::read(input)?,
455 easing: Read::read(input)?,
456 },
457 31 => Self::CameraOffsetReset {
458 duration: Read::read(input)?,
459 easing: Read::read(input)?,
460 },
461 32 => Self::CameraShake {
462 strength: Read::read(input)?,
463 roughness: Read::read(input)?,
464 fade_in: Read::read(input)?,
465 fade_out: Read::read(input)?,
466 duration: Read::read(input)?,
467 },
468 33 => Self::PlaySound {
469 sound: Read::read(input)?,
470 volume: Read::read(input)?,
471 pitch: Read::read(input)?,
472 },
473 34 => Self::PlayMusic {
474 music: Read::read(input)?,
475 volume: Read::read(input)?,
476 pitch: Read::read(input)?,
477 },
478 35 => Self::SetDirection {
479 target_objects: Read::read(input)?,
480 direction: Read::read(input)?,
481 },
482 36 => Self::SetGravity {
483 target_objects: Read::read(input)?,
484 gravity: Read::read(input)?,
485 },
486 37 => Self::SetVelocity {
487 target_objects: Read::read(input)?,
488 velocity: Read::read(input)?,
489 },
490 38 => Self::SetCinematic {
491 enabled: Read::read(input)?,
492 },
493 39 => Self::SetInputEnabled {
494 enabled: Read::read(input)?,
495 },
496 40 => Self::SetTimerEnabled {
497 enabled: Read::read(input)?,
498 },
499 41 => Self::GameTextShow {
500 text: Read::read(input)?,
501 duration: Read::read(input)?,
502 },
503 42 => Self::DialogueShow {
504 text: Read::read(input)?,
505 position: Read::read(input)?,
506 reverse_direction: Read::read(input)?,
507 },
508 43 => Self::StopScript {
509 script: Read::read(input)?,
510 },
511 44 => Self::TransitionIn {
512 type_: Read::read(input)?,
513 color: Read::read(input)?,
514 duration: Read::read(input)?,
515 easing: Read::read(input)?,
516 },
517 45 => Self::TransitionOut {
518 type_: Read::read(input)?,
519 color: Read::read(input)?,
520 duration: Read::read(input)?,
521 easing: Read::read(input)?,
522 },
523 46 => Self::TimeScale {
524 time_scale: Read::read(input)?,
525 duration: Read::read(input)?,
526 easing: Read::read(input)?,
527 },
528 47 => Self::RunFunction {
529 function: Read::read(input)?,
530 },
531 48 => Self::SetVariableOverTime {
532 variable: Read::read(input)?,
533 value: Read::read(input)?,
534 duration: Read::read(input)?,
535 easing: Read::read(input)?,
536 },
537 49 => Self::RepeatForEachObject {
538 target_objects: Read::read(input)?,
539 actions: Read::read(input)?,
540 },
541 50 => Self::StopSound {
542 sound_instance: Read::read(input)?,
543 fade_out: Read::read(input)?,
544 },
545 51 => Self::PlayParticleSystem {
546 target_objects: Read::read(input)?,
547 },
548 52 => Self::StopParticleSystem {
549 target_objects: Read::read(input)?,
550 clear: Read::read(input)?,
551 },
552
553 n => return Err(Error::InvalidActionType(n)),
554 })
555 }
556}
557
558impl Write for ActionType {
559 #[allow(clippy::too_many_lines)]
560 fn write(&self, output: &mut impl std::io::Write) -> Result<(), Error> {
561 match self {
562 Self::Repeat { actions, count } => {
563 actions.write(output)?;
564 count.write(output)
565 }
566 Self::RepeatWhile { actions, condition } => {
567 actions.write(output)?;
568 condition.write(output)
569 }
570 Self::ConditionBlock {
571 if_actions,
572 else_actions,
573 condition,
574 } => {
575 if_actions.write(output)?;
576 else_actions.write(output)?;
577 condition.write(output)
578 }
579 Self::Wait { duration } => duration.write(output),
580 Self::WaitFrames { frames } => frames.write(output),
581 Self::Move {
582 target_objects,
583 position,
584 global,
585 duration,
586 easing,
587 } => {
588 target_objects.write(output)?;
589 position.write(output)?;
590 global.write(output)?;
591 duration.write(output)?;
592 easing.write(output)
593 }
594 Self::Scale {
595 target_objects,
596 scale,
597 duration,
598 easing,
599 } => {
600 target_objects.write(output)?;
601 scale.write(output)?;
602 duration.write(output)?;
603 easing.write(output)
604 }
605 Self::Rotate {
606 target_objects,
607 rotation,
608 shortest_path,
609 global,
610 duration,
611 easing,
612 } => {
613 target_objects.write(output)?;
614 rotation.write(output)?;
615 shortest_path.write(output)?;
616 global.write(output)?;
617 duration.write(output)?;
618 easing.write(output)
619 }
620 Self::RotateAround {
621 target_objects,
622 pivot,
623 rotation,
624 rotate_target,
625 duration,
626 easing,
627 } => {
628 target_objects.write(output)?;
629 pivot.write(output)?;
630 rotation.write(output)?;
631 rotate_target.write(output)?;
632 duration.write(output)?;
633 easing.write(output)
634 }
635 Self::SetVariable { variable, value } => {
636 variable.write(output)?;
637 value.write(output)
638 }
639 Self::ResetVariable { variable } => variable.write(output),
640 Self::ResetObject { target_objects }
641 | Self::Activate { target_objects }
642 | Self::Deactivate { target_objects }
643 | Self::Kill { target_objects }
644 | Self::PlayParticleSystem { target_objects } => target_objects.write(output),
645 Self::SetColor {
646 target_objects,
647 color,
648 channel,
649 duration,
650 easing,
651 } => {
652 target_objects.write(output)?;
653 color.write(output)?;
654 channel.write(output)?;
655 duration.write(output)?;
656 easing.write(output)
657 }
658 Self::SetTransparency {
659 target_objects,
660 transparency,
661 channel,
662 duration,
663 easing,
664 } => {
665 target_objects.write(output)?;
666 transparency.write(output)?;
667 channel.write(output)?;
668 duration.write(output)?;
669 easing.write(output)
670 }
671 Self::SetSecondaryColor {
672 target_objects,
673 color,
674 duration,
675 easing,
676 } => {
677 target_objects.write(output)?;
678 color.write(output)?;
679 duration.write(output)?;
680 easing.write(output)
681 }
682 Self::SetSecondaryTransparency {
683 target_objects,
684 transparency,
685 duration,
686 easing,
687 } => {
688 target_objects.write(output)?;
689 transparency.write(output)?;
690 duration.write(output)?;
691 easing.write(output)
692 }
693 Self::SetBorderColor {
694 target_objects,
695 color,
696 duration,
697 easing,
698 } => {
699 target_objects.write(output)?;
700 color.write(output)?;
701 duration.write(output)?;
702 easing.write(output)
703 }
704 Self::SetBorderTransparency {
705 target_objects,
706 transparency,
707 duration,
708 easing,
709 } => {
710 target_objects.write(output)?;
711 transparency.write(output)?;
712 duration.write(output)?;
713 easing.write(output)
714 }
715 Self::SetSprite {
716 target_objects,
717 sprite,
718 } => {
719 target_objects.write(output)?;
720 sprite.write(output)
721 }
722 Self::SetText {
723 target_objects,
724 text,
725 } => {
726 target_objects.write(output)?;
727 text.write(output)
728 }
729 Self::SetEnabled {
730 target_objects,
731 enabled,
732 } => {
733 target_objects.write(output)?;
734 enabled.write(output)
735 }
736 Self::Damage {
737 target_objects,
738 damage,
739 } => {
740 target_objects.write(output)?;
741 damage.write(output)
742 }
743 Self::CameraPan {
744 position,
745 duration,
746 easing,
747 } => {
748 position.write(output)?;
749 duration.write(output)?;
750 easing.write(output)
751 }
752 Self::GameFinish | Self::CameraFollowPlayer => Ok(()),
753 Self::CameraZoom {
754 viewport_size,
755 duration,
756 easing,
757 } => {
758 viewport_size.write(output)?;
759 duration.write(output)?;
760 easing.write(output)
761 }
762 Self::CameraZoomReset { duration, easing } => {
763 duration.write(output)?;
764 easing.write(output)
765 }
766 Self::CameraOffset {
767 offset,
768 duration,
769 easing,
770 } => {
771 offset.write(output)?;
772 duration.write(output)?;
773 easing.write(output)
774 }
775 Self::CameraOffsetReset { duration, easing } => {
776 duration.write(output)?;
777 easing.write(output)
778 }
779 Self::CameraShake {
780 strength,
781 roughness,
782 fade_in,
783 fade_out,
784 duration,
785 } => {
786 strength.write(output)?;
787 roughness.write(output)?;
788 fade_in.write(output)?;
789 fade_out.write(output)?;
790 duration.write(output)
791 }
792 Self::PlaySound {
793 sound,
794 volume,
795 pitch,
796 } => {
797 sound.write(output)?;
798 volume.write(output)?;
799 pitch.write(output)
800 }
801 Self::PlayMusic {
802 music,
803 volume,
804 pitch,
805 } => {
806 music.write(output)?;
807 volume.write(output)?;
808 pitch.write(output)
809 }
810 Self::SetDirection {
811 target_objects,
812 direction,
813 } => {
814 target_objects.write(output)?;
815 direction.write(output)
816 }
817 Self::SetGravity {
818 target_objects,
819 gravity,
820 } => {
821 target_objects.write(output)?;
822 gravity.write(output)
823 }
824 Self::SetVelocity {
825 target_objects,
826 velocity,
827 } => {
828 target_objects.write(output)?;
829 velocity.write(output)
830 }
831 Self::SetCinematic { enabled }
832 | Self::SetInputEnabled { enabled }
833 | Self::SetTimerEnabled { enabled } => enabled.write(output),
834 Self::GameTextShow { text, duration } => {
835 text.write(output)?;
836 duration.write(output)
837 }
838 Self::DialogueShow {
839 text,
840 position,
841 reverse_direction,
842 } => {
843 text.write(output)?;
844 position.write(output)?;
845 reverse_direction.write(output)
846 }
847 Self::StopScript { script } => script.write(output),
848 Self::TransitionIn {
849 type_,
850 color,
851 duration,
852 easing,
853 } => {
854 type_.write(output)?;
855 color.write(output)?;
856 duration.write(output)?;
857 easing.write(output)
858 }
859 Self::TransitionOut {
860 type_,
861 color,
862 duration,
863 easing,
864 } => {
865 type_.write(output)?;
866 color.write(output)?;
867 duration.write(output)?;
868 easing.write(output)
869 }
870 Self::TimeScale {
871 time_scale,
872 duration,
873 easing,
874 } => {
875 time_scale.write(output)?;
876 duration.write(output)?;
877 easing.write(output)
878 }
879 Self::RunFunction { function } => function.write(output),
880 Self::SetVariableOverTime {
881 variable,
882 value,
883 duration,
884 easing,
885 } => {
886 variable.write(output)?;
887 value.write(output)?;
888 duration.write(output)?;
889 easing.write(output)
890 }
891 Self::RepeatForEachObject {
892 target_objects,
893 actions,
894 } => {
895 target_objects.write(output)?;
896 actions.write(output)
897 }
898 Self::StopSound {
899 sound_instance,
900 fade_out,
901 } => {
902 sound_instance.write(output)?;
903 fade_out.write(output)
904 }
905 Self::StopParticleSystem {
906 target_objects,
907 clear,
908 } => {
909 target_objects.write(output)?;
910 clear.write(output)
911 }
912 }
913 }
914}