1extern crate hashbrown;
2
3use crate::prelude::*;
4use crate::num::*;
5use crate::rc::{ RcStr, Counter, AtomicCounter };
6use hashbrown::HashSet;
7
8struct JewelStore<C = AtomicCounter>
9where
10 C: Counter
11{
12 modifiers: HashSet<Modifier<C>>,
13 jewels: Vec<Jewel<C>>
14}
15
16struct Jewel<C = AtomicCounter>
17where
18 C: Counter
19{
20 level: u16,
21 size: i16,
22 modifiers: JewelModifiers<C>
23}
24
25enum JewelModifiers<C = AtomicCounter>
26where
27 C: Counter
28{
29 Chipped([ModifierInstance<C>; 1]),
30 Flawed([ModifierInstance<C>; 2]),
31 Flawless([ModifierInstance<C>; 3]),
32 Perfect([ModifierInstance<C>; 4])
33}
34
35struct ModifierInstance<C = AtomicCounter>
36where
37 C: Counter
38{
39 modifier: Modifier<C>,
40 value: ModifierValue
41}
42
43struct Modifier<C = AtomicCounter>
44where
45 C: Counter
46{
47 inner: RcStr<C, ModifierMeta<C>>
48}
49
50struct ModifierMeta<C = AtomicCounter>
51where
52 C: Counter
53{
54 display_name: RcStr<C>,
55 modifier_type: ModifierType
56}
57
58enum ModifierType {
61 Flag,
66
67 NumericValue {
69 decimal_shift: u8
76 }
77}
78
79struct ModifierValue {
81 raw: i32
84}
85
86impl JewelStore {
87 #[inline]
88 fn new() -> Self {
89 Self::with_counter()
90 }
91
92 #[inline]
93 fn with_counter<C>() -> JewelStore<C>
94 where
95 C: Counter
96 {
97 JewelStore {
98 modifiers: HashSet::new(),
99 jewels: Vec::new()
100 }
101 }
102}
103
104impl<C> JewelStore<C>
105where
106 C: Counter
107{
108 #[inline]
111 fn add_modifier(&mut self, id: &str, display_name: &str, modifier_type: ModifierType) -> Result<(), ()> {
112 if self.modifiers.get(id).is_none() {
113 let modifier = Modifier::new(id, display_name, modifier_type);
114
115 unsafe {
117 self.modifiers.insert_unique_unchecked(modifier);
118 }
119
120 Ok(())
121 } else {
122 Err(())
123 }
124 }
125}
126
127impl<C> Modifier<C>
128where
129 C: Counter
130{
131 #[inline]
137 fn new(id: &str, display_name: &str, modifier_type: ModifierType) -> Self {
138 Self {
139 inner: RcStr::with_metadata(id, ModifierMeta {
140 display_name: RcStr::new(display_name),
141 modifier_type
142 })
143 }
144 }
145}
146
147impl<C> Borrow<str> for Modifier<C>
148where
149 C: Counter
150{
151 #[inline]
152 fn borrow(&self) -> &str {
153 &self.inner
154 }
155}
156
157impl<C> Clone for Modifier<C>
158where
159 C: Counter
160{
161 #[inline]
162 fn clone(&self) -> Self {
163 Self { inner: self.inner.clone() }
164 }
165}
166
167impl<C, C2> PartialEq<Modifier<C2>> for Modifier<C>
168where
169 C: Counter,
170 C2: Counter
171{
172 #[inline]
173 fn eq(&self, other: &Modifier<C2>) -> bool {
174 *self.inner == *other.inner
175 }
176}
177
178impl<C> Eq for Modifier<C>
179where
180 C: Counter
181{}
182
183impl<C> Hash for Modifier<C>
184where
185 C: Counter
186{
187 #[inline]
188 fn hash<H>(&self, state: &mut H)
189 where
190 H: Hasher
191 {
192 Hash::hash(&*self.inner, state)
193 }
194}
195
196impl ModifierValue {
197 const MAX: i32 = i32::MAX >> 1;
199
200 const MIN: i32 = i32::MIN >> 1;
202
203 #[inline]
204 fn new(value: i32, is_legendary: bool) -> Self {
205 Self::new_checked(value, is_legendary)
206 .expect("modifier value out of bounds")
207 }
208
209 #[inline]
210 fn new_checked(value: i32, is_legendary: bool) -> Option<Self> {
211 (Self::MIN..=Self::MAX).contains(&value).then(|| {
212 unsafe { Self::new_unchecked(value, is_legendary) }
214 })
215 }
216
217 #[inline]
221 unsafe fn new_unchecked(value: i32, is_legendary: bool) -> Self {
222 Self { raw: value | (is_legendary.into_i32() << 31) }
223 }
224
225 #[inline]
226 fn value(&self) -> i32 {
227 (self.raw << 1) >> 1
230 }
231
232 #[inline]
233 fn is_legendary(&self) -> bool {
234 self.raw >> 31 == 1
235 }
236}