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 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 pub fn physics_group(&self) -> &Group {
72 self.groups
73 .iter()
74 .find(|group| group.is_physics_group())
75 .unwrap()
76 }
77
78 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 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 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 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 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 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 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 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 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 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 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 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 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 pub fn physics() -> Self {
383 Group {
384 name: String::from("Game"),
385 ..Group::default()
386 }
387 }
388}
389
390impl TilesLayer {
391 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 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 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 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 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 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 {}