homm5_scaner/entity/
art.rs1use serde::{Serialize, Deserialize};
2use super::{Scan, Output, FileStructure, CollectFiles};
3use quick_xml::{Reader, events::Event};
4use std::collections::HashMap;
5use homm5_types::art::AdvMapArtifactShared;
6
7impl Output for AdvMapArtifactShared {
8 type ID = u16;
9
10 fn to_lua(&self, id: Option<Self::ID>) -> String {
11 let is_sellable = if self.CanBeGeneratedToSell == true {"1"} else {"nil"};
12 format!(
13 "\t[{}] = {{
14 is_sellable = {},
15 name = \"{}\",
16 desc = \"{}\",
17 icon = \"{}\",
18 cost = {},
19 slot = {},
20 type = {}
21 }},\n",
22 id.unwrap() - 1,
23 is_sellable,
24 self.NameFileRef.as_ref().unwrap().href.as_ref().unwrap_or(&String::new()),
25 self.DescriptionFileRef.as_ref().unwrap().href.as_ref().unwrap_or(&String::new()),
26 self.Icon.as_ref().unwrap().href.as_ref().unwrap_or(&String::new()),
27 self.CostOfGold,
28 self.Slot,
29 self.Type
30 )
31 }
32
33 fn to_json(&self) -> String {
34 serde_json::to_string_pretty(self).unwrap()
35 }
36}
37
38#[derive(Debug, Serialize, Deserialize)]
39#[allow(non_snake_case)]
40pub struct ArtObject {
41 pub ID: String,
42 pub obj: Option<String>
43}
44
45#[derive(Debug, Serialize, Deserialize)]
46pub struct ArtObjects {
47 #[serde(rename = "Item")]
48 pub arts: Vec<ArtObject>
49}
50
51pub struct ArtFileCollector {}
52
53impl CollectFiles for ArtFileCollector {
54 fn collect(&self, files: &HashMap<String, FileStructure>, collected_files: &mut Vec<(String, FileStructure)>) {
55 let arts_xdb = files.iter()
56 .find(|f| f.0 == "GameMechanics/RefTables/Artifacts.xdb".to_lowercase().as_str())
57 .unwrap();
58 let mut buf = Vec::new();
60 let mut reader = Reader::from_str(arts_xdb.1.content.as_str());
61 reader.trim_text(true);
62 reader.expand_empty_elements(true);
63 loop {
64 match reader.read_event_into(&mut buf) {
65 Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
66 Ok(Event::Eof) => break,
67 Ok(Event::Start(e)) => {
68 match e.name().as_ref() {
69 b"obj" => {
70 let end = e.to_end().into_owned();
71 let text = reader.read_text(end.name()).unwrap().to_string();
72 let text = format!("<obj>{}</obj>", text);
73 collected_files.push(("GameMechanics/RefTables/Artifacts.xdb".to_lowercase(), FileStructure{
74 pak: arts_xdb.1.pak.clone(),
75 modified: arts_xdb.1.modified,
76 content: text
77 }));
78 }
79 _=> {}
80 }
81 }
82 _ => ()
83 }
84 buf.clear();
85 }
86 }
87}
88
89pub struct ArtScaner {
90 pub id: u16,
91}
92
93impl Scan<u16> for ArtScaner {
94 fn get_id(&self) -> Option<u16> {
95 Some(self.id)
96 }
97
98 #[allow(unused_variables)]
99 fn scan(&mut self, file_key: &String, entity: &String, files: &HashMap<String, FileStructure>) -> Option<Box<dyn Output<ID = u16>>> {
100 let art_de: Result<AdvMapArtifactShared, quick_xml::DeError> = quick_xml::de::from_str(entity);
101 match art_de {
102 Ok(art) => {
103 self.id += 1;
104 Some(Box::new(art))
105 }
106 Err(e) => {
107 println!("error deserializing artifact {}", e.to_string());
108 None
109 }
110 }
111 }
112}