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}