use crate::{models::item::Sex, static_content::possession_type::PossessionType}; use once_cell::sync::OnceCell; use rand::seq::IteratorRandom; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; #[derive(Serialize, Deserialize, Eq, Ord, Clone, PartialEq, PartialOrd, Debug)] pub enum SpeciesType { Human, Dog, Robot, Rat, } impl SpeciesType { pub fn sample_body_part(&self) -> BodyPart { let mut rng = rand::thread_rng(); species_info_map() .get(&self) .and_then(|sp| sp.body_parts.iter().choose(&mut rng)) .unwrap_or(&BodyPart::Head) .clone() } } #[derive(Eq, Ord, Clone, PartialEq, PartialOrd, Debug)] pub enum BodyPart { Head, Face, Chest, Back, Groin, Arms, Hands, Legs, Feet, } impl BodyPart { pub fn display(&self, _sex: Option) -> &'static str { use BodyPart::*; match self { Head => "head", Face => "face", Chest => "chest", Back => "back", Groin => "groin", Arms => "arms", Hands => "hands", Legs => "legs", Feet => "feet", } } pub fn copula(&self, sex: Option) -> &'static str { use BodyPart::*; match self { Head => "is", Face => "is", Chest => match sex { Some(Sex::Female) => "are", _ => "is", }, Back => "is", Groin => "is", Arms => "are", Hands => "are", Legs => "are", Feet => "are", } } } pub struct SpeciesInfo { pub body_parts: Vec, pub corpse_butchers_into: Vec, pub can_open_door: bool, } pub fn species_info_map() -> &'static BTreeMap { static INFOMAP: OnceCell> = OnceCell::new(); INFOMAP.get_or_init(|| { vec![ ( SpeciesType::Human, SpeciesInfo { body_parts: vec![ BodyPart::Head, BodyPart::Face, BodyPart::Chest, BodyPart::Back, BodyPart::Groin, BodyPart::Arms, BodyPart::Hands, BodyPart::Legs, BodyPart::Feet, ], corpse_butchers_into: vec![ PossessionType::Steak, PossessionType::Steak, PossessionType::AnimalSkin, PossessionType::SeveredHead, ], can_open_door: true, }, ), ( SpeciesType::Dog, SpeciesInfo { body_parts: vec![ BodyPart::Head, BodyPart::Face, BodyPart::Chest, BodyPart::Back, BodyPart::Groin, BodyPart::Legs, BodyPart::Feet, ], corpse_butchers_into: vec![ PossessionType::Steak, PossessionType::AnimalSkin, PossessionType::SeveredHead, ], can_open_door: false, }, ), ( SpeciesType::Rat, SpeciesInfo { body_parts: vec![ BodyPart::Head, BodyPart::Face, BodyPart::Chest, BodyPart::Back, BodyPart::Groin, BodyPart::Legs, BodyPart::Feet, ], corpse_butchers_into: vec![ PossessionType::Steak, PossessionType::AnimalSkin, PossessionType::SeveredHead, ], can_open_door: false, }, ), ( SpeciesType::Robot, SpeciesInfo { body_parts: vec![ BodyPart::Head, BodyPart::Face, BodyPart::Chest, BodyPart::Back, BodyPart::Legs, BodyPart::Feet, ], corpse_butchers_into: vec![], can_open_door: false, }, ), ] .into_iter() .collect() }) }