1use core::fmt;
2use std::collections::BTreeMap;
3
4use serde::{Deserialize, Serialize};
5
6use crate::{
7 action::Action, spell::Spell, Alignment, AttributeInfo, ConditionType, OtherAttribute,
8};
9
10#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
11pub struct Item {
12 pub id: String,
13 pub name: String,
14 pub attributes: BTreeMap<AttributeType, Attribute>,
15}
16
17#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
18pub enum AttributeType {
19 ItemType(AttributeInfo),
20 ItemRarity(AttributeInfo),
21 Attunement(AttributeInfo),
22 EffectType(AttributeInfo),
23 WeaponType(AttributeInfo),
24 ArmorType(AttributeInfo),
25 Conditions(AttributeInfo),
26 AttachedSpells(AttributeInfo),
27 HasCharges(AttributeInfo),
28 Other(AttributeInfo),
29}
30
31#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
32pub enum Attribute {
33 ItemType(ItemType),
34 ItemRarity(ItemRarity),
35 Attunement(Attuneable),
36 WeaponType(WeaponType),
37 ArmorType(ArmorType),
38 Conditions(ConditionType),
39 AttachedSpell(Spell),
40 HasCharges(Charge),
41 Inventory(Vec<Item>),
42 Other(OtherAttribute),
43 Action(Action),
44}
45
46#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
47pub enum ItemType {
48 Armor,
49 Potion,
50 Ring,
51 Rod,
52 Scroll,
53 Staff,
54 Wand,
55 Weapon,
56 WondrousItem,
57}
58
59impl fmt::Display for ItemType {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 match &self {
62 ItemType::WondrousItem => write!(f, "Wondrous Item"),
63 other => write!(f, "{:?}", other),
64 }
65 }
66}
67
68#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
69pub enum ItemRarity {
70 Common,
71 Uncommon,
72 Rare,
73 VeryRare,
74 Legendary,
75 Artifact,
76 Varies,
77 Unknown,
78}
79
80impl fmt::Display for ItemRarity {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 match &self {
83 ItemRarity::VeryRare => write!(f, "Very Rare"),
84 ItemRarity::Unknown => write!(f, "Unknown Rarity"),
85 other => write!(f, "{:?}", other),
86 }
87 }
88}
89
90#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
91pub struct Attuneable {
92 pub attuneable: bool,
93 pub alignments: Vec<Alignment>,
94}
95
96impl fmt::Display for Attuneable {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 write!(
99 f,
100 "({}{}{:?})",
101 if self.attuneable {
102 "requires attunement "
103 } else {
104 ""
105 },
106 if !self.alignments.is_empty() {
107 ""
108 } else {
109 ", "
110 },
111 self.alignments
112 .iter()
113 .map(|x| x.to_string() + ",")
114 .collect::<String>()
115 .trim_end_matches(",")
116 )
117 }
118}
119
120#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
121pub enum WeaponType {
122 Sword,
123}
124
125impl fmt::Display for WeaponType {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 write!(f, "{:?}", self)
128 }
129}
130
131#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
132pub enum ArmorType {
133 Shield,
134}
135
136impl fmt::Display for ArmorType {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 write!(f, "{:?}", self)
139 }
140}
141
142#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
143pub struct Charge {
144 pub num: i32,
145 pub time: TimeDivision,
146}
147
148impl fmt::Display for Charge {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 write!(f, "{}/{}", self.num, self.time.to_string())
151 }
152}
153
154#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
155pub enum TimeDivision {
156 Round,
157 Second,
158 Minute,
159 Hour,
160 Day,
161 Month,
162 Year,
163}
164
165impl fmt::Display for TimeDivision {
166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 write!(f, "{:?}", self)
168 }
169}
170
171impl TimeDivision {
172 pub fn to_plural_string(&self) -> String {
173 format!("{:?}s", self)
174 }
175}