veloren_common/comp/body/
bird_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::BirdMedium(body) }
31}
32
33make_case_elim!(
34    species,
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)]
50    pub enum Species {
51        SnowyOwl = 0,
52        HornedOwl = 1,
53        Duck = 2,
54        Cockatiel = 3,
55        Chicken = 4,
56        Bat = 5,
57        Penguin = 6,
58        Goose = 7,
59        Peacock = 8,
60        Eagle = 9,
61        Parrot = 10,
62        Crow = 11,
63        Dodo = 12,
64        Parakeet = 13,
65        Puffin = 14,
66        Toucan = 15,
67        BloodmoonBat = 16,
68        VampireBat = 17,
69    }
70);
71
72/// Data representing per-species generic data.
73///
74/// NOTE: Deliberately don't (yet?) implement serialize.
75#[derive(Clone, Debug, Deserialize)]
76pub struct AllSpecies<SpeciesMeta> {
77    pub snowy_owl: SpeciesMeta,
78    pub horned_owl: SpeciesMeta,
79    pub duck: SpeciesMeta,
80    pub cockatiel: SpeciesMeta,
81    pub chicken: SpeciesMeta,
82    pub bat: SpeciesMeta,
83    pub penguin: SpeciesMeta,
84    pub goose: SpeciesMeta,
85    pub peacock: SpeciesMeta,
86    pub eagle: SpeciesMeta,
87    pub parrot: SpeciesMeta,
88    pub crow: SpeciesMeta,
89    pub dodo: SpeciesMeta,
90    pub parakeet: SpeciesMeta,
91    pub puffin: SpeciesMeta,
92    pub toucan: SpeciesMeta,
93    pub bloodmoon_bat: SpeciesMeta,
94    pub vampire_bat: SpeciesMeta,
95}
96
97impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
98    type Output = SpeciesMeta;
99
100    #[inline]
101    fn index(&self, &index: &'a Species) -> &Self::Output {
102        match index {
103            Species::SnowyOwl => &self.snowy_owl,
104            Species::HornedOwl => &self.horned_owl,
105            Species::Duck => &self.duck,
106            Species::Cockatiel => &self.cockatiel,
107            Species::Chicken => &self.chicken,
108            Species::Bat => &self.bat,
109            Species::Penguin => &self.penguin,
110            Species::Goose => &self.goose,
111            Species::Peacock => &self.peacock,
112            Species::Eagle => &self.eagle,
113            Species::Parrot => &self.parrot,
114            Species::Crow => &self.crow,
115            Species::Dodo => &self.dodo,
116            Species::Parakeet => &self.parakeet,
117            Species::Puffin => &self.puffin,
118            Species::Toucan => &self.toucan,
119            Species::BloodmoonBat => &self.bloodmoon_bat,
120            Species::VampireBat => &self.vampire_bat,
121        }
122    }
123}
124
125pub const ALL_SPECIES: [Species; 18] = [
126    Species::SnowyOwl,
127    Species::HornedOwl,
128    Species::Duck,
129    Species::Cockatiel,
130    Species::Chicken,
131    Species::Bat,
132    Species::Penguin,
133    Species::Goose,
134    Species::Peacock,
135    Species::Eagle,
136    Species::Parrot,
137    Species::Crow,
138    Species::Dodo,
139    Species::Parakeet,
140    Species::Puffin,
141    Species::Toucan,
142    Species::BloodmoonBat,
143    Species::VampireBat,
144];
145
146impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
147    type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
148    type Item = Species;
149
150    fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
151}
152
153make_case_elim!(
154    body_type,
155    #[derive(
156        Copy,
157        Clone,
158        Debug,
159        Display,
160        EnumString,
161        PartialEq,
162        Eq,
163        PartialOrd,
164        Ord,
165        Hash,
166        Serialize,
167        Deserialize,
168    )]
169    #[repr(u32)]
170    pub enum BodyType {
171        Female = 0,
172        Male = 1,
173    }
174);
175pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];