diff options
Diffstat (limited to 'src/entities')
-rw-r--r-- | src/entities/entity_char.rs | 2 | ||||
-rw-r--r-- | src/entities/item.rs | 44 | ||||
-rw-r--r-- | src/entities/mod.rs | 3 | ||||
-rw-r--r-- | src/entities/raw_types.rs | 104 | ||||
-rw-r--r-- | src/entities/raws.rs | 44 | ||||
-rw-r--r-- | src/entities/raws/noodles.json | 14 |
6 files changed, 180 insertions, 31 deletions
diff --git a/src/entities/entity_char.rs b/src/entities/entity_char.rs index 578aaf3da5c3..2f845820021e 100644 --- a/src/entities/entity_char.rs +++ b/src/entities/entity_char.rs @@ -4,7 +4,9 @@ use termion::color; #[derive(Debug, Deserialize)] pub struct EntityChar { + #[serde(default)] color: Color, + #[serde(rename = "char")] chr: char, } diff --git a/src/entities/item.rs b/src/entities/item.rs new file mode 100644 index 000000000000..d0ecc090e2e4 --- /dev/null +++ b/src/entities/item.rs @@ -0,0 +1,44 @@ +use crate::display; +use crate::entities::raws::{raw, EntityRaw, ItemType}; +use crate::entities::EntityID; +use crate::types::Position; +use std::io::{self, Write}; + +#[derive(Debug, Clone)] +pub struct Item { + pub id: Option<EntityID>, + pub typ: &'static ItemType<'static>, + pub position: Position, +} + +impl Item { + pub fn new_from_raw(name: &'static str, position: Position) -> Self { + match raw(name) { + EntityRaw::Item(typ) => Self::new_with_type(typ, position), + _ => panic!("Invalid raw type for {:?}, expected Item", name), + } + } + + pub fn new_with_type( + typ: &'static ItemType<'static>, + position: Position, + ) -> Self { + Item { + id: None, + typ, + position, + } + } + + pub fn is_edible(&self) -> bool { + self.typ.is_edible() + } +} + +entity!(Item); + +impl display::Draw for Item { + fn do_draw(&self, out: &mut Write) -> io::Result<()> { + write!(out, "{}", self.typ.chr) + } +} diff --git a/src/entities/mod.rs b/src/entities/mod.rs index ed83f2f462db..c54a587e6aba 100644 --- a/src/entities/mod.rs +++ b/src/entities/mod.rs @@ -3,12 +3,15 @@ pub mod entity; pub mod character; pub mod creature; pub mod entity_char; +pub mod item; +pub mod raw_types; pub mod raws; pub use character::Character; pub use creature::Creature; pub use entity::{Entity, Identified}; pub use entity_char::EntityChar; +pub use item::Item; pub use raws::raw; pub type EntityID = u32; diff --git a/src/entities/raw_types.rs b/src/entities/raw_types.rs new file mode 100644 index 000000000000..8f64e60d9cd4 --- /dev/null +++ b/src/entities/raw_types.rs @@ -0,0 +1,104 @@ +use crate::entities::entity_char::EntityChar; +use crate::messages::Message; +use crate::types::Speed; + +#[derive(Debug, Deserialize)] +pub struct CreatureType<'a> { + /// The name of the creature. Used in raw lookups. + pub name: &'a str, + + /// A description of the entity, used by the "look" command + pub description: &'a str, + + #[serde(rename = "char")] + pub chr: EntityChar, + pub max_hitpoints: u16, + pub speed: Speed, + pub friendly: bool, +} + +#[derive(Debug, Deserialize)] +pub struct EdibleItem<'a> { + #[serde(borrow)] + pub eat_message: Option<Message<'a>>, + + /// The number of hitpoints that eating this item heals + pub hitpoints_healed: u16, +} + +#[derive(Debug, Deserialize)] +pub struct ItemType<'a> { + pub name: &'a str, + + /// A description of the item, used by the "look" command + pub description: &'a str, + + pub edible_item: Option<EdibleItem<'a>>, + + #[serde(rename = "char")] + pub chr: EntityChar, +} + +#[cfg(test)] +mod item_type_tests { + use super::*; + + #[test] + fn test_deserialize_item_type() { + let result = serde_json::from_str( + r#"{ + "Item": { + "name": "noodles", + "description": "You know exactly what kind of noodles", + "char": { "char": "n" }, + "edible_item": { + "eat_message": "You slurp up the noodles", + "hitpoints_healed": 2 + } + } + }"#, + ) + .unwrap(); + assert_matches!(result, EntityRaw::Item(_)); + if let EntityRaw::Item(item) = result { + assert_eq!(item.name, "noodles"); + } + + let toml_result = toml::from_str( + r#"[Item] +name = "noodles" +description = "You know exactly what kind of noodles" +char = { char = "๐" } +edible_item = { eat_message = "You slurp up the noodles", hitpoints_healed = 2 } +"#, + ) + .unwrap(); + + assert_matches!(toml_result, EntityRaw::Item(_)); + if let EntityRaw::Item(item) = toml_result { + assert_eq!(item.name, "noodles"); + } + } +} + +impl<'a> ItemType<'a> { + pub fn is_edible(&self) -> bool { + self.edible_item.is_some() + } +} + +#[derive(Debug, Deserialize)] +pub enum EntityRaw<'a> { + Creature(#[serde(borrow)] CreatureType<'a>), + Item(#[serde(borrow)] ItemType<'a>), +} + +impl<'a> EntityRaw<'a> { + pub fn name(&self) -> &'a str { + use EntityRaw::*; + match self { + Creature(typ) => typ.name, + Item(typ) => typ.name, + } + } +} diff --git a/src/entities/raws.rs b/src/entities/raws.rs index da061d89d8d6..2c4a8203cb17 100644 --- a/src/entities/raws.rs +++ b/src/entities/raws.rs @@ -1,37 +1,8 @@ -use crate::entities::entity_char::EntityChar; -use crate::types::Speed; +pub use crate::entities::raw_types::{CreatureType, EntityRaw, ItemType}; use std::collections::HashMap; -#[derive(Debug, Deserialize)] -pub struct CreatureType<'a> { - /// The name of the creature. Used in raw lookups. - pub name: &'a str, - - /// A description of the entity, used by the "look" command - pub description: &'a str, - - #[serde(rename = "char")] - pub chr: EntityChar, - pub max_hitpoints: u16, - pub speed: Speed, - pub friendly: bool, -} - -#[derive(Debug, Deserialize)] -pub enum EntityRaw<'a> { - Creature(#[serde(borrow)] CreatureType<'a>), -} - -impl<'a> EntityRaw<'a> { - pub fn name(&self) -> &'a str { - match self { - EntityRaw::Creature(typ) => typ.name, - } - } -} - static_cfg! { - static ref RAWS: Vec<EntityRaw<'static>> = toml_dir("src/entities/raws"); + static ref RAWS: Vec<EntityRaw<'static>> = cfg_dir("src/entities/raws"); } lazy_static! { @@ -54,3 +25,14 @@ pub fn raw(name: &'static str) -> &'static EntityRaw<'static> { .map(|e| *e) .expect(format!("Raw not found: {}", name).as_str()) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_raws() { + RAWS_BY_NAME.keys(); + assert_eq!(raw("noodles").name(), "noodles"); + } +} diff --git a/src/entities/raws/noodles.json b/src/entities/raws/noodles.json new file mode 100644 index 000000000000..d4b773cac533 --- /dev/null +++ b/src/entities/raws/noodles.json @@ -0,0 +1,14 @@ +{ + "Item": { + "name": "noodles", + "char": { + "char": "๐" + }, + "description": "You know exactly what kind of noodles", + "edible_item": { + "eat_message": "You slurp up the noodles", + "hitpoints_healed": 2 + }, + "display_name": "big bowl o' noodles" + } +} |