about summary refs log tree commit diff
path: root/src/entities
diff options
context:
space:
mode:
authorGriffin Smith <root@gws.fyi>2019-07-28T21·45-0400
committerGriffin Smith <root@gws.fyi>2019-07-28T21·45-0400
commit6c1eba67629504f10fa08ee68fb31f507c99b0d1 (patch)
treed5af8f3eb6dc32a1308a20863e5c8814a4634098 /src/entities
parentf22bcad817ee354b355d29b6b289894e2d15cfaa (diff)
Allow converting generated levels to entities
Add a new Wall entity, and allow converting generated levels to entity
maps containing them, then finally displaying them using some of
the (now expanded) box drawing machinery.
Diffstat (limited to 'src/entities')
-rw-r--r--src/entities/entity.rs29
-rw-r--r--src/entities/environment.rs34
-rw-r--r--src/entities/mod.rs3
-rw-r--r--src/entities/util.rs72
4 files changed, 121 insertions, 17 deletions
diff --git a/src/entities/entity.rs b/src/entities/entity.rs
index 30f7ea9a3dae..7fedb77b2562 100644
--- a/src/entities/entity.rs
+++ b/src/entities/entity.rs
@@ -1,5 +1,6 @@
-use crate::display::Draw;
+use crate::display::DrawWithNeighbors;
 use crate::entities::EntityID;
+use crate::types::Neighbors;
 use crate::types::{Positioned, PositionedMut};
 use downcast_rs::Downcast;
 use std::fmt::Debug;
@@ -37,7 +38,7 @@ impl<ID, A: Identified<ID>> Identified<ID> for Box<A> {
 }
 
 pub trait Entity:
-    Positioned + PositionedMut + Identified<EntityID> + Draw + Downcast
+    Positioned + PositionedMut + Identified<EntityID> + DrawWithNeighbors + Downcast
 {
 }
 
@@ -52,10 +53,10 @@ impl Identified<EntityID> for Box<dyn Entity> {
 
 #[macro_export]
 macro_rules! identified {
-    ($name: ident, $typ: ident) => {
+    ($name: ident, $typ: path) => {
         identified!($name, $typ, id);
     };
-    ($name: ident, $typ: ident, $attr: ident) => {
+    ($name: ident, $typ: path, $attr: ident) => {
         impl crate::entities::entity::Identified<$typ> for $name {
             fn opt_id(&self) -> Option<$typ> {
                 self.$attr
@@ -68,20 +69,14 @@ macro_rules! identified {
     };
 }
 
-#[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)
+impl DrawWithNeighbors for Box<dyn Entity> {
+    fn do_draw_with_neighbors<'a, 'b>(
+        &'a self,
+        out: &'b mut Write,
+        neighbors: &'a Neighbors<Vec<&'a Box<dyn Entity>>>,
+    ) -> io::Result<()> {
+        (**self).do_draw_with_neighbors(out, neighbors)
     }
 }
diff --git a/src/entities/environment.rs b/src/entities/environment.rs
new file mode 100644
index 000000000000..64366a505496
--- /dev/null
+++ b/src/entities/environment.rs
@@ -0,0 +1,34 @@
+use crate::display;
+use crate::display::draw_box::{BoxStyle, Stylable};
+use crate::entities::Entity;
+use crate::types::{Neighbors, Position};
+use std::io::{self, Write};
+
+entity! {
+    pub struct Wall {
+        pub style: BoxStyle
+    }
+}
+
+impl Wall {
+    pub fn new(position: Position, style: BoxStyle) -> Self {
+        new_entity!(Wall { position, style })
+    }
+}
+
+impl display::DrawWithNeighbors for Wall {
+    fn do_draw_with_neighbors<'a, 'b>(
+        &'a self,
+        out: &'b mut Write,
+        neighbors: &'a Neighbors<Vec<&'a Box<dyn Entity>>>,
+    ) -> io::Result<()> {
+        let neighbor_styles: Neighbors<Option<BoxStyle>> =
+            neighbors.map(|es| {
+                es.iter()
+                    .filter_map(|e| e.downcast_ref::<Wall>())
+                    .map(|wall| wall.style)
+                    .next()
+            });
+        write!(out, "{}", neighbor_styles.style(self.style))
+    }
+}
diff --git a/src/entities/mod.rs b/src/entities/mod.rs
index c54a587e6aba..3fe84c76f8ef 100644
--- a/src/entities/mod.rs
+++ b/src/entities/mod.rs
@@ -1,8 +1,11 @@
 #[macro_use]
 pub mod entity;
+#[macro_use]
+pub mod util;
 pub mod character;
 pub mod creature;
 pub mod entity_char;
+pub mod environment;
 pub mod item;
 pub mod raw_types;
 pub mod raws;
diff --git a/src/entities/util.rs b/src/entities/util.rs
new file mode 100644
index 000000000000..6c11ffadf994
--- /dev/null
+++ b/src/entities/util.rs
@@ -0,0 +1,72 @@
+#[macro_export]
+macro_rules! new_entity {
+    ($name: ident) => {
+        new_entity!($name, {})
+    };
+
+    ($name: ident { position: $position:expr $(, $fields:tt)* }) => {
+        $name {
+            id: None,
+            position: $position,
+            $($fields)*
+        }
+    };
+
+    ($name: ident { $position:expr $(, $fields:tt)* }) => {
+        $name {
+            id: None,
+            position: $position,
+            $($fields)*
+        }
+    };
+}
+
+#[macro_export]
+macro_rules! boring_entity {
+    ($name:ident) => {
+        entity! {
+            pub struct $name {}
+        }
+
+        impl $name {
+            #[allow(dead_code)]
+            pub fn new(position: $crate::types::Position) -> Self {
+                $name { id: None, position }
+            }
+        }
+    };
+
+    ($name:ident, char: $char: expr) => {
+        boring_entity!($name);
+
+        impl $crate::display::Draw for $name {
+            fn do_draw(&self, out: &mut Write) -> io::Result<()> {
+                write!(out, "{}", $char)
+            }
+        }
+    };
+}
+
+#[macro_export]
+macro_rules! entity {
+    ($name: ident) => {
+        positioned!($name);
+        positioned_mut!($name);
+        identified!($name, $crate::entities::EntityID);
+        impl $crate::entities::entity::Entity for $name {}
+    };
+
+    (pub struct $name:ident { $($struct_contents:tt)* } $($rest:tt)*) => {
+        #[derive(Debug, PartialEq, Eq, Clone)]
+        pub struct $name {
+            pub id: Option<$crate::entities::EntityID>,
+            pub position: $crate::types::Position,
+            $($struct_contents)*
+        }
+
+        entity!($name);
+        entity!($($rest)*);
+    };
+
+    () => {};
+}