1use std::cell::RefCell;
4use std::rc::Rc;
5
6use quick_xml::events::BytesStart;
7use serde::Serialize;
8
9use error::Error;
10use crate::xml::{self, getTagAttr};
11
12#[derive(Clone, Serialize)]
14pub struct MapLocation
15{
16 pub map: String,
18 pub desc: Option<String>,
20}
21
22impl MapLocation
23{
24 fn fromXML(x: &[u8]) -> Result<Self, Error>
33 {
34 let mut map = String::new();
35 let mut desc = String::new();
36 let mut p = xml::Parser::new();
37 p.addTextHandler("map", |_, text| {
38 map = text.to_owned();
39 Ok(())
40 });
41 p.addTextHandler("description", |_, text| {
42 desc = text.to_owned();
43 Ok(())
44 });
45 p.parse(x)?;
46 drop(p);
47 Ok(Self {
48 map,
49 desc: if desc.is_empty() { None } else { Some(desc) }
50 })
51 }
52}
53
54#[derive(Default, Clone, Serialize)]
56pub struct Growth
57{
58 pub agility: u8,
59 pub intelligence: u8,
60 pub max_level: u8,
61 pub attack: u8,
62 pub defense: u8,
63 pub mp: u8,
64 pub exp: u8,
65 pub hp: u8,
66}
67
68impl Growth
69{
70 fn fromXMLTag(tag: &BytesStart) -> Result<Self, Error>
71 {
72 let agility: u8 = xml::getTagAttr(tag, "agl")?.ok_or_else(
73 || xmlerr!("Agility value not found"))?;
74 let intelligence: u8 = xml::getTagAttr(tag, "int")?.ok_or_else(
75 || xmlerr!("Inteligence value not found"))?;
76 let max_level: u8 = xml::getTagAttr(tag, "maxlvl")?.ok_or_else(
77 || xmlerr!("Max level value not found"))?;
78 let attack: u8 = xml::getTagAttr(tag, "atk")?.ok_or_else(
79 || xmlerr!("Attack value not found"))?;
80 let defense: u8 = xml::getTagAttr(tag, "def")?.ok_or_else(
81 || xmlerr!("Defense value not found"))?;
82 let mp: u8 = xml::getTagAttr(tag, "mp")?.ok_or_else(
83 || xmlerr!("MP value not found"))?;
84 let exp: u8 = xml::getTagAttr(tag, "exp")?.ok_or_else(
85 || xmlerr!("EXP value not found"))?;
86 let hp: u8 = xml::getTagAttr(tag, "hp")?.ok_or_else(
87 || xmlerr!("HP value not found"))?;
88 Ok(Self {
89 agility, intelligence, max_level, attack, defense, mp, exp, hp,
90 })
91 }
92}
93
94
95#[derive(Clone, Serialize)]
97pub struct Monster
98{
99 pub name: String,
101 pub in_story: bool,
103 pub locations: Vec<MapLocation>,
106 pub skills: Vec<String>,
108 pub growth: Growth,
110 pub family: String,
112}
113
114impl Monster
115{
116 fn fromXML(x: &[u8], family: String) -> Result<Self, Error>
117 {
118 let mut name = String::new();
119 let mut in_story = false;
120 let mut locations = Vec::new();
121 let mut skills = Vec::new();
122 let mut growth = Growth::default();
123
124 let mut p = xml::Parser::new();
125 p.addBeginHandler("monster", |_, tag| {
126 name = xml::getTagAttr(tag, "name")?.ok_or_else(
127 || xmlerr!("Monster name value not found"))?;
128 in_story = xml::getTagAttr(tag, "in_story")?.ok_or_else(
129 || xmlerr!("In_story value not found"))?;
130 Ok(())
131 });
132 p.addTagHandler("location", |_, tag| {
133 locations.push(MapLocation::fromXML(tag)?);
134 Ok(())
135 });
136 p.addTextHandler("skill", |_, text| {
137 skills.push(text.to_owned());
138 Ok(())
139 });
140 p.addBeginHandler("growth", |_, tag| {
141 growth = Growth::fromXMLTag(tag)?;
142 Ok(())
143 });
144 p.parse(x)?;
145 drop(p);
146
147 Ok(Self { name, in_story, locations, skills, growth, family})
148 }
149}
150
151#[derive(Default, Clone, Serialize)]
153pub struct Family
154{
155 pub name: String,
157 pub members: Vec<String>,
159}
160
161#[derive(Default, Clone, Serialize)]
163pub struct Info
164{
165 pub monsters: Vec<Monster>,
167 pub families: Vec<Family>,
169}
170
171impl Info
172{
173 pub fn fromXML(x: &[u8]) -> Result<Self, Error>
174 {
175 let family = Rc::new(RefCell::new(Family::default()));
176 let mut monsters = Vec::new();
177 let mut families = Vec::new();
178
179 let mut p = xml::Parser::new();
180 p.addBeginHandler("family", |_, tag| {
181 family.borrow_mut().name = getTagAttr(tag, "name")?
182 .ok_or_else(|| xmlerr!("Family name not found"))?;
183 Ok(())
184 });
185 p.addEndHandler("family", |_, _| {
186 families.push(family.take());
187 *family.borrow_mut() = Family::default();
188 Ok(())
189 });
190 p.addTagHandler("monster", |_, tag| {
191 let monster = Monster::fromXML(tag, family.borrow().name.clone())?;
192 family.borrow_mut().members.push(monster.name.clone());
193 monsters.push(monster);
194 Ok(())
195 });
196
197 p.parse(x)?;
198 drop(p);
199 Ok(Self { monsters, families })
200 }
201}