gdritter repos delve / bcb7942
Add a richer Rust Card type Getty Ritter 6 years ago
1 changed file(s) with 95 addition(s) and 22 deletion(s). Collapse all Expand all
1313
1414 const SCALE: i32 = 3;
1515
16 #[derive(Debug)]
17 struct Card<'a> {
18 name: &'a str,
19 icon: String,
20 card_type: CardType<'a>,
21 }
22
23 #[derive(Debug)]
24 enum CardType<'a> {
25 Monster {
26 hp: &'a str,
27 melee: Option<&'a str>,
28 ranged: Option<&'a str>,
29 arcane: Option<&'a str>,
30 defense: Option<&'a str>,
31 action: &'a str,
32 effect: &'a str,
33 },
34 Weapon {
35 weapon_type: WeaponType,
36 ability: &'a str,
37 effect: &'a str,
38 },
39 Generic {
40 kind: Kind,
41 effect: &'a str,
42 },
43 }
44
45 #[derive(Debug)]
46 enum Kind { Ability, Equipment, Item, Plant, Treasure }
47
48 #[derive(Debug)]
49 enum WeaponType { Melee, Ranged, Arcane }
50
51 impl<'a> Card<'a> {
52 fn from_record(rec: &'a rrecutils::Record)
53 -> Result<Card<'a>, failure::Error>
54 {
55 let name = rec.get("Name")?;
56
57 let card_type = match rec.get_type()? {
58 "Weapon" => CardType::Weapon {
59 weapon_type: match rec.get("Type")? {
60 "melee" => WeaponType::Melee,
61 "ranged" => WeaponType::Ranged,
62 "magic" | "arcane" => WeaponType::Arcane,
63 t => bail!("Unknown weapon type: {}", t),
64 },
65 ability: rec.get("Ability")?,
66 effect: rec.get("Effect")?,
67 },
68 "Monster" => CardType::Monster {
69 hp: rec.get("HP")?,
70 melee: rec.get("Melee").ok(),
71 ranged: rec.get("Ranged").ok(),
72 arcane: rec.get("Arcane").ok(),
73 defense: rec.get("Defense").ok(),
74 action: rec.get("Action")?,
75 effect: rec.get("Effect")?,
76 },
77 t => CardType::Generic {
78 kind: match t {
79 "Ability" => Kind::Ability,
80 "Item" => Kind::Item,
81 "Equipment" => Kind::Equipment,
82 "Plant" => Kind::Plant,
83 "Treasure" => Kind::Treasure,
84 _ => bail!("Unknown card type: {}", t),
85 },
86 effect: rec.get("Effect")?,
87 }
88 };
89
90
91 let icon = format!("icon");
92
93 Ok(Card { name, icon, card_type })
94 }
95 }
96
1697 fn draw_card(rec: &rrecutils::Record) -> Result<(), failure::Error> {
1798 let typ = match rec.rec_type {
1899 Some(ref t) => t,
19100 None => return Ok(()),
20101 };
21 let name = rec.get("Name")
22 .ok_or(format_err!("Weapon found with no Name!"))?;
102 let _ = Card::from_record(rec)?;
103 let name = rec.get("Name")?;
23104
24105 let surf = cairo::ImageSurface::create(
25106 cairo::Format::Rgb24,
52133 "Weapon" => format!(
53134 "{} (Weapon, {})",
54135 name,
55 rec.get("Type")
56 .ok_or(format_err!("Missing Type for {}", name))?
136 rec.get("Type")?
57137 .to_title_case(),
58138 ),
59139 "Ability" | "Equipment" | "Item" | "Plant" | "Treasure" =>
60140 format!("{} ({})", name, typ),
61141 "Monster" => {
62142 let mut buf = String::new();
63 let hp = rec.get("HP").ok_or(format_err!("Missing HP for {}", name))?;
143 let hp = rec.get("HP")?;
64144 buf.push_str(&format!("{} (Beast <span font='8' font_weight='heavy'>HP</span>{}", name, hp));
65 if let Some(m) = rec.get("Melee") {
145 if let Ok(m) = rec.get("Melee") {
66146 buf.push_str(&format!(" <span font='8' font_weight='heavy'>M</span>{}", m));
67147 }
68 if let Some(m) = rec.get("Ranged") {
148 if let Ok(m) = rec.get("Ranged") {
69149 buf.push_str(&format!(" <span font='8' font_weight='heavy'>R</span>{}", m));
70150 }
71 if let Some(m) = rec.get("Arcane") {
151 if let Ok(m) = rec.get("Arcane") {
72152 buf.push_str(&format!(" <span font='8' font_weight='heavy'>A</span>{}", m));
73153 }
74 if let Some(m) = rec.get("Defense") {
154 if let Ok(m) = rec.get("Defense") {
75155 buf.push_str(&format!(" <span font='8' font_weight='heavy'>D</span>{}", m));
76156 }
77157 buf.push_str(")");
99179 match typ.as_ref() {
100180 "Weapon" => {
101181 buf.push_str("<span font_weight=\"bold\">");
102 buf.push_str(rec.get("Ability")
103 .ok_or(format_err!("Missing Ability for {}", name))?);
182 buf.push_str(rec.get("Ability")?);
104183 buf.push_str(":</span> ");
105 buf.push_str(rec.get("Effect")
106 .ok_or(format_err!("Missing Effect for {}", name))?);
184 buf.push_str(rec.get("Effect")?);
107185 }
108186 "Ability" | "Equipment" | "Item" | "Plant" | "Treasure" =>
109 buf.push_str(rec.get("Effect")
110 .ok_or(format_err!("Missing Effect for {}", name))?),
187 buf.push_str(rec.get("Effect")?),
111188 "Monster" => {
112189 buf.push_str("<span font_weight=\"bold\">");
113 buf.push_str(rec.get("Action")
114 .ok_or(format_err!("Missing Action for {}", name))?);
190 buf.push_str(rec.get("Action")?);
115191 buf.push_str(":</span> ");
116 buf.push_str(rec.get("Effect")
117 .ok_or(format_err!("Missing Effect for {}", name))?);
192 buf.push_str(rec.get("Effect")?);
118193 }
119194 _ => bail!("Unknown type: {}", typ),
120195 }
129204 let icon_path = special_icon.unwrap_or(format!(
130205 "../icons/{}-icon.svg",
131206 match typ.as_ref() {
132 "Weapon" => rec.get("Type")
133 .ok_or(format_err!("Missing Type for {}", name))?
134 .to_owned(),
207 "Weapon" => rec.get("Type")?.to_owned(),
135208 _ => typ.to_lowercase(),
136209 },
137210 ));