mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Wider roads, better structure
This commit is contained in:
parent
1dab08075e
commit
cd97a4b2fc
@ -67,14 +67,23 @@ impl Site {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_road(&mut self, land: &Land, rng: &mut impl Rng, a: Vec2<i32>, b: Vec2<i32>) -> Option<Id<Plot>> {
|
pub fn create_road(&mut self, land: &Land, rng: &mut impl Rng, a: Vec2<i32>, b: Vec2<i32>, w: i32) -> Option<Id<Plot>> {
|
||||||
const MAX_ITERS: usize = 4096;
|
const MAX_ITERS: usize = 4096;
|
||||||
let heuristic = |tile: &Vec2<i32>| if self.tiles.get(*tile).is_obstacle() { 100.0 } else { 0.0 };
|
let heuristic = |tile: &Vec2<i32>| {
|
||||||
|
for y in 0..w {
|
||||||
|
for x in 0..w {
|
||||||
|
if self.tiles.get(*tile + Vec2::new(x, y)).is_obstacle() {
|
||||||
|
return 100.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(tile.distance_squared(b) as f32).sqrt()
|
||||||
|
};
|
||||||
let path = Astar::new(MAX_ITERS, a, &heuristic, DefaultHashBuilder::default()).poll(
|
let path = Astar::new(MAX_ITERS, a, &heuristic, DefaultHashBuilder::default()).poll(
|
||||||
MAX_ITERS,
|
MAX_ITERS,
|
||||||
&heuristic,
|
&heuristic,
|
||||||
|tile| { let tile = *tile; CARDINALS.iter().map(move |dir| tile + *dir) },
|
|tile| { let tile = *tile; CARDINALS.iter().map(move |dir| tile + *dir) },
|
||||||
|a, b| (a.distance_squared(*b) as f32).sqrt(),
|
|a, b| rng.gen_range(1.0..1.5),
|
||||||
|tile| *tile == b,
|
|tile| *tile == b,
|
||||||
).into_path()?;
|
).into_path()?;
|
||||||
|
|
||||||
@ -89,11 +98,15 @@ impl Site {
|
|||||||
self.roads.push(plot);
|
self.roads.push(plot);
|
||||||
|
|
||||||
for &tile in path.iter() {
|
for &tile in path.iter() {
|
||||||
self.tiles.set(tile, Tile {
|
for y in 0..w {
|
||||||
|
for x in 0..w {
|
||||||
|
self.tiles.set(tile + Vec2::new(x, y), Tile {
|
||||||
kind: TileKind::Road,
|
kind: TileKind::Road,
|
||||||
plot: Some(plot),
|
plot: Some(plot),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Some(plot)
|
Some(plot)
|
||||||
}
|
}
|
||||||
@ -101,21 +114,24 @@ impl Site {
|
|||||||
pub fn find_aabr(&mut self, search_pos: Vec2<i32>, area_range: Range<u32>, min_dims: Extent2<u32>) -> Option<(Aabr<i32>, Vec2<i32>)> {
|
pub fn find_aabr(&mut self, search_pos: Vec2<i32>, area_range: Range<u32>, min_dims: Extent2<u32>) -> Option<(Aabr<i32>, Vec2<i32>)> {
|
||||||
self.tiles.find_near(
|
self.tiles.find_near(
|
||||||
search_pos,
|
search_pos,
|
||||||
|center, _| if CARDINALS.iter().any(|&dir| self.tiles.get(center + dir).kind == TileKind::Road) {
|
|center, _| self.tiles.grow_aabr(center, area_range.clone(), min_dims)
|
||||||
self.tiles.grow_aabr(center, area_range.clone(), min_dims).ok()
|
.ok()
|
||||||
} else {
|
.filter(|aabr| {
|
||||||
None
|
(aabr.min.x..aabr.max.x).any(|x| self.tiles.get(Vec2::new(x, aabr.min.y - 1)).kind == TileKind::Road)
|
||||||
},
|
|| (aabr.min.x..aabr.max.x).any(|x| self.tiles.get(Vec2::new(x, aabr.max.y)).kind == TileKind::Road)
|
||||||
|
|| (aabr.min.y..aabr.max.y).any(|y| self.tiles.get(Vec2::new(aabr.min.x - 1, y)).kind == TileKind::Road)
|
||||||
|
|| (aabr.min.y..aabr.max.y).any(|y| self.tiles.get(Vec2::new(aabr.max.x, y)).kind == TileKind::Road)
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_roadside_aabr(&mut self, rng: &mut impl Rng, area_range: Range<u32>, min_dims: Extent2<u32>) -> Option<(Aabr<i32>, Vec2<i32>)> {
|
pub fn find_roadside_aabr(&mut self, rng: &mut impl Rng, area_range: Range<u32>, min_dims: Extent2<u32>) -> Option<(Aabr<i32>, Vec2<i32>)> {
|
||||||
let dir = Vec2::<f32>::zero().map(|_| rng.gen_range(-1.0..1.0)).normalized();
|
let dir = Vec2::<f32>::zero().map(|_| rng.gen_range(-1.0..1.0)).normalized();
|
||||||
let search_pos = if rng.gen() {
|
let search_pos = if rng.gen() {
|
||||||
self.plot(*self.plazas.choose(rng)?).root_tile + (dir * 5.0).map(|e: f32| e.round() as i32)
|
self.plot(*self.plazas.choose(rng)?).root_tile + (dir * 4.0).map(|e: f32| e.round() as i32)
|
||||||
} else {
|
} else {
|
||||||
if let PlotKind::Road(path) = &self.plot(*self.roads.choose(rng)?).kind {
|
if let PlotKind::Road(path) = &self.plot(*self.roads.choose(rng)?).kind {
|
||||||
*path.nodes().choose(rng)? + (dir * 1.5).map(|e: f32| e.round() as i32)
|
*path.nodes().choose(rng)? + (dir * 1.0).map(|e: f32| e.round() as i32)
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@ -128,11 +144,11 @@ impl Site {
|
|||||||
let pos = attempt(32, || {
|
let pos = attempt(32, || {
|
||||||
self.plazas
|
self.plazas
|
||||||
.choose(rng)
|
.choose(rng)
|
||||||
.map(|&p| self.plot(p).root_tile + Vec2::new(rng.gen_range(-20..20), rng.gen_range(-20..20)))
|
.map(|&p| self.plot(p).root_tile + (Vec2::new(rng.gen_range(-1.0..1.0), rng.gen_range(-1.0..1.0)).normalized() * 24.0).map(|e| e as i32))
|
||||||
.filter(|&tile| self
|
.filter(|&tile| self
|
||||||
.plazas
|
.plazas
|
||||||
.iter()
|
.iter()
|
||||||
.all(|&p| self.plot(p).root_tile.distance_squared(tile) > 16i32.pow(2))
|
.all(|&p| self.plot(p).root_tile.distance_squared(tile) > 20i32.pow(2))
|
||||||
&& rng.gen_range(0..48) > tile.map(|e| e.abs()).reduce_max())
|
&& rng.gen_range(0..48) > tile.map(|e| e.abs()).reduce_max())
|
||||||
})
|
})
|
||||||
.unwrap_or_else(Vec2::zero);
|
.unwrap_or_else(Vec2::zero);
|
||||||
@ -152,13 +168,14 @@ impl Site {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let mut already_pathed = vec![plaza];
|
let mut already_pathed = vec![plaza];
|
||||||
for _ in 0..2 {
|
// One major, one minor road
|
||||||
|
for width in (1..=2).rev() {
|
||||||
if let Some(&p) = self.plazas
|
if let Some(&p) = self.plazas
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|p| !already_pathed.contains(p))
|
.filter(|p| !already_pathed.contains(p))
|
||||||
.min_by_key(|&&p| self.plot(p).root_tile.distance_squared(pos))
|
.min_by_key(|&&p| self.plot(p).root_tile.distance_squared(pos))
|
||||||
{
|
{
|
||||||
self.create_road(land, rng, self.plot(p).root_tile, pos);
|
self.create_road(land, rng, self.plot(p).root_tile, pos, width);
|
||||||
already_pathed.push(p);
|
already_pathed.push(p);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@ -179,7 +196,7 @@ impl Site {
|
|||||||
let build_chance = Lottery::from(vec![
|
let build_chance = Lottery::from(vec![
|
||||||
(1.0, 0),
|
(1.0, 0),
|
||||||
(48.0, 1),
|
(48.0, 1),
|
||||||
(2.0, 2),
|
(5.0, 2),
|
||||||
(1.0, 3),
|
(1.0, 3),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -197,7 +214,7 @@ impl Site {
|
|||||||
},
|
},
|
||||||
// House
|
// House
|
||||||
1 => {
|
1 => {
|
||||||
let size = (2.0 + rng.gen::<f32>().powf(4.0) * 3.0).round() as u32;
|
let size = (2.0 + rng.gen::<f32>().powf(8.0) * 3.0).round() as u32;
|
||||||
if let Some((aabr, _)) = attempt(10, || site.find_roadside_aabr(rng, 4..(size + 1).pow(2), Extent2::broadcast(size))) {
|
if let Some((aabr, _)) = attempt(10, || site.find_roadside_aabr(rng, 4..(size + 1).pow(2), Extent2::broadcast(size))) {
|
||||||
let plot = site.create_plot(Plot {
|
let plot = site.create_plot(Plot {
|
||||||
kind: PlotKind::House,
|
kind: PlotKind::House,
|
||||||
|
Loading…
Reference in New Issue
Block a user