veloren_common/comp/body/
quadruped_medium.rs

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// Renaming any enum entries here (re-ordering is fine) will require a
34// database migration to ensure pets correctly de-serialize on player login.
35#[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/// Data representing per-species generic data.
91///
92/// NOTE: Deliberately don't (yet?) implement serialize.
93#[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
228// Renaming any enum entries here (re-ordering is fine) will require a
229// database migration to ensure pets correctly de-serialize on player login.
230make_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];