diff options
author | Griffin Smith <root@gws.fyi> | 2019-07-28T21·45-0400 |
---|---|---|
committer | Griffin Smith <root@gws.fyi> | 2019-07-28T21·45-0400 |
commit | 6c1eba67629504f10fa08ee68fb31f507c99b0d1 (patch) | |
tree | d5af8f3eb6dc32a1308a20863e5c8814a4634098 /src/entities | |
parent | f22bcad817ee354b355d29b6b289894e2d15cfaa (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.rs | 29 | ||||
-rw-r--r-- | src/entities/environment.rs | 34 | ||||
-rw-r--r-- | src/entities/mod.rs | 3 | ||||
-rw-r--r-- | src/entities/util.rs | 72 |
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)*); + }; + + () => {}; +} |