From bb935dd9c79b238fa5cf0e5ec283653456ed2497 Mon Sep 17 00:00:00 2001 From: surrsurus Date: Thu, 27 Sep 2018 21:49:26 -0400 Subject: [PATCH] Add Structures --- src/core/world/dungeon/builder/mod.rs | 5 +- src/core/world/dungeon/builder/simple.rs | 2 +- src/core/world/dungeon/builder/structure.rs | 117 ++++++++++++++++++++ src/core/world/dungeon/mod.rs | 13 ++- strct/PillarsA.em | 9 ++ 5 files changed, 139 insertions(+), 7 deletions(-) create mode 100644 src/core/world/dungeon/builder/structure.rs create mode 100644 strct/PillarsA.em diff --git a/src/core/world/dungeon/builder/mod.rs b/src/core/world/dungeon/builder/mod.rs index 57aa1206..79400d3b 100644 --- a/src/core/world/dungeon/builder/mod.rs +++ b/src/core/world/dungeon/builder/mod.rs @@ -11,4 +11,7 @@ pub mod fussy; pub use self::fussy::Fussy; pub mod simple; -pub use self::simple::Simple; \ No newline at end of file +pub use self::simple::Simple; + +pub mod structure; +pub use self::structure::Structure; \ No newline at end of file diff --git a/src/core/world/dungeon/builder/simple.rs b/src/core/world/dungeon/builder/simple.rs index 05b414e3..76ee9d50 100644 --- a/src/core/world/dungeon/builder/simple.rs +++ b/src/core/world/dungeon/builder/simple.rs @@ -144,7 +144,7 @@ impl Simple { /// - /// Return a new `Dungeon` + /// Return a new `Simple` /// pub fn new(grid: Grid) -> Simple { diff --git a/src/core/world/dungeon/builder/structure.rs b/src/core/world/dungeon/builder/structure.rs new file mode 100644 index 00000000..f91822ba --- /dev/null +++ b/src/core/world/dungeon/builder/structure.rs @@ -0,0 +1,117 @@ +extern crate rand; +use self::rand::{thread_rng, Rng}; + +use std::io::prelude::*; +use std::fs::{self}; + +use core::world::dungeon::builder::Buildable; + +use core::world::dungeon::map::{FloorType, Grid, Tile, TileType, WallType}; + +/// +/// Simple dungeon builder +/// +/// This builder places a number of small rooms (respective to map size) +/// all connected by corridors. +/// +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Structure { + grid: Grid, + w: usize, + h: usize, +} + +impl Structure { + + /// + /// Add a random structure + /// + fn add_rand_struct(&mut self) { + + // Okay. Hang on + + // RNG + let mut rng = rand::thread_rng(); + + // Create a vector out of collecting the read_dir by mapping the unwrapped paths + let paths : Vec<_> = fs::read_dir("./strct").unwrap().map(|res| res.unwrap().path()).collect(); + + // Choose a random element + let mut file = fs::File::open(rng.choose(&paths).unwrap()).unwrap(); + + // Create empty string + let mut s = String::new(); + + // Read to string + file.read_to_string(&mut s).unwrap(); + + // Turn string to 2d array of tiles + let mut strct : Grid = vec![]; + let mut line : Vec = vec![]; + + for c in s.chars() { + if c != '\n' { + let tile = { + match c { + '#' => Tile::new("Wall", ' ', (40, 40, 40), (33, 33, 33), TileType::Wall(WallType::Normal)), + '.' => Tile::new("Floor", ' ', (27, 27, 27), (20, 20, 20), TileType::Floor(FloorType::Normal)), + '"' => Tile::new("Tall Grass", '"', (76, 74, 75), (20, 20, 20), TileType::TallGrass), + _ => panic!("Unknown character: {}", c) + } + }; + line.push(tile); + } else { + strct.push(line); + line = vec![]; + } + } + + // Rotate randomly + // NOTE: Not done + + // Read details of vector + let w = strct.len(); + let h = strct[0].len(); + + // Add to map if possible + let x = rng.gen_range(0, w + 1); + let y = rng.gen_range(0, h + 1); + + // Break + if x + w > self.w - 1 || y + h > self.h - 1 { return; } + + for tx in x..x+w { + for ty in y..y+h { + self.grid[tx][ty] = strct[tx-x][ty-y].clone(); + } + } + + } + + /// + /// Return a new `Simple` + /// + pub fn new(grid: Grid) -> Structure { + + // Make a new dungeon with our fresh grid of size `w` by `h` + let s = Structure { + grid: grid.clone(), + w: grid.len(), + h: grid[0].len(), + }; + + return s; + } + +} + +impl Buildable for Structure { + + type Output = Tile; + + fn build(&mut self) -> Grid { + self.add_rand_struct(); + return self.grid.clone(); + } + +} diff --git a/src/core/world/dungeon/mod.rs b/src/core/world/dungeon/mod.rs index 6f89d55c..2b6dd105 100644 --- a/src/core/world/dungeon/mod.rs +++ b/src/core/world/dungeon/mod.rs @@ -16,7 +16,7 @@ use self::automata::{Automaton, DrunkardsWalk}; // Privately use builders mod builder; -use self::builder::{Buildable, Fussy, Simple}; +use self::builder::{Buildable, Fussy, Simple, Structure}; mod dungeon_tests; @@ -117,6 +117,9 @@ impl Dungeon { // Mostly orderly - Long corridors that occassionally deviate grid = drunk(0.25, 1000, &mut grid); + // Add structures + grid = Structure::new(grid).build(); + // Biome generation // Mostly just a proof of concept. Biomes are generated by comparing noise maps to the grid then flipping biomes @@ -138,9 +141,9 @@ impl Dungeon { grid[x][y].set_fg((67, 57, 57)); grid[x][y].set_bg((60, 50, 50)); }, - TileType::UpStair | TileType::DownStair => { + TileType::UpStair | TileType::DownStair | TileType::TallGrass => { grid[x][y].set_bg((25, 20, 20)); - } + }, _ => { grid[x][y].set_fg((32, 27, 27)); grid[x][y].set_bg((25, 20, 20)); @@ -163,7 +166,7 @@ impl Dungeon { grid[x][y].set_fg((57, 57, 57)); grid[x][y].set_bg((50, 50, 50)); }, - TileType::UpStair | TileType::DownStair => { + TileType::UpStair | TileType::DownStair | TileType::TallGrass => { grid[x][y].set_bg((20, 20, 20)); } _ => { @@ -188,7 +191,7 @@ impl Dungeon { grid[x][y].set_fg((57, 57, 67)); grid[x][y].set_bg((50, 50, 60)); }, - TileType::UpStair | TileType::DownStair => { + TileType::UpStair | TileType::DownStair | TileType::TallGrass => { grid[x][y].set_bg((20, 20, 25)); } _ => { diff --git a/strct/PillarsA.em b/strct/PillarsA.em new file mode 100644 index 00000000..194fe9c5 --- /dev/null +++ b/strct/PillarsA.em @@ -0,0 +1,9 @@ +###.##.### +#........# +#.#....#.# +#...""...# +...""""... +#...""...# +#.#....#.# +#........# +###.##.### \ No newline at end of file