wolfrpg_map_parser/event.rs
1use crate::byte_utils::{as_u32_be, as_u32_le, parse_string};
2use crate::page::Page;
3#[cfg(feature = "serde")]
4use serde::{Serialize, Deserialize};
5
6const EVENT_SIGNATURE: u32 = 0x6f393000;
7
8/// An event on a specific map.
9///
10/// An event is any NPC or item that can interact with the player or can be interacted with.
11/// This struct contains detailed information about the position of the event and one or more pages
12/// containing extra details on how to render the event, plus the scripts related to this event.
13#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14#[derive(PartialEq, Clone)]
15#[allow(unused)]
16pub struct Event {
17 id: u32,
18 name: String,
19 position_x: u32,
20 position_y: u32,
21 unknown1: u32,
22 pages: Vec<Page>
23}
24
25impl Event {
26 /// Parse raw bytes into a single [`Event`] struct.
27 ///
28 /// Use of this method is highly discouraged unless you know exactly what you are doing.
29 /// Prefer using [`Map::parse`] and then extract what you want from the structure tree.
30 ///
31 /// # Panics
32 /// This function will panic if the given bytes do not represent a valid event structure.
33 ///
34 /// This might be caused by unaligned bytes, corrupt files, incompatible format updates and
35 /// library bugs.
36 /// If you are confident you are doing everything right, feel free to report an issue on [GitHub].
37 ///
38 /// [`Map::parse`]: crate::map::Map::parse
39 /// [GitHub]: https://github.com/G1org1owo/wolfrpg-map-parser/issues
40 pub fn parse(bytes: &[u8]) -> (usize, Self) {
41 let mut offset: usize = 0;
42
43 let signature: u32 = as_u32_be(&bytes[offset..offset + 4]);
44 offset += 4;
45
46 if signature != EVENT_SIGNATURE {
47 panic!("Invalid event signature: {:02x}.", signature);
48 }
49
50 offset += 1; // padding
51
52 let id: u32 = as_u32_le(&bytes[offset..offset+4]);
53 offset += 4;
54
55 let (bytes_read, name): (usize, String) = parse_string(&bytes[offset..]);
56 offset += bytes_read;
57
58 let position_x: u32 = as_u32_le(&bytes[offset..offset+4]);
59 offset += 4;
60
61 let position_y: u32 = as_u32_le(&bytes[offset..offset+4]);
62 offset += 4;
63
64 let page_count: u32 = as_u32_le(&bytes[offset..offset+4]);
65 offset += 4;
66
67 let unknown1: u32 = as_u32_le(&bytes[offset..offset+4]);
68 offset += 4;
69
70 let mut pages: Vec<Page> = vec![];
71 for _ in 0..page_count {
72 let (bytes_read, page): (usize, Page) = Page::parse(&bytes[offset..]);
73 offset += bytes_read;
74 pages.push(page);
75 }
76
77 let event_end: u8 = bytes[offset];
78 offset += 1;
79
80 if event_end != 0x70 {
81 panic!("Expected event end but found {:02x}.", event_end);
82 }
83
84 (offset, Self {
85 id,
86 name,
87 position_x,
88 position_y,
89 unknown1,
90 pages,
91 })
92 }
93
94 /// Parse raw bytes into an [`Event`] collection.
95 ///
96 /// Use of this method is highly discouraged unless you know exactly what you are doing.
97 /// Prefer using [`Map::parse`] and then extract what you want from the structure tree.
98 ///
99 /// # Panics
100 /// This function will panic if the given bytes do not represent a valid event list structure.
101 ///
102 /// This might be caused by unaligned bytes, corrupt files, incompatible format updates and
103 /// library bugs.
104 /// If you are confident you are doing everything right, feel free to report an issue on [GitHub].
105 ///
106 /// [`Map::parse`]: crate::map::Map::parse
107 /// [GitHub]: https://github.com/G1org1owo/wolfrpg-map-parser/issues
108 pub fn parse_multiple(bytes: &[u8], count: u32) -> (usize, Vec<Self>) {
109 let mut offset: usize = 0;
110 let mut events: Vec<Event> = Vec::new();
111
112 for _ in 0..count {
113 let (bytes_read, event): (usize, Self) = Self::parse(&bytes[offset..]);
114
115 offset += bytes_read;
116 events.push(event);
117 }
118
119 (offset, events)
120 }
121
122 /// The unique identifier of this event.
123 pub fn id(&self) -> u32 {
124 self.id
125 }
126
127 /// The name of this event.
128 ///
129 /// This is only useful to recognize different events from a programming standpoint and is not
130 /// shown in game whatsoever.
131 pub fn name(&self) -> &str {
132 &self.name
133 }
134
135 /// Mutable reference accessor for [`Event::name`] .
136 pub fn name_mut(&mut self) -> &mut String {
137 &mut self.name
138 }
139
140 /// The x coordinate of this event, in tiles.
141 pub fn position_x(&self) -> u32 {
142 self.position_x
143 }
144
145 /// Mutable reference accessor for [`Event::position_x`].
146 pub fn position_x_mut(&mut self) -> &mut u32 {
147 &mut self.position_x
148 }
149
150 /// The y coordinate of this event, in tiles.
151 pub fn position_y(&self) -> u32 {
152 self.position_y
153 }
154
155 /// Mutable reference accessor for [`Event::position_y`].
156 pub fn position_y_mut(&mut self) -> &mut u32 {
157 &mut self.position_y
158 }
159
160 /// A collection of pages representing the different states this event can be in.
161 ///
162 /// Each event can have up to ten pages describing its behaviour. The page that is actually run
163 /// is the one with the highest index that meets the requirements of its [`Page::event_trigger`]
164 /// and [`Page::conditions`] fields.
165 pub fn pages(&self) -> &Vec<Page> {
166 &self.pages
167 }
168
169 /// Mutable reference accessor for [`Event::pages`].
170 pub fn pages_mut(&mut self) -> &mut Vec<Page> {
171 &mut self.pages
172 }
173}