luminol_data/rmxp/
animation.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_path_alox, optional_path_serde, rpg::AudioFile, Color, Path, Table2,
19};
20
21#[derive(Default, Debug, serde::Deserialize, serde::Serialize)]
22#[derive(alox_48::Deserialize, alox_48::Serialize)]
23#[marshal(class = "RPG::Animation")]
24pub struct Animation {
25    #[serde(with = "id_serde")]
26    #[marshal(with = "id_alox")]
27    pub id: usize,
28    pub name: String,
29    #[serde(with = "optional_path_serde")]
30    #[marshal(with = "optional_path_alox")]
31    pub animation_name: Path,
32    pub animation_hue: i32,
33    pub position: Position,
34    pub frame_max: usize,
35    pub frames: Vec<Frame>,
36    pub timings: Vec<Timing>,
37}
38
39#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
40#[derive(alox_48::Deserialize, alox_48::Serialize)]
41#[marshal(class = "RPG::Animation::Timing")]
42pub struct Timing {
43    pub frame: usize,
44    pub se: AudioFile,
45    pub flash_scope: Scope,
46    pub flash_color: Color,
47    pub flash_duration: usize,
48    pub condition: Condition,
49}
50
51impl Default for Timing {
52    fn default() -> Self {
53        Self {
54            frame: 0,
55            se: AudioFile::default(),
56            flash_scope: Scope::default(),
57            flash_color: Color::default(),
58            flash_duration: 1,
59            condition: Condition::default(),
60        }
61    }
62}
63
64#[derive(Default, Debug, Clone, serde::Deserialize, serde::Serialize)]
65#[derive(alox_48::Deserialize, alox_48::Serialize)]
66#[marshal(class = "RPG::Animation::Frame")]
67pub struct Frame {
68    pub cell_max: usize,
69    pub cell_data: Table2,
70}
71
72impl Frame {
73    /// Returns one more than the maximum cell number in this frame.
74    #[inline]
75    pub fn len(&self) -> usize {
76        self.cell_max.min(self.cell_data.xsize())
77    }
78
79    /// Returns true if there are no cells in this frame, otherwise false.
80    #[inline]
81    pub fn is_empty(&self) -> bool {
82        self.cell_max == 0 || self.cell_data.is_empty()
83    }
84}
85
86#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
87#[derive(
88    num_enum::TryFromPrimitive,
89    num_enum::IntoPrimitive,
90    strum::Display,
91    strum::EnumIter
92)]
93#[derive(serde::Deserialize, serde::Serialize)]
94#[derive(alox_48::Deserialize, alox_48::Serialize)]
95#[repr(u8)]
96#[serde(into = "u8")]
97#[serde(try_from = "u8")]
98#[marshal(into = "u8")]
99#[marshal(try_from = "u8")]
100pub enum Position {
101    Top = 0,
102    #[default]
103    Middle = 1,
104    Bottom = 2,
105    Screen = 3,
106}
107
108#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
109#[derive(
110    num_enum::TryFromPrimitive,
111    num_enum::IntoPrimitive,
112    strum::Display,
113    strum::EnumIter
114)]
115#[derive(serde::Deserialize, serde::Serialize)]
116#[derive(alox_48::Deserialize, alox_48::Serialize)]
117#[repr(u8)]
118#[serde(into = "u8")]
119#[serde(try_from = "u8")]
120#[marshal(into = "u8")]
121#[marshal(try_from = "u8")]
122pub enum Scope {
123    #[default]
124    None = 0,
125    Target = 1,
126    Screen = 2,
127    #[strum(to_string = "Hide Target")]
128    HideTarget = 3,
129}
130
131#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
132#[derive(
133    num_enum::TryFromPrimitive,
134    num_enum::IntoPrimitive,
135    strum::Display,
136    strum::EnumIter
137)]
138#[derive(serde::Deserialize, serde::Serialize)]
139#[derive(alox_48::Deserialize, alox_48::Serialize)]
140#[repr(u8)]
141#[serde(into = "u8")]
142#[serde(try_from = "u8")]
143#[marshal(into = "u8")]
144#[marshal(try_from = "u8")]
145pub enum Condition {
146    #[default]
147    None = 0,
148    Hit = 1,
149    Miss = 2,
150}