exolvl/types/
action_type.rs

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}