|
@@ -3,6 +3,7 @@ use super::{Rect};
|
|
|
use std::cmp::{max, min};
|
|
|
use specs::prelude::*;
|
|
|
use serde::{Serialize, Deserialize};
|
|
|
+use std::collections::HashSet;
|
|
|
|
|
|
pub const MAPWIDTH : usize = 80;
|
|
|
pub const MAPHEIGHT : usize = 38;
|
|
@@ -25,6 +26,7 @@ pub struct Map {
|
|
|
pub visible_tiles: Vec<bool>,
|
|
|
pub blocked : Vec<bool>,
|
|
|
pub depth: i32,
|
|
|
+ pub bloodstains : HashSet<usize>,
|
|
|
|
|
|
#[serde(skip_serializing)]
|
|
|
#[serde(skip_deserializing)]
|
|
@@ -90,6 +92,7 @@ impl Map {
|
|
|
visible_tiles : vec![false; MAPCOUNT],
|
|
|
blocked : vec![false; MAPCOUNT],
|
|
|
depth: new_depth,
|
|
|
+ bloodstains: HashSet::new(),
|
|
|
tile_content : vec![Vec::new(); MAPCOUNT]
|
|
|
};
|
|
|
|
|
@@ -208,23 +211,61 @@ impl BaseMap for Map {
|
|
|
// return map
|
|
|
// }
|
|
|
|
|
|
+fn is_revealed_and_wall(map: &Map, x: i32, y: i32) -> bool {
|
|
|
+ let idx = map.xy_idx(x, y);
|
|
|
+ map.tiles[idx] == TileType::Wall && map.revealed_tiles[idx]
|
|
|
+}
|
|
|
+
|
|
|
+fn wall_glyph(map : &Map, x: i32, y:i32) -> rltk::FontCharType {
|
|
|
+ if x < 1 || x > map.width-2 || y < 1 || y > map.height-2 as i32 { return 35; }
|
|
|
+ let mut mask : u8 = 0;
|
|
|
+
|
|
|
+ if is_revealed_and_wall(map, x, y - 1) { mask +=1; }
|
|
|
+ if is_revealed_and_wall(map, x, y + 1) { mask +=2; }
|
|
|
+ if is_revealed_and_wall(map, x - 1, y) { mask +=4; }
|
|
|
+ if is_revealed_and_wall(map, x + 1, y) { mask +=8; }
|
|
|
+
|
|
|
+ match mask {
|
|
|
+ 0 => { 9 } // Pillar because we can't see neighbors
|
|
|
+ 1 => { 186 } // Wall only to the north
|
|
|
+ 2 => { 186 } // Wall only to the south
|
|
|
+ 3 => { 186 } // Wall to the north and south
|
|
|
+ 4 => { 205 } // Wall only to the west
|
|
|
+ 5 => { 188 } // Wall to the north and west
|
|
|
+ 6 => { 187 } // Wall to the south and west
|
|
|
+ 7 => { 185 } // Wall to the north, south and west
|
|
|
+ 8 => { 205 } // Wall only to the east
|
|
|
+ 9 => { 200 } // Wall to the north and east
|
|
|
+ 10 => { 201 } // Wall to the south and east
|
|
|
+ 11 => { 204 } // Wall to the north, south and east
|
|
|
+ 12 => { 205 } // Wall to the east and west
|
|
|
+ 13 => { 202 } // Wall to the east, west, and south
|
|
|
+ 14 => { 203 } // Wall to the east, west, and north
|
|
|
+ 15 => { 206 } // ╬ Wall on all sides
|
|
|
+ _ => { 35 } // We missed one?
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
pub fn draw_map(ecs: &World, ctx : &mut Rltk) {
|
|
|
let map = ecs.fetch::<Map>();
|
|
|
|
|
|
let mut y = 0;
|
|
|
let mut x = 0;
|
|
|
+
|
|
|
for (idx,tile) in map.tiles.iter().enumerate() {
|
|
|
// Render a tile depending upon the tile type
|
|
|
if map.revealed_tiles[idx] {
|
|
|
let glyph;
|
|
|
let mut fg;
|
|
|
+ let mut bg = RGB::from_f32(0., 0., 0.);
|
|
|
+
|
|
|
match tile {
|
|
|
TileType::Floor => {
|
|
|
glyph = rltk::to_cp437('.');
|
|
|
fg = RGB::from_f32(1.0, 0.5, 0.7);
|
|
|
}
|
|
|
TileType::Wall => {
|
|
|
- glyph = rltk::to_cp437('#');
|
|
|
+ glyph = wall_glyph(&*map, x, y);
|
|
|
fg = RGB::from_f32(1.0, 0.6, 0.);
|
|
|
}
|
|
|
TileType::DownStairs => {
|
|
@@ -232,8 +273,19 @@ pub fn draw_map(ecs: &World, ctx : &mut Rltk) {
|
|
|
fg = RGB::from_f32(0.0,1.0,1.0);
|
|
|
}
|
|
|
}
|
|
|
- if !map.visible_tiles[idx] { fg = fg.to_greyscale() }
|
|
|
- ctx.set(x, y, fg, RGB::from_f32(0., 0., 0.), glyph);
|
|
|
+ // Render bloodstains
|
|
|
+ if map.bloodstains.contains(&idx) {
|
|
|
+ bg = RGB::from_f32(0.75, 0., 0.);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Fog of war
|
|
|
+ if !map.visible_tiles[idx] {
|
|
|
+ fg = fg.to_greyscale();
|
|
|
+ bg = RGB::from_f32(0., 0., 0.); // Don't show blood out of visual range
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ ctx.set(x, y, fg, bg, glyph);
|
|
|
}
|
|
|
|
|
|
// Move the coordinates
|