dnd_character/
abilities.rs1use std::{
2 iter::Sum,
3 ops::{Add, AddAssign},
4};
5
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Default, Clone)]
9#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
11#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
12pub struct AbilityScore {
13 pub score: u8,
14 pub proficiency: bool,
15}
16
17impl Add for AbilityScore {
18 type Output = Self;
19
20 fn add(self, other: Self) -> Self {
21 Self {
22 score: self.score + other.score,
23 proficiency: self.proficiency || other.proficiency,
24 }
25 }
26}
27
28impl AddAssign for AbilityScore {
29 fn add_assign(&mut self, other: Self) {
30 self.score += other.score;
31 self.proficiency = self.proficiency || other.proficiency;
32 }
33}
34
35impl Sum for AbilityScore {
36 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
37 let mut total = AbilityScore::default();
38
39 for ability in iter {
40 total += ability;
41 }
42
43 total
44 }
45}
46
47impl AbilityScore {
48 pub fn new(score: u8, proficiency: bool) -> Self {
49 Self { score, proficiency }
50 }
51 pub fn modifier(&self, proficiency_bonus: u8) -> i8 {
54 ((self.score as i8 - 10) as f32 / 2f32).floor() as i8
55 + if self.proficiency {
56 proficiency_bonus as i8
57 } else {
58 0
59 }
60 }
61}
62
63pub const ABILITY_NAMES: [&str; 6] = [
64 "strength",
65 "dexterity",
66 "constitution",
67 "intelligence",
68 "wisdom",
69 "charisma",
70];
71
72#[derive(Debug, Default, Clone)]
73#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
74#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
75#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
76pub struct Abilities {
77 pub strength: AbilityScore,
78 pub dexterity: AbilityScore,
79 pub constitution: AbilityScore,
80 pub intelligence: AbilityScore,
81 pub wisdom: AbilityScore,
82 pub charisma: AbilityScore,
83}
84
85impl Add for Abilities {
86 type Output = Self;
87
88 fn add(self, other: Self) -> Self {
89 Self {
90 strength: self.strength + other.strength,
91 dexterity: self.dexterity + other.dexterity,
92 constitution: self.constitution + other.constitution,
93 intelligence: self.intelligence + other.intelligence,
94 wisdom: self.wisdom + other.wisdom,
95 charisma: self.charisma + other.charisma,
96 }
97 }
98}
99
100impl AddAssign for Abilities {
101 fn add_assign(&mut self, other: Self) {
102 self.strength += other.strength;
103 self.dexterity += other.dexterity;
104 self.constitution += other.constitution;
105 self.intelligence += other.intelligence;
106 self.wisdom += other.wisdom;
107 self.charisma += other.charisma;
108 }
109}
110
111impl Sum for Abilities {
112 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
113 let mut total = Abilities::default();
114
115 for abilities_set in iter {
116 total += abilities_set; }
118
119 total
120 }
121}