visibility_system.rs 1.5 KB

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