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) =>
45 {
50 !matches!(
51 quad_med.species,
52 quadruped_medium::Species::Catoblepas
53 | quadruped_medium::Species::Mammoth
54 | quadruped_medium::Species::Hirdrasil
55 )
56 },
57 Body::QuadrupedLow(_)
58 | Body::QuadrupedSmall(_)
59 | Body::BirdMedium(_)
60 | Body::Crustacean(_) => true,
61 _ => false,
62 }
63}
64
65pub fn is_mountable(
66 mount: &Body,
67 mount_mass: &Mass,
68 rider: Option<&Body>,
69 rider_mass: Option<&Mass>,
70) -> bool {
71 let is_light_enough = rider_mass.is_some_and(|r| r.0 / mount_mass.0 < 0.7);
72
73 match mount {
74 Body::Humanoid(_) => matches!(rider, Some(Body::BirdMedium(_))) && is_light_enough,
75 Body::Ship(_) => true,
76 Body::Object(_) => false,
77 Body::ItemDrop(_) => false,
78 _ => is_light_enough,
79 }
80}
81
82impl Component for Pet {
83 type Storage = specs::VecStorage<Self>;
87}