diff options
Diffstat (limited to 'src/map/mod.rs')
| -rw-r--r-- | src/map/mod.rs | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/src/map/mod.rs b/src/map/mod.rs new file mode 100644 index 0000000..93f51a2 --- /dev/null +++ b/src/map/mod.rs @@ -0,0 +1,122 @@ +pub mod data; +pub mod icon; +pub mod icon_renderer; +pub mod mappable; +pub mod polygon_room; +pub mod rect_room; +pub mod wall; + +pub use data::MapData; +pub use icon::*; +pub use mappable::Mappable; +pub use polygon_room::*; +pub use rect_room::*; +pub use wall::*; + +use crate::transform::Transform; +use icon_renderer::IconRenderer; +use raylib::drawing::RaylibDrawHandle; +use raylib::{RaylibHandle, RaylibThread}; +use std::rc::Rc; + +pub struct Map { + rect_rooms: Vec<RectRoom>, + polygon_rooms: Vec<PolygonRoom>, + walls: Vec<Wall>, + icons: Vec<Icon>, + icon_renderer: Rc<IconRenderer>, +} + +impl Map { + pub fn new(rl: &mut RaylibHandle, rlt: &RaylibThread) -> Self { + Self { + rect_rooms: Vec::new(), + polygon_rooms: Vec::new(), + walls: Vec::new(), + icons: Vec::new(), + icon_renderer: Rc::new(IconRenderer::new(rl, rlt)), + } + } + + pub fn push_rect_room(&mut self, room_data: RectRoomData) { + self.rect_rooms.push(RectRoom::from_data(room_data)); + } + + pub fn push_polygon_room(&mut self, room_data: PolygonRoomData) { + self.polygon_rooms.push(PolygonRoom::from_data(room_data)); + } + + pub fn push_wall(&mut self, wall_data: WallData) { + /* Check for intersections with any wall that was arleady created so the wall ends can be + * rendered properly. + */ + let mut start_intersects = false; + let mut end_intersects = false; + for wall in &self.walls { + if wall.data().contains_collinear(wall_data.start) { + start_intersects = true; + } + if wall.data().contains_collinear(wall_data.end) { + end_intersects = true; + } + + // Currently, additional intersections can be ignored, since it is just a yes-no-question + if start_intersects && end_intersects { + break; + } + } + + self.walls + .push(Wall::from_data(wall_data, start_intersects, end_intersects)); + } + + pub fn push_icon(&mut self, icon: Icon) { + self.icons.push(icon); + } + + pub fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) { + for element in self.iter() { + element.draw(rld, transform); + } + } + + pub fn icon_renderer(&self) -> Rc<IconRenderer> { + self.icon_renderer.clone() + } + + /// Retain all map elements that fulfill the given predicate. + pub fn retain<F>(&mut self, mut f: F) + where + F: FnMut(&dyn Mappable) -> bool, + { + // Call retain on all vectors containing the maps actual types. + self.rect_rooms.retain(|r| f(r as &dyn Mappable)); + self.polygon_rooms.retain(|p| f(p as &dyn Mappable)); + self.walls.retain(|w| f(w as &dyn Mappable)); + self.icons.retain(|i| f(i as &dyn Mappable)); + } + + /// Iterator over all elements as objects when an operation needs to go over all elements of the + /// map. + pub fn iter(&self) -> impl Iterator<Item = &dyn Mappable> { + self.rect_rooms + .iter() + .map(|r| r as &dyn Mappable) + .chain(self.polygon_rooms.iter().map(|p| p as &dyn Mappable)) + .chain(self.walls.iter().map(|w| w as &dyn Mappable)) + .chain(self.icons.iter().map(|i| i as &dyn Mappable)) + } + + pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut dyn Mappable> { + self.rect_rooms + .iter_mut() + .map(|r| r as &mut dyn Mappable) + .chain( + self.polygon_rooms + .iter_mut() + .map(|p| p as &mut dyn Mappable), + ) + .chain(self.walls.iter_mut().map(|w| w as &mut dyn Mappable)) + .chain(self.icons.iter_mut().map(|i| i as &mut dyn Mappable)) + } +} |
