veloren_common/comp/body/
crustacean.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::Crustacean(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        Crab = 0,
54        SoldierCrab = 1,
55        Karkatha = 2,
56    }
57);
58
59/// Data representing per-species generic data.
60#[derive(Clone, Debug, Serialize, Deserialize)]
61pub struct AllSpecies<SpeciesMeta> {
62    pub crab: SpeciesMeta,
63    pub soldier_crab: SpeciesMeta,
64    pub karkatha: SpeciesMeta,
65}
66
67impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
68    type Output = SpeciesMeta;
69
70    #[inline]
71    fn index(&self, &index: &'a Species) -> &Self::Output {
72        match index {
73            Species::Crab => &self.crab,
74            Species::SoldierCrab => &self.soldier_crab,
75            Species::Karkatha => &self.karkatha,
76        }
77    }
78}
79
80pub const ALL_SPECIES: [Species; 3] = [Species::Crab, Species::SoldierCrab, Species::Karkatha];
81
82impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
83    type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
84    type Item = Species;
85
86    fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
87}
88
89make_case_elim!(
90    body_type,
91    #[derive(
92        Copy,
93        Clone,
94        Debug,
95        Display,
96        EnumString,
97        PartialEq,
98        Eq,
99        PartialOrd,
100        Ord,
101        Hash,
102        Serialize,
103        Deserialize,
104    )]
105    #[repr(u32)]
106    pub enum BodyType {
107        Female = 0,
108        Male = 1,
109    }
110);
111pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];