about summary refs log tree commit diff
path: root/src/level_gen/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/level_gen/mod.rs')
-rw-r--r--src/level_gen/mod.rs100
1 files changed, 99 insertions, 1 deletions
diff --git a/src/level_gen/mod.rs b/src/level_gen/mod.rs
index 4df57a408f..df742bb3a1 100644
--- a/src/level_gen/mod.rs
+++ b/src/level_gen/mod.rs
@@ -1,3 +1,101 @@
+use crate::display::draw_box::BoxStyle;
+use crate::display::utils::clone_times;
+use crate::display::DrawWithNeighbors;
+use crate::entities::entity::Entity;
+use crate::entities::environment::Wall;
+use crate::types::entity_map::EntityMap;
+use crate::types::pos;
+use itertools::Itertools;
+use std::io;
+
 pub mod cave_automata;
-pub mod display;
 pub mod util;
+
+pub fn level_to_entities(level: Vec<Vec<bool>>) -> EntityMap<Box<dyn Entity>> {
+    let mut res: EntityMap<Box<dyn Entity>> = EntityMap::new();
+
+    let xmax = level.len() as i16;
+    let ymax = if xmax == 0 {
+        0i16
+    } else {
+        level[0].len() as i16
+    };
+
+    let get = |mut x: i16, mut y: i16| {
+        if x < 0 {
+            x = 0;
+        }
+        if y < 0 {
+            y = 0;
+        }
+        if x >= xmax - 1 {
+            x = xmax - 1;
+        }
+        if y >= ymax - 1 {
+            y = ymax - 1;
+        }
+        level[x as usize][y as usize]
+    };
+
+    for x in 0..xmax {
+        for y in 0..ymax {
+            if get(x, y) {
+                // don't output walls that are surrounded on all 8 sides by
+                // walls
+                if (x == 0 || get(x - 1, y))
+                    && (y == 0 || get(x, y - 1))
+                    && (x == xmax - 1 || get(x + 1, y))
+                    && (y == ymax - 1 || get(x, y + 1))
+                    && ((x == 0 && y == 0) || get(x - 1, y - 1))
+                    && ((x == 0 && y == ymax - 1) || get(x - 1, y + 1))
+                    && ((x == xmax - 1 && y == 0) || get(x + 1, y - 1))
+                    && ((x == xmax - 1 && y == ymax - 1) || get(x + 1, y + 1))
+                {
+                    continue;
+                }
+                res.insert(Box::new(Wall::new(
+                    pos(y as i16, x as i16),
+                    BoxStyle::Thin,
+                )));
+            }
+        }
+    }
+
+    res
+}
+
+pub fn draw_level<W: io::Write>(
+    level: Vec<Vec<bool>>,
+    out: &mut W,
+) -> io::Result<()> {
+    if level.len() == 0 {
+        return Ok(());
+    }
+
+    let mut lines = clone_times::<Vec<char>, Vec<Vec<char>>>(
+        clone_times(' ', level[0].len() as u16),
+        level.len() as u16,
+    );
+
+    let em = level_to_entities(level);
+
+    for entity in em.entities() {
+        let mut buf = Vec::new();
+        entity.do_draw_with_neighbors(
+            &mut buf,
+            &em.neighbor_entities(entity.position()),
+        )?;
+        let buf_s = std::str::from_utf8(&buf).unwrap();
+        if let Some(chr) = buf_s.chars().next() {
+            lines[entity.position().y as usize][entity.position().x as usize] =
+                chr;
+        }
+    }
+
+    let res = lines
+        .iter()
+        .map(|line| line.iter().collect::<String>())
+        .join("\n");
+
+    write!(out, "{}", res)
+}