rpgmxp_types/
event_page.rs

1use crate::EventCommand;
2use crate::EventPageCondition;
3use crate::EventPageGraphic;
4use crate::MoveRoute;
5use ruby_marshal::FromValue;
6use ruby_marshal::FromValueContext;
7use ruby_marshal::FromValueError;
8use ruby_marshal::IntoValue;
9use ruby_marshal::IntoValueError;
10use ruby_marshal::ObjectValue;
11use ruby_marshal::SymbolValue;
12use ruby_marshal::Value;
13use ruby_marshal::ValueArena;
14use ruby_marshal::ValueHandle;
15
16const OBJECT_NAME: &[u8] = b"RPG::Event::Page";
17
18const MOVE_TYPE_FIELD: &[u8] = b"@move_type";
19const LIST_FIELD: &[u8] = b"@list";
20const CONDITION_FIELD: &[u8] = b"@condition";
21const DIRECTION_FIX_FIELD: &[u8] = b"@direction_fix";
22const MOVE_ROUTE_FIELD: &[u8] = b"@move_route";
23const TRIGGER_FIELD: &[u8] = b"@trigger";
24const STEP_ANIME_FIELD: &[u8] = b"@step_anime";
25const MOVE_FREQUENCY_FIELD: &[u8] = b"@move_frequency";
26const GRAPHIC_FIELD: &[u8] = b"@graphic";
27const ALWAYS_ON_TOP_FIELD: &[u8] = b"@always_on_top";
28const WALK_ANIME_FIELD: &[u8] = b"@walk_anime";
29const MOVE_SPEED_FIELD: &[u8] = b"@move_speed";
30const THROUGH_FIELD: &[u8] = b"@through";
31
32#[derive(Debug, serde::Deserialize, serde::Serialize)]
33pub struct EventPage {
34    pub move_type: i32,
35    pub list: Vec<EventCommand>,
36    pub condition: EventPageCondition,
37    pub direction_fix: bool,
38    pub move_route: MoveRoute,
39    pub trigger: i32,
40    pub step_anime: bool,
41    pub move_frequency: i32,
42    pub graphic: EventPageGraphic,
43    pub always_on_top: bool,
44    pub walk_anime: bool,
45    pub move_speed: i32,
46    pub through: bool,
47}
48
49impl<'a> FromValue<'a> for EventPage {
50    fn from_value(ctx: &FromValueContext<'a>, value: &Value) -> Result<Self, FromValueError> {
51        let object: &ObjectValue = FromValue::from_value(ctx, value)?;
52        let name = object.name();
53        let name: &SymbolValue = ctx.from_value(name.into())?;
54        let name = name.value();
55        if name != OBJECT_NAME {
56            return Err(FromValueError::UnexpectedObjectName { name: name.into() });
57        }
58
59        let instance_variables = object.instance_variables();
60
61        let mut move_type_field = None;
62        let mut list_field = None;
63        let mut condition_field = None;
64        let mut direction_fix_field = None;
65        let mut move_route_field = None;
66        let mut trigger_field = None;
67        let mut step_anime_field = None;
68        let mut move_frequency_field = None;
69        let mut graphic_field = None;
70        let mut always_on_top_field = None;
71        let mut walk_anime_field = None;
72        let mut move_speed_field = None;
73        let mut through_field = None;
74
75        for (key, value) in instance_variables.iter().copied() {
76            let key: &SymbolValue = ctx.from_value(key.into())?;
77            let key = key.value();
78
79            match key {
80                MOVE_TYPE_FIELD => {
81                    if move_type_field.is_some() {
82                        return Err(FromValueError::DuplicateInstanceVariable {
83                            name: MOVE_TYPE_FIELD.into(),
84                        });
85                    }
86
87                    move_type_field = Some(ctx.from_value(value)?);
88                }
89                LIST_FIELD => {
90                    if list_field.is_some() {
91                        return Err(FromValueError::DuplicateInstanceVariable {
92                            name: LIST_FIELD.into(),
93                        });
94                    }
95
96                    list_field = Some(ctx.from_value(value)?);
97                }
98                CONDITION_FIELD => {
99                    if condition_field.is_some() {
100                        return Err(FromValueError::DuplicateInstanceVariable {
101                            name: CONDITION_FIELD.into(),
102                        });
103                    }
104
105                    condition_field = Some(ctx.from_value(value)?);
106                }
107                DIRECTION_FIX_FIELD => {
108                    if direction_fix_field.is_some() {
109                        return Err(FromValueError::DuplicateInstanceVariable {
110                            name: DIRECTION_FIX_FIELD.into(),
111                        });
112                    }
113
114                    direction_fix_field = Some(ctx.from_value(value)?);
115                }
116                MOVE_ROUTE_FIELD => {
117                    if move_route_field.is_some() {
118                        return Err(FromValueError::DuplicateInstanceVariable {
119                            name: MOVE_ROUTE_FIELD.into(),
120                        });
121                    }
122
123                    move_route_field = Some(ctx.from_value(value)?);
124                }
125                TRIGGER_FIELD => {
126                    if trigger_field.is_some() {
127                        return Err(FromValueError::DuplicateInstanceVariable {
128                            name: TRIGGER_FIELD.into(),
129                        });
130                    }
131
132                    trigger_field = Some(ctx.from_value(value)?);
133                }
134                STEP_ANIME_FIELD => {
135                    if step_anime_field.is_some() {
136                        return Err(FromValueError::DuplicateInstanceVariable {
137                            name: STEP_ANIME_FIELD.into(),
138                        });
139                    }
140
141                    step_anime_field = Some(ctx.from_value(value)?);
142                }
143                MOVE_FREQUENCY_FIELD => {
144                    if move_frequency_field.is_some() {
145                        return Err(FromValueError::DuplicateInstanceVariable {
146                            name: MOVE_FREQUENCY_FIELD.into(),
147                        });
148                    }
149
150                    move_frequency_field = Some(ctx.from_value(value)?);
151                }
152                GRAPHIC_FIELD => {
153                    if graphic_field.is_some() {
154                        return Err(FromValueError::DuplicateInstanceVariable {
155                            name: GRAPHIC_FIELD.into(),
156                        });
157                    }
158
159                    graphic_field = Some(ctx.from_value(value)?);
160                }
161                ALWAYS_ON_TOP_FIELD => {
162                    if always_on_top_field.is_some() {
163                        return Err(FromValueError::DuplicateInstanceVariable {
164                            name: ALWAYS_ON_TOP_FIELD.into(),
165                        });
166                    }
167
168                    always_on_top_field = Some(ctx.from_value(value)?);
169                }
170                WALK_ANIME_FIELD => {
171                    if walk_anime_field.is_some() {
172                        return Err(FromValueError::DuplicateInstanceVariable {
173                            name: WALK_ANIME_FIELD.into(),
174                        });
175                    }
176
177                    walk_anime_field = Some(ctx.from_value(value)?);
178                }
179                MOVE_SPEED_FIELD => {
180                    if move_speed_field.is_some() {
181                        return Err(FromValueError::DuplicateInstanceVariable {
182                            name: MOVE_SPEED_FIELD.into(),
183                        });
184                    }
185
186                    move_speed_field = Some(ctx.from_value(value)?);
187                }
188                THROUGH_FIELD => {
189                    if through_field.is_some() {
190                        return Err(FromValueError::DuplicateInstanceVariable {
191                            name: THROUGH_FIELD.into(),
192                        });
193                    }
194
195                    through_field = Some(ctx.from_value(value)?);
196                }
197                _ => {
198                    return Err(FromValueError::UnknownInstanceVariable { name: key.into() });
199                }
200            }
201        }
202
203        let move_type = move_type_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
204            name: MOVE_TYPE_FIELD.into(),
205        })?;
206        let list = list_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
207            name: LIST_FIELD.into(),
208        })?;
209        let condition = condition_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
210            name: CONDITION_FIELD.into(),
211        })?;
212        let direction_fix =
213            direction_fix_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
214                name: DIRECTION_FIX_FIELD.into(),
215            })?;
216        let move_route =
217            move_route_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
218                name: MOVE_ROUTE_FIELD.into(),
219            })?;
220        let trigger = trigger_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
221            name: TRIGGER_FIELD.into(),
222        })?;
223        let step_anime =
224            step_anime_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
225                name: STEP_ANIME_FIELD.into(),
226            })?;
227        let move_frequency =
228            move_frequency_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
229                name: MOVE_FREQUENCY_FIELD.into(),
230            })?;
231        let graphic = graphic_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
232            name: GRAPHIC_FIELD.into(),
233        })?;
234        let always_on_top =
235            always_on_top_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
236                name: ALWAYS_ON_TOP_FIELD.into(),
237            })?;
238        let walk_anime =
239            walk_anime_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
240                name: WALK_ANIME_FIELD.into(),
241            })?;
242        let move_speed =
243            move_speed_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
244                name: MOVE_SPEED_FIELD.into(),
245            })?;
246        let through = through_field.ok_or_else(|| FromValueError::MissingInstanceVariable {
247            name: THROUGH_FIELD.into(),
248        })?;
249
250        Ok(Self {
251            move_type,
252            list,
253            condition,
254            direction_fix,
255            move_route,
256            trigger,
257            step_anime,
258            move_frequency,
259            graphic,
260            always_on_top,
261            walk_anime,
262            move_speed,
263            through,
264        })
265    }
266}
267
268impl IntoValue for EventPage {
269    fn into_value(self, arena: &mut ValueArena) -> Result<ValueHandle, IntoValueError> {
270        let object_name = arena.create_symbol(OBJECT_NAME.into());
271
272        let move_type_field_key = arena.create_symbol(MOVE_TYPE_FIELD.into());
273        let list_field_key = arena.create_symbol(LIST_FIELD.into());
274        let condition_field_key = arena.create_symbol(CONDITION_FIELD.into());
275        let direction_fix_field_key = arena.create_symbol(DIRECTION_FIX_FIELD.into());
276        let move_route_field_key = arena.create_symbol(MOVE_ROUTE_FIELD.into());
277        let trigger_field_key = arena.create_symbol(TRIGGER_FIELD.into());
278        let step_anime_field_key = arena.create_symbol(STEP_ANIME_FIELD.into());
279        let move_frequency_field_key = arena.create_symbol(MOVE_FREQUENCY_FIELD.into());
280        let graphic_field_key = arena.create_symbol(GRAPHIC_FIELD.into());
281        let always_on_top_field_key = arena.create_symbol(ALWAYS_ON_TOP_FIELD.into());
282        let walk_anime_field_key = arena.create_symbol(WALK_ANIME_FIELD.into());
283        let move_speed_field_key = arena.create_symbol(MOVE_SPEED_FIELD.into());
284        let through_field_key = arena.create_symbol(THROUGH_FIELD.into());
285
286        let move_type_field_value = self.move_type.into_value(arena)?;
287        let list_field_value = self.list.into_value(arena)?;
288        let condition_field_value = self.condition.into_value(arena)?;
289        let direction_fix_field_value = self.direction_fix.into_value(arena)?;
290        let move_route_field_value = self.move_route.into_value(arena)?;
291        let trigger_field_value = self.trigger.into_value(arena)?;
292        let step_anime_field_value = self.step_anime.into_value(arena)?;
293        let move_frequency_field_value = self.move_frequency.into_value(arena)?;
294        let graphic_field_value = self.graphic.into_value(arena)?;
295        let always_on_top_field_value = self.always_on_top.into_value(arena)?;
296        let walk_anime_field_value = self.walk_anime.into_value(arena)?;
297        let move_speed_field_value = self.move_speed.into_value(arena)?;
298        let through_field_value = self.through.into_value(arena)?;
299
300        let fields = vec![
301            (move_type_field_key, move_type_field_value),
302            (list_field_key, list_field_value),
303            (condition_field_key, condition_field_value),
304            (direction_fix_field_key, direction_fix_field_value),
305            (move_route_field_key, move_route_field_value),
306            (trigger_field_key, trigger_field_value),
307            (step_anime_field_key, step_anime_field_value),
308            (move_frequency_field_key, move_frequency_field_value),
309            (graphic_field_key, graphic_field_value),
310            (always_on_top_field_key, always_on_top_field_value),
311            (walk_anime_field_key, walk_anime_field_value),
312            (move_speed_field_key, move_speed_field_value),
313            (through_field_key, through_field_value),
314        ];
315
316        let object = arena.create_object(object_name, fields);
317
318        Ok(object.into())
319    }
320}