wolfrpg_map_parser/
map.rs

1#[cfg(feature = "serde")]
2use serde::{Serialize, Deserialize};
3use crate::byte_utils::{as_u32_vec, as_u32_le};
4use crate::event::Event;
5
6const MAP_SIGNATURE: &[u8]
7    = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x4F\x4C\x46\x4D\x00\x00\x00\x00\x00";
8
9/// A Wolf RPG Editor map (.mps) file.
10///
11/// Contains all information needed for rendering a level, from the single tiles to the events
12/// set to happen.
13///
14/// # Examples
15/// ```
16/// use wolfrpg_map_parser::Map;
17/// use std::fs;
18///
19/// match fs::read("filepath.mps") {
20///     Ok(bytes) => {
21///         let map: Map = Map::parse(&bytes);
22///         // Data manipulation ...
23///     }
24///     Err(_) => {
25///         // Error handling ...
26///     }
27/// }
28/// ```
29#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
30#[derive(PartialEq, Clone)]
31pub struct Map {
32    tileset: u32,
33    width: u32,
34    height: u32,
35    layer1: Vec<u32>,
36    layer2: Vec<u32>,
37    layer3: Vec<u32>,
38    events: Vec<Event>,
39}
40
41impl Map {
42    /// Parse raw bytes into a [`Map`] struct.
43    ///
44    /// This is the main driver that should be used when loading a .mps file. Using other methods is
45    /// highly discouraged, unless you know what you are doing and need that extra bit of speed.
46    ///
47    /// # Panics
48    /// This function will panic if the given bytes do not represent a valid map structure.
49    ///
50    /// This might be caused by corrupt files, incompatible format updates and library bugs.
51    /// In each of these cases, feel free to report an issue on [GitHub].
52    ///
53    /// [GitHub]: https://github.com/G1org1owo/wolfrpg-map-parser/issues
54    ///
55    /// # Examples
56    /// ```
57    /// use wolfrpg_map_parser::Map;
58    /// use std::fs;
59    ///
60    /// match fs::read("filepath.mps") {
61    ///     Ok(bytes) => {
62    ///         let map: Map = Map::parse(&bytes);
63    ///         // Data manipulation ...
64    ///     }
65    ///     Err(_) => {
66    ///         // Error handling ...
67    ///     }
68    /// }
69    /// ```
70    pub fn parse(bytes: &[u8]) -> Self {
71        let mut offset: usize = 0;
72
73        let magic: &[u8] = &bytes[offset..offset+20];
74        offset += 20;
75
76        if magic != MAP_SIGNATURE {
77            panic!("Invalid WOLF map signature.");
78        }
79
80        offset += 5; // Unknown data
81
82        let skippable: usize = as_u32_le(&bytes[offset..offset+4]) as usize;
83        offset += 4;
84        offset += skippable;
85
86        let tileset: u32 = as_u32_le(&bytes[offset..offset+4]);
87        offset += 4;
88
89        let width: u32 = as_u32_le(&bytes[offset..offset+4]);
90        offset += 4;
91
92        let height: u32 = as_u32_le(&bytes[offset..offset+4]);
93        offset += 4;
94
95        let event_count: u32 = as_u32_le(&bytes[offset..offset+4]);
96        offset += 4;
97
98        let layer_length: usize = (width * height * 4) as usize;
99        let layer1: Vec<u32> = as_u32_vec(
100            &bytes[offset..offset + layer_length],
101        );
102        offset += layer_length;
103
104        let layer2: Vec<u32> = as_u32_vec(
105            &bytes[offset..offset + layer_length]
106        );
107        offset += layer_length;
108
109        let layer3: Vec<u32> = as_u32_vec(
110            &bytes[offset..offset + layer_length]
111        );
112        offset += layer_length;
113
114        let (bytes_read, events): (usize, Vec<Event>)
115            = Event::parse_multiple(&bytes[offset..], event_count);
116        offset += bytes_read;
117
118        let map_end: u8 = bytes[offset];
119
120        if map_end != 0x66 {
121            panic!("Expected map end but found {:02x}.", map_end);
122        }
123
124        Self {
125            tileset,
126            width,
127            height,
128            layer1,
129            layer2,
130            layer3,
131            events
132        }
133    }
134
135    /// The ID of the set of pictures used for each tile.
136    pub fn tileset(&self) -> u32 {
137        self.tileset
138    }
139
140    /// Mutable reference accessor for [`Map::tileset`].
141    pub fn tileset_mut(&mut self) -> &mut u32 {
142        &mut self.tileset
143    }
144
145    /// The width of the map, in tiles.
146    pub fn width(&self) -> u32 {
147        self.width
148    }
149
150    /// Mutable reference accessor for [`Map::width`].
151    pub fn width_mut(&mut self) -> &mut u32 {
152        &mut self.width
153    }
154
155    /// The height of the map, in tiles.
156    pub fn height(&self) -> u32 {
157        self.height
158    }
159
160    /// Mutable reference accessor for [`Map::height`].
161    pub fn height_mut(&mut self) -> &mut u32 {
162        &mut self.height
163    }
164
165    /// The bottom-most layer of tiles.
166    ///
167    /// Each layer is painted above the lower ones.
168    pub fn layer1(&self) -> &Vec<u32> {
169        &self.layer1
170    }
171
172    /// Mutable reference accessor for [`Map::layer1`].
173    pub fn layer1_mut(&mut self) -> &mut Vec<u32> {
174        &mut self.layer1
175    }
176
177    /// The middle layer of tiles.
178    ///
179    /// Each layer is painted above the lower ones.
180    pub fn layer2(&self) -> &Vec<u32> {
181        &self.layer2
182    }
183
184    /// Mutable reference accessor for [`Map::layer2`].
185    pub fn layer2_mut(&mut self) -> &mut Vec<u32> {
186        &mut self.layer2
187    }
188
189    /// The top-most layer of tiles.
190    ///
191    /// Each layer is painted above the lower ones.
192    pub fn layer3(&self) -> &Vec<u32> {
193        &self.layer3
194    }
195
196    /// Mutable reference accessor for [`Map::layer3`].
197    pub fn layer3_mut(&mut self) -> &mut Vec<u32> {
198        &mut self.layer3
199    }
200
201    /// A collection of all the events set on this map.
202    ///
203    /// Events are painted above each other based on the following priority:
204    /// 1. If [`Page::options::above_hero`] is `true`, then the event has the highest priority.
205    /// 2. If [`Page::options::above_hero`] is `false` and [`Page::options::slip_through`] is `false`,
206    ///     then the event has the second-highest priority.
207    /// 3. if [`Page::options::above_hero`] is `false` and [`Page::options::slip_through`] is `true`,
208    ///     then the event has the lowest-priority.
209    ///
210    /// When events have the same priority, they are displayed in order of [`Event::id`].
211    ///
212    /// [`Page::options::above_hero`]: (event::page::options::Options::above_hero)
213    /// [`Page::options::slip_through`]: (event::page::options::Options::slip_through)
214    pub fn events(&self) -> &Vec<Event> {
215        &self.events
216    }
217
218    /// Mutable reference accessor for [`Map::events`].
219    pub fn events_mut(&mut self) -> &mut Vec<Event> {
220        &mut self.events
221    }
222}