1 use specs::prelude::*;
2 use super::{Viewshed, Position, Map, Player};
3 use rltk::{field_of_view, Point};
4
5 pub struct VisibilitySystem {}
6
7 impl<'a> System<'a> for VisibilitySystem {
8 type SystemData = ( WriteExpect<'a, Map>,
9 Entities<'a>,
10 WriteStorage<'a, Viewshed>,
11 WriteStorage<'a, Position>,
12 ReadStorage<'a, Player>);
13
14 fn run(&mut self, data : Self::SystemData) {
15 let (mut map, entities, mut viewshed, pos, player) = data;
16
17 for (ent,viewshed,pos) in (&entities, &mut viewshed, &pos).join() {
18 if viewshed.dirty {
19 viewshed.dirty = false;
20 viewshed.visible_tiles.clear();
21 viewshed.visible_tiles = field_of_view(Point::new(pos.x, pos.y), viewshed.range, &*map);
22 viewshed.visible_tiles.retain(|p| p.x >= 0 && p.x < map.width && p.y >= 0 && p.y < map.height );
23
24 // If this is the player, reveal what they can see
25 let _p : Option<&Player> = player.get(ent);
26 if let Some(_p) = _p {
27 for t in map.visible_tiles.iter_mut() { *t = false };
28 for vis in viewshed.visible_tiles.iter() {
29 let idx = map.xy_idx(vis.x, vis.y);
30 map.revealed_tiles[idx] = true;
31 map.visible_tiles[idx] = true;
32 }
33 }
34 }
35 }
36 }
37 }