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}