1use crate::{make_case_elim, make_proj_elim};
2use rand::{seq::SliceRandom, thread_rng};
3use serde::{Deserialize, Serialize};
4use strum::{Display, EnumString};
5
6make_proj_elim!(
7 body,
8 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
9 pub struct Body {
10 pub species: Species,
11 pub body_type: BodyType,
12 }
13);
14
15impl Body {
16 pub fn random() -> Self {
17 let mut rng = thread_rng();
18 let species = *ALL_SPECIES.choose(&mut rng).unwrap();
19 Self::random_with(&mut rng, &species)
20 }
21
22 #[inline]
23 pub fn random_with(rng: &mut impl rand::Rng, &species: &Species) -> Self {
24 let body_type = *ALL_BODY_TYPES.choose(rng).unwrap();
25 Self { species, body_type }
26 }
27}
28
29impl From<Body> for super::Body {
30 fn from(body: Body) -> Self { super::Body::QuadrupedMedium(body) }
31}
32
33#[derive(
36 Copy,
37 Clone,
38 Debug,
39 Display,
40 EnumString,
41 PartialEq,
42 Eq,
43 PartialOrd,
44 Ord,
45 Hash,
46 Serialize,
47 Deserialize,
48)]
49#[repr(u32)]
50pub enum Species {
51 Grolgar = 0,
52 Saber = 1,
53 Tiger = 2,
54 Tuskram = 3,
55 Lion = 6,
56 Tarasque = 7,
57 Wolf = 8,
58 Frostfang = 9,
59 Mouflon = 10,
60 Catoblepas = 11,
61 Bonerattler = 12,
62 Deer = 13,
63 Hirdrasil = 14,
64 Roshwalr = 15,
65 Donkey = 16,
66 Camel = 17,
67 Zebra = 18,
68 Antelope = 19,
69 Kelpie = 20,
70 Horse = 21,
71 Barghest = 22,
72 Cattle = 23,
73 Darkhound = 24,
74 Highland = 25,
75 Yak = 26,
76 Panda = 27,
77 Bear = 28,
78 Dreadhorn = 29,
79 Moose = 30,
80 Snowleopard = 31,
81 Mammoth = 32,
82 Ngoubou = 33,
83 Llama = 34,
84 Alpaca = 35,
85 Akhlut = 36,
86 Bristleback = 37,
87 ClaySteed = 38,
88}
89
90#[derive(Clone, Debug, Deserialize)]
94pub struct AllSpecies<SpeciesMeta> {
95 pub grolgar: SpeciesMeta,
96 pub saber: SpeciesMeta,
97 pub tiger: SpeciesMeta,
98 pub tuskram: SpeciesMeta,
99 pub lion: SpeciesMeta,
100 pub tarasque: SpeciesMeta,
101 pub wolf: SpeciesMeta,
102 pub frostfang: SpeciesMeta,
103 pub mouflon: SpeciesMeta,
104 pub catoblepas: SpeciesMeta,
105 pub bonerattler: SpeciesMeta,
106 pub deer: SpeciesMeta,
107 pub hirdrasil: SpeciesMeta,
108 pub roshwalr: SpeciesMeta,
109 pub donkey: SpeciesMeta,
110 pub camel: SpeciesMeta,
111 pub zebra: SpeciesMeta,
112 pub antelope: SpeciesMeta,
113 pub kelpie: SpeciesMeta,
114 pub horse: SpeciesMeta,
115 pub barghest: SpeciesMeta,
116 pub cattle: SpeciesMeta,
117 pub darkhound: SpeciesMeta,
118 pub highland: SpeciesMeta,
119 pub yak: SpeciesMeta,
120 pub panda: SpeciesMeta,
121 pub bear: SpeciesMeta,
122 pub dreadhorn: SpeciesMeta,
123 pub moose: SpeciesMeta,
124 pub snowleopard: SpeciesMeta,
125 pub mammoth: SpeciesMeta,
126 pub ngoubou: SpeciesMeta,
127 pub llama: SpeciesMeta,
128 pub alpaca: SpeciesMeta,
129 pub akhlut: SpeciesMeta,
130 pub bristleback: SpeciesMeta,
131 pub claysteed: SpeciesMeta,
132}
133
134impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
135 type Output = SpeciesMeta;
136
137 #[inline]
138 fn index(&self, &index: &'a Species) -> &Self::Output {
139 match index {
140 Species::Grolgar => &self.grolgar,
141 Species::Saber => &self.saber,
142 Species::Tiger => &self.tiger,
143 Species::Tuskram => &self.tuskram,
144 Species::Lion => &self.lion,
145 Species::Tarasque => &self.tarasque,
146 Species::Wolf => &self.wolf,
147 Species::Frostfang => &self.frostfang,
148 Species::Mouflon => &self.mouflon,
149 Species::Catoblepas => &self.catoblepas,
150 Species::Bonerattler => &self.bonerattler,
151 Species::Deer => &self.deer,
152 Species::Hirdrasil => &self.hirdrasil,
153 Species::Roshwalr => &self.roshwalr,
154 Species::Donkey => &self.donkey,
155 Species::Camel => &self.camel,
156 Species::Zebra => &self.zebra,
157 Species::Antelope => &self.antelope,
158 Species::Kelpie => &self.kelpie,
159 Species::Horse => &self.horse,
160 Species::Barghest => &self.barghest,
161 Species::Cattle => &self.cattle,
162 Species::Darkhound => &self.darkhound,
163 Species::Highland => &self.highland,
164 Species::Yak => &self.yak,
165 Species::Panda => &self.panda,
166 Species::Bear => &self.bear,
167 Species::Dreadhorn => &self.dreadhorn,
168 Species::Moose => &self.moose,
169 Species::Snowleopard => &self.snowleopard,
170 Species::Mammoth => &self.mammoth,
171 Species::Ngoubou => &self.ngoubou,
172 Species::Llama => &self.llama,
173 Species::Alpaca => &self.alpaca,
174 Species::Akhlut => &self.akhlut,
175 Species::Bristleback => &self.bristleback,
176 Species::ClaySteed => &self.claysteed,
177 }
178 }
179}
180
181pub const ALL_SPECIES: [Species; 37] = [
182 Species::Grolgar,
183 Species::Saber,
184 Species::Tiger,
185 Species::Tuskram,
186 Species::Lion,
187 Species::Tarasque,
188 Species::Wolf,
189 Species::Frostfang,
190 Species::Mouflon,
191 Species::Catoblepas,
192 Species::Bonerattler,
193 Species::Deer,
194 Species::Hirdrasil,
195 Species::Roshwalr,
196 Species::Donkey,
197 Species::Camel,
198 Species::Zebra,
199 Species::Antelope,
200 Species::Kelpie,
201 Species::Horse,
202 Species::Barghest,
203 Species::Cattle,
204 Species::Darkhound,
205 Species::Highland,
206 Species::Yak,
207 Species::Panda,
208 Species::Bear,
209 Species::Dreadhorn,
210 Species::Moose,
211 Species::Snowleopard,
212 Species::Mammoth,
213 Species::Ngoubou,
214 Species::Llama,
215 Species::Alpaca,
216 Species::Akhlut,
217 Species::Bristleback,
218 Species::ClaySteed,
219];
220
221impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
222 type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
223 type Item = Species;
224
225 fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
226}
227
228make_case_elim!(
231 body_type,
232 #[derive(
233 Copy,
234 Clone,
235 Debug,
236 Display,
237 EnumString,
238 PartialEq,
239 Eq,
240 PartialOrd,
241 Ord,
242 Hash,
243 Serialize,
244 Deserialize,
245 )]
246 #[repr(u32)]
247 pub enum BodyType {
248 Female = 0,
249 Male = 1,
250 }
251);
252
253pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];