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