blastmud/blastmud_game/src/static_content/species.rs

167 lines
4.8 KiB
Rust

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<Sex>) -> &'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<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 can_open_door: bool,
}
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,
],
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()
})
}