veloren_common/comp/
pet.rs1use crate::comp::{body::Body, quadruped_medium};
2use crossbeam_utils::atomic::AtomicCell;
3use specs::Component;
4use std::{num::NonZeroU64, sync::Arc};
5
6use super::Mass;
7
8pub type PetId = AtomicCell<Option<NonZeroU64>>;
9
10#[derive(Clone, Debug)]
12pub struct Pet {
13 database_id: Arc<PetId>,
14}
15
16impl Pet {
17 #[doc(hidden)]
21 pub fn get_database_id(&self) -> Arc<PetId> { Arc::clone(&self.database_id) }
22
23 pub fn new_from_database(database_id: NonZeroU64) -> Self {
24 Self {
25 database_id: Arc::new(AtomicCell::new(Some(database_id))),
26 }
27 }
28}
29
30impl Default for Pet {
31 fn default() -> Self {
32 Self {
33 database_id: Arc::new(AtomicCell::new(None)),
34 }
35 }
36}
37
38pub fn is_tameable(body: &Body) -> bool {
40 match body {
44 Body::QuadrupedMedium(quad_med) => !matches!(
45 quad_med.species,
46 quadruped_medium::Species::Catoblepas
47 | quadruped_medium::Species::Mammoth
48 | quadruped_medium::Species::Elephant
49 | quadruped_medium::Species::Hirdrasil
50 ),
51 Body::QuadrupedLow(_)
52 | Body::QuadrupedSmall(_)
53 | Body::BirdMedium(_)
54 | Body::Crustacean(_) => true,
55 _ => false,
56 }
57}
58
59pub fn is_mountable(
60 mount: &Body,
61 mount_mass: &Mass,
62 rider: Option<&Body>,
63 rider_mass: Option<&Mass>,
64) -> bool {
65 let is_light_enough = rider_mass.is_some_and(|r| r.0 / mount_mass.0 < 0.7);
66
67 match mount {
68 Body::Humanoid(_) => matches!(rider, Some(Body::BirdMedium(_))) && is_light_enough,
69 Body::Ship(_) => true,
70 Body::Object(_) => false,
71 Body::Item(_) => false,
72 _ => is_light_enough,
73 }
74}
75
76impl Component for Pet {
77 type Storage = specs::VecStorage<Self>;
81}