about summary refs log tree commit diff
path: root/src/entities
diff options
context:
space:
mode:
Diffstat (limited to 'src/entities')
-rw-r--r--src/entities/character.rs15
-rw-r--r--src/entities/creature.rs24
-rw-r--r--src/entities/entity.rs87
-rw-r--r--src/entities/mod.rs18
-rw-r--r--src/entities/raws.rs1
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)