2022-12-26 01:30:59 +11:00
|
|
|
use serde::{Serialize, Deserialize};
|
|
|
|
use std::collections::BTreeMap;
|
2023-01-22 22:43:44 +11:00
|
|
|
use crate::{
|
|
|
|
language,
|
|
|
|
static_content::species::SpeciesType,
|
|
|
|
};
|
2023-01-15 23:16:02 +11:00
|
|
|
use super::session::Session;
|
2022-12-26 01:30:59 +11:00
|
|
|
|
2022-12-31 19:33:31 +11:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
2022-12-26 01:30:59 +11:00
|
|
|
pub enum BuffCause {
|
|
|
|
WaitingTask { task_code: String, task_type: String },
|
|
|
|
ByItem { item_code: String, item_type: String }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
|
|
|
pub enum BuffImpact {
|
|
|
|
ChangeStat { stat: StatType, magnitude: i16 },
|
2023-01-20 23:08:40 +11:00
|
|
|
ChangeSkill { skill: SkillType, magnitude: i16 }
|
2022-12-26 01:30:59 +11:00
|
|
|
}
|
|
|
|
|
2022-12-31 19:33:31 +11:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
2022-12-26 01:30:59 +11:00
|
|
|
pub struct Buff {
|
2023-01-20 23:08:40 +11:00
|
|
|
pub description: String,
|
|
|
|
pub cause: BuffCause,
|
|
|
|
pub impacts: Vec<BuffImpact>
|
2022-12-26 01:30:59 +11:00
|
|
|
}
|
|
|
|
|
2023-01-15 23:16:02 +11:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
|
|
|
pub enum SkillType {
|
2023-01-20 23:08:40 +11:00
|
|
|
Appraise,
|
2023-01-15 23:16:02 +11:00
|
|
|
Blades,
|
|
|
|
Bombs,
|
|
|
|
Chemistry,
|
|
|
|
Climb,
|
|
|
|
Clubs,
|
|
|
|
Craft,
|
|
|
|
Dodge,
|
|
|
|
Fish,
|
|
|
|
Fists,
|
|
|
|
Flails,
|
2023-01-20 23:08:40 +11:00
|
|
|
Focus,
|
2023-01-15 23:16:02 +11:00
|
|
|
Fuck,
|
|
|
|
Hack,
|
|
|
|
Locksmith,
|
|
|
|
Medic,
|
|
|
|
Persuade,
|
|
|
|
Pilot,
|
|
|
|
Pistols,
|
|
|
|
Quickdraw,
|
|
|
|
Repair,
|
|
|
|
Ride,
|
|
|
|
Rifles,
|
|
|
|
Scavenge,
|
|
|
|
Science,
|
|
|
|
Sneak,
|
|
|
|
Spears,
|
|
|
|
Swim,
|
|
|
|
Teach,
|
|
|
|
Throw,
|
|
|
|
Track,
|
|
|
|
Wrestle,
|
|
|
|
Whips
|
|
|
|
}
|
|
|
|
|
2023-01-20 23:08:40 +11:00
|
|
|
impl SkillType {
|
|
|
|
pub fn values() -> Vec<SkillType> {
|
|
|
|
use SkillType::*;
|
|
|
|
vec!(
|
|
|
|
Appraise,
|
|
|
|
Blades,
|
|
|
|
Bombs,
|
|
|
|
Chemistry,
|
|
|
|
Climb,
|
|
|
|
Clubs,
|
|
|
|
Craft,
|
|
|
|
Dodge,
|
|
|
|
Fish,
|
|
|
|
Fists,
|
|
|
|
Flails,
|
|
|
|
Focus,
|
|
|
|
Fuck,
|
|
|
|
Hack,
|
|
|
|
Locksmith,
|
|
|
|
Medic,
|
|
|
|
Persuade,
|
|
|
|
Pilot,
|
|
|
|
Pistols,
|
|
|
|
Quickdraw,
|
|
|
|
Repair,
|
|
|
|
Ride,
|
|
|
|
Rifles,
|
|
|
|
Scavenge,
|
|
|
|
Science,
|
|
|
|
Sneak,
|
|
|
|
Spears,
|
|
|
|
Swim,
|
|
|
|
Teach,
|
|
|
|
Throw,
|
|
|
|
Track,
|
|
|
|
Wrestle,
|
|
|
|
Whips
|
|
|
|
)
|
|
|
|
}
|
|
|
|
pub fn display(&self) -> &'static str {
|
|
|
|
use SkillType::*;
|
|
|
|
match self {
|
|
|
|
Appraise => "appraise",
|
|
|
|
Blades => "blades",
|
|
|
|
Bombs => "bombs",
|
|
|
|
Chemistry => "chemistry",
|
|
|
|
Climb => "climb",
|
|
|
|
Clubs => "clubs",
|
|
|
|
Craft => "craft",
|
|
|
|
Dodge => "dodge",
|
|
|
|
Fish => "fish",
|
|
|
|
Fists => "fists",
|
|
|
|
Flails => "flails",
|
|
|
|
Focus => "focus",
|
|
|
|
Fuck => "fuck",
|
|
|
|
Hack => "hack",
|
|
|
|
Locksmith => "locksmith",
|
|
|
|
Medic => "medic",
|
|
|
|
Persuade => "persuade",
|
|
|
|
Pilot => "pilot",
|
|
|
|
Pistols => "pistols",
|
|
|
|
Quickdraw => "quickdraw",
|
|
|
|
Repair => "repair",
|
|
|
|
Ride => "ride",
|
|
|
|
Rifles => "rifles",
|
|
|
|
Scavenge => "scavenge",
|
|
|
|
Science => "science",
|
|
|
|
Sneak => "sneak",
|
|
|
|
Spears => "spears",
|
|
|
|
Swim => "swim",
|
|
|
|
Teach => "teach",
|
|
|
|
Throw => "throw",
|
|
|
|
Track => "track",
|
|
|
|
Wrestle => "wrestle",
|
|
|
|
Whips => "whips"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-01-15 23:16:02 +11:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
|
|
|
pub enum StatType {
|
|
|
|
Brains,
|
|
|
|
Senses,
|
|
|
|
Brawn,
|
|
|
|
Reflexes,
|
|
|
|
Endurance,
|
|
|
|
Cool
|
|
|
|
}
|
|
|
|
|
2023-01-20 23:08:40 +11:00
|
|
|
impl StatType {
|
|
|
|
pub fn values() -> Vec<Self> {
|
|
|
|
use StatType::*;
|
|
|
|
vec!(
|
|
|
|
Brains,
|
|
|
|
Senses,
|
|
|
|
Brawn,
|
|
|
|
Reflexes,
|
|
|
|
Endurance,
|
|
|
|
Cool
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-31 00:59:14 +11:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
|
|
|
pub struct Pronouns {
|
|
|
|
pub subject: String,
|
|
|
|
pub object: String,
|
|
|
|
pub intensive: String,
|
|
|
|
pub possessive: String,
|
|
|
|
// And some miscellaneous details to determine context
|
|
|
|
pub is_plural: bool, // ... are instead of ... is
|
|
|
|
pub is_proper: bool, // When naming, just ... instead of The ...
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Pronouns {
|
|
|
|
pub fn default_inanimate() -> Pronouns {
|
|
|
|
Pronouns {
|
|
|
|
subject: "it".to_owned(),
|
|
|
|
object: "it".to_owned(),
|
|
|
|
intensive: "itself".to_owned(),
|
|
|
|
possessive: "its".to_owned(),
|
|
|
|
is_plural: false,
|
|
|
|
is_proper: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn default_animate() -> Pronouns {
|
|
|
|
Pronouns {
|
|
|
|
subject: "they".to_owned(),
|
|
|
|
object: "them".to_owned(),
|
|
|
|
intensive: "themselves".to_owned(),
|
|
|
|
possessive: "their".to_owned(),
|
|
|
|
is_plural: true,
|
|
|
|
is_proper: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
pub fn default_male() -> Pronouns {
|
|
|
|
Pronouns {
|
|
|
|
subject: "he".to_owned(),
|
|
|
|
object: "him".to_owned(),
|
|
|
|
intensive: "himself".to_owned(),
|
|
|
|
possessive: "his".to_owned(),
|
|
|
|
is_plural: false,
|
|
|
|
is_proper: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
pub fn default_female() -> Pronouns {
|
|
|
|
Pronouns {
|
|
|
|
subject: "she".to_owned(),
|
|
|
|
object: "her".to_owned(),
|
|
|
|
intensive: "herself".to_owned(),
|
|
|
|
possessive: "her".to_owned(),
|
|
|
|
is_plural: false,
|
|
|
|
is_proper: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-26 01:30:59 +11:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
|
|
|
pub enum Subattack {
|
|
|
|
Normal,
|
|
|
|
Powerattacking,
|
|
|
|
Feinting,
|
|
|
|
Grabbing,
|
|
|
|
Wrestling
|
|
|
|
}
|
|
|
|
|
2022-12-31 19:33:31 +11:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
2022-12-26 01:30:59 +11:00
|
|
|
pub enum LocationActionType {
|
|
|
|
Normal,
|
|
|
|
Sitting,
|
|
|
|
Reclining,
|
|
|
|
Worn, // Clothing etc...
|
|
|
|
Wielded,
|
2023-01-15 17:30:23 +11:00
|
|
|
Attacking(Subattack)
|
2022-12-26 01:30:59 +11:00
|
|
|
}
|
|
|
|
|
2022-12-31 19:33:31 +11:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
2022-12-31 18:42:13 +11:00
|
|
|
pub enum Sex {
|
|
|
|
Male,
|
|
|
|
Female,
|
|
|
|
}
|
|
|
|
|
2022-12-31 19:33:31 +11:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
2023-01-07 23:06:02 +11:00
|
|
|
pub enum ItemFlag {
|
2023-01-08 00:18:56 +11:00
|
|
|
NoSay,
|
|
|
|
NoSeeContents
|
2023-01-07 23:06:02 +11:00
|
|
|
}
|
|
|
|
|
2023-01-15 17:30:23 +11:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
|
|
|
#[serde(default)]
|
|
|
|
pub struct ActiveCombat {
|
|
|
|
pub attacking: Option<String>,
|
|
|
|
pub attacked_by: Vec<String>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for ActiveCombat {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
attacking: None,
|
|
|
|
attacked_by: vec!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-20 23:08:40 +11:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd)]
|
2023-01-07 23:06:02 +11:00
|
|
|
#[serde(default)]
|
2022-12-26 01:30:59 +11:00
|
|
|
pub struct Item {
|
|
|
|
pub item_code: String,
|
|
|
|
pub item_type: String,
|
2022-12-27 00:20:09 +11:00
|
|
|
pub display: String,
|
|
|
|
pub display_less_explicit: Option<String>,
|
2022-12-29 18:44:50 +11:00
|
|
|
pub details: Option<String>,
|
|
|
|
pub details_less_explicit: Option<String>,
|
2023-01-20 23:38:57 +11:00
|
|
|
pub aliases: Vec<String>,
|
2022-12-26 01:30:59 +11:00
|
|
|
pub location: String, // Item reference as item_type/item_code.
|
|
|
|
pub action_type: LocationActionType,
|
|
|
|
pub presence_target: Option<String>, // e.g. what are they sitting on.
|
|
|
|
pub is_static: bool,
|
2023-01-15 17:30:23 +11:00
|
|
|
pub is_dead: bool,
|
|
|
|
pub is_challenge_attack_only: bool,
|
2023-01-22 22:43:44 +11:00
|
|
|
pub species: SpeciesType,
|
|
|
|
pub health: u64,
|
2022-12-26 01:30:59 +11:00
|
|
|
pub total_xp: u64,
|
2023-01-20 23:08:40 +11:00
|
|
|
pub total_stats: BTreeMap<StatType, f64>,
|
|
|
|
pub total_skills: BTreeMap<SkillType, f64>,
|
2022-12-26 01:30:59 +11:00
|
|
|
pub temporary_buffs: Vec<Buff>,
|
2022-12-31 00:59:14 +11:00
|
|
|
pub pronouns: Pronouns,
|
2023-01-07 23:06:02 +11:00
|
|
|
pub flags: Vec<ItemFlag>,
|
2022-12-31 18:42:13 +11:00
|
|
|
pub sex: Option<Sex>,
|
2023-01-15 17:30:23 +11:00
|
|
|
pub active_combat: Option<ActiveCombat>,
|
2022-12-31 00:59:14 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Item {
|
2023-01-15 17:30:23 +11:00
|
|
|
pub fn display_for_sentence(&self, explicit_ok: bool, pluralise: usize, caps: bool) -> String {
|
|
|
|
let mut buf = String::new();
|
|
|
|
if self.is_dead {
|
|
|
|
if pluralise > 1 {
|
|
|
|
buf.push_str("the bodies of ");
|
|
|
|
} else {
|
|
|
|
buf.push_str("the body of ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !self.pronouns.is_proper && pluralise == 1 {
|
|
|
|
buf.push_str("a ");
|
|
|
|
}
|
|
|
|
if pluralise > 1 {
|
|
|
|
buf.push_str(&format!("{} ", pluralise));
|
|
|
|
}
|
|
|
|
let singular = if explicit_ok { &self.display } else {
|
|
|
|
self.display_less_explicit.as_ref().unwrap_or(&self.display) };
|
|
|
|
if pluralise > 1 {
|
|
|
|
buf.push_str(&language::pluralise(singular));
|
|
|
|
} else {
|
|
|
|
buf.push_str(singular);
|
|
|
|
}
|
|
|
|
|
|
|
|
if caps {
|
|
|
|
language::caps_first(&buf)
|
|
|
|
} else {
|
|
|
|
buf
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pub fn display_for_session<'l>(self: &'l Self, session: &Session) -> String {
|
|
|
|
self.display_for_sentence(!session.less_explicit_mode, 1, false)
|
2022-12-31 00:59:14 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn details_for_session<'l>(self: &'l Self, session: &Session) -> Option<&'l str>{
|
|
|
|
self.details.as_ref()
|
|
|
|
.map(|dets|
|
|
|
|
session.explicit_if_allowed(
|
|
|
|
dets.as_str(),
|
|
|
|
self.details_less_explicit.as_ref().map(String::as_str)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
2022-12-26 01:30:59 +11:00
|
|
|
}
|
2022-12-27 00:20:09 +11:00
|
|
|
|
|
|
|
impl Default for Item {
|
|
|
|
fn default() -> Self {
|
2023-01-15 17:30:23 +11:00
|
|
|
Self {
|
2022-12-27 00:20:09 +11:00
|
|
|
item_code: "unset".to_owned(),
|
|
|
|
item_type: "unset".to_owned(),
|
|
|
|
display: "Item".to_owned(),
|
|
|
|
display_less_explicit: None,
|
2022-12-29 18:44:50 +11:00
|
|
|
details: None,
|
|
|
|
details_less_explicit: None,
|
2023-01-20 23:38:57 +11:00
|
|
|
aliases: vec!(),
|
2022-12-27 00:20:09 +11:00
|
|
|
location: "room/storage".to_owned(),
|
|
|
|
action_type: LocationActionType::Normal,
|
|
|
|
presence_target: None,
|
|
|
|
is_static: false,
|
2023-01-15 17:30:23 +11:00
|
|
|
is_dead: false,
|
|
|
|
is_challenge_attack_only: true,
|
2023-01-22 22:43:44 +11:00
|
|
|
species: SpeciesType::Human,
|
|
|
|
health: 40,
|
2022-12-27 00:20:09 +11:00
|
|
|
total_xp: 0,
|
|
|
|
total_stats: BTreeMap::new(),
|
|
|
|
total_skills: BTreeMap::new(),
|
2022-12-31 00:59:14 +11:00
|
|
|
temporary_buffs: Vec::new(),
|
2022-12-31 18:42:13 +11:00
|
|
|
pronouns: Pronouns::default_inanimate(),
|
2023-01-07 23:06:02 +11:00
|
|
|
flags: vec!(),
|
2023-01-15 17:30:23 +11:00
|
|
|
sex: None,
|
|
|
|
active_combat: Some(Default::default()),
|
2022-12-27 00:20:09 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|