veloren_common/comp/body/
quadruped_low.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::QuadrupedLow(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.
35make_case_elim!(
36    species,
37    #[derive(
38        Copy,
39        Clone,
40        Debug,
41        Display,
42        EnumString,
43        PartialEq,
44        Eq,
45        PartialOrd,
46        Ord,
47        Hash,
48        Serialize,
49        Deserialize,
50    )]
51    #[repr(u32)]
52    pub enum Species {
53        Crocodile = 0,
54        Alligator = 1,
55        Salamander = 2,
56        Monitor = 3,
57        Asp = 4,
58        Tortoise = 5,
59        Pangolin = 6,
60        Maneater = 7,
61        Sandshark = 8,
62        Hakulaq = 9,
63        Lavadrake = 10,
64        Basilisk = 11,
65        Deadwood = 12,
66        Icedrake = 13,
67        SeaCrocodile = 14,
68        Dagon = 15,
69        Rocksnapper = 16,
70        Rootsnapper = 17,
71        Reefsnapper = 18,
72        Elbst = 19,
73        Mossdrake = 20,
74        Driggle = 21,
75        Snaretongue = 22,
76        Hydra = 23,
77    }
78);
79
80/// Data representing per-species generic data.
81///
82/// NOTE: Deliberately don't (yet?) implement serialize.
83#[derive(Clone, Debug, Deserialize)]
84pub struct AllSpecies<SpeciesMeta> {
85    pub crocodile: SpeciesMeta,
86    pub sea_crocodile: SpeciesMeta,
87    pub alligator: SpeciesMeta,
88    pub salamander: SpeciesMeta,
89    pub elbst: SpeciesMeta,
90    pub monitor: SpeciesMeta,
91    pub asp: SpeciesMeta,
92    pub tortoise: SpeciesMeta,
93    pub rocksnapper: SpeciesMeta,
94    pub rootsnapper: SpeciesMeta,
95    pub reefsnapper: SpeciesMeta,
96    pub pangolin: SpeciesMeta,
97    pub maneater: SpeciesMeta,
98    pub sandshark: SpeciesMeta,
99    pub hakulaq: SpeciesMeta,
100    pub dagon: SpeciesMeta,
101    pub lavadrake: SpeciesMeta,
102    pub basilisk: SpeciesMeta,
103    pub deadwood: SpeciesMeta,
104    pub icedrake: SpeciesMeta,
105    pub mossdrake: SpeciesMeta,
106    pub driggle: SpeciesMeta,
107    pub snaretongue: SpeciesMeta,
108    pub hydra: SpeciesMeta,
109}
110
111impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
112    type Output = SpeciesMeta;
113
114    #[inline]
115    fn index(&self, &index: &'a Species) -> &Self::Output {
116        match index {
117            Species::Crocodile => &self.crocodile,
118            Species::SeaCrocodile => &self.sea_crocodile,
119            Species::Alligator => &self.alligator,
120            Species::Salamander => &self.salamander,
121            Species::Elbst => &self.elbst,
122            Species::Monitor => &self.monitor,
123            Species::Asp => &self.asp,
124            Species::Tortoise => &self.tortoise,
125            Species::Rocksnapper => &self.rocksnapper,
126            Species::Rootsnapper => &self.rootsnapper,
127            Species::Reefsnapper => &self.reefsnapper,
128            Species::Pangolin => &self.pangolin,
129            Species::Maneater => &self.maneater,
130            Species::Sandshark => &self.sandshark,
131            Species::Hakulaq => &self.hakulaq,
132            Species::Dagon => &self.dagon,
133            Species::Lavadrake => &self.lavadrake,
134            Species::Basilisk => &self.basilisk,
135            Species::Deadwood => &self.deadwood,
136            Species::Icedrake => &self.icedrake,
137            Species::Mossdrake => &self.mossdrake,
138            Species::Driggle => &self.driggle,
139            Species::Snaretongue => &self.snaretongue,
140            Species::Hydra => &self.hydra,
141        }
142    }
143}
144
145pub const ALL_SPECIES: [Species; 24] = [
146    Species::Crocodile,
147    Species::SeaCrocodile,
148    Species::Alligator,
149    Species::Salamander,
150    Species::Elbst,
151    Species::Monitor,
152    Species::Asp,
153    Species::Tortoise,
154    Species::Rocksnapper,
155    Species::Rootsnapper,
156    Species::Reefsnapper,
157    Species::Pangolin,
158    Species::Maneater,
159    Species::Sandshark,
160    Species::Hakulaq,
161    Species::Dagon,
162    Species::Lavadrake,
163    Species::Basilisk,
164    Species::Deadwood,
165    Species::Icedrake,
166    Species::Mossdrake,
167    Species::Driggle,
168    Species::Snaretongue,
169    Species::Hydra,
170];
171
172impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
173    type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
174    type Item = Species;
175
176    fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
177}
178
179// Renaming any enum entries here (re-ordering is fine) will require a
180// database migration to ensure pets correctly de-serialize on player login.
181make_case_elim!(
182    body_type,
183    #[derive(
184        Copy,
185        Clone,
186        Debug,
187        Display,
188        EnumString,
189        PartialEq,
190        Eq,
191        PartialOrd,
192        Ord,
193        Hash,
194        Serialize,
195        Deserialize,
196    )]
197    #[repr(u32)]
198    pub enum BodyType {
199        Female = 0,
200        Male = 1,
201    }
202);
203pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];