doryen_fov/
lib.rs

1mod fov_dummy;
2mod fov_recursive_shadowcasting;
3mod fov_restrictive;
4
5pub use fov_dummy::*;
6pub use fov_recursive_shadowcasting::*;
7pub use fov_restrictive::*;
8
9/// Some basic structure to store map cells' transparency and fov computation result
10pub struct MapData {
11    /// width of the map in cells
12    pub width: usize,
13    /// height of the map in cells
14    pub height: usize,
15    /// width x height vector of transparency information
16    pub transparent: Vec<bool>,
17    /// width x height vector of field of view information
18    pub fov: Vec<bool>,
19}
20
21impl MapData {
22    /// create a new empty map : no walls and empty field of view
23    pub fn new(width: usize, height: usize) -> Self {
24        Self {
25            width,
26            height,
27            transparent: vec![true;width*height],
28            fov:vec![false;width*height],
29        }
30    }
31    /// reset the fov information to false
32    pub fn clear_fov(&mut self) {
33        for off in 0..self.width*self.height {
34            self.fov[off] = false;
35        }
36    }
37    pub fn is_in_fov(&self, x: usize, y: usize) -> bool {
38        self.fov[x + y*self.width]
39    }
40    pub fn is_transparent(&self, x: usize, y: usize) -> bool {
41        self.transparent[x + y*self.width]
42    }
43    pub fn set_fov(&mut self, x: usize, y: usize, in_fov: bool) {
44        self.fov[x + y*self.width] = in_fov;
45    }
46    pub fn set_transparent(&mut self, x: usize, y: usize, is_transparent: bool) {
47        self.transparent[x + y*self.width] = is_transparent;
48    }
49}
50
51/// Some algorithm to compute a field of view
52/// x,y : observer position on the map
53/// max_radius : max distance in cells where the observer can see. 0 = infinite
54/// light_walls : are walls limiting the field of view inside the field of view ?
55pub trait FovAlgorithm {
56    fn compute_fov(&mut self, map: &mut MapData, x: usize, y: usize,
57        max_radius: usize, light_walls: bool);
58}
59
60#[cfg(test)]
61mod tests {
62    use crate::{FovAlgorithm, FovDummy, FovRecursiveShadowCasting, FovRestrictive, MapData};
63
64    #[test]
65    fn fov_dummy() {
66        let mut fov = FovDummy::new();
67        let mut map = MapData::new(10, 10);
68        map.set_transparent(5,5,false);
69        fov.compute_fov(&mut map, 0, 0, 0, false);
70        for y in 0..10 {
71            for x in 0..10 {
72                assert_eq!(map.transparent[x + y * 10], map.fov[x + y*10]);
73            }
74        }
75    }
76
77    #[test]
78    fn fov_shadowcasting() {
79        let mut fov = FovRecursiveShadowCasting::new();
80        let mut map = MapData::new(10, 10);
81        map.set_transparent(5,5,false);
82        fov.compute_fov(&mut map, 5, 6, 0, false);
83        assert_eq!(map.is_in_fov(5,6), true);
84        assert_eq!(map.is_in_fov(5,7), true);
85        assert_eq!(map.is_in_fov(5,5), false);
86        assert_eq!(map.is_in_fov(5,4), false);
87    }
88
89    #[test]
90    fn fov_mrpas() {
91        let mut fov = FovRestrictive::new();
92        let mut map = MapData::new(10, 10);
93        map.set_transparent(5,5,false);
94        fov.compute_fov(&mut map, 5, 6, 0, false);
95        assert_eq!(map.is_in_fov(5,6), true);
96        assert_eq!(map.is_in_fov(5,7), true);
97        assert_eq!(map.is_in_fov(5,5), false);
98        assert_eq!(map.is_in_fov(5,4), false);
99    }
100}