aboutsummaryrefslogtreecommitdiff
path: root/src/map/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/mod.rs')
-rw-r--r--src/map/mod.rs122
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))
+ }
+}