diff options
Diffstat (limited to 'src/entities')
-rw-r--r-- | src/entities/character.rs | 15 | ||||
-rw-r--r-- | src/entities/creature.rs | 24 | ||||
-rw-r--r-- | src/entities/entity.rs | 87 | ||||
-rw-r--r-- | src/entities/mod.rs | 18 | ||||
-rw-r--r-- | src/entities/raws.rs | 1 |
5 files changed, 120 insertions, 25 deletions
diff --git a/src/entities/character.rs b/src/entities/character.rs index fb5a89591c95..7bcb8b5c87e4 100644 --- a/src/entities/character.rs +++ b/src/entities/character.rs @@ -1,5 +1,5 @@ use crate::display; -use crate::entities::Entity; +use crate::entities::EntityID; use crate::types::{Position, Speed}; use proptest_derive::Arbitrary; use std::io::{self, Write}; @@ -9,6 +9,8 @@ const DEFAULT_SPEED: Speed = Speed(100); #[derive(Debug, PartialEq, Eq, Arbitrary, Clone)] pub struct Character { + pub id: Option<EntityID>, + /// The position of the character, relative to the game pub position: Position, } @@ -16,6 +18,7 @@ pub struct Character { impl Character { pub fn new() -> Character { Character { + id: None, position: Position { x: 0, y: 0 }, } } @@ -23,12 +26,14 @@ impl Character { pub fn speed(&self) -> Speed { Speed(100) } -} -positioned!(Character); -positioned_mut!(Character); + pub fn damage(&self) -> u16 { + // TODO + 1 + } +} -impl Entity for Character {} +entity!(Character); impl display::Draw for Character { fn do_draw(&self, out: &mut Write) -> io::Result<()> { diff --git a/src/entities/creature.rs b/src/entities/creature.rs index 6ddeade21845..55445f951b45 100644 --- a/src/entities/creature.rs +++ b/src/entities/creature.rs @@ -1,11 +1,13 @@ use crate::display; use crate::entities::raws::CreatureType; use crate::entities::raws::EntityRaw; -use crate::entities::{raw, Entity}; +use crate::entities::{raw, EntityID}; use crate::types::Position; use std::io::{self, Write}; +#[derive(Debug)] pub struct Creature { + pub id: Option<EntityID>, pub typ: &'static CreatureType<'static>, pub position: Position, pub hitpoints: u16, @@ -24,17 +26,29 @@ impl Creature { position: Position, ) -> Self { Creature { + id: None, typ, position, hitpoints: typ.max_hitpoints, } } -} -positioned!(Creature); -positioned_mut!(Creature); + /// Damage the given creature by the given amount + pub fn damage(&mut self, amount: u16) { + if self.hitpoints <= amount { + self.hitpoints = 0; + } else { + self.hitpoints -= amount; + } + } + + /// Returns true if this creature has died + pub fn dead(&self) -> bool { + self.hitpoints <= 0 + } +} -impl Entity for Creature {} +entity!(Creature); impl display::Draw for Creature { fn do_draw(&self, out: &mut Write) -> io::Result<()> { diff --git a/src/entities/entity.rs b/src/entities/entity.rs new file mode 100644 index 000000000000..30f7ea9a3dae --- /dev/null +++ b/src/entities/entity.rs @@ -0,0 +1,87 @@ +use crate::display::Draw; +use crate::entities::EntityID; +use crate::types::{Positioned, PositionedMut}; +use downcast_rs::Downcast; +use std::fmt::Debug; +use std::io::{self, Write}; + +pub trait Identified<ID>: Debug { + fn opt_id(&self) -> Option<ID>; + fn set_id(&mut self, id: ID); + + fn id(&self) -> ID { + self.opt_id() + .expect(format!("Entity ({:?}) is not in the game", self).as_str()) + } +} + +impl<'a, A, ID> Identified<ID> for &'a mut A +where + A: Identified<ID>, +{ + fn opt_id(&self) -> Option<ID> { + (**self).opt_id() + } + fn set_id(&mut self, id: ID) { + (**self).set_id(id); + } +} + +impl<ID, A: Identified<ID>> Identified<ID> for Box<A> { + fn opt_id(&self) -> Option<ID> { + (**self).opt_id() + } + fn set_id(&mut self, id: ID) { + (**self).set_id(id); + } +} + +pub trait Entity: + Positioned + PositionedMut + Identified<EntityID> + Draw + Downcast +{ +} + +impl Identified<EntityID> for Box<dyn Entity> { + fn opt_id(&self) -> Option<EntityID> { + (**self).opt_id() + } + fn set_id(&mut self, id: EntityID) { + (**self).set_id(id); + } +} + +#[macro_export] +macro_rules! identified { + ($name: ident, $typ: ident) => { + identified!($name, $typ, id); + }; + ($name: ident, $typ: ident, $attr: ident) => { + impl crate::entities::entity::Identified<$typ> for $name { + fn opt_id(&self) -> Option<$typ> { + self.$attr + } + + fn set_id(&mut self, id: $typ) { + self.$attr = Some(id) + } + } + }; +} + +#[macro_export] +macro_rules! entity { + ($name: ident) => { + positioned!($name); + positioned_mut!($name); + identified!($name, EntityID); + impl crate::entities::entity::Entity for $name {} + }; +} + +impl_downcast!(Entity); + +impl Draw for Box<dyn Entity> { + fn do_draw(&self, out: &mut Write) -> io::Result<()> { + (**self).do_draw(out) + } +} diff --git a/src/entities/mod.rs b/src/entities/mod.rs index c4f46bf4a723..ed83f2f462db 100644 --- a/src/entities/mod.rs +++ b/src/entities/mod.rs @@ -1,3 +1,5 @@ +#[macro_use] +pub mod entity; pub mod character; pub mod creature; pub mod entity_char; @@ -5,20 +7,8 @@ pub mod raws; pub use character::Character; pub use creature::Creature; +pub use entity::{Entity, Identified}; pub use entity_char::EntityChar; pub use raws::raw; -use crate::display::Draw; -use crate::types::{Positioned, PositionedMut}; -use downcast_rs::Downcast; -use std::io::{self, Write}; - -pub trait Entity: Positioned + PositionedMut + Draw + Downcast {} - -impl_downcast!(Entity); - -impl Draw for Box<dyn Entity> { - fn do_draw(&self, out: &mut Write) -> io::Result<()> { - (**self).do_draw(out) - } -} +pub type EntityID = u32; diff --git a/src/entities/raws.rs b/src/entities/raws.rs index beeb90a40cea..da061d89d8d6 100644 --- a/src/entities/raws.rs +++ b/src/entities/raws.rs @@ -49,7 +49,6 @@ lazy_static! { } pub fn raw(name: &'static str) -> &'static EntityRaw<'static> { - debug!("{:?}", RAWS_BY_NAME.keys().collect::<Vec<&&'static str>>()); RAWS_BY_NAME .get(name) .map(|e| *e) |