blastmud/blastmud_game/src/static_content/species.rs
Condorra 2747dddd90 Allow buying, wearing and removing clothes.
Step 2 will be to make clothes serve a functional purpose as armour.
2023-05-23 20:37:27 +10:00

132 lines
3.5 KiB
Rust

use once_cell::sync::OnceCell;
use serde::{Serialize, Deserialize};
use std::collections::BTreeMap;
use crate::{
models::item::Sex,
static_content::possession_type::PossessionType,
};
use rand::seq::IteratorRandom;
#[derive(Serialize, Deserialize, Eq, Ord, Clone, PartialEq, PartialOrd, Debug)]
pub enum SpeciesType {
Human,
Dog
}
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<Sex>) -> &'static str {
use BodyPart::*;
match self {
Head => "head",
Face => "face",
Chest => match sex {
Some(Sex::Female) => "breasts",
_ => "chest",
},
Back => "back",
Groin => match sex {
Some(Sex::Male) => "penis",
Some(Sex::Female) => "vagina",
_ => "groin"
},
Arms => "arms",
Hands => "hands",
Legs => "legs",
Feet => "feet"
}
}
pub fn copula(&self, sex: Option<Sex>) -> &'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<BodyPart>,
pub corpse_butchers_into: Vec<PossessionType>,
}
pub fn species_info_map() -> &'static BTreeMap<SpeciesType, SpeciesInfo> {
static INFOMAP: OnceCell<BTreeMap<SpeciesType, SpeciesInfo>> = 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,
),
}
),
(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,
),
}
),
).into_iter().collect()
})
}