data/
skill.rs

1//! Data structures and logic for skills
2
3use quick_xml::events::BytesStart;
4use serde::Serialize;
5
6use error::Error;
7use crate::xml;
8
9/// Stat requirement for a skill to be learnt
10#[derive(Clone, Serialize, Default)]
11pub struct Requirements
12{
13    pub agility: u32,
14    pub intelligence: u32,
15    pub level: u32,
16    pub attack: u32,
17    pub defense: u32,
18    pub mp: u32,
19    pub hp: u32,
20}
21
22impl Requirements
23{
24    fn fromXMLTag(tag: &BytesStart) -> Result<Self, Error>
25    {
26        let agility: u32 =  xml::getTagAttr(tag, "agl")?.ok_or_else(
27            || xmlerr!("Agility value not found"))?;
28        let intelligence: u32 =  xml::getTagAttr(tag, "int")?.ok_or_else(
29            || xmlerr!("Inteligence value not found"))?;
30        let level: u32 =  xml::getTagAttr(tag, "lvl")?.ok_or_else(
31            || xmlerr!("Level value not found"))?;
32        let attack: u32 =  xml::getTagAttr(tag, "atk")?.ok_or_else(
33            || xmlerr!("Attack value not found"))?;
34        let defense: u32 =  xml::getTagAttr(tag, "def")?.ok_or_else(
35            || xmlerr!("Defense value not found"))?;
36        let mp: u32 =  xml::getTagAttr(tag, "mp")?.ok_or_else(
37            || xmlerr!("MP value not found"))?;
38        let hp: u32 =  xml::getTagAttr(tag, "hp")?.ok_or_else(
39            || xmlerr!("HP value not found"))?;
40        Ok(Self {
41            agility, intelligence, level, attack, defense, mp, hp,
42        })
43    }
44}
45
46/// A skill
47#[derive(Default, Clone, Serialize)]
48pub struct Skill
49{
50    /// Name of the skill
51    pub name: String,
52    /// Stats requirements of the skill
53    pub requirements: Requirements,
54    pub upgrade_from: Option<String>,
55    pub upgrade_to: Option<String>,
56    pub combine_from: Vec<String>,
57}
58
59impl Skill
60{
61    /// This will not populate the `upgrade_to` field.
62    pub fn fromXML(x: &[u8]) -> Result<Self, Error>
63    {
64        let mut skill = Self::default();
65        let combine_from = String::from("combine-from");
66        let mut p = xml::Parser::new();
67        p.addBeginHandler("skill-data", |_, tag| {
68            skill.name = xml::getTagAttr(tag, "name")?.ok_or_else(
69                || xmlerr!("Skill name value not found"))?;
70            Ok(())
71        });
72        p.addTextHandler("precursor", |_, text| {
73            skill.upgrade_from = Some(text.to_owned());
74            Ok(())
75        });
76        p.addTextHandler("skill", |xml_path, text| {
77            if xml_path.get(xml_path.len() - 2) == Some(&combine_from)
78            {
79                skill.combine_from.push(text.to_owned());
80            }
81            Ok(())
82        });
83        p.addBeginHandler("skill-requirements", |_, tag| {
84            skill.requirements = Requirements::fromXMLTag(tag)?;
85            Ok(())
86        });
87
88        p.parse(x)?;
89        drop(p);
90        Ok(skill)
91    }
92}