veloren_common/comp/body/
biped_large.rs

1use crate::{make_case_elim, make_proj_elim};
2use common_i18n::Content;
3use rand::{seq::SliceRandom, thread_rng};
4use serde::{Deserialize, Serialize};
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    /// Should be only used with npc-tell_monster.
29    ///
30    /// If you want to use for displaying names in HUD, add new strings.
31    /// If you want to use for anything else, add new strings.
32    pub fn localize_npc(&self) -> Option<Content> {
33        let key = match &self.species {
34            Species::Ogre => match self.body_type {
35                BodyType::Male => "body-npc-speech-biped_large-ogre-male",
36                BodyType::Female => "body-npc-speech-biped_large-ogre-female",
37            },
38            Species::Cyclops => "body-npc-speech-biped_large-cyclops",
39            Species::Wendigo => "body-npc-speech-biped_large-wendigo",
40            Species::Werewolf => "body-npc-speech-biped_large-werewolf",
41            Species::Cavetroll => "body-npc-speech-biped_large-cave_troll",
42            Species::Mountaintroll => "body-npc-speech-biped_large-mountain_troll",
43            Species::Swamptroll => "body-npc-speech-biped_large-swamp_troll",
44            Species::Blueoni => "body-npc-speech-biped_large-blue_oni",
45            Species::Redoni => "body-npc-speech-biped_large-red_oni",
46            Species::Tursus => "body-npc-speech-biped_large-tursus",
47            Species::Dullahan => "body-npc-speech-biped_large-dullahan",
48            Species::Occultsaurok => "body-npc-speech-biped_large-occult_saurok",
49            Species::Mightysaurok => "body-npc-speech-biped_large-mighty_saurok",
50            Species::Slysaurok => "body-npc-speech-biped_large-sly_saurok",
51            Species::Mindflayer => "body-npc-speech-biped_large-mindflayer",
52            Species::Minotaur => "body-npc-speech-biped_large-minotaur",
53            Species::Tidalwarrior => "body-npc-speech-biped_large-tidal_warrior",
54            Species::Yeti => "body-npc-speech-biped_large-yeti",
55            Species::Harvester => "body-npc-speech-biped_large-harvester",
56            Species::Cultistwarlord => "body-npc-speech-biped_large-cultist_warlord",
57            Species::Cultistwarlock => "body-npc-speech-biped_large-cultist_warlock",
58            Species::Huskbrute => "body-npc-speech-biped_large-husk_brute",
59            Species::Gigasfrost => "body-npc-speech-biped_large-gigas_frost",
60            Species::AdletElder => "body-npc-speech-biped_large-adlet_elder",
61            Species::SeaBishop => "body-npc-speech-biped_large-sea_bishop",
62            Species::HaniwaGeneral => "body-npc-speech-biped_large-haniwa_general",
63            Species::TerracottaBesieger => "body-npc-speech-biped_large-terracotta_besieger",
64            Species::TerracottaDemolisher => "body-npc-speech-biped_large-terracotta_demolisher",
65            Species::TerracottaPunisher => "body-npc-speech-biped_large-terracotta_punisher",
66            Species::TerracottaPursuer => "body-npc-speech-biped_large-terracotta_pursuer",
67            Species::Cursekeeper => "body-npc-speech-biped_large-cursekeeper",
68            Species::Forgemaster => "body-npc-speech-biped_large-forgemaster",
69            Species::Strigoi => "body-npc-speech-biped_large-strigoi",
70            Species::Executioner => "body-npc-speech-biped_large-executioner",
71        };
72
73        Some(Content::localized(key))
74    }
75}
76
77impl From<Body> for super::Body {
78    fn from(body: Body) -> Self { super::Body::BipedLarge(body) }
79}
80
81make_case_elim!(
82    species,
83    #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
84    #[repr(u32)]
85    pub enum Species {
86        Ogre = 0,
87        Cyclops = 1,
88        Wendigo = 2,
89        Cavetroll = 3,
90        Mountaintroll = 4,
91        Swamptroll = 5,
92        Dullahan = 6,
93        Werewolf = 7,
94        Occultsaurok = 8,
95        Mightysaurok = 9,
96        Slysaurok = 10,
97        Mindflayer = 11,
98        Minotaur = 12,
99        Tidalwarrior = 13,
100        Yeti = 14,
101        Harvester = 15,
102        Blueoni = 16,
103        Redoni = 17,
104        Cultistwarlord = 18,
105        Cultistwarlock = 19,
106        Huskbrute = 20,
107        Tursus = 21,
108        Gigasfrost = 22,
109        AdletElder = 23,
110        SeaBishop = 24,
111        HaniwaGeneral = 25,
112        TerracottaBesieger = 26,
113        TerracottaDemolisher = 27,
114        TerracottaPunisher = 28,
115        TerracottaPursuer = 29,
116        Cursekeeper = 30,
117        Forgemaster = 31,
118        Strigoi = 32,
119        Executioner = 33,
120    }
121);
122
123/// Data representing per-species generic data.
124///
125/// NOTE: Deliberately don't (yet?) implement serialize.
126#[derive(Clone, Debug, Deserialize)]
127pub struct AllSpecies<SpeciesMeta> {
128    pub ogre: SpeciesMeta,
129    pub cyclops: SpeciesMeta,
130    pub wendigo: SpeciesMeta,
131    pub troll_cave: SpeciesMeta,
132    pub troll_mountain: SpeciesMeta,
133    pub troll_swamp: SpeciesMeta,
134    pub dullahan: SpeciesMeta,
135    pub werewolf: SpeciesMeta,
136    pub saurok_occult: SpeciesMeta,
137    pub saurok_mighty: SpeciesMeta,
138    pub saurok_sly: SpeciesMeta,
139    pub mindflayer: SpeciesMeta,
140    pub minotaur: SpeciesMeta,
141    pub tidalwarrior: SpeciesMeta,
142    pub yeti: SpeciesMeta,
143    pub harvester: SpeciesMeta,
144    pub oni_blue: SpeciesMeta,
145    pub oni_red: SpeciesMeta,
146    pub cultist_warlord: SpeciesMeta,
147    pub cultist_warlock: SpeciesMeta,
148    pub husk_brute: SpeciesMeta,
149    pub tursus: SpeciesMeta,
150    pub gigas_frost: SpeciesMeta,
151    pub adlet_elder: SpeciesMeta,
152    pub sea_bishop: SpeciesMeta,
153    pub haniwa_general: SpeciesMeta,
154    pub terracotta_besieger: SpeciesMeta,
155    pub terracotta_demolisher: SpeciesMeta,
156    pub terracotta_punisher: SpeciesMeta,
157    pub terracotta_pursuer: SpeciesMeta,
158    pub cursekeeper: SpeciesMeta,
159    pub forgemaster: SpeciesMeta,
160    pub strigoi: SpeciesMeta,
161    pub executioner: SpeciesMeta,
162}
163
164impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
165    type Output = SpeciesMeta;
166
167    #[inline]
168    fn index(&self, &index: &'a Species) -> &Self::Output {
169        match index {
170            Species::Ogre => &self.ogre,
171            Species::Cyclops => &self.cyclops,
172            Species::Wendigo => &self.wendigo,
173            Species::Cavetroll => &self.troll_cave,
174            Species::Mountaintroll => &self.troll_mountain,
175            Species::Swamptroll => &self.troll_swamp,
176            Species::Dullahan => &self.dullahan,
177            Species::Werewolf => &self.werewolf,
178            Species::Occultsaurok => &self.saurok_occult,
179            Species::Mightysaurok => &self.saurok_mighty,
180            Species::Slysaurok => &self.saurok_sly,
181            Species::Mindflayer => &self.mindflayer,
182            Species::Minotaur => &self.minotaur,
183            Species::Tidalwarrior => &self.tidalwarrior,
184            Species::Yeti => &self.yeti,
185            Species::Harvester => &self.harvester,
186            Species::Blueoni => &self.oni_blue,
187            Species::Redoni => &self.oni_red,
188            Species::Cultistwarlord => &self.cultist_warlord,
189            Species::Cultistwarlock => &self.cultist_warlock,
190            Species::Huskbrute => &self.husk_brute,
191            Species::Tursus => &self.tursus,
192            Species::Gigasfrost => &self.gigas_frost,
193            Species::AdletElder => &self.adlet_elder,
194            Species::SeaBishop => &self.sea_bishop,
195            Species::HaniwaGeneral => &self.haniwa_general,
196            Species::TerracottaBesieger => &self.terracotta_besieger,
197            Species::TerracottaDemolisher => &self.terracotta_demolisher,
198            Species::TerracottaPunisher => &self.terracotta_punisher,
199            Species::TerracottaPursuer => &self.terracotta_pursuer,
200            Species::Cursekeeper => &self.cursekeeper,
201            Species::Forgemaster => &self.forgemaster,
202            Species::Strigoi => &self.strigoi,
203            Species::Executioner => &self.executioner,
204        }
205    }
206}
207
208pub const ALL_SPECIES: [Species; 34] = [
209    Species::Ogre,
210    Species::Cyclops,
211    Species::Wendigo,
212    Species::Cavetroll,
213    Species::Mountaintroll,
214    Species::Swamptroll,
215    Species::Dullahan,
216    Species::Werewolf,
217    Species::Occultsaurok,
218    Species::Mightysaurok,
219    Species::Slysaurok,
220    Species::Mindflayer,
221    Species::Minotaur,
222    Species::Tidalwarrior,
223    Species::Yeti,
224    Species::Harvester,
225    Species::Blueoni,
226    Species::Redoni,
227    Species::Cultistwarlord,
228    Species::Cultistwarlock,
229    Species::Huskbrute,
230    Species::Tursus,
231    Species::Gigasfrost,
232    Species::AdletElder,
233    Species::SeaBishop,
234    Species::HaniwaGeneral,
235    Species::TerracottaBesieger,
236    Species::TerracottaDemolisher,
237    Species::TerracottaPunisher,
238    Species::TerracottaPursuer,
239    Species::Cursekeeper,
240    Species::Forgemaster,
241    Species::Strigoi,
242    Species::Executioner,
243];
244
245impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
246    type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
247    type Item = Species;
248
249    fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
250}
251
252make_case_elim!(
253    body_type,
254    #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
255    #[repr(u32)]
256    pub enum BodyType {
257        Female = 0,
258        Male = 1,
259    }
260);
261pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];