luminol_data/shared/
event.rs

1// Copyright (C) 2024 Melody Madeline Lyons
2//
3// This file is part of Luminol.
4//
5// Luminol is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Luminol is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Luminol.  If not, see <http://www.gnu.org/licenses/>.
17use crate::{
18    id_alox, id_serde, optional_id_alox, optional_id_serde, optional_path_alox,
19    optional_path_serde, rpg::MoveRoute, BlendMode, ParameterType, Path,
20};
21
22#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
23#[derive(alox_48::Deserialize, alox_48::Serialize)]
24#[marshal(class = "RPG::Event")]
25pub struct Event {
26    // #[serde(with = "id_serde")]
27    // #[marshal(with = "id_alox")]
28    pub id: usize,
29    pub name: String,
30    pub x: i32,
31    pub y: i32,
32    pub pages: Vec<EventPage>,
33
34    #[serde(skip)]
35    #[marshal(skip)]
36    pub extra_data: EventExtraData,
37}
38
39#[derive(Debug, Default, Clone)]
40pub struct EventExtraData {
41    /// Whether or not the event editor for this event is open
42    pub is_editor_open: bool,
43    pub graphic_modified: std::cell::Cell<bool>,
44}
45
46impl Event {
47    #[must_use]
48    pub fn new(x: i32, y: i32, id: usize) -> Self {
49        Self {
50            id,
51            name: format!("EV{id:0>3}"),
52            x,
53            y,
54            pages: vec![EventPage::default()],
55
56            extra_data: EventExtraData::default(),
57        }
58    }
59}
60
61#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)]
62#[derive(alox_48::Deserialize, alox_48::Serialize)]
63#[marshal(class = "RPG::CommonEvent")]
64pub struct CommonEvent {
65    #[serde(with = "id_serde")]
66    #[marshal(with = "id_alox")]
67    pub id: usize,
68    pub name: String,
69    pub trigger: usize,
70    pub switch_id: usize,
71    pub list: Vec<EventCommand>,
72}
73
74#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
75#[derive(alox_48::Deserialize, alox_48::Serialize)]
76#[marshal(class = "RPG::Event::Page")]
77pub struct EventPage {
78    pub condition: EventCondition,
79    pub graphic: Graphic,
80    pub move_type: MoveType,
81    pub move_speed: MoveSpeed,
82    pub move_frequency: MoveFreq,
83    pub move_route: MoveRoute,
84    pub walk_anime: bool,
85    pub step_anime: bool,
86    pub direction_fix: bool,
87    pub through: bool,
88    pub always_on_top: bool,
89    pub trigger: EventTrigger,
90    pub list: Vec<EventCommand>,
91}
92
93#[derive(serde::Deserialize, serde::Serialize)]
94#[derive(alox_48::Deserialize, alox_48::Serialize)]
95#[derive(Debug, Clone, Copy, PartialEq)]
96#[derive(num_enum::TryFromPrimitive, num_enum::IntoPrimitive)]
97#[derive(strum::Display, strum::EnumIter)]
98#[serde(try_from = "u8", into = "u8")]
99#[marshal(try_from = "u8", into = "u8")]
100#[repr(u8)]
101pub enum EventTrigger {
102    #[strum(to_string = "Action Button")]
103    ActionButton,
104    #[strum(to_string = "Player Touch")]
105    PlayerTouch,
106    #[strum(to_string = "Event Touch")]
107    EventTouch,
108    #[strum(to_string = "Autorun")]
109    Autorun,
110    #[strum(to_string = "Parallel Process")]
111    Parallel,
112}
113
114#[derive(serde::Deserialize, serde::Serialize)]
115#[derive(alox_48::Deserialize, alox_48::Serialize)]
116#[derive(Debug, Clone, Copy, PartialEq)]
117#[derive(num_enum::TryFromPrimitive, num_enum::IntoPrimitive)]
118#[derive(strum::Display, strum::EnumIter)]
119#[serde(try_from = "u8", into = "u8")]
120#[marshal(try_from = "u8", into = "u8")]
121#[repr(u8)]
122pub enum MoveType {
123    Fixed,
124    Random,
125    Approach,
126    Custom,
127}
128
129#[derive(serde::Deserialize, serde::Serialize)]
130#[derive(alox_48::Deserialize, alox_48::Serialize)]
131#[derive(Debug, Clone, Copy, PartialEq)]
132#[derive(num_enum::TryFromPrimitive, num_enum::IntoPrimitive)]
133#[derive(strum::Display, strum::EnumIter)]
134#[serde(try_from = "u8", into = "u8")]
135#[marshal(try_from = "u8", into = "u8")]
136#[repr(u8)]
137pub enum MoveFreq {
138    Lowest = 1,
139    Lower,
140    Low,
141    High,
142    Higher,
143    Highest,
144}
145
146#[derive(serde::Deserialize, serde::Serialize)]
147#[derive(alox_48::Deserialize, alox_48::Serialize)]
148#[derive(Debug, Clone, Copy, PartialEq)]
149#[derive(num_enum::TryFromPrimitive, num_enum::IntoPrimitive)]
150#[derive(strum::Display, strum::EnumIter)]
151#[serde(try_from = "u8", into = "u8")]
152#[marshal(try_from = "u8", into = "u8")]
153#[repr(u8)]
154pub enum MoveSpeed {
155    Slowest = 1,
156    Slower,
157    Slow,
158    Fast,
159    Faster,
160    Fastest,
161}
162
163impl Default for EventPage {
164    fn default() -> Self {
165        Self {
166            condition: EventCondition::default(),
167            graphic: Graphic::default(),
168            move_type: MoveType::Fixed,
169            move_speed: MoveSpeed::Slow,
170            move_frequency: MoveFreq::Low,
171            move_route: MoveRoute::default(),
172            walk_anime: true,
173            step_anime: false,
174            direction_fix: false,
175            through: false,
176            always_on_top: false,
177            trigger: EventTrigger::ActionButton,
178            list: vec![],
179        }
180    }
181}
182
183#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
184#[derive(alox_48::Deserialize, alox_48::Serialize)]
185#[marshal(class = "RPG::Event::Page::Graphic")]
186pub struct Graphic {
187    #[serde(with = "optional_id_serde")]
188    #[marshal(with = "optional_id_alox")]
189    pub tile_id: Option<usize>,
190    #[serde(with = "optional_path_serde")]
191    #[marshal(with = "optional_path_alox")]
192    pub character_name: Path,
193    pub character_hue: i32,
194    pub direction: i32,
195    pub pattern: i32,
196    pub opacity: i32,
197    pub blend_type: BlendMode,
198}
199
200impl Default for Graphic {
201    fn default() -> Self {
202        Self {
203            tile_id: None,
204            character_name: None,
205            character_hue: 0,
206            direction: 2,
207            pattern: 0,
208            opacity: 255,
209            blend_type: BlendMode::Normal,
210        }
211    }
212}
213
214#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
215#[derive(alox_48::Deserialize, alox_48::Serialize)]
216#[marshal(class = "RPG::Event::Page::Condition")]
217pub struct EventCondition {
218    pub switch1_valid: bool,
219    pub switch2_valid: bool,
220    pub variable_valid: bool,
221    pub self_switch_valid: bool,
222    #[serde(with = "id_serde")]
223    #[marshal(with = "id_alox")]
224    pub switch1_id: usize,
225    #[serde(with = "id_serde")]
226    #[marshal(with = "id_alox")]
227    pub switch2_id: usize,
228    #[serde(with = "id_serde")]
229    #[marshal(with = "id_alox")]
230    pub variable_id: usize,
231    pub variable_value: i32,
232    pub self_switch_ch: SelfSwitch,
233}
234
235impl Default for EventCondition {
236    fn default() -> Self {
237        Self {
238            switch1_valid: false,
239            switch2_valid: false,
240            variable_valid: false,
241            self_switch_valid: false,
242            switch1_id: 0,
243            switch2_id: 0,
244            variable_id: 0,
245            variable_value: 0,
246            self_switch_ch: SelfSwitch::A,
247        }
248    }
249}
250
251#[derive(serde::Deserialize, serde::Serialize)]
252#[derive(alox_48::Deserialize, alox_48::Serialize)]
253#[derive(Debug, Clone, Copy, PartialEq)]
254#[derive(strum::Display, strum::EnumIter)]
255#[serde(from = "String", into = "String")]
256#[marshal(from = "String", into = "String")]
257pub enum SelfSwitch {
258    A,
259    B,
260    C,
261    D,
262}
263
264impl From<String> for SelfSwitch {
265    fn from(value: String) -> Self {
266        match value.as_str() {
267            "A" => Self::A,
268            "B" => Self::B,
269            "C" => Self::C,
270            "D" => Self::D,
271            _ => panic!("wrong value for self switch"),
272        }
273    }
274}
275
276impl From<SelfSwitch> for String {
277    fn from(val: SelfSwitch) -> Self {
278        match val {
279            SelfSwitch::A => "A".to_string(),
280            SelfSwitch::B => "B".to_string(),
281            SelfSwitch::C => "C".to_string(),
282            SelfSwitch::D => "D".to_string(),
283        }
284    }
285}
286
287#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
288#[derive(alox_48::Deserialize, alox_48::Serialize)]
289#[allow(missing_docs)]
290#[marshal(class = "RPG::EventCommand")]
291pub struct EventCommand {
292    pub code: u16,
293    pub indent: usize,
294    pub parameters: Vec<ParameterType>,
295
296    #[marshal(default = "rand::random")]
297    #[marshal(skip)]
298    #[serde(default = "rand::random")]
299    #[serde(skip)]
300    pub guid: u16,
301}