rpgmxp_tool/commands/compile_assets/
xp.rs

1use super::generate_arraylike_rx_data;
2use super::generate_map_infos_data;
3use super::generate_ruby_data;
4use super::generate_scripts_data;
5use super::set_extension_str;
6use super::FileSink;
7use anyhow::Context;
8use rpgmxp_types::Actor;
9use rpgmxp_types::Animation;
10use rpgmxp_types::Armor;
11use rpgmxp_types::Class;
12use rpgmxp_types::CommonEvent;
13use rpgmxp_types::Enemy;
14use rpgmxp_types::Item;
15use rpgmxp_types::Skill;
16use rpgmxp_types::State;
17use rpgmxp_types::Tileset;
18use rpgmxp_types::Troop;
19use rpgmxp_types::Weapon;
20use std::fs::File;
21use std::path::Path;
22
23pub fn compile(
24    entry_path: &Path,
25    entry_file_type: std::fs::FileType,
26    relative_path: &Path,
27    relative_path_components: Vec<&str>,
28    file_sink: &mut FileSink,
29) -> anyhow::Result<()> {
30    match relative_path_components.as_slice() {
31        ["Data", "Scripts.rxdata"] if entry_file_type.is_dir() => {
32            println!("packing \"{}\"", relative_path.display());
33
34            let scripts_data = generate_scripts_data(entry_path)?;
35            let size = u32::try_from(scripts_data.len())?;
36
37            file_sink.write_file(&relative_path_components, size, &*scripts_data)?;
38        }
39        ["Data", "Scripts.rxdata", ..] => {
40            // Ignore entries, we explore them in the above branch.
41        }
42        ["Data", "CommonEvents.rxdata"] if entry_file_type.is_dir() => {
43            println!("packing \"{}\"", relative_path.display());
44
45            let rx_data = generate_arraylike_rx_data::<CommonEvent>(entry_path)?;
46            let size = u32::try_from(rx_data.len())?;
47
48            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
49        }
50        ["Data", "CommonEvents.rxdata", ..] => {
51            // Ignore entries, we explore them in the above branch.
52        }
53        ["Data", "Actors.rxdata"] if entry_file_type.is_dir() => {
54            println!("packing \"{}\"", relative_path.display());
55
56            let rx_data = generate_arraylike_rx_data::<Actor>(entry_path)?;
57            let size = u32::try_from(rx_data.len())?;
58
59            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
60        }
61        ["Data", "Actors.rxdata", ..] => {
62            // Ignore entries, we explore them in the above branch.
63        }
64        ["Data", "Weapons.rxdata"] if entry_file_type.is_dir() => {
65            println!("packing \"{}\"", relative_path.display());
66
67            let rx_data = generate_arraylike_rx_data::<Weapon>(entry_path)?;
68            let size = u32::try_from(rx_data.len())?;
69
70            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
71        }
72        ["Data", "Weapons.rxdata", ..] => {
73            // Ignore entries, we explore them in the above branch.
74        }
75        ["Data", "Armors.rxdata"] if entry_file_type.is_dir() => {
76            println!("packing \"{}\"", relative_path.display());
77
78            let rx_data = generate_arraylike_rx_data::<Armor>(entry_path)?;
79            let size = u32::try_from(rx_data.len())?;
80
81            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
82        }
83        ["Data", "Armors.rxdata", ..] => {
84            // Ignore entries, we explore them in the above branch.
85        }
86        ["Data", "Skills.rxdata"] if entry_file_type.is_dir() => {
87            println!("packing \"{}\"", relative_path.display());
88
89            let rx_data = generate_arraylike_rx_data::<Skill>(entry_path)?;
90            let size = u32::try_from(rx_data.len())?;
91
92            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
93        }
94        ["Data", "Skills.rxdata", ..] => {
95            // Ignore entries, we explore them in the above branch.
96        }
97        ["Data", "States.rxdata"] if entry_file_type.is_dir() => {
98            println!("packing \"{}\"", relative_path.display());
99
100            let rx_data = generate_arraylike_rx_data::<State>(entry_path)?;
101            let size = u32::try_from(rx_data.len())?;
102
103            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
104        }
105        ["Data", "States.rxdata", ..] => {
106            // Ignore entries, we explore them in the above branch.
107        }
108        ["Data", "Items.rxdata"] if entry_file_type.is_dir() => {
109            println!("packing \"{}\"", relative_path.display());
110
111            let rx_data = generate_arraylike_rx_data::<Item>(entry_path)?;
112            let size = u32::try_from(rx_data.len())?;
113
114            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
115        }
116        ["Data", "Items.rxdata", ..] => {
117            // Ignore entries, we explore them in the above branch.
118        }
119        ["Data", "Enemies.rxdata"] if entry_file_type.is_dir() => {
120            println!("packing \"{}\"", relative_path.display());
121
122            let rx_data = generate_arraylike_rx_data::<Enemy>(entry_path)?;
123            let size = u32::try_from(rx_data.len())?;
124
125            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
126        }
127        ["Data", "Enemies.rxdata", ..] => {
128            // Ignore entries, we explore them in the above branch.
129        }
130        ["Data", "Classes.rxdata"] if entry_file_type.is_dir() => {
131            println!("packing \"{}\"", relative_path.display());
132
133            let rx_data = generate_arraylike_rx_data::<Class>(entry_path)?;
134            let size = u32::try_from(rx_data.len())?;
135
136            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
137        }
138        ["Data", "Classes.rxdata", ..] => {
139            // Ignore entries, we explore them in the above branch.
140        }
141        ["Data", "Troops.rxdata"] if entry_file_type.is_dir() => {
142            println!("packing \"{}\"", relative_path.display());
143
144            let rx_data = generate_arraylike_rx_data::<Troop>(entry_path)?;
145            let size = u32::try_from(rx_data.len())?;
146
147            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
148        }
149        ["Data", "Troops.rxdata", ..] => {
150            // Ignore entries, we explore them in the above branch.
151        }
152        ["Data", "Tilesets.rxdata"] if entry_file_type.is_dir() => {
153            println!("packing \"{}\"", relative_path.display());
154
155            let rx_data = generate_arraylike_rx_data::<Tileset>(entry_path)?;
156            let size = u32::try_from(rx_data.len())?;
157
158            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
159        }
160        ["Data", "Tilesets.rxdata", ..] => {
161            // Ignore entries, we explore them in the above branch.
162        }
163        ["Data", "MapInfos.rxdata"] if entry_file_type.is_dir() => {
164            println!("packing \"{}\"", relative_path.display());
165
166            let rx_data = generate_map_infos_data(entry_path)?;
167            let size = u32::try_from(rx_data.len())?;
168
169            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
170        }
171        ["Data", "MapInfos.rxdata", ..] => {
172            // Ignore entries, we explore them in the above branch.
173        }
174        ["Data", "System.json"] if entry_file_type.is_file() => {
175            println!("packing \"{}\"", relative_path.display());
176
177            let data = generate_ruby_data::<rpgmxp_types::System>(entry_path)?;
178            let size = u32::try_from(data.len())?;
179
180            let mut relative_path_components = relative_path_components.clone();
181            *relative_path_components.last_mut().unwrap() = "System.rxdata";
182
183            file_sink.write_file(&relative_path_components, size, &*data)?;
184        }
185        ["Data", "Animations.rxdata"] if entry_file_type.is_dir() => {
186            println!("packing \"{}\"", relative_path.display());
187
188            let rx_data = generate_arraylike_rx_data::<Animation>(entry_path)?;
189            let size = u32::try_from(rx_data.len())?;
190
191            file_sink.write_file(&relative_path_components, size, &*rx_data)?;
192        }
193        ["Data", "Animations.rxdata", ..] => {
194            // Ignore entries, we explore them in the above branch.
195        }
196        ["Data", file] if crate::util::is_map_file_name(file, "json") => {
197            println!("packing \"{}\"", relative_path.display());
198
199            let map_data = generate_ruby_data::<rpgmxp_types::Map>(entry_path)?;
200            let size = u32::try_from(map_data.len())?;
201
202            let renamed_file = set_extension_str(file, "rxdata");
203            let mut relative_path_components = relative_path_components.clone();
204            *relative_path_components.last_mut().unwrap() = renamed_file.as_str();
205
206            file_sink.write_file(&relative_path_components, size, &*map_data)?;
207        }
208        relative_path_components if entry_file_type.is_file() => {
209            // Copy file by default
210            println!("packing \"{}\"", relative_path.display());
211
212            let input_file = File::open(entry_path).with_context(|| {
213                format!(
214                    "failed to open input file from \"{}\"",
215                    entry_path.display()
216                )
217            })?;
218            let metadata = input_file.metadata()?;
219            let size = u32::try_from(metadata.len())?;
220
221            file_sink.write_file(relative_path_components, size, input_file)?;
222        }
223        _ => {}
224    }
225
226    Ok(())
227}