1pub mod arthropod;
2pub mod biped_large;
3pub mod biped_small;
4pub mod bird_large;
5pub mod bird_medium;
6pub mod crustacean;
7pub mod dragon;
8pub mod fish_medium;
9pub mod fish_small;
10pub mod golem;
11pub mod humanoid;
12pub mod item;
13pub mod object;
14pub mod parts;
15pub mod plugin;
16pub mod quadruped_low;
17pub mod quadruped_medium;
18pub mod quadruped_small;
19pub mod ship;
20pub mod theropod;
21
22use crate::{
23 assets::{BoxedError, FileAsset, load_ron},
24 consts::{HUMAN_DENSITY, WATER_DENSITY},
25 npc::NpcKind,
26};
27use common_base::enum_iter;
28use common_i18n::Content;
29use serde::{Deserialize, Serialize};
30use specs::{Component, DerefFlaggedStorage};
31use strum::{Display, IntoEnumIterator};
32use vek::*;
33
34use super::{BuffKind, CapsulePrism, Collider, Density, Mass, Scale};
35
36enum_iter! {
37 #[derive(
38 Copy, Clone, Debug, Display, PartialEq, PartialOrd, Ord, Eq, Hash, Serialize, Deserialize,
39 )]
40 #[repr(u32)]
41 pub enum Body {
42 Humanoid(humanoid::Body) = 0,
43 QuadrupedSmall(quadruped_small::Body) = 1,
44 QuadrupedMedium(quadruped_medium::Body) = 2,
45 BirdMedium(bird_medium::Body) = 3,
46 FishMedium(fish_medium::Body) = 4,
47 Dragon(dragon::Body) = 5,
48 BirdLarge(bird_large::Body) = 6,
49 FishSmall(fish_small::Body) = 7,
50 BipedLarge(biped_large::Body) = 8,
51 BipedSmall(biped_small::Body) = 9,
52 Object(object::Body) = 10,
53 Golem(golem::Body) = 11,
54 Theropod(theropod::Body) = 12,
55 QuadrupedLow(quadruped_low::Body) = 13,
56 Ship(ship::Body) = 14,
57 Arthropod(arthropod::Body) = 15,
58 Item(item::Body) = 16,
59 Crustacean(crustacean::Body) = 17,
60 Plugin(plugin::Body) = 18,
61 }
62}
63
64impl Default for Body {
66 fn default() -> Self {
67 Body::QuadrupedSmall(quadruped_small::Body {
68 species: quadruped_small::Species::Frog,
69 body_type: quadruped_small::BodyType::Female,
70 })
71 }
72}
73
74#[derive(Clone, Debug, Deserialize, Serialize)]
76pub struct BodyData<BodyMeta, SpeciesData> {
77 pub body: BodyMeta,
79 pub species: SpeciesData,
81}
82
83#[derive(Clone, Debug, Deserialize, Serialize)]
89pub struct AllBodies<BodyMeta, SpeciesMeta> {
90 pub humanoid: BodyData<BodyMeta, humanoid::AllSpecies<SpeciesMeta>>,
91 pub quadruped_small: BodyData<BodyMeta, quadruped_small::AllSpecies<SpeciesMeta>>,
92 pub quadruped_medium: BodyData<BodyMeta, quadruped_medium::AllSpecies<SpeciesMeta>>,
93 pub bird_medium: BodyData<BodyMeta, bird_medium::AllSpecies<SpeciesMeta>>,
94 pub fish_medium: BodyData<BodyMeta, fish_medium::AllSpecies<SpeciesMeta>>,
95 pub dragon: BodyData<BodyMeta, dragon::AllSpecies<SpeciesMeta>>,
96 pub bird_large: BodyData<BodyMeta, bird_large::AllSpecies<SpeciesMeta>>,
97 pub fish_small: BodyData<BodyMeta, fish_small::AllSpecies<SpeciesMeta>>,
98 pub biped_large: BodyData<BodyMeta, biped_large::AllSpecies<SpeciesMeta>>,
99 pub biped_small: BodyData<BodyMeta, biped_small::AllSpecies<SpeciesMeta>>,
100 pub object: BodyData<BodyMeta, ()>,
101 pub item: BodyData<BodyMeta, ()>,
102 pub golem: BodyData<BodyMeta, golem::AllSpecies<SpeciesMeta>>,
103 pub theropod: BodyData<BodyMeta, theropod::AllSpecies<SpeciesMeta>>,
104 pub quadruped_low: BodyData<BodyMeta, quadruped_low::AllSpecies<SpeciesMeta>>,
105 pub ship: BodyData<BodyMeta, ()>,
106 pub arthropod: BodyData<BodyMeta, arthropod::AllSpecies<SpeciesMeta>>,
107 pub crustacean: BodyData<BodyMeta, crustacean::AllSpecies<SpeciesMeta>>,
108 pub plugin: BodyData<BodyMeta, plugin::AllSpecies<SpeciesMeta>>,
109}
110
111impl<BodyMeta, SpeciesMeta> AllBodies<BodyMeta, SpeciesMeta> {
112 pub fn get_species_meta<'a>(&'a self, body: &Body) -> Option<&'a SpeciesMeta> {
117 Some(match body {
118 Body::Humanoid(b) => &self.humanoid.species[&b.species],
119 Body::QuadrupedSmall(b) => &self.quadruped_small.species[&b.species],
120 Body::QuadrupedMedium(b) => &self.quadruped_medium.species[&b.species],
121 Body::BirdMedium(b) => &self.bird_medium.species[&b.species],
122 Body::BirdLarge(b) => &self.bird_large.species[&b.species],
123 Body::FishMedium(b) => &self.fish_medium.species[&b.species],
124 Body::Dragon(b) => &self.dragon.species[&b.species],
125 Body::FishSmall(b) => &self.fish_small.species[&b.species],
126 Body::BipedLarge(b) => &self.biped_large.species[&b.species],
127 Body::BipedSmall(b) => &self.biped_small.species[&b.species],
128 Body::Golem(b) => &self.golem.species[&b.species],
129 Body::Theropod(b) => &self.theropod.species[&b.species],
130 Body::QuadrupedLow(b) => &self.quadruped_low.species[&b.species],
131 Body::Arthropod(b) => &self.arthropod.species[&b.species],
132 Body::Crustacean(b) => &self.crustacean.species[&b.species],
133 Body::Plugin(b) => &self.plugin.species[&b.species],
134 Body::Item(_) | Body::Ship(_) | Body::Object(_) => return None,
135 })
136 }
137}
138
139impl<BodyMeta, SpeciesMeta> core::ops::Index<NpcKind> for AllBodies<BodyMeta, SpeciesMeta> {
141 type Output = BodyMeta;
142
143 #[inline]
144 fn index(&self, index: NpcKind) -> &Self::Output {
145 match index {
146 NpcKind::Humanoid => &self.humanoid.body,
147 NpcKind::Pig => &self.quadruped_small.body,
148 NpcKind::Wolf => &self.quadruped_medium.body,
149 NpcKind::Duck => &self.bird_medium.body,
150 NpcKind::Phoenix => &self.bird_large.body,
151 NpcKind::Marlin => &self.fish_medium.body,
152 NpcKind::Clownfish => &self.fish_small.body,
153 NpcKind::Ogre => &self.biped_large.body,
154 NpcKind::Gnome => &self.biped_small.body,
155 NpcKind::StoneGolem => &self.golem.body,
156 NpcKind::Archaeos => &self.theropod.body,
157 NpcKind::Reddragon => &self.dragon.body,
158 NpcKind::Crocodile => &self.quadruped_low.body,
159 NpcKind::Tarantula => &self.arthropod.body,
160 NpcKind::Crab => &self.crustacean.body,
161 NpcKind::Plugin => &self.plugin.body,
162 }
163 }
164}
165
166impl<BodyMeta, SpeciesMeta> core::ops::Index<&Body> for AllBodies<BodyMeta, SpeciesMeta> {
168 type Output = BodyMeta;
169
170 #[inline]
171 fn index(&self, index: &Body) -> &Self::Output {
172 match index {
173 Body::Humanoid(_) => &self.humanoid.body,
174 Body::QuadrupedSmall(_) => &self.quadruped_small.body,
175 Body::QuadrupedMedium(_) => &self.quadruped_medium.body,
176 Body::BirdMedium(_) => &self.bird_medium.body,
177 Body::BirdLarge(_) => &self.bird_large.body,
178 Body::FishMedium(_) => &self.fish_medium.body,
179 Body::Dragon(_) => &self.dragon.body,
180 Body::FishSmall(_) => &self.fish_small.body,
181 Body::BipedLarge(_) => &self.biped_large.body,
182 Body::BipedSmall(_) => &self.biped_small.body,
183 Body::Object(_) => &self.object.body,
184 Body::Item(_) => &self.item.body,
185 Body::Golem(_) => &self.golem.body,
186 Body::Theropod(_) => &self.theropod.body,
187 Body::QuadrupedLow(_) => &self.quadruped_low.body,
188 Body::Arthropod(_) => &self.arthropod.body,
189 Body::Ship(_) => &self.ship.body,
190 Body::Crustacean(_) => &self.crustacean.body,
191 Body::Plugin(_) => &self.plugin.body,
192 }
193 }
194}
195
196impl<
197 BodyMeta: Send + Sync + for<'de> serde::Deserialize<'de> + 'static,
198 SpeciesMeta: Send + Sync + for<'de> serde::Deserialize<'de> + 'static,
199> FileAsset for AllBodies<BodyMeta, SpeciesMeta>
200{
201 const EXTENSION: &'static str = "ron";
202
203 fn from_bytes(bytes: std::borrow::Cow<[u8]>) -> Result<Self, BoxedError> { load_ron(&bytes) }
204}
205
206#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
217pub enum Gender {
218 Masculine,
219 Feminine,
220 Neuter,
221}
222
223impl Body {
224 pub fn is_same_species_as(&self, other: &Body) -> bool {
225 match self {
226 Body::Humanoid(b1) => match other {
227 Body::Humanoid(b2) => b1.species == b2.species,
228 _ => false,
229 },
230 Body::QuadrupedSmall(b1) => match other {
231 Body::QuadrupedSmall(b2) => b1.species == b2.species,
232 _ => false,
233 },
234 Body::QuadrupedMedium(b1) => match other {
235 Body::QuadrupedMedium(b2) => b1.species == b2.species,
236 _ => false,
237 },
238 Body::BirdMedium(b1) => match other {
239 Body::BirdMedium(b2) => b1.species == b2.species,
240 _ => false,
241 },
242 Body::BirdLarge(b1) => match other {
243 Body::BirdLarge(b2) => b1.species == b2.species,
244 _ => false,
245 },
246 Body::FishMedium(b1) => match other {
247 Body::FishMedium(b2) => b1.species == b2.species,
248 _ => false,
249 },
250 Body::Dragon(b1) => match other {
251 Body::Dragon(b2) => b1.species == b2.species,
252 _ => false,
253 },
254 Body::FishSmall(b1) => match other {
255 Body::FishSmall(b2) => b1.species == b2.species,
256 _ => false,
257 },
258 Body::BipedLarge(b1) => match other {
259 Body::BipedLarge(b2) => b1.species == b2.species,
260 _ => false,
261 },
262 Body::BipedSmall(b1) => match other {
263 Body::BipedSmall(b2) => b1.species == b2.species,
264 _ => false,
265 },
266 Body::Object(_) => false,
267 Body::Item(_) => false,
268 Body::Golem(b1) => match other {
269 Body::Golem(b2) => b1.species == b2.species,
270 _ => false,
271 },
272 Body::Theropod(b1) => match other {
273 Body::Theropod(b2) => b1.species == b2.species,
274 _ => false,
275 },
276 Body::QuadrupedLow(b1) => match other {
277 Body::QuadrupedLow(b2) => b1.species == b2.species,
278 _ => false,
279 },
280 Body::Arthropod(b1) => match other {
281 Body::Arthropod(b2) => b1.species == b2.species,
282 _ => false,
283 },
284 Body::Ship(_) => false,
285 Body::Crustacean(b1) => match other {
286 Body::Crustacean(b2) => b1.species == b2.species,
287 _ => false,
288 },
289 Body::Plugin(b1) => match other {
290 Body::Plugin(b2) => b1.species == b2.species,
291 _ => false,
292 },
293 }
294 }
295
296 pub fn heads(&self) -> Option<usize> {
298 match self {
299 Body::QuadrupedLow(body) => match body.species {
300 quadruped_low::Species::Hydra => Some(3),
301 _ => None,
302 },
303 _ => None,
304 }
305 }
306
307 pub fn has_free_will(&self) -> bool {
309 match self {
310 Body::Humanoid(_) | Body::BipedLarge(_) | Body::BipedSmall(_) => true,
311 Body::Crustacean(body) => match body.species {
312 crustacean::Species::Crab => false,
313 crustacean::Species::SoldierCrab => false,
314 crustacean::Species::Karkatha => true,
315 },
316 Body::QuadrupedSmall(_)
317 | Body::QuadrupedMedium(_)
318 | Body::BirdMedium(_)
319 | Body::FishMedium(_)
320 | Body::Dragon(_)
321 | Body::BirdLarge(_)
322 | Body::FishSmall(_)
323 | Body::Object(_)
324 | Body::Golem(_)
325 | Body::Theropod(_)
326 | Body::QuadrupedLow(_)
327 | Body::Ship(_)
328 | Body::Arthropod(_)
329 | Body::Item(_)
330 | Body::Plugin(_) => false,
331 }
332 }
333
334 pub fn is_humanoid(&self) -> bool { matches!(self, Body::Humanoid(_)) }
335
336 pub fn is_campfire(&self) -> bool { matches!(self, Body::Object(object::Body::CampfireLit)) }
337
338 pub fn is_portal(&self) -> bool {
339 matches!(
340 self,
341 Body::Object(object::Body::Portal | object::Body::PortalActive)
342 )
343 }
344
345 pub fn bleeds(&self) -> bool {
346 !matches!(
347 self,
348 Body::Object(_) | Body::Ship(_) | Body::Item(_) | Body::Golem(_)
349 )
350 }
351
352 pub fn stride_length(&self) -> f32 {
355 if let Body::Humanoid(body) = self {
356 body.scaler() * 3.75
357 } else {
358 let dims = self.dimensions();
360 0.65 + (dims.y + dims.z) * 0.6
361 }
362 }
363
364 pub fn scale(&self) -> Scale {
365 let s = match self {
366 Body::BirdMedium(bird_medium) => match bird_medium.species {
367 bird_medium::Species::Bat | bird_medium::Species::VampireBat => 0.5,
368 _ => 1.0,
369 },
370 _ => 1.0,
371 };
372 Scale(s)
373 }
374
375 pub fn density(&self) -> Density {
378 let d = match self {
379 Body::BirdMedium(_) => 700.0,
381 Body::BirdLarge(_) => 2_200.0,
382
383 Body::Dragon(_) => 5_000.0,
384
385 Body::Golem(_) => WATER_DENSITY * 2.5,
386 Body::Humanoid(_) => HUMAN_DENSITY,
387 Body::Ship(ship) => ship.density().0,
388 Body::Object(object) => object.density().0,
389 Body::Item(item) => item.density().0,
390 _ => HUMAN_DENSITY,
391 };
392 Density(d)
393 }
394
395 pub fn mass(&self) -> Mass {
399 let m = match self {
400 Body::BipedLarge(body) => match body.species {
401 biped_large::Species::Slysaurok => 400.0,
402 biped_large::Species::Occultsaurok => 400.0,
403 biped_large::Species::Mightysaurok => 400.0,
404 biped_large::Species::Mindflayer => 420.0,
405 biped_large::Species::Minotaur => 500.0,
406 biped_large::Species::Cavetroll => 600.0,
407 biped_large::Species::Mountaintroll => 600.0,
408 biped_large::Species::Swamptroll => 600.0,
409 biped_large::Species::Gigasfrost | biped_large::Species::Gigasfire => 400.0,
410 biped_large::Species::AdletElder => 350.0,
411 biped_large::Species::HaniwaGeneral => 360.0,
412 biped_large::Species::TerracottaBesieger
413 | biped_large::Species::TerracottaDemolisher
414 | biped_large::Species::TerracottaPunisher
415 | biped_large::Species::TerracottaPursuer
416 | biped_large::Species::Cursekeeper => 380.0,
417 biped_large::Species::Forgemaster => 1600.0,
418 _ => 400.0,
419 },
420 Body::BipedSmall(body) => match body.species {
421 biped_small::Species::IronDwarf => 1000.0,
422 biped_small::Species::Flamekeeper => 1000.0,
423 biped_small::Species::Boreal => 270.0,
424 _ => 50.0,
425 },
426 Body::BirdMedium(body) => match body.species {
428 bird_medium::Species::SnowyOwl => 3.0,
429 bird_medium::Species::HornedOwl => 3.0,
430 bird_medium::Species::Duck => 3.5,
431 bird_medium::Species::Cockatiel => 2.0,
432 bird_medium::Species::Chicken => 2.5, bird_medium::Species::Bat => 1.5,
434 bird_medium::Species::Penguin => 10.0,
435 bird_medium::Species::Eagle => 7.0, bird_medium::Species::Goose => 3.5, bird_medium::Species::Parrot => 1.0,
438 bird_medium::Species::Peacock => 6.0,
439 bird_medium::Species::Crow => 3.0,
440 bird_medium::Species::Dodo => 4.0,
441 bird_medium::Species::Parakeet => 1.0,
442 bird_medium::Species::Puffin => 2.0,
443 bird_medium::Species::Toucan => 4.5,
444 bird_medium::Species::BloodmoonBat => 1.5,
445 bird_medium::Species::VampireBat => 1.5,
446 },
447 Body::BirdLarge(_) => 250.0,
448 Body::Dragon(_) => 20_000.0,
449 Body::FishMedium(_) => 5.0,
450 Body::FishSmall(_) => 1.0,
451 Body::Golem(_) => 10_000.0,
452 Body::Humanoid(humanoid) => {
453 65.0 * humanoid.height() / 1.75f32
462 },
463 Body::Object(obj) => obj.mass().0,
464 Body::Item(item) => item.mass().0,
465 Body::QuadrupedLow(body) => match body.species {
466 quadruped_low::Species::Alligator => 360.0, quadruped_low::Species::Snaretongue => 280.0,
468 quadruped_low::Species::Asp => 300.0,
469 quadruped_low::Species::Crocodile => 360.0,
472 quadruped_low::Species::SeaCrocodile => 410.0,
473 quadruped_low::Species::Deadwood => 200.0,
474 quadruped_low::Species::Monitor => 200.0,
475 quadruped_low::Species::Pangolin => 300.0,
476 quadruped_low::Species::Salamander => 350.0,
477 quadruped_low::Species::Elbst => 350.0,
478 quadruped_low::Species::Tortoise => 300.0,
479 quadruped_low::Species::Lavadrake => 700.0,
480 quadruped_low::Species::Icedrake => 700.0,
481 quadruped_low::Species::Mossdrake => 700.0,
482 quadruped_low::Species::Rocksnapper => 450.0,
483 quadruped_low::Species::Rootsnapper => 450.0,
484 quadruped_low::Species::Reefsnapper => 450.0,
485 quadruped_low::Species::Maneater => 80.0,
486 quadruped_low::Species::Sandshark => 450.0,
487 quadruped_low::Species::Hakulaq => 400.0,
488 quadruped_low::Species::Dagon => 600.0,
489 quadruped_low::Species::Basilisk => 800.0,
490 quadruped_low::Species::Driggle => 55.0,
491 quadruped_low::Species::Hydra => 800.0,
492 },
493 Body::QuadrupedMedium(body) => match body.species {
494 quadruped_medium::Species::Bear => 500.0, quadruped_medium::Species::Cattle => 575.0, quadruped_medium::Species::Deer => 80.0,
497 quadruped_medium::Species::Donkey => 200.0,
498 quadruped_medium::Species::Highland => 200.0,
499 quadruped_medium::Species::Horse => 300.0, quadruped_medium::Species::Kelpie => 250.0,
501 quadruped_medium::Species::Lion => 170.0, quadruped_medium::Species::Panda => 200.0,
503 quadruped_medium::Species::Saber => 130.0,
504 quadruped_medium::Species::Yak => 200.0,
505 quadruped_medium::Species::Dreadhorn => 500.0,
506 quadruped_medium::Species::Mammoth => 1500.0,
507 quadruped_medium::Species::Elephant => 1500.0,
508 quadruped_medium::Species::Catoblepas => 300.0,
509 _ => 200.0,
510 },
511 Body::QuadrupedSmall(body) => match body.species {
512 quadruped_small::Species::Axolotl => 1.0,
513 quadruped_small::Species::Batfox => 10.0,
514 quadruped_small::Species::Beaver => 10.0,
515 quadruped_small::Species::Boar => 80.0, quadruped_small::Species::Cat => 4.0, quadruped_small::Species::Dog => 30.0, quadruped_small::Species::Fox => 10.0,
519 quadruped_small::Species::Frog => 1.0,
520 quadruped_small::Species::Fungome => 10.0,
521 quadruped_small::Species::Gecko => 1.0,
522 quadruped_small::Species::Goat => 50.0,
523 quadruped_small::Species::Hare => 10.0,
524 quadruped_small::Species::Holladon => 70.0,
525 quadruped_small::Species::Hyena => 70.0, quadruped_small::Species::Jackalope => 10.0,
527 quadruped_small::Species::Pig => 20.0,
528 quadruped_small::Species::Porcupine => 5.0,
529 quadruped_small::Species::Quokka => 10.0,
530 quadruped_small::Species::Rabbit => 2.0,
531 quadruped_small::Species::Raccoon => 30.0,
532 quadruped_small::Species::Rat => 1.0,
533 quadruped_small::Species::Sheep => 50.0,
534 quadruped_small::Species::Skunk => 5.0,
535 quadruped_small::Species::Squirrel => 1.0,
536 quadruped_small::Species::Truffler => 70.0,
537 quadruped_small::Species::Turtle => 40.0,
538 quadruped_small::Species::Seal => 15.0,
539 quadruped_small::Species::TreantSapling => 80.0,
540 quadruped_small::Species::MossySnail => 5.0,
541 },
542 Body::Theropod(body) => match body.species {
543 theropod::Species::Archaeos => 8_000.0,
546 theropod::Species::Ntouka => 8_000.0,
547 theropod::Species::Odonto => 8_000.0,
548 theropod::Species::Dodarock => 700.0,
549 theropod::Species::Sandraptor => 500.0,
550 theropod::Species::Snowraptor => 500.0,
551 theropod::Species::Sunlizard => 500.0,
552 theropod::Species::Woodraptor => 500.0,
553 theropod::Species::Yale => 1_000.0,
554 theropod::Species::Axebeak => 300.0,
555 },
556 Body::Ship(ship) => ship.mass().0,
557 Body::Arthropod(_) => 200.0,
558 Body::Crustacean(body) => match body.species {
560 crustacean::Species::Crab | crustacean::Species::SoldierCrab => 50.0,
561 crustacean::Species::Karkatha => 1200.0,
562 },
563 Body::Plugin(body) => body.mass().0,
564 };
565 Mass(m)
566 }
567
568 pub fn dimensions(&self) -> Vec3<f32> {
573 match self {
574 Body::BipedLarge(body) => match body.species {
575 biped_large::Species::Cyclops => Vec3::new(5.6, 3.0, 8.0),
576 biped_large::Species::Dullahan => Vec3::new(4.6, 3.0, 5.5),
577 biped_large::Species::Mightysaurok => Vec3::new(4.0, 3.0, 3.4),
578 biped_large::Species::Mindflayer => Vec3::new(4.4, 3.0, 8.5),
579 biped_large::Species::Minotaur => Vec3::new(6.0, 3.0, 8.0),
580 biped_large::Species::Occultsaurok => Vec3::new(4.0, 3.0, 3.4),
581 biped_large::Species::Slysaurok => Vec3::new(4.0, 3.0, 3.4),
582 biped_large::Species::Werewolf => Vec3::new(4.0, 3.0, 3.5),
583 biped_large::Species::Harvester => Vec3::new(4.6, 3.0, 5.4),
584 biped_large::Species::Cultistwarlord => Vec3::new(3.0, 3.0, 4.5),
585 biped_large::Species::Cultistwarlock => Vec3::new(3.0, 3.0, 3.5),
586 biped_large::Species::Huskbrute => Vec3::new(4.6, 3.0, 5.0),
587 biped_large::Species::Tursus => Vec3::new(4.0, 3.0, 4.0),
588 biped_large::Species::Gigasfrost => Vec3::new(6.0, 3.0, 11.0),
589 biped_large::Species::Gigasfire => Vec3::new(6.0, 3.0, 11.0),
590 biped_large::Species::AdletElder => Vec3::new(3.5, 3.0, 4.0),
591 biped_large::Species::SeaBishop => Vec3::new(3.7, 2.5, 3.4),
592 biped_large::Species::HaniwaGeneral => Vec3::new(3.3, 2.3, 3.6),
593 biped_large::Species::TerracottaBesieger => Vec3::new(3.8, 3.0, 5.0),
594 biped_large::Species::TerracottaDemolisher => Vec3::new(3.3, 2.5, 3.6),
595 biped_large::Species::TerracottaPunisher => Vec3::new(3.3, 2.5, 3.8),
596 biped_large::Species::TerracottaPursuer => Vec3::new(3.3, 2.5, 3.8),
597 biped_large::Species::Cursekeeper => Vec3::new(3.8, 3.0, 5.0),
598 biped_large::Species::Forgemaster => Vec3::new(6.5, 5.0, 8.0),
599 biped_large::Species::Strigoi => Vec3::new(3.8, 3.0, 5.0),
600 biped_large::Species::Executioner => Vec3::new(2.8, 2.8, 4.7),
601 biped_large::Species::Tidalwarrior => Vec3::new(7.0, 8.2, 6.8),
602 biped_large::Species::Cavetroll => Vec3::new(4.6, 3.0, 5.0),
603 biped_large::Species::Mountaintroll => Vec3::new(4.6, 3.0, 5.0),
604 biped_large::Species::Swamptroll => Vec3::new(4.6, 3.0, 4.5),
605 biped_large::Species::Yeti => Vec3::new(4.6, 3.0, 4.8),
606 biped_large::Species::Blueoni => Vec3::new(4.6, 3.0, 4.8),
607 biped_large::Species::Redoni => Vec3::new(4.6, 3.0, 4.5),
608 biped_large::Species::Ogre => match body.body_type {
609 biped_large::BodyType::Male => Vec3::new(4.6, 3.0, 5.6),
610 biped_large::BodyType::Female => Vec3::new(4.6, 3.0, 5.9),
611 },
612 biped_large::Species::Wendigo => Vec3::new(4.6, 3.0, 6.0),
613 },
614 Body::BipedSmall(body) => match body.species {
615 biped_small::Species::Gnarling => Vec3::new(1.0, 0.75, 1.4),
616 biped_small::Species::Haniwa => Vec3::new(1.3, 1.0, 2.2),
617 biped_small::Species::Adlet => Vec3::new(1.3, 1.0, 2.0),
618 biped_small::Species::Sahagin => Vec3::new(1.3, 2.0, 1.7),
619 biped_small::Species::Myrmidon => Vec3::new(1.3, 1.0, 2.2),
620 biped_small::Species::Husk => Vec3::new(1.7, 0.7, 2.7),
621 biped_small::Species::Boreal => Vec3::new(2.6, 2.0, 4.6),
622 biped_small::Species::Ashen => Vec3::new(1.3, 2.0, 2.5),
623 biped_small::Species::Bushly => Vec3::new(1.2, 1.3, 1.6),
624 biped_small::Species::Cactid => Vec3::new(1.0, 0.75, 1.4),
625 biped_small::Species::Irrwurz => Vec3::new(1.5, 1.5, 2.0),
626 biped_small::Species::IronDwarf => Vec3::new(1.3, 2.0, 2.5),
627 biped_small::Species::ShamanicSpirit => Vec3::new(1.3, 2.0, 2.3),
628 biped_small::Species::Jiangshi => Vec3::new(1.3, 1.8, 2.5),
629 biped_small::Species::Flamekeeper => Vec3::new(1.5, 1.5, 2.5),
630 biped_small::Species::TreasureEgg => Vec3::new(1.1, 1.1, 1.4),
631 biped_small::Species::GnarlingChieftain => Vec3::new(1.0, 0.75, 1.4),
632 biped_small::Species::BloodmoonHeiress => Vec3::new(3.5, 3.5, 5.5),
633 biped_small::Species::Bloodservant => Vec3::new(1.3, 1.8, 2.5),
634 biped_small::Species::Harlequin => Vec3::new(1.3, 2.0, 2.5),
635 biped_small::Species::GoblinThug => Vec3::new(1.3, 1.0, 1.6),
636 biped_small::Species::GoblinChucker => Vec3::new(1.3, 1.0, 1.6),
637 biped_small::Species::GoblinRuffian => Vec3::new(1.3, 1.0, 1.6),
638 biped_small::Species::GreenLegoom => Vec3::new(0.9, 0.8, 1.15),
639 biped_small::Species::OchreLegoom => Vec3::new(0.9, 0.8, 1.15),
640 biped_small::Species::PurpleLegoom => Vec3::new(0.9, 0.8, 1.15),
641 biped_small::Species::RedLegoom => Vec3::new(0.9, 0.8, 1.15),
642 biped_small::Species::UmberLegoom => Vec3::new(0.9, 0.8, 1.15),
643 biped_small::Species::Gnome => Vec3::new(1.0, 0.75, 1.4),
644 biped_small::Species::Mandragora => Vec3::new(1.0, 0.75, 1.4),
646 biped_small::Species::Kappa => Vec3::new(1.0, 0.75, 1.4),
647 biped_small::Species::Gnoll => Vec3::new(1.0, 0.75, 1.4),
648 },
649 Body::BirdLarge(body) => match body.species {
650 bird_large::Species::Cockatrice => Vec3::new(2.5, 5.5, 3.5),
651 bird_large::Species::Roc => Vec3::new(2.2, 7.5, 4.0),
652 bird_large::Species::FlameWyvern
653 | bird_large::Species::FrostWyvern
654 | bird_large::Species::CloudWyvern
655 | bird_large::Species::SeaWyvern
656 | bird_large::Species::WealdWyvern => Vec3::new(2.5, 9.0, 4.5),
657 bird_large::Species::Phoenix => Vec3::new(2.0, 6.0, 4.4),
658 },
659 Body::Dragon(body) => match body.species {
660 dragon::Species::Reddragon => Vec3::new(16.0, 10.0, 16.0),
661 },
662 Body::FishMedium(body) => match body.species {
663 fish_medium::Species::Marlin => Vec3::new(0.5, 2.0, 0.8),
664 fish_medium::Species::Icepike => Vec3::new(0.5, 2.0, 0.8),
665 },
666 Body::FishSmall(body) => match body.species {
667 fish_small::Species::Clownfish => Vec3::new(0.3, 1.2, 0.6),
668 fish_small::Species::Piranha => Vec3::new(0.3, 1.2, 0.6),
669 },
670 Body::Golem(body) => match body.species {
671 golem::Species::CoralGolem => Vec3::new(3.0, 5.0, 4.0),
672 golem::Species::ClayGolem => Vec3::new(6.8, 3.5, 7.5),
673 golem::Species::AncientEffigy => Vec3::new(2.5, 2.5, 3.8),
674 golem::Species::Mogwai => Vec3::new(2.5, 2.5, 3.8),
675 golem::Species::StoneGolem => Vec3::new(10.0, 4.5, 9.0),
676 golem::Species::Treant => Vec3::new(7.8, 4.5, 5.8),
677 golem::Species::WoodGolem => Vec3::new(5.8, 4.5, 7.2),
678 golem::Species::Gravewarden => Vec3::new(7.3, 4.5, 7.7),
679 golem::Species::IronGolem => Vec3::new(9.8, 4.5, 9.4),
680 },
681 Body::Humanoid(humanoid) => {
682 let height = humanoid.height();
683 Vec3::new(height / 1.3, 1.75 / 2.0, height)
684 },
685 Body::Object(object) => object.dimensions(),
686 Body::Item(item) => item.dimensions(),
687 Body::QuadrupedMedium(body) => match body.species {
688 quadruped_medium::Species::Akhlut => Vec3::new(2.5, 7.0, 3.0),
689 quadruped_medium::Species::Barghest => Vec3::new(2.0, 4.4, 2.7),
690 quadruped_medium::Species::Bear => Vec3::new(2.0, 3.8, 3.0),
691 quadruped_medium::Species::Catoblepas => Vec3::new(2.0, 4.0, 2.3),
692 quadruped_medium::Species::Cattle => Vec3::new(2.0, 3.6, 2.4),
693 quadruped_medium::Species::Deer => Vec3::new(2.0, 3.0, 2.2),
694 quadruped_medium::Species::Dreadhorn => Vec3::new(3.5, 7.0, 4.0),
695 quadruped_medium::Species::Frostfang => Vec3::new(1.5, 3.0, 1.5),
696 quadruped_medium::Species::Grolgar => Vec3::new(2.0, 4.0, 2.0),
697 quadruped_medium::Species::Highland => Vec3::new(2.0, 3.6, 2.4),
698 quadruped_medium::Species::Horse => Vec3::new(1.6, 3.0, 2.4),
699 quadruped_medium::Species::Lion => Vec3::new(2.0, 3.3, 2.0),
700 quadruped_medium::Species::Moose => Vec3::new(2.0, 4.0, 2.5),
701 quadruped_medium::Species::Bristleback => Vec3::new(2.0, 3.0, 2.0),
702 quadruped_medium::Species::Roshwalr => Vec3::new(3.4, 5.2, 3.7),
703 quadruped_medium::Species::Saber => Vec3::new(2.0, 3.0, 2.0),
704 quadruped_medium::Species::Tarasque => Vec3::new(2.0, 4.0, 2.6),
705 quadruped_medium::Species::Yak => Vec3::new(2.0, 3.6, 3.0),
706 quadruped_medium::Species::Mammoth => Vec3::new(7.5, 11.5, 8.0),
707 quadruped_medium::Species::Elephant => Vec3::new(7.5, 11.5, 8.0),
708 quadruped_medium::Species::Ngoubou => Vec3::new(2.0, 3.2, 2.4),
709 quadruped_medium::Species::Llama => Vec3::new(2.0, 2.5, 2.6),
710 quadruped_medium::Species::ClaySteed => Vec3::new(2.2, 4.8, 4.0),
711 quadruped_medium::Species::Alpaca => Vec3::new(2.0, 2.0, 2.0),
712 quadruped_medium::Species::Camel => Vec3::new(2.0, 4.0, 3.5),
713 quadruped_medium::Species::Wolf => Vec3::new(1.25, 3.0, 1.8),
714 quadruped_medium::Species::Tiger => Vec3::new(2.0, 3.0, 2.0),
716 quadruped_medium::Species::Tuskram => Vec3::new(2.0, 3.0, 2.0),
717 quadruped_medium::Species::Mouflon => Vec3::new(2.0, 3.0, 2.0),
718 quadruped_medium::Species::Bonerattler => Vec3::new(2.0, 3.0, 2.0),
719 quadruped_medium::Species::Hirdrasil => Vec3::new(2.0, 3.0, 2.0),
720 quadruped_medium::Species::Donkey => Vec3::new(2.0, 3.0, 2.0),
721 quadruped_medium::Species::Zebra => Vec3::new(2.0, 3.0, 2.0),
722 quadruped_medium::Species::Antelope => Vec3::new(2.0, 3.0, 2.0),
723 quadruped_medium::Species::Kelpie => Vec3::new(2.0, 3.0, 2.0),
724 quadruped_medium::Species::Darkhound => Vec3::new(2.0, 3.0, 2.0),
725 quadruped_medium::Species::Panda => Vec3::new(2.0, 3.0, 2.0),
726 quadruped_medium::Species::Snowleopard => Vec3::new(2.0, 3.0, 2.0),
727 },
728 Body::QuadrupedSmall(body) => match body.species {
729 quadruped_small::Species::Batfox => Vec3::new(1.4, 1.7, 1.3),
730 quadruped_small::Species::Holladon => Vec3::new(1.3, 1.9, 1.5),
731 quadruped_small::Species::Hyena => Vec3::new(1.2, 1.4, 1.3),
732 quadruped_small::Species::Truffler => Vec3::new(1.2, 1.8, 2.2),
733 quadruped_small::Species::MossySnail => Vec3::new(1.4, 1.4, 1.2),
734 quadruped_small::Species::Gecko => Vec3::new(1.2, 1.2, 0.5),
735 quadruped_small::Species::Pig => Vec3::new(1.2, 1.2, 1.0),
737 quadruped_small::Species::Fox => Vec3::new(1.2, 1.2, 1.0),
738 quadruped_small::Species::Sheep => Vec3::new(1.2, 1.2, 1.0),
739 quadruped_small::Species::Boar => Vec3::new(1.2, 1.2, 1.0),
740 quadruped_small::Species::Jackalope => Vec3::new(1.2, 1.2, 1.0),
741 quadruped_small::Species::Skunk => Vec3::new(1.2, 1.2, 1.0),
742 quadruped_small::Species::Cat => Vec3::new(1.2, 1.2, 1.0),
743 quadruped_small::Species::Raccoon => Vec3::new(1.2, 1.2, 1.0),
744 quadruped_small::Species::Quokka => Vec3::new(1.2, 1.2, 1.0),
745 quadruped_small::Species::Goat => Vec3::new(1.2, 1.2, 1.0),
746 quadruped_small::Species::Rabbit => Vec3::new(1.2, 1.2, 1.0),
747 quadruped_small::Species::Frog => Vec3::new(1.2, 1.2, 1.0),
748 quadruped_small::Species::Rat => Vec3::new(1.2, 1.2, 1.0),
749 quadruped_small::Species::Axolotl => Vec3::new(1.2, 1.2, 1.0),
750 quadruped_small::Species::Turtle => Vec3::new(1.2, 1.2, 1.0),
751 quadruped_small::Species::Squirrel => Vec3::new(1.2, 1.2, 1.0),
752 quadruped_small::Species::Fungome => Vec3::new(1.2, 1.2, 1.0),
753 quadruped_small::Species::Porcupine => Vec3::new(1.2, 1.2, 1.0),
754 quadruped_small::Species::Beaver => Vec3::new(1.2, 1.2, 1.0),
755 quadruped_small::Species::Hare => Vec3::new(1.2, 1.2, 1.0),
756 quadruped_small::Species::Dog => Vec3::new(1.2, 1.2, 1.0),
757 quadruped_small::Species::Seal => Vec3::new(1.2, 1.2, 1.0),
758 quadruped_small::Species::TreantSapling => Vec3::new(1.2, 1.2, 1.0),
759 },
760 Body::QuadrupedLow(body) => match body.species {
761 quadruped_low::Species::Asp => Vec3::new(2.0, 3.0, 1.7),
762 quadruped_low::Species::Crocodile => Vec3::new(1.0, 2.8, 1.3),
763 quadruped_low::Species::SeaCrocodile => Vec3::new(1.2, 4.5, 1.3),
764 quadruped_low::Species::Deadwood => Vec3::new(1.3, 1.3, 1.4),
765 quadruped_low::Species::Hakulaq => Vec3::new(1.8, 3.0, 2.0),
766 quadruped_low::Species::Dagon => Vec3::new(3.0, 6.0, 2.0),
767 quadruped_low::Species::Icedrake => Vec3::new(2.0, 5.5, 2.5),
768 quadruped_low::Species::Lavadrake => Vec3::new(2.0, 5.5, 2.5),
769 quadruped_low::Species::Mossdrake => Vec3::new(2.0, 5.5, 2.5),
770 quadruped_low::Species::Maneater => Vec3::new(2.0, 3.7, 4.0),
771 quadruped_low::Species::Monitor => Vec3::new(1.4, 3.2, 1.3),
772 quadruped_low::Species::Pangolin => Vec3::new(1.0, 2.6, 1.1),
773 quadruped_low::Species::Rocksnapper => Vec3::new(2.5, 3.5, 2.9),
774 quadruped_low::Species::Rootsnapper => Vec3::new(2.5, 3.5, 2.9),
775 quadruped_low::Species::Reefsnapper => Vec3::new(2.5, 3.5, 2.9),
776 quadruped_low::Species::Sandshark => Vec3::new(2.1, 4.3, 1.7),
777 quadruped_low::Species::Basilisk => Vec3::new(2.7, 6.0, 2.9),
778 quadruped_low::Species::Salamander => Vec3::new(1.7, 4.0, 1.3),
779 quadruped_low::Species::Elbst => Vec3::new(1.7, 4.0, 1.3),
780 quadruped_low::Species::Tortoise => Vec3::new(1.7, 2.7, 1.5),
781 quadruped_low::Species::Driggle => Vec3::new(1.6, 2.7, 1.0),
782 quadruped_low::Species::Snaretongue => Vec3::new(2.0, 2.8, 1.6),
783 quadruped_low::Species::Hydra => Vec3::new(3.0, 5.0, 2.8),
784 quadruped_low::Species::Alligator => Vec3::new(1.0, 1.6, 1.3),
786 },
787 Body::Ship(ship) => ship.dimensions(),
788 Body::Theropod(body) => match body.species {
789 theropod::Species::Archaeos => Vec3::new(4.5, 8.5, 8.0),
790 theropod::Species::Ntouka => Vec3::new(4.5, 9.0, 6.6),
791 theropod::Species::Odonto => Vec3::new(4.5, 8.0, 6.6),
792 theropod::Species::Dodarock => Vec3::new(2.0, 3.0, 2.6),
793 theropod::Species::Sandraptor => Vec3::new(2.0, 3.0, 2.6),
794 theropod::Species::Snowraptor => Vec3::new(2.0, 3.0, 2.6),
795 theropod::Species::Sunlizard => Vec3::new(2.0, 3.6, 2.5),
796 theropod::Species::Woodraptor => Vec3::new(2.0, 3.0, 2.6),
797 theropod::Species::Yale => Vec3::new(2.0, 3.2, 4.0),
798 theropod::Species::Axebeak => Vec3::new(2.0, 3.6, 3.0),
799 },
800 Body::Arthropod(body) => match body.species {
801 arthropod::Species::Tarantula => Vec3::new(4.0, 4.0, 1.8),
802 arthropod::Species::Blackwidow => Vec3::new(4.0, 4.0, 2.0),
803 arthropod::Species::Antlion => Vec3::new(4.0, 4.0, 2.2),
804 arthropod::Species::Hornbeetle => Vec3::new(3.2, 3.2, 1.3),
805 arthropod::Species::Leafbeetle => Vec3::new(2.4, 2.8, 1.2),
806 arthropod::Species::Stagbeetle => Vec3::new(3.2, 3.2, 1.3),
807 arthropod::Species::Weevil => Vec3::new(2.2, 2.4, 1.1),
808 arthropod::Species::Cavespider => Vec3::new(4.0, 4.0, 1.4),
809 arthropod::Species::Moltencrawler => Vec3::new(3.2, 4.0, 1.5),
810 arthropod::Species::Mosscrawler => Vec3::new(3.2, 4.0, 1.4),
811 arthropod::Species::Sandcrawler => Vec3::new(3.2, 4.0, 1.4),
812 arthropod::Species::Dagonite => Vec3::new(3.2, 4.7, 1.4),
813 arthropod::Species::Emberfly => Vec3::new(1.3, 1.5, 0.9),
814 },
815 Body::BirdMedium(body) => match body.species {
816 bird_medium::Species::SnowyOwl => Vec3::new(1.2, 1.2, 0.9),
817 bird_medium::Species::HornedOwl => Vec3::new(1.2, 1.2, 0.9),
818 bird_medium::Species::Duck => Vec3::new(0.8, 1.3, 0.8),
819 bird_medium::Species::Cockatiel => Vec3::new(0.8, 1.0, 0.7),
820 bird_medium::Species::Chicken => Vec3::new(1.2, 1.5, 0.9),
821 bird_medium::Species::Bat => Vec3::new(2.0, 1.8, 1.3),
822 bird_medium::Species::Penguin => Vec3::new(1.0, 1.0, 1.2),
823 bird_medium::Species::Goose => Vec3::new(1.5, 1.5, 1.1),
824 bird_medium::Species::Peacock => Vec3::new(1.6, 1.8, 1.4),
825 bird_medium::Species::Eagle => Vec3::new(1.5, 2.2, 1.0),
826 bird_medium::Species::Parrot => Vec3::new(1.2, 1.5, 1.1),
827 bird_medium::Species::Crow => Vec3::new(1.0, 1.2, 0.8),
828 bird_medium::Species::Dodo => Vec3::new(1.2, 1.8, 1.1),
829 bird_medium::Species::Parakeet => Vec3::new(0.8, 0.9, 0.7),
830 bird_medium::Species::Puffin => Vec3::new(1.0, 1.0, 1.0),
831 bird_medium::Species::Toucan => Vec3::new(2.1, 1.1, 1.2),
832 bird_medium::Species::BloodmoonBat => Vec3::new(3.5, 3.5, 2.5),
833 bird_medium::Species::VampireBat => Vec3::new(2.0, 1.8, 1.3),
834 },
835 Body::Crustacean(body) => match body.species {
836 crustacean::Species::Crab => Vec3::new(1.2, 1.2, 0.7),
837 crustacean::Species::SoldierCrab => Vec3::new(1.2, 1.2, 1.0),
838 crustacean::Species::Karkatha => Vec3::new(10.0, 10.0, 7.5),
839 },
840 Body::Plugin(body) => body.dimensions(),
841 }
842 }
843
844 pub fn max_radius(&self) -> f32 {
848 let dim = self.dimensions();
849 let (x, y) = (dim.x, dim.y);
850
851 x.max(y) / 2.0
852 }
853
854 pub fn front_radius(&self) -> f32 { self.dimensions().y / 2.0 }
855
856 pub fn min_radius(&self) -> f32 {
857 let (_p0, _p1, radius) = self.sausage();
858
859 radius
860 }
861
862 pub fn sausage(&self) -> (Vec2<f32>, Vec2<f32>, f32) {
867 let dim = self.dimensions();
879 let (width, length) = (dim.x, dim.y);
881
882 if length > width {
883 let radius = width / 2.0;
885
886 let a = length - 2.0 * radius;
887
888 let p0 = Vec2::new(0.0, -a / 2.0);
889 let p1 = Vec2::new(0.0, a / 2.0);
890
891 (p0, p1, radius)
892 } else {
893 let radius = length / 2.0;
895
896 let a = width - 2.0 * radius;
897
898 let p0 = Vec2::new(-a / 2.0, 0.0);
899 let p1 = Vec2::new(a / 2.0, 0.0);
900
901 (p0, p1, radius)
902 }
903 }
904
905 pub fn collider(&self) -> Collider {
907 if let Body::Ship(ship) = self {
908 ship.make_collider()
909 } else {
910 let (p0, p1, radius) = self.sausage();
911
912 Collider::CapsulePrism(CapsulePrism {
913 p0,
914 p1,
915 radius,
916 z_min: 0.0,
917 z_max: self.height(),
918 })
919 }
920 }
921
922 pub fn spacing_radius(&self) -> f32 {
927 self.max_radius()
928 + match self {
929 Body::QuadrupedSmall(body) => match body.species {
930 quadruped_small::Species::Rat => 0.0,
931 _ => 2.0,
932 },
933 Body::QuadrupedLow(body) => match body.species {
934 quadruped_low::Species::Hakulaq => 0.0,
935 _ => 2.0,
936 },
937 Body::BipedSmall(body) => match body.species {
938 biped_small::Species::Husk => 3.0,
939 _ => 2.0,
940 },
941 _ => 2.0,
942 }
943 }
944
945 pub fn height(&self) -> f32 { self.dimensions().z }
947
948 pub fn base_energy(&self) -> u16 {
949 match self {
950 Body::BipedLarge(biped_large) => match biped_large.species {
951 biped_large::Species::Dullahan => 400,
952 biped_large::Species::Cultistwarlord | biped_large::Species::Cultistwarlock => 240,
953 _ => 300,
954 },
955 Body::BirdLarge(body) => match body.species {
956 bird_large::Species::Cockatrice => 400,
957 bird_large::Species::Phoenix => 600,
958 bird_large::Species::Roc => 500,
959 bird_large::Species::FlameWyvern => 600,
960 bird_large::Species::CloudWyvern => 600,
961 bird_large::Species::FrostWyvern => 600,
962 bird_large::Species::SeaWyvern => 600,
963 bird_large::Species::WealdWyvern => 600,
964 },
965 Body::Humanoid(_) => 100,
966 Body::Object(object::Body::Crux) => 0,
967 _ => 100,
968 }
969 }
970
971 pub fn has_death_protection(&self) -> bool { matches!(self, Body::Humanoid(_)) }
974
975 pub fn base_health(&self) -> u16 {
976 match self {
977 Body::Humanoid(_) => 100,
978 Body::QuadrupedSmall(quadruped_small) => match quadruped_small.species {
979 quadruped_small::Species::Batfox => 40,
981 quadruped_small::Species::Boar => 55,
982 quadruped_small::Species::Fox => 25,
983 quadruped_small::Species::Goat => 30,
984 quadruped_small::Species::Hare => 20,
985 quadruped_small::Species::Holladon => 25,
986 quadruped_small::Species::Jackalope => 30,
987 quadruped_small::Species::MossySnail => 15,
988 quadruped_small::Species::Porcupine => 25,
989 quadruped_small::Species::Sheep => 30,
990 quadruped_small::Species::TreantSapling => 20,
991 quadruped_small::Species::Truffler => 70,
992 quadruped_small::Species::Hyena => 85,
994 quadruped_small::Species::Beaver => 20,
996 quadruped_small::Species::Cat => 25,
997 quadruped_small::Species::Dog => 30,
998 quadruped_small::Species::Fungome => 15,
999 quadruped_small::Species::Pig => 25,
1000 quadruped_small::Species::Quokka => 15,
1001 quadruped_small::Species::Rabbit => 15,
1002 quadruped_small::Species::Raccoon => 20,
1003 quadruped_small::Species::Rat => 10,
1004 quadruped_small::Species::Seal => 20,
1005 quadruped_small::Species::Skunk => 20,
1006 quadruped_small::Species::Turtle => 10,
1007 _ => 5,
1008 },
1009 Body::QuadrupedMedium(quadruped_medium) => match quadruped_medium.species {
1010 quadruped_medium::Species::Alpaca => 55,
1012 quadruped_medium::Species::Antelope => 70,
1013 quadruped_medium::Species::Darkhound => 80,
1014 quadruped_medium::Species::Camel => 100,
1015 quadruped_medium::Species::Cattle => 90,
1016 quadruped_medium::Species::Deer => 55,
1017 quadruped_medium::Species::Donkey => 65,
1018 quadruped_medium::Species::Horse => 75,
1019 quadruped_medium::Species::Llama => 65,
1020 quadruped_medium::Species::Mouflon => 75,
1021 quadruped_medium::Species::Zebra => 90,
1022 quadruped_medium::Species::Barghest => 120,
1024 quadruped_medium::Species::Bear => 240,
1025 quadruped_medium::Species::Bristleback => 175,
1026 quadruped_medium::Species::Bonerattler => 100,
1027 quadruped_medium::Species::Frostfang => 185,
1028 quadruped_medium::Species::Highland => 205,
1029 quadruped_medium::Species::Kelpie => 150,
1030 quadruped_medium::Species::Lion => 175,
1031 quadruped_medium::Species::Moose => 265,
1032 quadruped_medium::Species::Panda => 215,
1033 quadruped_medium::Species::Saber => 210,
1034 quadruped_medium::Species::Snowleopard => 175,
1035 quadruped_medium::Species::Tiger => 205,
1036 quadruped_medium::Species::Tuskram => 175,
1037 quadruped_medium::Species::Wolf => 110,
1038 quadruped_medium::Species::Yak => 215,
1039 quadruped_medium::Species::Akhlut => 720,
1041 quadruped_medium::Species::Catoblepas => 720,
1042 quadruped_medium::Species::ClaySteed => 400,
1043 quadruped_medium::Species::Dreadhorn => 690,
1044 quadruped_medium::Species::Grolgar => 450,
1045 quadruped_medium::Species::Hirdrasil => 480,
1046 quadruped_medium::Species::Mammoth => 880,
1047 quadruped_medium::Species::Elephant => 880,
1048 quadruped_medium::Species::Ngoubou => 590,
1049 quadruped_medium::Species::Roshwalr => 640,
1050 quadruped_medium::Species::Tarasque => 370,
1051 },
1052 Body::FishMedium(fish_medium) => match fish_medium.species {
1053 fish_medium::Species::Marlin => 50,
1055 fish_medium::Species::Icepike => 90,
1056 },
1057 Body::Dragon(_) => 500,
1058 Body::BirdLarge(bird_large) => match bird_large.species {
1059 bird_large::Species::Cockatrice => 540,
1061 bird_large::Species::Roc => 450,
1062 bird_large::Species::FlameWyvern
1064 | bird_large::Species::CloudWyvern
1065 | bird_large::Species::FrostWyvern
1066 | bird_large::Species::SeaWyvern
1067 | bird_large::Species::WealdWyvern => 1000,
1068 bird_large::Species::Phoenix => 2000,
1069 },
1070 Body::BirdMedium(bird_medium) => match bird_medium.species {
1071 bird_medium::Species::Bat => 10,
1073 bird_medium::Species::Chicken => 10,
1074 bird_medium::Species::Cockatiel => 10,
1075 bird_medium::Species::Dodo => 20,
1076 bird_medium::Species::Duck => 10,
1077 bird_medium::Species::Parakeet => 10,
1078 bird_medium::Species::Peacock => 20,
1079 bird_medium::Species::Penguin => 10,
1080 bird_medium::Species::Puffin => 20,
1081 bird_medium::Species::Crow => 15,
1083 bird_medium::Species::Eagle => 35,
1084 bird_medium::Species::Goose => 25,
1085 bird_medium::Species::HornedOwl => 35,
1086 bird_medium::Species::Parrot => 15,
1087 bird_medium::Species::SnowyOwl => 35,
1088 bird_medium::Species::Toucan => 15,
1089 bird_medium::Species::VampireBat => 100,
1091 bird_medium::Species::BloodmoonBat => 1200,
1092 },
1093 Body::FishSmall(fish_small) => match fish_small.species {
1094 fish_small::Species::Clownfish => 5,
1096 fish_small::Species::Piranha => 10,
1098 },
1099 Body::BipedLarge(biped_large) => match biped_large.species {
1100 biped_large::Species::Ogre => 320,
1101 biped_large::Species::Cyclops => 1000,
1102 biped_large::Species::Wendigo => 280,
1103 biped_large::Species::Cavetroll => 240,
1104 biped_large::Species::Mountaintroll => 240,
1105 biped_large::Species::Swamptroll => 240,
1106 biped_large::Species::Dullahan => 600,
1107 biped_large::Species::Mindflayer => 2000,
1108 biped_large::Species::Tidalwarrior => 1600,
1109 biped_large::Species::Yeti => 1800,
1110 biped_large::Species::Minotaur => 3000,
1111 biped_large::Species::Harvester => 1300,
1112 biped_large::Species::Blueoni => 240,
1113 biped_large::Species::Redoni => 240,
1114 biped_large::Species::Huskbrute => 800,
1115 biped_large::Species::Cultistwarlord => 200,
1116 biped_large::Species::Cultistwarlock => 200,
1117 biped_large::Species::Gigasfrost => 30000,
1118 biped_large::Species::Gigasfire => 25000,
1119 biped_large::Species::AdletElder => 1500,
1120 biped_large::Species::Tursus => 300,
1121 biped_large::Species::SeaBishop => 550,
1122 biped_large::Species::HaniwaGeneral => 600,
1123 biped_large::Species::TerracottaBesieger
1124 | biped_large::Species::TerracottaDemolisher
1125 | biped_large::Species::TerracottaPunisher
1126 | biped_large::Species::TerracottaPursuer => 300,
1127 biped_large::Species::Cursekeeper => 3000,
1128 biped_large::Species::Forgemaster => 10000,
1129 biped_large::Species::Strigoi => 800,
1130 biped_large::Species::Executioner => 800,
1131 _ => 120,
1132 },
1133 Body::BipedSmall(biped_small) => match biped_small.species {
1134 biped_small::Species::GoblinThug
1135 | biped_small::Species::GoblinChucker
1136 | biped_small::Species::GoblinRuffian => 30,
1137 biped_small::Species::GreenLegoom
1138 | biped_small::Species::OchreLegoom
1139 | biped_small::Species::PurpleLegoom
1140 | biped_small::Species::RedLegoom
1141 | biped_small::Species::UmberLegoom => 25,
1142 biped_small::Species::Cactid => 50,
1143 biped_small::Species::Gnarling => 50,
1144 biped_small::Species::GnarlingChieftain => 150,
1145 biped_small::Species::Mandragora => 65,
1146 biped_small::Species::Adlet => 65,
1147 biped_small::Species::Sahagin => 85,
1148 biped_small::Species::Haniwa => 100,
1149 biped_small::Species::Myrmidon => 100,
1150 biped_small::Species::Husk => 50,
1151 biped_small::Species::Boreal => 800,
1152 biped_small::Species::Ashen => 300,
1153 biped_small::Species::IronDwarf => 250,
1154 biped_small::Species::Irrwurz => 100,
1155 biped_small::Species::ShamanicSpirit => 240,
1156 biped_small::Species::Jiangshi => 250,
1157 biped_small::Species::Flamekeeper => 2000,
1158 biped_small::Species::BloodmoonHeiress => 2000,
1159 biped_small::Species::Bloodservant => 300,
1160 biped_small::Species::Harlequin => 500,
1161 _ => 60,
1162 },
1163 Body::Object(object) => match object {
1164 object::Body::TrainingDummy => 60000,
1165 object::Body::Crossbow => 80,
1166 object::Body::Flamethrower => 80,
1167 object::Body::Lavathrower => 80,
1168 object::Body::BarrelOrgan => 500,
1169 object::Body::HaniwaSentry => 60,
1170 object::Body::SeaLantern => 100,
1171 object::Body::TerracottaStatue => 600,
1172 object::Body::GnarlingTotemGreen => 15,
1173 object::Body::GnarlingTotemRed | object::Body::GnarlingTotemWhite => 15,
1174 object::Body::Crux => 350,
1175 _ => 1000,
1176 },
1177 Body::Item(_) => 1000,
1178 Body::Golem(golem) => match golem.species {
1179 golem::Species::WoodGolem => 120,
1180 golem::Species::ClayGolem => 350,
1181 golem::Species::Gravewarden => 1000,
1182 golem::Species::CoralGolem => 550,
1183 golem::Species::AncientEffigy => 250,
1184 golem::Species::Mogwai => 500,
1185 golem::Species::IronGolem => 2500,
1186 _ => 1000,
1187 },
1188 Body::Theropod(theropod) => match theropod.species {
1189 theropod::Species::Dodarock => 20,
1191 theropod::Species::Axebeak => 275,
1193 theropod::Species::Sandraptor => 110,
1194 theropod::Species::Snowraptor => 110,
1195 theropod::Species::Sunlizard => 110,
1196 theropod::Species::Woodraptor => 110,
1197 theropod::Species::Yale => 610,
1199 theropod::Species::Archaeos => 880,
1201 theropod::Species::Ntouka => 880,
1202 theropod::Species::Odonto => 1320,
1203 },
1204 Body::QuadrupedLow(quadruped_low) => match quadruped_low.species {
1205 quadruped_low::Species::Driggle => 50,
1207 quadruped_low::Species::Pangolin => 20,
1208 quadruped_low::Species::Tortoise => 45,
1209 quadruped_low::Species::Alligator => 130,
1211 quadruped_low::Species::Asp => 175,
1212 quadruped_low::Species::Crocodile => 145,
1213 quadruped_low::Species::Deadwood => 85,
1214 quadruped_low::Species::Elbst => 145,
1215 quadruped_low::Species::Hakulaq => 155,
1216 quadruped_low::Species::Monitor => 95,
1217 quadruped_low::Species::Salamander => 210,
1218 quadruped_low::Species::SeaCrocodile => 180,
1219 quadruped_low::Species::Dagon => 1200,
1221 quadruped_low::Species::Icedrake => 340,
1222 quadruped_low::Species::Lavadrake => 340,
1223 quadruped_low::Species::Maneater => 510,
1224 quadruped_low::Species::Mossdrake => 340,
1225 quadruped_low::Species::Rocksnapper => 400,
1226 quadruped_low::Species::Reefsnapper => 400,
1227 quadruped_low::Species::Rootsnapper => 400,
1228 quadruped_low::Species::Sandshark => 540,
1229 quadruped_low::Species::Hydra => 1000,
1230 quadruped_low::Species::Basilisk => 660,
1232 quadruped_low::Species::Snaretongue => 1500,
1233 },
1234 Body::Arthropod(arthropod) => match arthropod.species {
1235 arthropod::Species::Dagonite => 70,
1237 arthropod::Species::Emberfly => 20,
1238 arthropod::Species::Leafbeetle => 40,
1239 arthropod::Species::Weevil => 40,
1240 arthropod::Species::Cavespider => 170,
1242 arthropod::Species::Hornbeetle => 170,
1243 arthropod::Species::Moltencrawler => 145,
1244 arthropod::Species::Mosscrawler => 145,
1245 arthropod::Species::Sandcrawler => 145,
1246 arthropod::Species::Stagbeetle => 170,
1247 arthropod::Species::Tarantula => 155,
1248 arthropod::Species::Antlion => 480,
1250 arthropod::Species::Blackwidow => 370,
1251 },
1252 Body::Ship(_) => 1000,
1253 Body::Crustacean(crustacean) => match crustacean.species {
1254 crustacean::Species::Crab => 40,
1256 crustacean::Species::SoldierCrab => 50,
1258 crustacean::Species::Karkatha => 2000,
1259 },
1260 Body::Plugin(body) => body.base_health(),
1261 }
1262 }
1263
1264 pub fn flying_height(&self) -> f32 {
1265 match self {
1266 Body::BirdLarge(_) => 50.0,
1267 Body::BirdMedium(_) => 40.0,
1268 Body::Dragon(_) => 60.0,
1269 Body::Ship(ship) => ship.flying_height(),
1270 _ => 0.0,
1271 }
1272 }
1273
1274 pub fn immune_to(&self, buff: BuffKind) -> bool {
1275 match buff {
1276 BuffKind::Bleeding => match self {
1277 Body::Golem(_) | Body::Ship(_) => true,
1278 Body::Object(object) => !matches!(object, object::Body::TrainingDummy),
1279 Body::BipedSmall(b) => matches!(
1280 b.species,
1281 biped_small::Species::Husk
1282 | biped_small::Species::Boreal
1283 | biped_small::Species::IronDwarf
1284 | biped_small::Species::Haniwa
1285 | biped_small::Species::ShamanicSpirit
1286 | biped_small::Species::Jiangshi
1287 ),
1288 Body::BipedLarge(b) => matches!(
1289 b.species,
1290 biped_large::Species::Huskbrute
1291 | biped_large::Species::Gigasfrost
1292 | biped_large::Species::Gigasfire
1293 | biped_large::Species::Dullahan
1294 | biped_large::Species::HaniwaGeneral
1295 | biped_large::Species::TerracottaBesieger
1296 | biped_large::Species::TerracottaDemolisher
1297 | biped_large::Species::TerracottaPunisher
1298 | biped_large::Species::TerracottaPursuer
1299 | biped_large::Species::Cursekeeper
1300 ),
1301 Body::QuadrupedMedium(b) => {
1302 matches!(b.species, quadruped_medium::Species::ClaySteed)
1303 },
1304 _ => false,
1305 },
1306 BuffKind::Crippled => match self {
1307 Body::Golem(_) | Body::Ship(_) => true,
1308 Body::Object(object) => !matches!(object, object::Body::TrainingDummy),
1309 Body::BipedLarge(b) => matches!(
1310 b.species,
1311 biped_large::Species::Dullahan | biped_large::Species::HaniwaGeneral
1312 ),
1313 Body::BipedSmall(b) => matches!(b.species, biped_small::Species::Haniwa),
1314 Body::QuadrupedMedium(b) => {
1315 matches!(b.species, quadruped_medium::Species::ClaySteed)
1316 },
1317 _ => false,
1318 },
1319 BuffKind::Burning => match self {
1320 Body::Golem(g) => matches!(
1321 g.species,
1322 golem::Species::Gravewarden
1323 | golem::Species::AncientEffigy
1324 | golem::Species::IronGolem
1325 ),
1326 Body::BipedSmall(b) => matches!(
1327 b.species,
1328 biped_small::Species::Haniwa
1329 | biped_small::Species::Flamekeeper
1330 | biped_small::Species::IronDwarf
1331 ),
1332 Body::Object(object) => matches!(
1333 object,
1334 object::Body::HaniwaSentry
1335 | object::Body::Lavathrower
1336 | object::Body::Flamethrower
1337 | object::Body::TerracottaStatue
1338 | object::Body::Crux
1339 ),
1340 Body::QuadrupedLow(q) => matches!(
1341 q.species,
1342 quadruped_low::Species::Lavadrake | quadruped_low::Species::Salamander
1343 ),
1344 Body::BirdLarge(b) => matches!(
1345 b.species,
1346 bird_large::Species::Phoenix
1347 | bird_large::Species::Cockatrice
1348 | bird_large::Species::FlameWyvern
1349 | bird_large::Species::CloudWyvern
1350 | bird_large::Species::FrostWyvern
1351 | bird_large::Species::SeaWyvern
1352 | bird_large::Species::WealdWyvern
1353 ),
1354 Body::Arthropod(b) => matches!(b.species, arthropod::Species::Moltencrawler),
1355 Body::BipedLarge(b) => matches!(
1356 b.species,
1357 biped_large::Species::Cyclops
1358 | biped_large::Species::Minotaur
1359 | biped_large::Species::Forgemaster
1360 | biped_large::Species::Gigasfire
1361 ),
1362 _ => false,
1363 },
1364 BuffKind::Ensnared => match self {
1365 Body::BipedLarge(b) => matches!(b.species, biped_large::Species::Harvester),
1366 Body::Arthropod(_) => true,
1367 _ => false,
1368 },
1369 BuffKind::Regeneration => {
1370 matches!(
1371 self,
1372 Body::Object(
1373 object::Body::GnarlingTotemRed
1374 | object::Body::GnarlingTotemGreen
1375 | object::Body::GnarlingTotemWhite
1376 | object::Body::Crux
1377 )
1378 )
1379 },
1380 BuffKind::Frozen => match self {
1381 Body::BipedLarge(b) => matches!(
1382 b.species,
1383 biped_large::Species::Yeti
1384 | biped_large::Species::Gigasfrost
1385 | biped_large::Species::Tursus
1386 ),
1387 Body::QuadrupedLow(q) => matches!(q.species, quadruped_low::Species::Icedrake),
1388 Body::BirdLarge(b) => matches!(b.species, bird_large::Species::FrostWyvern),
1389 Body::BipedSmall(b) => matches!(b.species, biped_small::Species::Boreal),
1390 Body::QuadrupedMedium(b) => matches!(
1391 b.species,
1392 quadruped_medium::Species::Roshwalr | quadruped_medium::Species::Frostfang
1393 ),
1394 _ => false,
1395 },
1396 BuffKind::ProtectingWard => matches!(self, Body::Object(object::Body::BarrelOrgan)),
1397 _ => false,
1398 }
1399 }
1400
1401 pub fn negates_buff(&self, buff: BuffKind) -> bool {
1404 self.immune_to(buff)
1405 || match buff {
1406 BuffKind::Burning => match self {
1407 Body::BipedSmall(b) => matches!(b.species, biped_small::Species::Ashen),
1408 _ => false,
1409 },
1410 _ => false,
1411 }
1412 }
1413
1414 pub fn combat_multiplier(&self) -> f32 {
1418 match self {
1419 Body::Object(object) => match object {
1420 object::Body::BarrelOrgan | object::Body::ArrowTurret => 0.05,
1421 object::Body::TerracottaStatue => 1.5,
1422 _ => 0.0,
1423 },
1424 Body::Ship(_) => 0.0,
1425 Body::BipedLarge(b) => match b.species {
1426 biped_large::Species::Gigasfire => 1.2,
1427 biped_large::Species::Mindflayer => 4.35,
1428 biped_large::Species::Minotaur => 4.05,
1429 biped_large::Species::Tidalwarrior => 2.75,
1430 biped_large::Species::Yeti => 2.25,
1431 _ => 1.0,
1432 },
1433 Body::BipedSmall(b) => match b.species {
1434 biped_small::Species::Ashen => 1.33,
1435 biped_small::Species::IronDwarf => 2.0,
1436 biped_small::Species::Flamekeeper => 4.0,
1437 biped_small::Species::GreenLegoom
1438 | biped_small::Species::OchreLegoom
1439 | biped_small::Species::PurpleLegoom
1440 | biped_small::Species::RedLegoom
1441 | biped_small::Species::UmberLegoom => 0.8,
1442 _ => 1.0,
1443 },
1444 Body::Golem(g) => match g.species {
1445 golem::Species::Gravewarden => 2.45,
1446 _ => 1.0,
1447 },
1448 Body::QuadrupedLow(b) => match b.species {
1449 quadruped_low::Species::Snaretongue => 2.0,
1450 _ => 1.0,
1451 },
1452 Body::QuadrupedSmall(b) => match b.species {
1453 quadruped_small::Species::Axolotl | quadruped_small::Species::Gecko => 0.6,
1454 _ => 1.0,
1455 },
1456 #[expect(unreachable_patterns)] Body::FishMedium(b) => match b.species {
1458 fish_medium::Species::Marlin | fish_medium::Species::Icepike => 0.6,
1459 _ => 1.0,
1460 },
1461 #[expect(unreachable_patterns)] Body::FishSmall(b) => match b.species {
1463 fish_small::Species::Clownfish | fish_small::Species::Piranha => 0.6,
1464 _ => 1.0,
1465 },
1466 Body::Crustacean(b) => match b.species {
1467 crustacean::Species::Crab | crustacean::Species::SoldierCrab => 0.6,
1468 _ => 1.0,
1469 },
1470 _ => 1.0,
1471 }
1472 }
1473
1474 pub fn base_poise(&self) -> u16 {
1475 match self {
1476 Body::Humanoid(_) => 100,
1477 Body::BipedLarge(biped_large) => match biped_large.species {
1478 biped_large::Species::Mindflayer => 777,
1479 biped_large::Species::Minotaur => 340,
1480 biped_large::Species::Forgemaster => 300,
1481 biped_large::Species::Gigasfrost => 990,
1482 biped_large::Species::Gigasfire => 990,
1483 _ => 300,
1484 },
1485 Body::BipedSmall(b) => match b.species {
1486 biped_small::Species::GnarlingChieftain => 130,
1487 biped_small::Species::IronDwarf | biped_small::Species::Flamekeeper => 300,
1488 biped_small::Species::Boreal => 470,
1489 _ => 100,
1490 },
1491 Body::BirdLarge(b) => match b.species {
1492 bird_large::Species::FlameWyvern
1493 | bird_large::Species::FrostWyvern
1494 | bird_large::Species::CloudWyvern
1495 | bird_large::Species::SeaWyvern
1496 | bird_large::Species::WealdWyvern => 220,
1497 _ => 165,
1498 },
1499 Body::Golem(_) => 365,
1500 Body::QuadrupedMedium(b) => match b.species {
1501 quadruped_medium::Species::Bear | quadruped_medium::Species::Grolgar => 195,
1502 quadruped_medium::Species::Cattle
1503 | quadruped_medium::Species::Llama
1504 | quadruped_medium::Species::Alpaca
1505 | quadruped_medium::Species::Camel
1506 | quadruped_medium::Species::ClaySteed
1507 | quadruped_medium::Species::Zebra
1508 | quadruped_medium::Species::Donkey
1509 | quadruped_medium::Species::Highland
1510 | quadruped_medium::Species::Horse
1511 | quadruped_medium::Species::Kelpie
1512 | quadruped_medium::Species::Hirdrasil
1513 | quadruped_medium::Species::Antelope => 165,
1514 quadruped_medium::Species::Deer => 140,
1515 quadruped_medium::Species::Wolf
1516 | quadruped_medium::Species::Tiger
1517 | quadruped_medium::Species::Barghest
1518 | quadruped_medium::Species::Bonerattler
1519 | quadruped_medium::Species::Darkhound
1520 | quadruped_medium::Species::Moose
1521 | quadruped_medium::Species::Snowleopard
1522 | quadruped_medium::Species::Akhlut
1523 | quadruped_medium::Species::Bristleback
1524 | quadruped_medium::Species::Catoblepas
1525 | quadruped_medium::Species::Lion => 190,
1526 quadruped_medium::Species::Panda => 150,
1527 quadruped_medium::Species::Saber
1528 | quadruped_medium::Species::Yak
1529 | quadruped_medium::Species::Frostfang
1530 | quadruped_medium::Species::Tarasque
1531 | quadruped_medium::Species::Tuskram
1532 | quadruped_medium::Species::Mouflon
1533 | quadruped_medium::Species::Roshwalr
1534 | quadruped_medium::Species::Dreadhorn => 205,
1535 quadruped_medium::Species::Mammoth
1536 | quadruped_medium::Species::Elephant
1537 | quadruped_medium::Species::Ngoubou => 230,
1538 },
1539 Body::QuadrupedLow(b) => match b.species {
1540 quadruped_low::Species::Dagon => 270,
1541 quadruped_low::Species::Crocodile
1542 | quadruped_low::Species::Deadwood
1543 | quadruped_low::Species::SeaCrocodile
1544 | quadruped_low::Species::Alligator
1545 | quadruped_low::Species::Sandshark
1546 | quadruped_low::Species::Snaretongue
1547 | quadruped_low::Species::Asp => 190,
1548 quadruped_low::Species::Tortoise
1549 | quadruped_low::Species::Rocksnapper
1550 | quadruped_low::Species::Rootsnapper
1551 | quadruped_low::Species::Reefsnapper
1552 | quadruped_low::Species::Maneater
1553 | quadruped_low::Species::Hakulaq
1554 | quadruped_low::Species::Lavadrake
1555 | quadruped_low::Species::Icedrake
1556 | quadruped_low::Species::Basilisk
1557 | quadruped_low::Species::Hydra
1558 | quadruped_low::Species::Mossdrake => 205,
1559 quadruped_low::Species::Elbst
1560 | quadruped_low::Species::Salamander
1561 | quadruped_low::Species::Monitor
1562 | quadruped_low::Species::Pangolin
1563 | quadruped_low::Species::Driggle => 130,
1564 },
1565 Body::Theropod(b) => match b.species {
1566 theropod::Species::Archaeos
1567 | theropod::Species::Ntouka
1568 | theropod::Species::Odonto => 240,
1569 theropod::Species::Yale => 220,
1570 _ => 195,
1571 },
1572 _ => 100,
1573 }
1574 }
1575
1576 pub fn eye_height(&self, scale: f32) -> f32 { self.height() * 0.8 * scale }
1578
1579 pub fn top_ratio(&self) -> f32 {
1587 match self {
1588 Body::Humanoid(_) => 0.35,
1590 Body::BipedLarge(_) => 0.25,
1592 Body::BipedSmall(_) => 0.45,
1594 _ => 0.2,
1596 }
1597 }
1598
1599 pub fn default_light_offset(&self) -> Vec3<f32> {
1600 match self {
1602 Body::Object(_) => Vec3::unit_z() * 0.5,
1603 _ => Vec3::unit_z(),
1604 }
1605 }
1606
1607 pub fn can_strafe(&self) -> bool {
1608 matches!(
1609 self,
1610 Body::Humanoid(_)
1611 | Body::BipedSmall(_)
1612 | Body::BipedLarge(_)
1613 | Body::Crustacean(crustacean::Body {
1614 species: crustacean::Species::Crab,
1615 ..
1616 })
1617 | Body::Ship(ship::Body::Train)
1619 )
1620 }
1621
1622 pub fn mount_offset(&self) -> Vec3<f32> {
1625 match self {
1626 Body::Humanoid(_) => (self.dimensions() * Vec3::new(0.5, 0.0, 0.6)).into_tuple(),
1627 Body::QuadrupedSmall(b) => match (b.species, b.body_type) {
1628 (quadruped_small::Species::Pig, _) => (0.0, 0.1, 0.6),
1629 (quadruped_small::Species::Fox, _) => (0.0, 0.1, 0.6),
1630 (quadruped_small::Species::Sheep, _) => (0.0, 0.1, 0.7),
1631 (quadruped_small::Species::Boar, _) => (0.0, -0.2, 1.0),
1632 (quadruped_small::Species::Jackalope, _) => (0.0, -0.1, 0.5),
1633 (quadruped_small::Species::Skunk, _) => (0.0, 0.0, 0.55),
1634 (quadruped_small::Species::Cat, _) => (0.0, 0.0, 0.45),
1635 (quadruped_small::Species::Batfox, _) => (0.0, -0.1, 0.7),
1636 (quadruped_small::Species::Raccoon, _) => (0.0, 0.0, 0.65),
1637 (quadruped_small::Species::Quokka, _) => (0.0, 0.1, 0.7),
1638 (quadruped_small::Species::Goat, _) => (0.0, 0.2, 0.7),
1639 (quadruped_small::Species::Holladon, _) => (0.0, -0.3, 1.05),
1640 (quadruped_small::Species::Hyena, _) => (0.0, -0.4, 0.95),
1641 (quadruped_small::Species::Rabbit, _) => (0.0, -0.05, 0.4),
1642 (quadruped_small::Species::Truffler, _) => (0.0, -0.5, 1.84),
1643 (quadruped_small::Species::Frog, _) => (0.0, -0.07, 0.35),
1644 (quadruped_small::Species::Rat, _) => (0.0, 0.35, 0.35),
1645 (quadruped_small::Species::Axolotl, _) => (0.0, 0.095, 0.295),
1646 (quadruped_small::Species::Gecko, _) => (0.0, 0.35, 0.25),
1647 (quadruped_small::Species::Turtle, _) => (0.0, -0.16, 0.5),
1648 (quadruped_small::Species::Squirrel, _) => (0.0, 0.16, 0.24),
1649 (quadruped_small::Species::Fungome, _) => (0.0, 0.03, 0.43),
1650 (quadruped_small::Species::Porcupine, _) => (0.0, 0.56, 0.74),
1651 (quadruped_small::Species::Beaver, _) => (0.0, 0.18, 0.7),
1652 (quadruped_small::Species::Hare, quadruped_small::BodyType::Female) => {
1653 (0.0, -0.21, 0.44)
1654 },
1655 (quadruped_small::Species::Hare, quadruped_small::BodyType::Male) => {
1656 (0.0, -0.21, 0.54)
1657 },
1658 (quadruped_small::Species::Dog, _) => (0.0, -0.27, 0.76),
1659 (quadruped_small::Species::Seal, _) => (0.0, -0.14, 0.54),
1660 (quadruped_small::Species::TreantSapling, _) => (0.0, -0.2, 1.03),
1661 (quadruped_small::Species::MossySnail, _) => (0.0, -0.34, 0.96),
1662 },
1663 Body::QuadrupedMedium(b) => match (b.species, b.body_type) {
1664 (quadruped_medium::Species::Grolgar, _) => (0.0, 0.4, 1.98),
1665 (quadruped_medium::Species::Saber, _) => (0.0, -0.1, 1.3),
1666 (quadruped_medium::Species::Tiger, _) => (0.0, 0.2, 1.63),
1667 (quadruped_medium::Species::Tuskram, _) => (0.0, -0.5, 1.5),
1668 (quadruped_medium::Species::Lion, _) => (0.0, 0.3, 1.5),
1669 (quadruped_medium::Species::Tarasque, _) => (0.0, 0.6, 2.0),
1670 (quadruped_medium::Species::Wolf, _) => (0.0, 0.5, 1.3),
1671 (quadruped_medium::Species::Frostfang, _) => (0.0, 0.05, 1.2),
1672 (quadruped_medium::Species::Mouflon, _) => (0.0, 0.3, 1.2),
1673 (quadruped_medium::Species::Catoblepas, _) => (0.0, 0.0, 2.0),
1674 (quadruped_medium::Species::Bonerattler, _) => (0.0, 0.5, 1.2),
1675 (quadruped_medium::Species::Deer, _) => (0.0, 0.2, 1.3),
1676 (quadruped_medium::Species::Hirdrasil, _) => (0.0, 0.0, 1.4),
1677 (quadruped_medium::Species::Roshwalr, _) => (0.0, 0.9, 3.2),
1678 (quadruped_medium::Species::Donkey, _) => (0.0, 0.5, 1.6),
1679 (quadruped_medium::Species::Camel, _) => (0.0, -0.1, 2.7),
1680 (quadruped_medium::Species::Zebra, _) => (0.0, 0.5, 1.8),
1681 (quadruped_medium::Species::Antelope, _) => (0.0, 0.3, 1.4),
1682 (quadruped_medium::Species::Kelpie, _) => (0.0, 0.5, 1.9),
1683 (quadruped_medium::Species::Horse, _) => (0.0, 0.0, 2.0),
1684 (quadruped_medium::Species::Barghest, _) => (0.0, 0.5, 2.3),
1685 (quadruped_medium::Species::Cattle, quadruped_medium::BodyType::Male) => {
1686 (0.0, 0.5, 2.5)
1687 },
1688 (quadruped_medium::Species::Cattle, quadruped_medium::BodyType::Female) => {
1689 (0.0, 0.7, 2.3)
1690 },
1691 (quadruped_medium::Species::Darkhound, _) => (0.0, 0.5, 1.4),
1692 (quadruped_medium::Species::Highland, _) => (0.0, 0.5, 2.3),
1693 (quadruped_medium::Species::Yak, _) => (0.0, 0.0, 3.0),
1694 (quadruped_medium::Species::Panda, _) => (0.0, -0.2, 1.4),
1695 (quadruped_medium::Species::Bear, _) => (0.0, -0.4, 2.35),
1696 (quadruped_medium::Species::Dreadhorn, _) => (0.0, 0.2, 3.8),
1697 (quadruped_medium::Species::Moose, _) => (0.0, -0.6, 2.1),
1698 (quadruped_medium::Species::Snowleopard, _) => (0.0, -0.5, 1.4),
1699 (quadruped_medium::Species::Mammoth, _) => (0.0, 4.9, 7.2),
1700 (quadruped_medium::Species::Elephant, _) => (0.0, 4.9, 7.2),
1701 (quadruped_medium::Species::Ngoubou, _) => (0.0, 0.3, 2.4),
1702 (quadruped_medium::Species::Llama, _) => (0.0, 0.1, 1.5),
1703 (quadruped_medium::Species::Alpaca, _) => (0.0, -0.1, 1.0),
1704 (quadruped_medium::Species::Akhlut, _) => (0.0, 1.9, 2.6),
1705 (quadruped_medium::Species::Bristleback, _) => (0.0, -0.4, 1.3),
1706 (quadruped_medium::Species::ClaySteed, _) => (0.0, -0.3, 2.8),
1707 },
1708 Body::BirdMedium(b) => match (b.species, b.body_type) {
1709 (bird_medium::Species::SnowyOwl, _) => (0.0, -0.25, 0.52),
1710 (bird_medium::Species::HornedOwl, _) => (0.0, -0.25, 0.45),
1711 (bird_medium::Species::Duck, _) => (0.0, -0.18, 0.47),
1712 (bird_medium::Species::Cockatiel, _) => (0.0, -0.05, 0.44),
1713 (bird_medium::Species::Chicken, bird_medium::BodyType::Female) => {
1714 (0.0, -0.13, 0.62)
1715 },
1716 (bird_medium::Species::Chicken, bird_medium::BodyType::Male) => (0.0, -0.1, 0.62),
1717 (bird_medium::Species::Bat, _) => (0.0, 0.02, 0.47),
1718 (bird_medium::Species::Penguin, _) => (0.0, -0.15, 0.88),
1719 (bird_medium::Species::Goose, _) => (0.0, -0.04, 0.74),
1720 (bird_medium::Species::Peacock, _) => (0.0, -0.18, 0.77),
1721 (bird_medium::Species::Eagle, _) => (0.0, -0.26, 0.64),
1722 (bird_medium::Species::Parrot, _) => (0.0, -0.18, 0.52),
1723 (bird_medium::Species::Crow, _) => (0.0, -0.08, 0.5),
1724 (bird_medium::Species::Dodo, _) => (0.0, -0.25, 0.7),
1725 (bird_medium::Species::Parakeet, _) => (0.0, -0.08, 0.42),
1726 (bird_medium::Species::Puffin, _) => (0.0, -0.21, 0.56),
1727 (bird_medium::Species::Toucan, _) => (0.0, -0.12, 0.52),
1728 (bird_medium::Species::BloodmoonBat, _) => (0.0, 0.1, 1.6),
1729 (bird_medium::Species::VampireBat, _) => (0.0, 0.02, 0.5),
1730 },
1731 Body::FishMedium(b) => match (b.species, b.body_type) {
1732 (fish_medium::Species::Marlin, _) => (0.0, 0.26, 0.6),
1733 (fish_medium::Species::Icepike, _) => (0.0, 0.34, 0.65),
1734 },
1735 Body::Dragon(b) => match (b.species, b.body_type) {
1736 (dragon::Species::Reddragon, _) => (0.0, 0.5, 20.5),
1737 },
1738 Body::BirdLarge(b) => match (b.species, b.body_type) {
1739 (bird_large::Species::Phoenix, _) => (0.0, 0.4, 3.1),
1740 (bird_large::Species::Cockatrice, _) => (0.0, 0.94, 2.98),
1741 (bird_large::Species::Roc, _) => (0.0, 2.18, 4.23),
1742 (bird_large::Species::FlameWyvern, _) => (0.0, 1.58, 3.28),
1743 (bird_large::Species::CloudWyvern, _) => (0.0, 1.7, 3.15),
1744 (bird_large::Species::FrostWyvern, _) => (0.0, 1.8, 3.09),
1745 (bird_large::Species::SeaWyvern, _) => (0.0, 1.41, 3.31),
1746 (bird_large::Species::WealdWyvern, _) => (0.0, 1.8, 3.46),
1747 },
1748 Body::FishSmall(b) => match (b.species, b.body_type) {
1749 (fish_small::Species::Clownfish, _) => (0.0, 0.05, 0.6),
1750 (fish_small::Species::Piranha, _) => (0.0, -0.065, 0.715),
1751 },
1752 Body::BipedLarge(b) => match (b.species, b.body_type) {
1753 (biped_large::Species::Ogre, biped_large::BodyType::Female) => (1.2, 0.2, 4.2),
1754 (biped_large::Species::Ogre, biped_large::BodyType::Male) => (1.5, -0.25, 4.5),
1755 (biped_large::Species::Cyclops, _) => (3.0, 1.1, 6.6),
1756 (biped_large::Species::Wendigo, _) => (1.25, -0.2, 4.3),
1757 (biped_large::Species::Cavetroll, _) => (1.8, 0.1, 4.1),
1758 (biped_large::Species::Mountaintroll, _) => (1.9, 0.5, 4.2),
1759 (biped_large::Species::Swamptroll, _) => (1.9, 0.0, 4.3),
1760 (biped_large::Species::Dullahan, _) => (0.0, -0.2, 4.5),
1761 (biped_large::Species::Werewolf, _) => (1.0, 1.0, 2.8),
1762 (biped_large::Species::Occultsaurok, _) => (0.0, 0.4, 3.4),
1763 (biped_large::Species::Mightysaurok, _) => (0.0, 0.4, 3.4),
1764 (biped_large::Species::Slysaurok, _) => (0.0, 0.4, 3.4),
1765 (biped_large::Species::Mindflayer, _) => (1.8, 0.6, 6.6),
1766 (biped_large::Species::Minotaur, _) => (2.1, 0.4, 6.6),
1767 (biped_large::Species::Tidalwarrior, _) => (0.0, -0.5, 7.4),
1768 (biped_large::Species::Yeti, _) => (1.6, 0.5, 3.7),
1769 (biped_large::Species::Harvester, _) => (1.3, 0.4, 2.6),
1770 (biped_large::Species::Blueoni, _) => (1.7, 0.4, 3.6),
1771 (biped_large::Species::Redoni, _) => (1.7, 0.4, 3.6),
1772 (biped_large::Species::Cultistwarlord, _) => (1.1, 0.3, 2.7),
1773 (biped_large::Species::Cultistwarlock, _) => (1.0, 0.3, 2.7),
1774 (biped_large::Species::Huskbrute, _) => (1.6, 0.2, 3.8),
1775 (biped_large::Species::Tursus, _) => (1.6, 0.5, 3.4),
1776 (biped_large::Species::Gigasfrost, _) => (2.5, 0.5, 7.3),
1777 (biped_large::Species::Gigasfire, _) => (2.5, 0.5, 7.3),
1778 (biped_large::Species::AdletElder, _) => (1.2, 0.6, 2.4),
1779 (biped_large::Species::SeaBishop, _) => (0.9, 0.2, 2.0),
1780 (biped_large::Species::HaniwaGeneral, _) => (1.2, 0.4, 2.4),
1781 (biped_large::Species::TerracottaBesieger, _) => (1.5, -0.2, 3.3),
1782 (biped_large::Species::TerracottaDemolisher, _) => (1.1, -0.1, 2.2),
1783 (biped_large::Species::TerracottaPunisher, _) => (1.1, -0.1, 2.1),
1784 (biped_large::Species::TerracottaPursuer, _) => (1.1, -0.1, 2.2),
1785 (biped_large::Species::Cursekeeper, _) => (1.3, -0.4, 3.0),
1786 (biped_large::Species::Forgemaster, _) => (2.6, 0.8, 6.1),
1787 (biped_large::Species::Strigoi, _) => (1.7, -0.1, 3.6),
1788 (biped_large::Species::Executioner, _) => (1.1, 0.1, 3.3),
1789 },
1790 Body::BipedSmall(b) => match (b.species, b.body_type) {
1791 (biped_small::Species::Gnome, _) => (0.0, -0.33, 1.22),
1792 (biped_small::Species::Sahagin, _) => (0.0, 0.0, 1.9),
1793 (biped_small::Species::Adlet, _) => (0.0, -0.35, 1.7),
1794 (biped_small::Species::Gnarling, _) => (0.0, -0.3, 1.07),
1795 (biped_small::Species::Mandragora, _) => (0.0, -0.25, 0.72),
1796 (biped_small::Species::Kappa, _) => (0.0, -0.34, 1.1),
1797 (biped_small::Species::Cactid, _) => (0.0, -0.25, 1.13),
1798 (biped_small::Species::Gnoll, _) => (0.0, -0.28, 1.25),
1799 (biped_small::Species::Haniwa, _) => (0.0, -0.6, 1.91),
1800 (biped_small::Species::Myrmidon, _) => (0.0, -0.89, 0.96),
1801 (biped_small::Species::Husk, _) => (0.0, -0.5, 2.32),
1802 (biped_small::Species::Boreal, _) => (0.0, -0.81, 4.4),
1803 (biped_small::Species::Ashen, _) => (0.0, -0.81, 4.4),
1804 (biped_small::Species::Bushly, _) => (0.0, -0.26, 1.81),
1805 (biped_small::Species::Irrwurz, _) => (0.0, -0.35, 1.42),
1806 (biped_small::Species::IronDwarf, _) => (0.0, -0.12, 2.98),
1807 (biped_small::Species::Flamekeeper, _) => (0.0, -0.31, 2.2),
1808 (biped_small::Species::ShamanicSpirit, _) => (0.0, -0.03, 2.29),
1809 (biped_small::Species::Jiangshi, _) => (0.0, -0.21, 2.53),
1810 (biped_small::Species::TreasureEgg, _) => (0.0, -0.31, 1.0),
1811 (biped_small::Species::GnarlingChieftain, _) => (0.0, -0.27, 1.28),
1812 (biped_small::Species::BloodmoonHeiress, _) => (0.0, -0.12, 5.22),
1813 (biped_small::Species::Bloodservant, _) => (0.0, -0.21, 2.26),
1814 (biped_small::Species::Harlequin, _) => (0.0, -0.26, 2.17),
1815 (biped_small::Species::GoblinThug, _) => (0.0, -0.37, 0.49),
1816 (biped_small::Species::GoblinChucker, _) => (0.0, -0.83, 0.49),
1817 (biped_small::Species::GoblinRuffian, _) => (0.0, -0.37, 0.49),
1818 (biped_small::Species::GreenLegoom, _) => (0.0, -0.4, 1.48),
1819 (biped_small::Species::OchreLegoom, _) => (0.0, -0.4, 1.2),
1820 (biped_small::Species::PurpleLegoom, _) => (0.0, -0.36, 1.66),
1821 (biped_small::Species::RedLegoom, _) => (0.0, -0.3, 1.4),
1822 (biped_small::Species::UmberLegoom, _) => (0.0, -0.3, 1.4),
1823 },
1824 Body::Golem(b) => match (b.species, b.body_type) {
1825 (golem::Species::StoneGolem, _) => (0.0, 0.2, 8.8),
1826 (golem::Species::Treant, _) => (0.0, 3.6, 6.4),
1827 (golem::Species::ClayGolem, _) => (0.0, 0.0, 7.8),
1828 (golem::Species::WoodGolem, _) => (0.0, 0.5, 7.2),
1829 (golem::Species::CoralGolem, _) => (0.0, 0.0, 4.0),
1830 (golem::Species::Gravewarden, _) => (0.0, -0.5, 7.5),
1831 (golem::Species::AncientEffigy, _) => (0.0, -0.2, 3.5),
1832 (golem::Species::Mogwai, _) => (0.0, 0.4, 3.7),
1833 (golem::Species::IronGolem, _) => (0.0, 0.2, 10.2),
1834 },
1835 Body::Theropod(b) => match (b.species, b.body_type) {
1836 (theropod::Species::Archaeos, _) => (0.0, 2.2, 6.1),
1837 (theropod::Species::Odonto, _) => (0.0, 4.1, 4.0),
1838 (theropod::Species::Sandraptor, _) => (0.0, -0.15, 1.63),
1839 (theropod::Species::Snowraptor, _) => (0.0, -0.15, 1.58),
1840 (theropod::Species::Woodraptor, _) => (0.0, -0.14, 1.66),
1841 (theropod::Species::Sunlizard, _) => (0.0, -0.2, 1.75),
1842 (theropod::Species::Yale, _) => (0.0, -0.615, 2.75),
1843 (theropod::Species::Ntouka, _) => (0.0, -1.1, 5.5),
1844 (theropod::Species::Dodarock, _) => (0.0, -0.09, 1.49),
1845 (theropod::Species::Axebeak, _) => (0.0, -0.34, 1.85),
1846 },
1847 Body::QuadrupedLow(b) => match (b.species, b.body_type) {
1848 (quadruped_low::Species::Crocodile, _) => (0.0, 0.35, 0.8),
1849 (quadruped_low::Species::Alligator, _) => (0.0, 0.27, 0.8),
1850 (quadruped_low::Species::Salamander, _) => (0.0, 0.21, 0.9),
1851 (quadruped_low::Species::Monitor, _) => (0.0, 0.01, 0.64),
1852 (quadruped_low::Species::Asp, _) => (0.0, 0.21, 1.2),
1853 (quadruped_low::Species::Tortoise, _) => (0.0, 0.01, 1.37),
1854 (quadruped_low::Species::Pangolin, _) => (0.0, -0.08, 1.08),
1855 (quadruped_low::Species::Maneater, _) => (0.0, 1.3, 2.0),
1856 (quadruped_low::Species::Sandshark, _) => (0.0, -0.48, 1.62),
1857 (quadruped_low::Species::Hakulaq, _) => (0.0, 0.49, 1.51),
1858 (quadruped_low::Species::Lavadrake, _) => (0.0, 0.22, 1.61),
1859 (quadruped_low::Species::Basilisk, _) => (0.0, -0.17, 2.71),
1860 (quadruped_low::Species::Deadwood, _) => (0.0, -0.15, 1.21),
1861 (quadruped_low::Species::Icedrake, _) => (0.0, -0.7, 2.28),
1862 (quadruped_low::Species::SeaCrocodile, _) => (0.1, 0.35, 1.03),
1863 (quadruped_low::Species::Dagon, _) => (0.1, 0.92, 1.32),
1864 (quadruped_low::Species::Rocksnapper, _) => (0.0, 0.72, 2.73),
1865 (quadruped_low::Species::Rootsnapper, _) => (0.0, -0.18, 3.13),
1866 (quadruped_low::Species::Reefsnapper, _) => (0.0, 0.22, 2.32),
1867 (quadruped_low::Species::Elbst, _) => (0.0, 0.22, 0.8),
1868 (quadruped_low::Species::Mossdrake, _) => (0.0, 0.22, 2.02),
1869 (quadruped_low::Species::Driggle, _) => (0.0, 0.5, 0.8),
1870 (quadruped_low::Species::Snaretongue, _) => (0.0, -0.54, 1.35),
1871 (quadruped_low::Species::Hydra, _) => (0.0, 0.28, 2.71),
1872 },
1873 Body::Arthropod(b) => match (b.species, b.body_type) {
1874 (arthropod::Species::Tarantula, _) => (0.0, -0.65, 1.66),
1875 (arthropod::Species::Blackwidow, _) => (0.0, -0.82, 2.48),
1876 (arthropod::Species::Antlion, _) => (0.0, -0.49, 1.98),
1877 (arthropod::Species::Hornbeetle, _) => (0.0, 0.27, 1.98),
1878 (arthropod::Species::Leafbeetle, _) => (0.0, -0.06, 1.1),
1879 (arthropod::Species::Stagbeetle, _) => (0.0, 0.6, 1.48),
1880 (arthropod::Species::Weevil, _) => (0.0, -0.1, 1.02),
1881 (arthropod::Species::Cavespider, _) => (0.0, -0.65, 1.82),
1882 (arthropod::Species::Moltencrawler, _) => (0.0, 0.43, 1.82),
1883 (arthropod::Species::Mosscrawler, _) => (0.0, 0.6, 1.82),
1884 (arthropod::Species::Sandcrawler, _) => (0.0, 0.6, 1.82),
1885 (arthropod::Species::Dagonite, _) => (0.0, 1.1, 2.15),
1886 (arthropod::Species::Emberfly, _) => (0.0, -0.28, 0.36),
1887 },
1888 Body::Crustacean(b) => match (b.species, b.body_type) {
1889 (crustacean::Species::Crab, _) => (0.0, -0.22, 0.36),
1890 (crustacean::Species::SoldierCrab, _) => (0.0, -0.14, 0.5),
1891 (crustacean::Species::Karkatha, _) => (0.0, -0.23, 7.66),
1892 },
1893 Body::Ship(ship) => match ship {
1894 ship::Body::DefaultAirship => (0.0, 0.0, 10.0),
1895 ship::Body::AirBalloon => (0.0, 0.0, 5.0),
1896 ship::Body::SailBoat => (-2.0, -5.0, 4.0),
1897 ship::Body::Galleon => (-2.0, -5.0, 4.0),
1898 ship::Body::Skiff => (1.0, -2.0, 2.0),
1899 ship::Body::Submarine => (1.0, -2.0, 2.0),
1900 ship::Body::Carriage => (1.0, -2.0, 2.0),
1901 ship::Body::Cart => (1.0, -2.0, 2.0),
1902 ship::Body::Volume => (0.0, 0.0, 0.0),
1903 ship::Body::Train => (1.0, -2.0, 2.0),
1904 },
1905 _ => (0.0, 0.0, 0.0),
1906 }
1907 .into()
1908 }
1909
1910 pub fn rider_offset(&self) -> Vec3<f32> {
1912 match self {
1913 Body::Humanoid(_) => [0.0, 0.0, 0.0],
1914 _ => [0.0, 0.0, 0.0],
1915 }
1916 .into()
1917 }
1918
1919 pub fn tether_offset_leader(&self) -> Vec3<f32> {
1920 Vec3::new(0.0, self.dimensions().y * -0.4, self.dimensions().z * 0.7)
1921 }
1922
1923 pub fn tether_offset_follower(&self) -> Vec3<f32> {
1924 Vec3::new(0.0, self.dimensions().y * 0.6, self.dimensions().z * 0.7)
1925 }
1926
1927 pub fn localize_npc(&self) -> Content {
1932 fn try_localize(body: &Body) -> Option<Content> {
1933 match body {
1934 Body::BipedLarge(biped_large) => biped_large.localize_npc(),
1935 _ => None,
1936 }
1937 }
1938
1939 try_localize(self).unwrap_or_else(|| Content::localized("noun-creature"))
1940 }
1941
1942 pub fn humanoid_gender(&self) -> Option<Gender> {
1944 match self {
1945 Body::Humanoid(b) => match b.body_type {
1946 humanoid::BodyType::Male => Some(Gender::Masculine),
1947 humanoid::BodyType::Female => Some(Gender::Feminine),
1948 },
1949 _ => None,
1950 }
1951 }
1952
1953 pub fn default_gender(&self) -> Gender {
1965 match self {
1966 Body::Humanoid(b) => match b.body_type {
1967 humanoid::BodyType::Male => Gender::Masculine,
1968 humanoid::BodyType::Female => Gender::Feminine,
1969 },
1970 Body::QuadrupedSmall(b) => match b.body_type {
1971 quadruped_small::BodyType::Male => Gender::Masculine,
1972 quadruped_small::BodyType::Female => Gender::Feminine,
1973 },
1974 Body::QuadrupedMedium(b) => match b.body_type {
1975 quadruped_medium::BodyType::Male => Gender::Masculine,
1976 quadruped_medium::BodyType::Female => Gender::Feminine,
1977 },
1978 Body::QuadrupedLow(b) => match b.body_type {
1979 quadruped_low::BodyType::Male => Gender::Masculine,
1980 quadruped_low::BodyType::Female => Gender::Feminine,
1981 },
1982 Body::BirdMedium(b) => match b.body_type {
1983 bird_medium::BodyType::Male => Gender::Masculine,
1984 bird_medium::BodyType::Female => Gender::Feminine,
1985 },
1986 Body::BirdLarge(b) => match b.body_type {
1987 bird_large::BodyType::Male => Gender::Masculine,
1988 bird_large::BodyType::Female => Gender::Feminine,
1989 },
1990 Body::FishMedium(b) => match b.body_type {
1991 fish_medium::BodyType::Male => Gender::Masculine,
1992 fish_medium::BodyType::Female => Gender::Feminine,
1993 },
1994 Body::FishSmall(b) => match b.body_type {
1995 fish_small::BodyType::Male => Gender::Masculine,
1996 fish_small::BodyType::Female => Gender::Feminine,
1997 },
1998 Body::Dragon(b) => match b.body_type {
1999 dragon::BodyType::Male => Gender::Masculine,
2000 dragon::BodyType::Female => Gender::Feminine,
2001 },
2002 Body::BipedLarge(b) => match b.body_type {
2003 biped_large::BodyType::Male => Gender::Masculine,
2004 biped_large::BodyType::Female => Gender::Feminine,
2005 },
2006 Body::BipedSmall(b) => match b.body_type {
2007 biped_small::BodyType::Male => Gender::Masculine,
2008 biped_small::BodyType::Female => Gender::Feminine,
2009 },
2010 Body::Golem(b) => match b.body_type {
2011 golem::BodyType::Male => Gender::Masculine,
2012 golem::BodyType::Female => Gender::Feminine,
2013 },
2014 Body::Theropod(b) => match b.body_type {
2015 theropod::BodyType::Male => Gender::Masculine,
2016 theropod::BodyType::Female => Gender::Feminine,
2017 },
2018 Body::Arthropod(b) => match b.body_type {
2019 arthropod::BodyType::Male => Gender::Masculine,
2020 arthropod::BodyType::Female => Gender::Feminine,
2021 },
2022 Body::Crustacean(b) => match b.body_type {
2023 crustacean::BodyType::Male => Gender::Masculine,
2024 crustacean::BodyType::Female => Gender::Feminine,
2025 },
2026 Body::Plugin(_) => Gender::Neuter,
2028 Body::Object(_) | Body::Ship(_) | Body::Item(_) => Gender::Neuter,
2029 }
2030 }
2031
2032 pub fn gender_attr(&self) -> &'static str {
2036 match self.default_gender() {
2037 Gender::Feminine => "fem",
2038 Gender::Masculine => "masc",
2039 Gender::Neuter => "neut",
2040 }
2041 }
2042}
2043
2044impl Component for Body {
2045 type Storage = DerefFlaggedStorage<Self, specs::VecStorage<Self>>;
2046}