twmap/map/
impls.rs

1use crate::map::*;
2
3use az::CheckedCast;
4use fixed::traits::ToFixed;
5use fixed::types::{I17F15, I22F10, I27F5};
6use image::RgbaImage;
7use ndarray::Array2;
8use vek::num_traits::{CheckedAdd, CheckedDiv, CheckedMul, One};
9use vek::{Extent2, Rgba, Uv};
10
11impl From<twstorage::Version> for Version {
12    fn from(value: twstorage::Version) -> Self {
13        match value {
14            twstorage::Version::DDNet06 => Version::DDNet06,
15            twstorage::Version::Teeworlds07 => Version::Teeworlds07,
16        }
17    }
18}
19
20impl From<Version> for twstorage::Version {
21    fn from(value: Version) -> Self {
22        match value {
23            Version::DDNet06 => twstorage::Version::DDNet06,
24            Version::Teeworlds07 => twstorage::Version::Teeworlds07,
25        }
26    }
27}
28
29impl Info {
30    pub const MAX_AUTHOR_LENGTH: usize = 31;
31    pub const MAX_VERSION_LENGTH: usize = 15;
32    pub const MAX_CREDITS_LENGTH: usize = 127;
33    pub const MAX_LICENSE_LENGTH: usize = 31;
34    pub const MAX_SETTING_LENGTH: usize = 255;
35}
36
37impl Image {
38    pub const MAX_NAME_LENGTH: usize = 127;
39}
40
41impl Envelope {
42    pub const MAX_NAME_LENGTH: usize = 31;
43}
44
45impl Group {
46    pub const MAX_NAME_LENGTH: usize = 11;
47}
48
49impl Layer {
50    pub const MAX_NAME_LENGTH: usize = 11;
51}
52
53impl Sound {
54    pub const MAX_NAME_LENGTH: usize = 127;
55}
56
57impl TwMap {
58    /// Returns a empty map struct with only the version set.
59    pub fn empty(version: Version) -> TwMap {
60        TwMap {
61            version,
62            info: Info::default(),
63            images: vec![],
64            envelopes: vec![],
65            groups: vec![],
66            sounds: vec![],
67        }
68    }
69
70    /// Returns a reference to the physics group.
71    pub fn physics_group(&self) -> &Group {
72        self.groups
73            .iter()
74            .find(|group| group.is_physics_group())
75            .unwrap()
76    }
77
78    /// Returns a mutable reference to the physics group.
79    pub fn physics_group_mut(&mut self) -> &mut Group {
80        self.groups
81            .iter_mut()
82            .find(|group| group.is_physics_group())
83            .unwrap()
84    }
85}
86
87impl Group {
88    /// Checks if the group contains any physics layers.
89    pub fn is_physics_group(&self) -> bool {
90        self.layers
91            .iter()
92            .any(|layer| layer.kind().is_physics_layer())
93    }
94}
95
96impl From<ExternalImage> for Image {
97    fn from(image: ExternalImage) -> Self {
98        Image::External(image)
99    }
100}
101
102impl From<EmbeddedImage> for Image {
103    fn from(image: EmbeddedImage) -> Self {
104        Image::Embedded(image)
105    }
106}
107
108impl Image {
109    pub const fn name(&self) -> &String {
110        match self {
111            Image::External(img) => &img.name,
112            Image::Embedded(img) => &img.name,
113        }
114    }
115
116    pub fn name_mut(&mut self) -> &mut String {
117        match self {
118            Image::External(img) => &mut img.name,
119            Image::Embedded(img) => &mut img.name,
120        }
121    }
122
123    pub fn size(&self) -> Extent2<u32> {
124        match self {
125            Image::External(image) => image.size,
126            Image::Embedded(image) => image.image.size(),
127        }
128    }
129
130    pub const fn image(&self) -> Option<&CompressedData<RgbaImage, ImageLoadInfo>> {
131        match self {
132            Image::External(_) => None,
133            Image::Embedded(image) => Some(&image.image),
134        }
135    }
136
137    pub fn image_mut(&mut self) -> Option<&mut CompressedData<RgbaImage, ImageLoadInfo>> {
138        match self {
139            Image::External(_) => None,
140            Image::Embedded(image) => Some(&mut image.image),
141        }
142    }
143
144    pub fn for_tilemap(&self) -> bool {
145        let size = self.size();
146        size.w % 16 == 0 && size.h % 16 == 0
147    }
148}
149
150impl CompressedData<RgbaImage, ImageLoadInfo> {
151    pub(crate) fn size(&self) -> Extent2<u32> {
152        match self {
153            CompressedData::Compressed(_, _, info) => info.size,
154            CompressedData::Loaded(image) => Extent2::new(image.width(), image.height()),
155        }
156    }
157}
158
159impl LayerKind {
160    pub(crate) const fn static_name(&self) -> &'static str {
161        use LayerKind::*;
162        match self {
163            Game => "Game",
164            Front => "Front",
165            Tele => "Tele",
166            Speedup => "Speedup",
167            Switch => "Switch",
168            Tune => "Tune",
169            _ => panic!(),
170        }
171    }
172
173    pub const fn is_physics_layer(&self) -> bool {
174        use LayerKind::*;
175        match self {
176            Game | Front | Tele | Speedup | Switch | Tune => true,
177            Tiles | Quads | Sounds | Invalid(_) => false,
178        }
179    }
180
181    pub const fn is_tile_map_layer(&self) -> bool {
182        use LayerKind::*;
183        match self {
184            Game | Tiles | Front | Tele | Speedup | Switch | Tune => true,
185            Quads | Sounds | Invalid(_) => false,
186        }
187    }
188}
189
190impl<T> CompressedData<Array2<T>, TilesLoadInfo> {
191    /// Returns the (height, width) 2-dimensional array of tiles.
192    pub fn shape(&self) -> Extent2<usize> {
193        match self {
194            CompressedData::Compressed(_, _, info) => info.size.numcast().unwrap(),
195            CompressedData::Loaded(array) => Extent2::new(array.ncols(), array.nrows()),
196        }
197    }
198}
199
200impl Layer {
201    /// Returns an identifier for the type of the layer.
202    pub const fn kind(&self) -> LayerKind {
203        use Layer::*;
204        match self {
205            Game(_) => LayerKind::Game,
206            Tiles(_) => LayerKind::Tiles,
207            Quads(_) => LayerKind::Quads,
208            Front(_) => LayerKind::Front,
209            Tele(_) => LayerKind::Tele,
210            Speedup(_) => LayerKind::Speedup,
211            Switch(_) => LayerKind::Switch,
212            Tune(_) => LayerKind::Tune,
213            Sounds(_) => LayerKind::Sounds,
214            Invalid(kind) => LayerKind::Invalid(*kind),
215        }
216    }
217
218    /// Returns the (height, width) of the 2-dimensional array of tiles, if the contained layer is a tilemap layer.
219    pub fn shape(&self) -> Option<Extent2<usize>> {
220        use Layer::*;
221        match self {
222            Game(l) => Some(l.tiles().shape()),
223            Tiles(l) => Some(l.tiles().shape()),
224            Quads(_) => None,
225            Front(l) => Some(l.tiles().shape()),
226            Tele(l) => Some(l.tiles().shape()),
227            Speedup(l) => Some(l.tiles().shape()),
228            Switch(l) => Some(l.tiles().shape()),
229            Tune(l) => Some(l.tiles().shape()),
230            Sounds(_) => None,
231            Invalid(_) => None,
232        }
233    }
234}
235
236impl Quad {
237    /// Creates a rectangle quad at the specified position and size.
238    /// Except position and size, it uses the default values of a newly created quad in the editor.
239    pub fn new(position: Vec2<I17F15>, size: Extent2<I17F15>) -> Option<Self> {
240        let two: Extent2<I17F15> = Extent2::broadcast(2.to_fixed::<I17F15>());
241        let size_halfed: Vec2<I17F15> = size.checked_div(&two)?.into();
242        let add = I17F15::one();
243        let sub = -add;
244        Some(Quad {
245            corners: [
246                position.checked_add(&size_halfed.checked_mul(&(sub, sub).into())?)?,
247                position.checked_add(&size_halfed.checked_mul(&(add, sub).into())?)?,
248                position.checked_add(&size_halfed.checked_mul(&(sub, add).into())?)?,
249                position.checked_add(&size_halfed.checked_mul(&(add, add).into())?)?,
250            ],
251            position: Vec2::zero(),
252            colors: [Rgba::white(); 4],
253            texture_coords: [
254                Uv::new(0, 0).checked_cast()?,
255                Uv::new(1, 0).checked_cast()?,
256                Uv::new(0, 1).checked_cast()?,
257                Uv::new(1, 1).checked_cast()?,
258            ],
259            position_env: None,
260            position_env_offset: 0,
261            color_env: None,
262            color_env_offset: 0,
263        })
264    }
265}
266
267impl Default for Quad {
268    /// Default settings of a newly created quad in the editor
269    fn default() -> Self {
270        Quad::new(Vec2::zero(), Extent2::broadcast(I17F15::from_num(2))).unwrap()
271    }
272}
273
274impl SoundArea {
275    pub fn position(&self) -> Vec2<I17F15> {
276        match self {
277            SoundArea::Rectangle(rekt) => rekt.position(),
278            SoundArea::Circle(disk) => disk.center,
279        }
280    }
281
282    pub fn set_position(&mut self, position: Vec2<I17F15>) {
283        match self {
284            SoundArea::Rectangle(rekt) => rekt.set_position(position),
285            SoundArea::Circle(disk) => disk.center = position,
286        }
287    }
288}
289
290impl Default for SoundSource {
291    /// Default settings of a newly created sound source in the editor
292    fn default() -> Self {
293        SoundSource {
294            area: SoundArea::Circle(Disk::new(Vec2::zero(), I27F5::from_bits(1500))),
295            looping: true,
296            panning: true,
297            delay: 0,
298            falloff: 80,
299            position_env: None,
300            position_env_offset: 0,
301            sound_env: None,
302            sound_env_offset: 0,
303        }
304    }
305}
306
307impl<T, U> From<T> for CompressedData<T, U> {
308    fn from(data: T) -> Self {
309        CompressedData::Loaded(data)
310    }
311}
312
313impl<T, U> CompressedData<T, U> {
314    /// Returns a reference to the inner loaded value. Panics if isn't loaded.
315    pub const fn unwrap_ref(&self) -> &T {
316        match self {
317            CompressedData::Compressed(_, _, _) => {
318                panic!("Data is still compressed, reference unwrap unsuccessful")
319            }
320            CompressedData::Loaded(data) => data,
321        }
322    }
323
324    /// Returns a mutable reference to the inner loaded value. Panics if isn't loaded.
325    pub fn unwrap_mut(&mut self) -> &mut T {
326        match self {
327            CompressedData::Compressed(_, _, _) => {
328                panic!("Data is still compressed, mut reference unwrap unsuccessful")
329            }
330            CompressedData::Loaded(data) => data,
331        }
332    }
333
334    /// Returns the inner loaded value. Panics if isn't loaded.
335    pub fn unwrap(self) -> T {
336        match self {
337            CompressedData::Compressed(_, _, _) => {
338                panic!("Data is still compressed, unwrap unsuccessful")
339            }
340            CompressedData::Loaded(data) => data,
341        }
342    }
343}
344
345impl Envelope {
346    /// Returns a reference to the name of the envelope.
347    pub const fn name(&self) -> &String {
348        use Envelope::*;
349        match self {
350            Position(env) => &env.name,
351            Color(env) => &env.name,
352            Sound(env) => &env.name,
353        }
354    }
355
356    /// Returns a mutable reference to the name of the envelope.
357    pub fn name_mut(&mut self) -> &mut String {
358        use Envelope::*;
359        match self {
360            Position(env) => &mut env.name,
361            Color(env) => &mut env.name,
362            Sound(env) => &mut env.name,
363        }
364    }
365}
366
367impl Default for Group {
368    fn default() -> Self {
369        Group {
370            offset: Vec2::zero(),
371            parallax: Vec2::broadcast(100),
372            layers: Vec::new(),
373            clipping: false,
374            clip: Rect::default(),
375            name: String::new(),
376        }
377    }
378}
379
380impl Group {
381    /// Constructor for the physics group, make sure not to change any values apart from the layers
382    pub fn physics() -> Self {
383        Group {
384            name: String::from("Game"),
385            ..Group::default()
386        }
387    }
388}
389
390impl TilesLayer {
391    /// Creates a tiles layer with the default values and the specified dimensions.
392    pub fn new(shape: (usize, usize)) -> Self {
393        TilesLayer {
394            detail: false,
395            color: Rgba::white(),
396            color_env: None,
397            color_env_offset: 0,
398            image: None,
399            tiles: Array2::default(shape).into(),
400            name: "".to_string(),
401            automapper_config: AutomapperConfig::default(),
402        }
403    }
404}
405
406impl Layer {
407    /// Returns a reference to the name of the layer.
408    pub fn name(&self) -> &str {
409        use Layer::*;
410        match self {
411            Game(_) => LayerKind::Game.static_name(),
412            Tiles(l) => &l.name,
413            Quads(l) => &l.name,
414            Front(_) => LayerKind::Front.static_name(),
415            Tele(_) => LayerKind::Tele.static_name(),
416            Speedup(_) => LayerKind::Speedup.static_name(),
417            Switch(_) => LayerKind::Switch.static_name(),
418            Tune(_) => LayerKind::Tune.static_name(),
419            Sounds(l) => &l.name,
420            Invalid(_) => panic!(),
421        }
422    }
423
424    /// Returns a mutable reference to the name of the layer, if the layer type supports an editable name.
425    pub fn name_mut(&mut self) -> Option<&mut String> {
426        use Layer::*;
427        match self {
428            Game(_) => None,
429            Tiles(l) => Some(&mut l.name),
430            Quads(l) => Some(&mut l.name),
431            Front(_) => None,
432            Tele(_) => None,
433            Speedup(_) => None,
434            Switch(_) => None,
435            Tune(_) => None,
436            Sounds(l) => Some(&mut l.name),
437            Invalid(_) => panic!(),
438        }
439    }
440}
441
442impl Tile {
443    /// Constructor, required due to unused bytes which will be set to 0.
444    pub const fn new(id: u8, flags: TileFlags) -> Self {
445        Tile {
446            id,
447            flags,
448            skip: 0,
449            unused: 0,
450        }
451    }
452}
453
454impl GameTile {
455    /// Constructor, required due to unused bytes which will be set to 0.
456    pub const fn new(id: u8, flags: TileFlags) -> Self {
457        GameTile {
458            id,
459            flags,
460            skip: 0,
461            unused: 0,
462        }
463    }
464}
465
466impl Speedup {
467    /// Constructor, required due to unused bytes which will be set to 0.
468    pub fn new(id: u8, force: u8, max_speed: u8, angle: i16) -> Self {
469        Speedup {
470            force,
471            max_speed,
472            id,
473            unused_padding: 0,
474            angle: angle.into(),
475        }
476    }
477}
478
479impl From<i16> for I16 {
480    fn from(x: i16) -> Self {
481        I16 {
482            bytes: x.to_le_bytes(),
483        }
484    }
485}
486
487impl From<I16> for i16 {
488    fn from(x: I16) -> Self {
489        i16::from_le_bytes(x.bytes)
490    }
491}
492
493impl BezierDefault for Rgba<I22F10> {
494    fn bezier_default() -> Self {
495        Rgba::from(I22F10::from_bits(0))
496    }
497}
498
499impl BezierDefault for Position {}
500
501impl Default for Volume {
502    fn default() -> Self {
503        Volume(I22F10::from_num(1))
504    }
505}
506
507impl BezierDefault for Volume {
508    fn bezier_default() -> Self {
509        Self(I22F10::from_num(0))
510    }
511}
512
513impl TilemapLayer for TilesLayer {
514    type TileType = Tile;
515
516    fn tiles(&self) -> &CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
517        &self.tiles
518    }
519
520    fn tiles_mut(&mut self) -> &mut CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
521        &mut self.tiles
522    }
523}
524
525impl TilemapLayer for GameLayer {
526    type TileType = GameTile;
527
528    fn tiles(&self) -> &CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
529        &self.tiles
530    }
531
532    fn tiles_mut(&mut self) -> &mut CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
533        &mut self.tiles
534    }
535}
536
537impl TilemapLayer for FrontLayer {
538    type TileType = GameTile;
539
540    fn tiles(&self) -> &CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
541        &self.tiles
542    }
543
544    fn tiles_mut(&mut self) -> &mut CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
545        &mut self.tiles
546    }
547}
548
549impl TilemapLayer for TeleLayer {
550    type TileType = Tele;
551
552    fn tiles(&self) -> &CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
553        &self.tiles
554    }
555
556    fn tiles_mut(&mut self) -> &mut CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
557        &mut self.tiles
558    }
559}
560
561impl TilemapLayer for SpeedupLayer {
562    type TileType = Speedup;
563
564    fn tiles(&self) -> &CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
565        &self.tiles
566    }
567
568    fn tiles_mut(&mut self) -> &mut CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
569        &mut self.tiles
570    }
571}
572
573impl TilemapLayer for SwitchLayer {
574    type TileType = Switch;
575
576    fn tiles(&self) -> &CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
577        &self.tiles
578    }
579
580    fn tiles_mut(&mut self) -> &mut CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
581        &mut self.tiles
582    }
583}
584
585impl TilemapLayer for TuneLayer {
586    type TileType = Tune;
587
588    fn tiles(&self) -> &CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
589        &self.tiles
590    }
591
592    fn tiles_mut(&mut self) -> &mut CompressedData<Array2<Self::TileType>, TilesLoadInfo> {
593        &mut self.tiles
594    }
595}
596
597impl AnyTile for Tile {
598    fn id(&self) -> u8 {
599        self.id
600    }
601
602    fn id_mut(&mut self) -> &mut u8 {
603        &mut self.id
604    }
605
606    fn flags(&self) -> Option<TileFlags> {
607        Some(self.flags)
608    }
609
610    fn flags_mut(&mut self) -> Option<&mut TileFlags> {
611        Some(&mut self.flags)
612    }
613}
614
615impl AnyTile for GameTile {
616    fn id(&self) -> u8 {
617        self.id
618    }
619
620    fn id_mut(&mut self) -> &mut u8 {
621        &mut self.id
622    }
623
624    fn flags(&self) -> Option<TileFlags> {
625        Some(self.flags)
626    }
627
628    fn flags_mut(&mut self) -> Option<&mut TileFlags> {
629        Some(&mut self.flags)
630    }
631}
632
633impl AnyTile for Switch {
634    fn id(&self) -> u8 {
635        self.id
636    }
637
638    fn id_mut(&mut self) -> &mut u8 {
639        &mut self.id
640    }
641
642    fn flags(&self) -> Option<TileFlags> {
643        Some(self.flags)
644    }
645
646    fn flags_mut(&mut self) -> Option<&mut TileFlags> {
647        Some(&mut self.flags)
648    }
649}
650
651impl AnyTile for Tele {
652    fn id(&self) -> u8 {
653        self.id
654    }
655
656    fn id_mut(&mut self) -> &mut u8 {
657        &mut self.id
658    }
659
660    fn flags(&self) -> Option<TileFlags> {
661        None
662    }
663
664    fn flags_mut(&mut self) -> Option<&mut TileFlags> {
665        None
666    }
667}
668
669impl AnyTile for Speedup {
670    fn id(&self) -> u8 {
671        self.id
672    }
673
674    fn id_mut(&mut self) -> &mut u8 {
675        &mut self.id
676    }
677
678    fn flags(&self) -> Option<TileFlags> {
679        None
680    }
681
682    fn flags_mut(&mut self) -> Option<&mut TileFlags> {
683        None
684    }
685}
686
687impl AnyTile for Tune {
688    fn id(&self) -> u8 {
689        self.id
690    }
691
692    fn id_mut(&mut self) -> &mut u8 {
693        &mut self.id
694    }
695
696    fn flags(&self) -> Option<TileFlags> {
697        None
698    }
699
700    fn flags_mut(&mut self) -> Option<&mut TileFlags> {
701        None
702    }
703}
704
705impl AnyLayer for GameLayer {
706    fn kind() -> LayerKind {
707        LayerKind::Game
708    }
709
710    fn get(layer: &Layer) -> Option<&Self> {
711        if let Layer::Game(l) = layer {
712            Some(l)
713        } else {
714            None
715        }
716    }
717
718    fn get_mut(layer: &mut Layer) -> Option<&mut Self> {
719        if let Layer::Game(l) = layer {
720            Some(l)
721        } else {
722            None
723        }
724    }
725}
726
727impl AnyLayer for TilesLayer {
728    fn kind() -> LayerKind {
729        LayerKind::Tiles
730    }
731
732    fn get(layer: &Layer) -> Option<&Self> {
733        if let Layer::Tiles(l) = layer {
734            Some(l)
735        } else {
736            None
737        }
738    }
739
740    fn get_mut(layer: &mut Layer) -> Option<&mut Self> {
741        if let Layer::Tiles(l) = layer {
742            Some(l)
743        } else {
744            None
745        }
746    }
747}
748
749impl AnyLayer for QuadsLayer {
750    fn kind() -> LayerKind {
751        LayerKind::Quads
752    }
753
754    fn get(layer: &Layer) -> Option<&Self> {
755        if let Layer::Quads(l) = layer {
756            Some(l)
757        } else {
758            None
759        }
760    }
761
762    fn get_mut(layer: &mut Layer) -> Option<&mut Self> {
763        if let Layer::Quads(l) = layer {
764            Some(l)
765        } else {
766            None
767        }
768    }
769}
770
771impl AnyLayer for FrontLayer {
772    fn kind() -> LayerKind {
773        LayerKind::Front
774    }
775
776    fn get(layer: &Layer) -> Option<&Self> {
777        if let Layer::Front(l) = layer {
778            Some(l)
779        } else {
780            None
781        }
782    }
783
784    fn get_mut(layer: &mut Layer) -> Option<&mut Self> {
785        if let Layer::Front(l) = layer {
786            Some(l)
787        } else {
788            None
789        }
790    }
791}
792
793impl AnyLayer for TeleLayer {
794    fn kind() -> LayerKind {
795        LayerKind::Tele
796    }
797
798    fn get(layer: &Layer) -> Option<&Self> {
799        if let Layer::Tele(l) = layer {
800            Some(l)
801        } else {
802            None
803        }
804    }
805
806    fn get_mut(layer: &mut Layer) -> Option<&mut Self> {
807        if let Layer::Tele(l) = layer {
808            Some(l)
809        } else {
810            None
811        }
812    }
813}
814
815impl AnyLayer for SpeedupLayer {
816    fn kind() -> LayerKind {
817        LayerKind::Speedup
818    }
819
820    fn get(layer: &Layer) -> Option<&Self> {
821        if let Layer::Speedup(l) = layer {
822            Some(l)
823        } else {
824            None
825        }
826    }
827
828    fn get_mut(layer: &mut Layer) -> Option<&mut Self> {
829        if let Layer::Speedup(l) = layer {
830            Some(l)
831        } else {
832            None
833        }
834    }
835}
836
837impl AnyLayer for SwitchLayer {
838    fn kind() -> LayerKind {
839        LayerKind::Switch
840    }
841
842    fn get(layer: &Layer) -> Option<&Self> {
843        if let Layer::Switch(l) = layer {
844            Some(l)
845        } else {
846            None
847        }
848    }
849
850    fn get_mut(layer: &mut Layer) -> Option<&mut Self> {
851        if let Layer::Switch(l) = layer {
852            Some(l)
853        } else {
854            None
855        }
856    }
857}
858
859impl AnyLayer for TuneLayer {
860    fn kind() -> LayerKind {
861        LayerKind::Tune
862    }
863
864    fn get(layer: &Layer) -> Option<&Self> {
865        if let Layer::Tune(l) = layer {
866            Some(l)
867        } else {
868            None
869        }
870    }
871
872    fn get_mut(layer: &mut Layer) -> Option<&mut Self> {
873        if let Layer::Tune(l) = layer {
874            Some(l)
875        } else {
876            None
877        }
878    }
879}
880
881impl AnyLayer for SoundsLayer {
882    fn kind() -> LayerKind {
883        LayerKind::Sounds
884    }
885
886    fn get(layer: &Layer) -> Option<&Self> {
887        if let Layer::Sounds(l) = layer {
888            Some(l)
889        } else {
890            None
891        }
892    }
893
894    fn get_mut(layer: &mut Layer) -> Option<&mut Self> {
895        if let Layer::Sounds(l) = layer {
896            Some(l)
897        } else {
898            None
899        }
900    }
901}
902
903impl PhysicsLayer for GameLayer {}
904impl PhysicsLayer for FrontLayer {}
905impl PhysicsLayer for TeleLayer {}
906impl PhysicsLayer for SpeedupLayer {}
907impl PhysicsLayer for SwitchLayer {}
908impl PhysicsLayer for TuneLayer {}