use crate::comp::{body::Body, phys::Mass, quadruped_medium, quadruped_small};
use crossbeam_utils::atomic::AtomicCell;
use specs::Component;
use std::{num::NonZeroU64, sync::Arc};
pub type PetId = AtomicCell<Option<NonZeroU64>>;
#[derive(Clone, Debug)]
pub struct Pet {
database_id: Arc<PetId>,
}
impl Pet {
#[doc(hidden)]
pub fn get_database_id(&self) -> Arc<PetId> { Arc::clone(&self.database_id) }
pub fn new_from_database(database_id: NonZeroU64) -> Self {
Self {
database_id: Arc::new(AtomicCell::new(Some(database_id))),
}
}
}
impl Default for Pet {
fn default() -> Self {
Self {
database_id: Arc::new(AtomicCell::new(None)),
}
}
}
pub fn is_tameable(body: &Body) -> bool {
match body {
Body::QuadrupedMedium(quad_med) =>
{
!matches!(
quad_med.species,
quadruped_medium::Species::Catoblepas
| quadruped_medium::Species::Mammoth
| quadruped_medium::Species::Hirdrasil
)
},
Body::QuadrupedLow(_)
| Body::QuadrupedSmall(_)
| Body::BirdMedium(_)
| Body::Crustacean(_) => true,
_ => false,
}
}
pub fn is_mountable(mount: &Body, rider: Option<&Body>) -> bool {
let is_light_enough =
|rider: Option<&Body>| -> bool { rider.map_or(false, |b| b.mass() <= Mass(500.0)) };
match mount {
Body::Humanoid(_) => matches!(rider, Some(Body::BirdMedium(_))),
Body::BipedLarge(_) => is_light_enough(rider),
Body::BirdLarge(_) => is_light_enough(rider),
Body::QuadrupedMedium(body) => match body.species {
quadruped_medium::Species::Alpaca
| quadruped_medium::Species::Antelope
| quadruped_medium::Species::Bear
| quadruped_medium::Species::Camel
| quadruped_medium::Species::Cattle
| quadruped_medium::Species::Deer
| quadruped_medium::Species::Donkey
| quadruped_medium::Species::Highland
| quadruped_medium::Species::Horse
| quadruped_medium::Species::Kelpie
| quadruped_medium::Species::Llama
| quadruped_medium::Species::Moose
| quadruped_medium::Species::Tuskram
| quadruped_medium::Species::Yak
| quadruped_medium::Species::Zebra
| quadruped_medium::Species::Grolgar
| quadruped_medium::Species::Wolf
| quadruped_medium::Species::Saber
| quadruped_medium::Species::Tiger => true,
quadruped_medium::Species::Mouflon => is_light_enough(rider),
_ => false,
},
Body::QuadrupedSmall(body) => match body.species {
quadruped_small::Species::Truffler => true,
quadruped_small::Species::Boar | quadruped_small::Species::Holladon => {
is_light_enough(rider)
},
_ => false,
},
Body::QuadrupedLow(_) => mount.mass() >= Mass(300.0) && is_light_enough(rider),
Body::Ship(_) => true,
_ => false,
}
}
impl Component for Pet {
type Storage = specs::VecStorage<Self>;
}