1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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.elements() {
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 elements(&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 elements_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))
}
}
|