1use core::fmt;
2use std::{collections::BTreeMap, hash::Hash};
3
4use serde::{Deserialize, Serialize};
5
6use crate::{DamageType, DieStat};
7
8#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
9pub struct Spell {
10 pub id: i32,
11 pub name: String,
12 pub description: String,
13 pub attributes: BTreeMap<AttributeType, Attribute>,
14}
15
16#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
17pub enum AttributeType {
18 SpellLevel,
19 CastingTime,
20 Duration,
21 Damage,
22 Range,
23 Area,
24 DamageType,
25 Components,
26 AttackBonus,
27 Save,
28}
29
30#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
31pub enum Attribute {
32 SpellLevel(SpellLevel),
33 CastingTime(CastingTime),
34 Duration(Duration),
35 Damage(DieStat),
36 Range(SpellRange),
37 Area(Area),
38 DamageType(DamageType),
39 Components(Components),
40 AttackBonus(i32),
41 Save(Save),
42}
43
44#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
45pub enum SpellLevel {
46 Cantrip,
47 Level1,
48 Level2,
49 Level3,
50 Level4,
51 Level5,
52 Level6,
53 Level7,
54 Level8,
55 Level9,
56}
57
58impl fmt::Display for SpellLevel {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 match &self {
61 SpellLevel::Cantrip => write!(f, "Cantrip"),
62 SpellLevel::Level1 => write!(f, "1st Level"),
63 SpellLevel::Level2 => write!(f, "2nd Level"),
64 SpellLevel::Level3 => write!(f, "3rd Level"),
65 SpellLevel::Level4 => write!(f, "4th Level"),
66 SpellLevel::Level5 => write!(f, "5th Level"),
67 SpellLevel::Level6 => write!(f, "6th Level"),
68 SpellLevel::Level7 => write!(f, "7th Level"),
69 SpellLevel::Level8 => write!(f, "8th Level"),
70 SpellLevel::Level9 => write!(f, "9th Level"),
71 }
72 }
73}
74
75#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
76pub enum CastingTime {
77 Action,
78 BonusAction,
79 Reaction,
80 Minute,
81 Hour,
82}
83
84impl fmt::Display for CastingTime {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 match &self {
87 CastingTime::Action => write!(f, "Action"),
88 CastingTime::BonusAction => write!(f, "Bonus Action"),
89 CastingTime::Reaction => write!(f, "Reaction"),
90 CastingTime::Minute => write!(f, "Minute"),
91 CastingTime::Hour => write!(f, "Hour"),
92 }
93 }
94}
95
96#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
97pub enum Duration {
98 Instantaneous,
99 Concentration,
100 Minute,
101 Hour,
102 Day,
103 UntilDispelled,
104 UntilDispelledOrTriggered,
105 UntilTriggered,
106}
107
108impl fmt::Display for Duration {
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 match &self {
111 Duration::Instantaneous => write!(f, "Instantaneous"),
112 Duration::Concentration => write!(f, "Concentration"),
113 Duration::Minute => write!(f, "Minute"),
114 Duration::Hour => write!(f, "Hour"),
115 Duration::Day => write!(f, "Day"),
116 Duration::UntilDispelled => write!(f, "Until Dispelled"),
117 Duration::UntilDispelledOrTriggered => write!(f, "Until Dispelled or Triggered"),
118 Duration::UntilTriggered => write!(f, "Until Triggered"),
119 }
120 }
121}
122
123#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
124pub enum SpellRange {
125 S,
126 Touch,
127 Range(i32),
128}
129
130impl fmt::Display for SpellRange {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 match &self {
133 SpellRange::S => write!(f, "Self"),
134 SpellRange::Touch => write!(f, "Touch"),
135 SpellRange::Range(range) => write!(f, "{}", range),
136 }
137 }
138}
139
140#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
141pub enum Area {
142 Cube(i32),
143 Sphere(i32),
144 Cone(i32),
145 Line(i32),
146 Cylinder(i32),
147 Wall(i32),
148}
149
150impl fmt::Display for Area {
151 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152 match &self {
153 Area::Cube(size) => write!(f, "{} ft. Cube", size),
154 Area::Sphere(size) => write!(f, "{} ft. Sphere", size),
155 Area::Cone(size) => write!(f, "{} ft. Cone", size),
156 Area::Line(size) => write!(f, "{} ft. Line", size),
157 Area::Cylinder(size) => write!(f, "{} ft. Cylinder", size),
158 Area::Wall(size) => write!(f, "{} ft. Wall", size),
159 }
160 }
161}
162
163#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
164pub enum Components {
165 V,
166 S,
167 M,
168 VS,
169 VM,
170 SM,
171 VSM,
172}
173
174impl fmt::Display for Components {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 match &self {
177 Components::V => write!(f, "V"),
178 Components::S => write!(f, "S"),
179 Components::M => write!(f, "M"),
180 Components::VS => write!(f, "V, S"),
181 Components::VM => write!(f, "V, M"),
182 Components::SM => write!(f, "S, M"),
183 Components::VSM => write!(f, "V, S, M"),
184 }
185 }
186}
187
188#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
189pub enum Save {
190 Strength(Option<i32>),
191 Dexterity(Option<i32>),
192 Constitution(Option<i32>),
193 Intelligence(Option<i32>),
194 Wisdom(Option<i32>),
195 Charisma(Option<i32>),
196}
197
198impl fmt::Display for Save {
199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200 match &self {
201 Save::Strength(Some(dc)) => write!(f, "Strength DC {}", dc),
202 Save::Dexterity(Some(dc)) => write!(f, "Dexterity DC {}", dc),
203 Save::Constitution(Some(dc)) => write!(f, "Constitution DC {}", dc),
204 Save::Intelligence(Some(dc)) => write!(f, "Intelligence DC {}", dc),
205 Save::Wisdom(Some(dc)) => write!(f, "Wisdom DC {}", dc),
206 Save::Charisma(Some(dc)) => write!(f, "Charisma DC {}", dc),
207 Save::Strength(None) => write!(f, "Strength"),
208 Save::Dexterity(None) => write!(f, "Dexterity"),
209 Save::Constitution(None) => write!(f, "Constitution"),
210 Save::Intelligence(None) => write!(f, "Intelligence"),
211 Save::Wisdom(None) => write!(f, "Wisdom"),
212 Save::Charisma(None) => write!(f, "Charisma"),
213 }
214 }
215}