Expand description
Rectangle region on the map
Fields§
§x1: usize
§x2: usize
§y1: usize
§y2: usize
Implementations§
source§impl Rect
impl Rect
sourcepub fn new(x: usize, y: usize, width: usize, height: usize) -> Rect
pub fn new(x: usize, y: usize, width: usize, height: usize) -> Rect
Examples found in repository?
More examples
src/filter/simple_rooms.rs (line 59)
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
fn build_rooms(&self, map: &MapBuffer, rng : &mut StdRng) -> MapBuffer {
let mut new_map = map.clone();
// Create room dimensions
for _ in 0..self.max_rooms {
let w = rng.random_range(self.min_room_size, self.max_room_size);
let h = rng.random_range(self.min_room_size, self.max_room_size);
let x = rng.random_range(1, new_map.width - w);
let y = rng.random_range(1, new_map.height - h);
let new_room = Rect::new(x, y, w, h);
let intersects = new_map.rooms.iter().any(|r| new_room.intersect(r));
if !intersects {
new_map.add_room(new_room);
}
}
new_map
}
src/filter/bsp_rooms.rs (line 48)
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
fn build_rooms(&self, map: &MapBuffer, rng : &mut StdRng) -> MapBuffer {
let mut new_map = map.clone();
// Start with a single map-sized rectangle
let mut rects = vec![Rect::new(2, 2, new_map.width-5, new_map.height-5)];
let first_room = rects[0];
rects.append(&mut self.split_into_subrects(first_room)); // Divide the first room
// Up to max_split times, we get a random rectangle and divide it. If its possible to squeeze a
// room in there, we place it and add it to the rooms list.
for _ in 0..self.max_split {
let rect = self.get_random_rect(rng, &rects);
let candidate = self.get_random_sub_rect(rect, rng);
if self.is_possible(candidate, &new_map) {
new_map.add_room(candidate);
rects.append(&mut self.split_into_subrects(rect));
}
}
new_map
}
fn split_into_subrects(&self, rect: Rect) -> Vec<Rect> {
let mut rects: Vec<Rect> = Vec::new();
let width = rect.width();
let height = rect.height();
let half_width = usize::max(width / 2, 1);
let half_height = usize::max(height / 2, 1);
rects.push(Rect::new( rect.x1, rect.y1, half_width, half_height ));
rects.push(Rect::new( rect.x1, rect.y1 + half_height, half_width, half_height ));
rects.push(Rect::new( rect.x1 + half_width, rect.y1, half_width, half_height ));
rects.push(Rect::new( rect.x1 + half_width, rect.y1 + half_height, half_width, half_height ));
rects
}
src/filter/bsp_interior.rs (line 50)
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
fn build(&self, rng: &mut StdRng, map: &MapBuffer) -> MapBuffer {
let mut new_map = map.clone();
let mut rects = vec![Rect::new(1, 1, new_map.width-2, new_map.height-2)];
let first_room = rects[0];
// Divide the first room
self.add_subrects(first_room, rng, &mut rects);
let rooms_copy = rects.clone();
for r in rooms_copy.iter() {
let room = *r;
new_map.add_room(room);
}
// Now we want corridors
for i in 0..new_map.rooms.len()-1 {
let room = new_map.rooms[i];
let next_room = new_map.rooms[i+1];
let start_x = rng.random_range(room.x1, room.x2);
let start_y = rng.random_range(room.y1, room.y2);
let end_x = rng.random_range(next_room.x1, next_room.x2);
let end_y = rng.random_range(next_room.y1, next_room.y2);
new_map.add_corridor(Point::new(start_x, start_y), Point::new(end_x, end_y));
}
new_map
}
fn add_subrects(&self, rect: Rect, rng: &mut StdRng, rects: &mut Vec<Rect>) {
// Remove the last rect from the list
if !rects.is_empty() {
rects.remove(rects.len() - 1);
}
// Calculate boundaries
let width = rect.x2 - rect.x1;
let height = rect.y2 - rect.y1;
let half_width = width / 2;
let half_height = height / 2;
let split = rng.roll_dice(1, 4);
if split <= 2 {
// Horizontal split
let h1 = Rect::new( rect.x1, rect.y1, half_width-1, height );
rects.push( h1 );
if half_width > self.min_room_size { self.add_subrects(h1, rng, rects); }
let h2 = Rect::new( rect.x1 + half_width, rect.y1, half_width, height );
rects.push( h2 );
if half_width > self.min_room_size { self.add_subrects(h2, rng, rects); }
} else {
// Vertical split
let v1 = Rect::new( rect.x1, rect.y1, width, half_height-1 );
rects.push(v1);
if half_height > self.min_room_size { self.add_subrects(v1, rng, rects); }
let v2 = Rect::new( rect.x1, rect.y1 + half_height, width, half_height );
rects.push(v2);
if half_height > self.min_room_size { self.add_subrects(v2, rng, rects); }
}
}
pub fn new_i32(x: i32, y: i32, width: i32, height: i32) -> Rect
sourcepub fn intersect(&self, other: &Rect) -> bool
pub fn intersect(&self, other: &Rect) -> bool
Returns true if this overlaps with other
Examples found in repository?
src/filter/simple_rooms.rs (line 60)
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
fn build_rooms(&self, map: &MapBuffer, rng : &mut StdRng) -> MapBuffer {
let mut new_map = map.clone();
// Create room dimensions
for _ in 0..self.max_rooms {
let w = rng.random_range(self.min_room_size, self.max_room_size);
let h = rng.random_range(self.min_room_size, self.max_room_size);
let x = rng.random_range(1, new_map.width - w);
let y = rng.random_range(1, new_map.height - h);
let new_room = Rect::new(x, y, w, h);
let intersects = new_map.rooms.iter().any(|r| new_room.intersect(r));
if !intersects {
new_map.add_room(new_room);
}
}
new_map
}
More examples
src/filter/bsp_rooms.rs (line 114)
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
fn is_possible(&self, rect: Rect, map: &MapBuffer) -> bool {
let mut expanded = rect;
expanded.x1 -= 2;
expanded.x2 += 2;
expanded.y1 -= 2;
expanded.y2 += 2;
let mut can_build = true;
for r in map.rooms.iter() {
if r.intersect(&rect) { can_build = false; }
}
for y in expanded.y1 ..= expanded.y2 {
for x in expanded.x1 ..= expanded.x2 {
if x > map.width - 2 { can_build = false; }
if y > map.height - 2 { can_build = false; }
if x < 1 { can_build = false; }
if y < 1 { can_build = false; }
if can_build && map.is_walkable(x as usize, y as usize) {
can_build = false;
}
}
}
can_build
}
sourcepub fn center(&self) -> Point
pub fn center(&self) -> Point
Examples found in repository?
src/filter/rooms_corridors_nearest.rs (line 29)
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
fn corridors(&self, map: &MapBuffer) -> MapBuffer {
let mut new_map = map.clone();
let mut connected : HashSet<usize> = HashSet::new();
for (i,room) in map.rooms.iter().enumerate() {
let mut room_distance : Vec<(usize, f32)> = Vec::new();
let room_center = room.center();
for (j,other_room) in new_map.rooms.iter().enumerate() {
if i != j && !connected.contains(&j) {
let other_center = other_room.center();
let distance = room_center.distance_to(&other_center);
room_distance.push((j, distance));
}
}
if !room_distance.is_empty() {
room_distance.sort_by(|a,b| a.1.partial_cmp(&b.1).unwrap() );
let dest_center = new_map.rooms[room_distance[0].0].center();
new_map.add_corridor(room_center, dest_center);
connected.insert(i);
}
}
new_map
}
sourcepub fn width(&self) -> usize
pub fn width(&self) -> usize
Examples found in repository?
src/filter/bsp_rooms.rs (line 69)
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
fn split_into_subrects(&self, rect: Rect) -> Vec<Rect> {
let mut rects: Vec<Rect> = Vec::new();
let width = rect.width();
let height = rect.height();
let half_width = usize::max(width / 2, 1);
let half_height = usize::max(height / 2, 1);
rects.push(Rect::new( rect.x1, rect.y1, half_width, half_height ));
rects.push(Rect::new( rect.x1, rect.y1 + half_height, half_width, half_height ));
rects.push(Rect::new( rect.x1 + half_width, rect.y1, half_width, half_height ));
rects.push(Rect::new( rect.x1 + half_width, rect.y1 + half_height, half_width, half_height ));
rects
}
fn get_random_rect(&self, rng : &mut StdRng, rects: &[Rect]) -> Rect {
if rects.len() == 1 { return rects[0]; }
let idx = rng.random_range(0, rects.len());
rects[idx]
}
fn get_random_sub_rect(&self, rect: Rect, rng: &mut StdRng) -> Rect {
let mut result = rect;
let rect_width = rect.width();
let rect_height = rect.height();
let w = usize::max(3, rng.random_range(1, usize::min(rect_width as usize, 20))) + 1;
let h = usize::max(3, rng.random_range(1, usize::min(rect_height as usize, 20))) + 1;
result.x1 += rng.random_range(0, 6);
result.y1 += rng.random_range(0, 6);
result.x2 = result.x1 + w;
result.y2 = result.y1 + h;
result
}
sourcepub fn height(&self) -> usize
pub fn height(&self) -> usize
Examples found in repository?
src/filter/bsp_rooms.rs (line 70)
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
fn split_into_subrects(&self, rect: Rect) -> Vec<Rect> {
let mut rects: Vec<Rect> = Vec::new();
let width = rect.width();
let height = rect.height();
let half_width = usize::max(width / 2, 1);
let half_height = usize::max(height / 2, 1);
rects.push(Rect::new( rect.x1, rect.y1, half_width, half_height ));
rects.push(Rect::new( rect.x1, rect.y1 + half_height, half_width, half_height ));
rects.push(Rect::new( rect.x1 + half_width, rect.y1, half_width, half_height ));
rects.push(Rect::new( rect.x1 + half_width, rect.y1 + half_height, half_width, half_height ));
rects
}
fn get_random_rect(&self, rng : &mut StdRng, rects: &[Rect]) -> Rect {
if rects.len() == 1 { return rects[0]; }
let idx = rng.random_range(0, rects.len());
rects[idx]
}
fn get_random_sub_rect(&self, rect: Rect, rng: &mut StdRng) -> Rect {
let mut result = rect;
let rect_width = rect.width();
let rect_height = rect.height();
let w = usize::max(3, rng.random_range(1, usize::min(rect_width as usize, 20))) + 1;
let h = usize::max(3, rng.random_range(1, usize::min(rect_height as usize, 20))) + 1;
result.x1 += rng.random_range(0, 6);
result.y1 += rng.random_range(0, 6);
result.x2 = result.x1 + w;
result.y2 = result.y1 + h;
result
}