mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fixed house entrances
This commit is contained in:
parent
8e2ca9cdec
commit
4a9581b54d
@ -164,22 +164,32 @@ impl Site {
|
||||
search_pos: Vec2<i32>,
|
||||
area_range: Range<u32>,
|
||||
min_dims: Extent2<u32>,
|
||||
) -> Option<(Aabr<i32>, Vec2<i32>)> {
|
||||
self.tiles.find_near(search_pos, |center, _| {
|
||||
) -> Option<(Aabr<i32>, Vec2<i32>, Vec2<i32>)> {
|
||||
let ((aabr, door_dir), door_pos) = self.tiles.find_near(search_pos, |center, _| {
|
||||
let dir = CARDINALS
|
||||
.iter()
|
||||
.find(|dir| self.tiles.get(center + *dir).is_road())?;
|
||||
self.tiles
|
||||
.grow_aabr(center, area_range.clone(), min_dims)
|
||||
.ok()
|
||||
.filter(|aabr| {
|
||||
(aabr.min.x..aabr.max.x)
|
||||
.any(|x| self.tiles.get(Vec2::new(x, aabr.min.y - 1)).is_road())
|
||||
|| (aabr.min.x..aabr.max.x)
|
||||
.any(|x| self.tiles.get(Vec2::new(x, aabr.max.y)).is_road())
|
||||
|| (aabr.min.y..aabr.max.y)
|
||||
.any(|y| self.tiles.get(Vec2::new(aabr.min.x - 1, y)).is_road())
|
||||
|| (aabr.min.y..aabr.max.y)
|
||||
.any(|y| self.tiles.get(Vec2::new(aabr.max.x, y)).is_road())
|
||||
})
|
||||
})
|
||||
.zip(Some(*dir))
|
||||
// .filter_map(|aabr| {
|
||||
// (aabr.min.x..aabr.max.x)
|
||||
// .find(|x| self.tiles.get(Vec2::new(x, aabr.min.y -
|
||||
// 1)).is_road()) .map(|x| Vec2::new(x,
|
||||
// aabr.min.y)) .or_else(||
|
||||
// (aabr.min.x..aabr.max.x) .find(|x|
|
||||
// self.tiles.get(Vec2::new(x, aabr.max.y)).is_road())
|
||||
// .map(|x| Vec2::new(x, aabr.max.y))
|
||||
// .or_else(|| (aabr.min.y..aabr.max.y)
|
||||
// .find(|y| self.tiles.get(Vec2::new(aabr.min.x - 1,
|
||||
// y)).is_road()) .map(|y| Vec2::new(aabr.min.x,
|
||||
// y)) .or_else(|| (aabr.min.y..aabr.max.y)
|
||||
// .find(|y| self.tiles.get(Vec2::new(aabr.max.x,
|
||||
// y)).is_road()) .map(|y| Vec2::new(aabr.max.x,
|
||||
// y))))) })
|
||||
})?;
|
||||
Some((aabr, door_pos, door_dir))
|
||||
}
|
||||
|
||||
pub fn find_roadside_aabr(
|
||||
@ -187,7 +197,7 @@ impl Site {
|
||||
rng: &mut impl Rng,
|
||||
area_range: Range<u32>,
|
||||
min_dims: Extent2<u32>,
|
||||
) -> Option<(Aabr<i32>, Vec2<i32>)> {
|
||||
) -> Option<(Aabr<i32>, Vec2<i32>, Vec2<i32>)> {
|
||||
let dir = Vec2::<f32>::zero()
|
||||
.map(|_| rng.gen_range(-1.0..1.0))
|
||||
.normalized();
|
||||
@ -200,6 +210,10 @@ impl Site {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
// self.tiles
|
||||
// .grow_aabr(center, area_range, min_dims)
|
||||
// .ok()
|
||||
|
||||
self.find_aabr(search_pos, area_range, min_dims)
|
||||
}
|
||||
|
||||
@ -337,7 +351,7 @@ impl Site {
|
||||
|
||||
site.make_plaza(land, &mut rng);
|
||||
|
||||
let build_chance = Lottery::from(vec![(64.0, 1), (5.0, 2), (8.0, 3), (0.75, 4)]);
|
||||
let build_chance = Lottery::from(vec![(64.0, 1), (5.0, 2), (8.0, 3), (1.75, 4)]);
|
||||
|
||||
let mut castles = 0;
|
||||
|
||||
@ -345,8 +359,8 @@ impl Site {
|
||||
match *build_chance.choose_seeded(rng.gen()) {
|
||||
// House
|
||||
1 => {
|
||||
let size = (2.0 + rng.gen::<f32>().powf(8.0) * 3.0).round() as u32;
|
||||
if let Some((aabr, door_tile)) = attempt(32, || {
|
||||
let size = (2.0 + rng.gen::<f32>().powf(5.0) * 1.5).round() as u32;
|
||||
if let Some((aabr, door_tile, door_dir)) = attempt(32, || {
|
||||
site.find_roadside_aabr(
|
||||
&mut rng,
|
||||
4..(size + 1).pow(2),
|
||||
@ -359,6 +373,7 @@ impl Site {
|
||||
&mut reseed(&mut rng),
|
||||
&site,
|
||||
door_tile,
|
||||
door_dir,
|
||||
aabr,
|
||||
)),
|
||||
root_tile: aabr.center(),
|
||||
@ -376,7 +391,7 @@ impl Site {
|
||||
},
|
||||
// Guard tower
|
||||
2 => {
|
||||
if let Some((_aabr, _)) = attempt(10, || {
|
||||
if let Some((_aabr, _, _door_dir)) = attempt(10, || {
|
||||
site.find_roadside_aabr(&mut rng, 4..4, Extent2::new(2, 2))
|
||||
}) {
|
||||
/*
|
||||
@ -400,6 +415,7 @@ impl Site {
|
||||
}
|
||||
},
|
||||
// Field
|
||||
/*
|
||||
3 => {
|
||||
attempt(10, || {
|
||||
let search_pos = attempt(16, || {
|
||||
@ -430,9 +446,10 @@ impl Site {
|
||||
}
|
||||
});
|
||||
},
|
||||
*/
|
||||
// Castle
|
||||
4 if castles < 1 => {
|
||||
if let Some((aabr, _entrance_tile)) = attempt(10, || {
|
||||
if let Some((aabr, _entrance_tile, _door_dir)) = attempt(10, || {
|
||||
site.find_roadside_aabr(&mut rng, 16 * 16..18 * 18, Extent2::new(16, 16))
|
||||
}) {
|
||||
let offset = rng.gen_range(5..(aabr.size().w.min(aabr.size().h) - 4));
|
||||
@ -634,7 +651,7 @@ impl Site {
|
||||
b.with_sprite(SpriteKind::Empty)
|
||||
}
|
||||
} else {
|
||||
Block::new(BlockKind::Rock, Rgb::new(55, 45, 50))
|
||||
Block::new(BlockKind::Earth, Rgb::new(0x6A, 0x47, 0x24))
|
||||
}
|
||||
})
|
||||
});
|
||||
@ -656,8 +673,8 @@ impl Site {
|
||||
if let TileKind::Road { a, b, w } = &tile.kind {
|
||||
if let Some(PlotKind::Road(path)) = tile.plot.map(|p| &self.plot(p).kind) {
|
||||
Some((LineSegment2 {
|
||||
start: self.tile_center_wpos(path.nodes()[*a as usize]).map(|e| e as f32),
|
||||
end: self.tile_center_wpos(path.nodes()[*b as usize]).map(|e| e as f32),
|
||||
start: self.tile_wpos(path.nodes()[*a as usize]).map(|e| e as f32),
|
||||
end: self.tile_wpos(path.nodes()[*b as usize]).map(|e| e as f32),
|
||||
}, *w))
|
||||
} else {
|
||||
None
|
||||
@ -683,7 +700,7 @@ impl Site {
|
||||
b.with_sprite(SpriteKind::Empty)
|
||||
}
|
||||
} else {
|
||||
Block::new(BlockKind::Rock, Rgb::new(55, 45, 50))
|
||||
Block::new(BlockKind::Earth, Rgb::new(0x6A, 0x47, 0x24))
|
||||
},
|
||||
));
|
||||
}
|
||||
@ -777,6 +794,11 @@ impl Site {
|
||||
|
||||
for x in aabb.min.x..aabb.max.x {
|
||||
for y in aabb.min.y..aabb.max.y {
|
||||
let col_tile = self.wpos_tile(Vec2::new(x, y));
|
||||
if col_tile.is_building() && col_tile.plot != Some(plot) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for z in aabb.min.z..aabb.max.z {
|
||||
let pos = Vec3::new(x, y, z);
|
||||
|
||||
|
@ -29,6 +29,7 @@ impl House {
|
||||
rng: &mut impl Rng,
|
||||
site: &Site,
|
||||
door_tile: Vec2<i32>,
|
||||
door_dir: Vec2<i32>,
|
||||
tile_aabr: Aabr<i32>,
|
||||
) -> Self {
|
||||
let levels = rng.gen_range(1..2 + (tile_aabr.max - tile_aabr.min).product() / 6) as u32;
|
||||
@ -37,34 +38,21 @@ impl House {
|
||||
min: site.tile_wpos(tile_aabr.min),
|
||||
max: site.tile_wpos(tile_aabr.max),
|
||||
};
|
||||
let max_x_door_offset = (door_tile_pos.x - bounds.max.x).abs();
|
||||
let max_y_door_offset = (door_tile_pos.y - bounds.max.y).abs();
|
||||
let min_x_door_offset = (door_tile_pos.x - bounds.min.x).abs();
|
||||
let min_y_door_offset = (door_tile_pos.y - bounds.min.y).abs();
|
||||
let front = if max_y_door_offset < max_x_door_offset
|
||||
&& max_y_door_offset < min_x_door_offset
|
||||
&& max_y_door_offset < min_y_door_offset
|
||||
{
|
||||
0
|
||||
} else if max_x_door_offset < max_y_door_offset
|
||||
&& max_x_door_offset < min_x_door_offset
|
||||
&& max_x_door_offset < min_y_door_offset
|
||||
{
|
||||
1
|
||||
} else if min_y_door_offset < max_y_door_offset
|
||||
&& min_y_door_offset < min_x_door_offset
|
||||
&& min_y_door_offset < max_x_door_offset
|
||||
{
|
||||
let front = if door_dir.y < 0 {
|
||||
2
|
||||
} else {
|
||||
} else if door_dir.x < 0 {
|
||||
3
|
||||
} else if door_dir.y > 0 {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
Self {
|
||||
door_tile: door_tile_pos,
|
||||
tile_aabr,
|
||||
bounds,
|
||||
alt: land.get_alt_approx(site.tile_center_wpos(door_tile)) as i32 + 2,
|
||||
alt: (land.get_alt_approx(site.tile_center_wpos(door_tile + door_dir)) + 1.0) as i32,
|
||||
levels,
|
||||
overhang: if levels > 3 {
|
||||
// Overhangs of 3 at this building height are ill-advised.
|
||||
@ -1928,8 +1916,12 @@ impl Structure for House {
|
||||
fill(prim(Primitive::Aabb(doorway2)), Fill::Block(Block::empty()));
|
||||
|
||||
// Fill in the right and left side doors
|
||||
let (door1, door1_ori, door2, door2_ori) = match self.front {
|
||||
let (door_gap, door1, door1_ori, door2, door2_ori) = match self.front {
|
||||
0 => (
|
||||
Aabb {
|
||||
min: Vec2::new(self.door_tile.x - 1, self.bounds.max.y + 1).with_z(alt),
|
||||
max: Vec2::new(self.door_tile.x + 3, self.bounds.max.y + 4).with_z(alt + 3),
|
||||
},
|
||||
Aabb {
|
||||
min: Vec2::new(self.door_tile.x, self.bounds.max.y).with_z(alt),
|
||||
max: Vec2::new(self.door_tile.x + 1, self.bounds.max.y + 1).with_z(alt + 1),
|
||||
@ -1942,6 +1934,10 @@ impl Structure for House {
|
||||
4,
|
||||
),
|
||||
1 => (
|
||||
Aabb {
|
||||
min: Vec2::new(self.bounds.max.x + 1, self.door_tile.y - 1).with_z(alt),
|
||||
max: Vec2::new(self.bounds.max.x + 4, self.door_tile.y + 3).with_z(alt + 3),
|
||||
},
|
||||
Aabb {
|
||||
min: Vec2::new(self.bounds.max.x, self.door_tile.y).with_z(alt),
|
||||
max: Vec2::new(self.bounds.max.x + 1, self.door_tile.y + 1).with_z(alt + 1),
|
||||
@ -1954,6 +1950,10 @@ impl Structure for House {
|
||||
6,
|
||||
),
|
||||
2 => (
|
||||
Aabb {
|
||||
min: Vec2::new(self.door_tile.x - 1, self.bounds.min.y - 4).with_z(alt),
|
||||
max: Vec2::new(self.door_tile.x + 3, self.bounds.min.y).with_z(alt + 3),
|
||||
},
|
||||
Aabb {
|
||||
min: Vec2::new(self.door_tile.x, self.bounds.min.y).with_z(alt),
|
||||
max: Vec2::new(self.door_tile.x + 1, self.bounds.min.y + 1).with_z(alt + 1),
|
||||
@ -1966,6 +1966,10 @@ impl Structure for House {
|
||||
4,
|
||||
),
|
||||
_ => (
|
||||
Aabb {
|
||||
min: Vec2::new(self.bounds.min.x - 4, self.door_tile.y - 1).with_z(alt),
|
||||
max: Vec2::new(self.bounds.min.x, self.door_tile.y + 3).with_z(alt + 3),
|
||||
},
|
||||
Aabb {
|
||||
min: Vec2::new(self.bounds.min.x, self.door_tile.y).with_z(alt),
|
||||
max: Vec2::new(self.bounds.min.x + 1, self.door_tile.y + 1).with_z(alt + 1),
|
||||
@ -1978,6 +1982,10 @@ impl Structure for House {
|
||||
6,
|
||||
),
|
||||
};
|
||||
fill(
|
||||
prim(Primitive::Aabb(door_gap)),
|
||||
Fill::Block(Block::air(SpriteKind::Empty)),
|
||||
);
|
||||
fill(
|
||||
prim(Primitive::Aabb(door1)),
|
||||
Fill::Block(Block::air(SpriteKind::Door).with_ori(door1_ori).unwrap()),
|
||||
|
@ -210,9 +210,13 @@ impl Tile {
|
||||
pub fn is_road(&self) -> bool { matches!(self.kind, TileKind::Road { .. }) }
|
||||
|
||||
pub fn is_obstacle(&self) -> bool {
|
||||
matches!(self.kind, TileKind::Hazard(_)) || self.is_building()
|
||||
}
|
||||
|
||||
pub fn is_building(&self) -> bool {
|
||||
matches!(
|
||||
self.kind,
|
||||
TileKind::Hazard(_) | TileKind::Building | TileKind::Castle | TileKind::Wall(_)
|
||||
TileKind::Building | TileKind::Castle | TileKind::Wall(_)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user