diff --git a/src/map.rs b/src/map.rs index 9e56083..1292c62 100644 --- a/src/map.rs +++ b/src/map.rs @@ -10,12 +10,13 @@ use crate::component::Viewshed; use crate::entity::{Player, TileType}; use crate::rect::Rect; -#[derive(Clone)] +#[derive(Clone, Default)] pub struct Map { pub tiles: Vec, pub rooms: Vec, pub width: i32, pub height: i32, + pub revealed_tiles: Vec, } impl Algorithm2D for Map { @@ -86,6 +87,7 @@ impl Map { rooms: vec![], width: 80, height: 50, + revealed_tiles: vec![false; 80 * 50], }; const MAX_ROOMS: i32 = 30; @@ -163,45 +165,38 @@ pub fn new_test() -> Vec { */ pub fn draw(ecs: &World, ctx: &mut Rltk) { - let mut viewsheds = ecs.write_storage::(); - let mut players = ecs.write_storage::(); let map = ecs.fetch::(); + let mut y = 0; + let mut x = 0; - (&mut players, &mut viewsheds).join().into_iter().for_each( - |(_player, viewshed)| { - let mut y = 0; - let mut x = 0; - map.tiles.iter().for_each(|tile| { - let pt = Point::new(x, y); - if viewshed.visible_tiles.contains(&pt) { - match tile { - TileType::Floor => { - ctx.set( - x, - y, - RGB::from_f32(0.5, 0.5, 0.5), - RGB::from_f32(0., 0., 0.), - rltk::to_cp437('.'), - ); - } - TileType::Wall => { - ctx.set( - x, - y, - RGB::from_f32(0.0, 1.0, 0.0), - RGB::from_f32(0., 0., 0.), - rltk::to_cp437('#'), - ); - } - } + map.tiles.iter().enumerate().for_each(|(idx, tile)| { + if map.revealed_tiles[idx] { + match tile { + TileType::Floor => { + ctx.set( + x, + y, + RGB::from_f32(0.5, 0.5, 0.5), + RGB::from_f32(0., 0., 0.), + rltk::to_cp437('.'), + ); } + TileType::Wall => { + ctx.set( + x, + y, + RGB::from_f32(0.0, 1.0, 0.0), + RGB::from_f32(0., 0., 0.), + rltk::to_cp437('#'), + ); + } + } + } - x += 1; - if x > 79 { - x = 0; - y += 1; - } - }); - }, - ); + x += 1; + if x > 79 { + x = 0; + y += 1; + } + }); } diff --git a/src/visibility.rs b/src/visibility.rs index 19b053d..5d24eaa 100644 --- a/src/visibility.rs +++ b/src/visibility.rs @@ -1,4 +1,4 @@ -use super::{Map, Position, Viewshed}; +use super::{Map, Player, Position, Viewshed}; use rltk::{field_of_view, Point}; use specs::prelude::*; @@ -6,22 +6,32 @@ pub struct VisibilitySystem {} impl<'a> System<'a> for VisibilitySystem { type SystemData = ( - ReadExpect<'a, Map>, + WriteExpect<'a, Map>, + Entities<'a>, WriteStorage<'a, Viewshed>, WriteStorage<'a, Position>, + ReadStorage<'a, Player>, ); fn run(&mut self, data: Self::SystemData) { - let (map, mut viewshed, pos) = data; - (&mut viewshed, &pos).join().into_iter().for_each( - |(viewshed, pos)| { + let (mut map, entities, mut viewshed, pos, player) = data; + (&entities, &mut viewshed, &pos) + .join() + .into_iter() + .for_each(|(ent, viewshed, pos)| { viewshed.visible_tiles.clear(); viewshed.visible_tiles = field_of_view( Point::new(pos.x, pos.y), viewshed.range, &*map, ); - }, - ); + let p: Option<&Player> = player.get(ent); + if let Some(p) = p { + viewshed.visible_tiles.iter().for_each(|vis| { + let idx = map.xy_idx(vis.x, vis.y); + map.revealed_tiles[idx] = true; + }); + } + }); } }