mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Better town layout
This commit is contained in:
parent
4a9581b54d
commit
bacb2aa504
@ -173,21 +173,6 @@ impl Site {
|
||||
.grow_aabr(center, area_range.clone(), min_dims)
|
||||
.ok()
|
||||
.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))
|
||||
}
|
||||
@ -202,22 +187,21 @@ impl Site {
|
||||
.map(|_| rng.gen_range(-1.0..1.0))
|
||||
.normalized();
|
||||
let search_pos = if rng.gen() {
|
||||
self.plot(*self.plazas.choose(rng)?).root_tile
|
||||
+ (dir * 4.0).map(|e: f32| e.round() as i32)
|
||||
let plaza = self.plot(*self.plazas.choose(rng)?);
|
||||
let sz = plaza.find_bounds().size();
|
||||
plaza.root_tile + dir.map(|e: f32| e.round() as i32) * (sz + 1)
|
||||
} else if let PlotKind::Road(path) = &self.plot(*self.roads.choose(rng)?).kind {
|
||||
*path.nodes().choose(rng)? + (dir * 1.0).map(|e: f32| e.round() as i32)
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
// self.tiles
|
||||
// .grow_aabr(center, area_range, min_dims)
|
||||
// .ok()
|
||||
|
||||
self.find_aabr(search_pos, area_range, min_dims)
|
||||
}
|
||||
|
||||
pub fn make_plaza(&mut self, land: &Land, rng: &mut impl Rng) -> Id<Plot> {
|
||||
let plaza_radius = rng.gen_range(1..4);
|
||||
let plaza_dist = 10.0 + plaza_radius as f32 * 5.0;
|
||||
let pos = attempt(32, || {
|
||||
self.plazas
|
||||
.choose(rng)
|
||||
@ -225,22 +209,22 @@ impl Site {
|
||||
self.plot(p).root_tile
|
||||
+ (Vec2::new(rng.gen_range(-1.0..1.0), rng.gen_range(-1.0..1.0))
|
||||
.normalized()
|
||||
* 24.0)
|
||||
* plaza_dist)
|
||||
.map(|e| e as i32)
|
||||
})
|
||||
.filter(|tile| !self.tiles.get(*tile).is_obstacle())
|
||||
.filter(|&tile| {
|
||||
self.plazas
|
||||
.iter()
|
||||
.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()
|
||||
self.plazas.iter().all(|&p| {
|
||||
self.plot(p).root_tile.distance_squared(tile) as f32
|
||||
> (plaza_dist * 0.85).powi(2)
|
||||
}) && rng.gen_range(0..48) > tile.map(|e| e.abs()).reduce_max()
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(Vec2::zero);
|
||||
|
||||
let aabr = Aabr {
|
||||
min: pos + Vec2::broadcast(-3),
|
||||
max: pos + Vec2::broadcast(4),
|
||||
min: pos + Vec2::broadcast(-plaza_radius),
|
||||
max: pos + Vec2::broadcast(plaza_radius + 1),
|
||||
};
|
||||
let plaza = self.create_plot(Plot {
|
||||
kind: PlotKind::Plaza,
|
||||
@ -254,16 +238,30 @@ impl Site {
|
||||
plot: Some(plaza),
|
||||
});
|
||||
|
||||
let mut already_pathed = vec![plaza];
|
||||
let mut already_pathed = vec![];
|
||||
// One major, one minor road
|
||||
for width in (1..=2).rev() {
|
||||
for i in (0..rng.gen_range(1.5..2.5) as u16).rev() {
|
||||
if let Some(&p) = self
|
||||
.plazas
|
||||
.iter()
|
||||
.filter(|p| !already_pathed.contains(p))
|
||||
.filter(|&&p| {
|
||||
!already_pathed.contains(&p)
|
||||
&& p != plaza
|
||||
&& already_pathed.iter().all(|&ap| {
|
||||
(self.plot(ap).root_tile - pos)
|
||||
.map(|e| e as f32)
|
||||
.normalized()
|
||||
.dot(
|
||||
(self.plot(p).root_tile - pos)
|
||||
.map(|e| e as f32)
|
||||
.normalized(),
|
||||
)
|
||||
< 0.0
|
||||
})
|
||||
})
|
||||
.min_by_key(|&&p| self.plot(p).root_tile.distance_squared(pos))
|
||||
{
|
||||
self.create_road(land, rng, self.plot(p).root_tile, pos, width);
|
||||
self.create_road(land, rng, self.plot(p).root_tile, pos, 2 /* + i */);
|
||||
already_pathed.push(p);
|
||||
} else {
|
||||
break;
|
||||
@ -351,7 +349,7 @@ impl Site {
|
||||
|
||||
site.make_plaza(land, &mut rng);
|
||||
|
||||
let build_chance = Lottery::from(vec![(64.0, 1), (5.0, 2), (8.0, 3), (1.75, 4)]);
|
||||
let build_chance = Lottery::from(vec![(64.0, 1), (5.0, 2), (8.0, 3), (5.0, 4)]);
|
||||
|
||||
let mut castles = 0;
|
||||
|
||||
@ -694,10 +692,15 @@ impl Site {
|
||||
(-6..4).for_each(|z| canvas.map(
|
||||
Vec3::new(wpos2d.x, wpos2d.y, alt + z),
|
||||
|b| if z >= 0 {
|
||||
if b.is_filled() {
|
||||
Block::empty()
|
||||
let sprite = if z == 0 && self.tile_wpos(tpos) == wpos2d && tpos.sum() % 2 == 0 {
|
||||
SpriteKind::StreetLamp
|
||||
} else {
|
||||
b.with_sprite(SpriteKind::Empty)
|
||||
SpriteKind::Empty
|
||||
};
|
||||
if b.is_filled() {
|
||||
Block::air(sprite)
|
||||
} else {
|
||||
b.with_sprite(sprite)
|
||||
}
|
||||
} else {
|
||||
Block::new(BlockKind::Earth, Rgb::new(0x6A, 0x47, 0x24))
|
||||
@ -795,7 +798,14 @@ 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) {
|
||||
if
|
||||
/* col_tile.is_building() && */
|
||||
col_tile
|
||||
.plot
|
||||
.and_then(|p| self.plots[p].z_range())
|
||||
.zip(self.plots[plot].z_range())
|
||||
.map_or(false, |(a, b)| a.end > b.end)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,13 @@ impl Plot {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn z_range(&self) -> Option<Range<i32>> {
|
||||
match &self.kind {
|
||||
PlotKind::House(house) => Some(house.z_range()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> &PlotKind { &self.kind }
|
||||
|
||||
pub fn root_tile(&self) -> Vec2<i32> { self.root_tile }
|
||||
|
@ -52,7 +52,7 @@ impl House {
|
||||
door_tile: door_tile_pos,
|
||||
tile_aabr,
|
||||
bounds,
|
||||
alt: (land.get_alt_approx(site.tile_center_wpos(door_tile + door_dir)) + 1.0) as i32,
|
||||
alt: land.get_alt_approx(site.tile_center_wpos(door_tile + door_dir)) as i32,
|
||||
levels,
|
||||
overhang: if levels > 3 {
|
||||
// Overhangs of 3 at this building height are ill-advised.
|
||||
@ -80,8 +80,12 @@ impl House {
|
||||
front,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn z_range(&self) -> Range<i32> { self.alt..self.alt + self.levels as i32 * STOREY }
|
||||
}
|
||||
|
||||
const STOREY: i32 = 5;
|
||||
|
||||
impl Structure for House {
|
||||
fn render<F: FnMut(Primitive) -> Id<Primitive>, G: FnMut(Id<Primitive>, Fill)>(
|
||||
&self,
|
||||
@ -90,8 +94,8 @@ impl Structure for House {
|
||||
mut prim: F,
|
||||
mut fill: G,
|
||||
) {
|
||||
let storey = 5;
|
||||
let roof = storey * self.levels as i32;
|
||||
let storey = STOREY;
|
||||
let roof = storey * self.levels as i32 - 1;
|
||||
let foundations = 12;
|
||||
let alt = self.alt + 1;
|
||||
|
||||
@ -495,8 +499,8 @@ impl Structure for House {
|
||||
// Walls
|
||||
// For each storey...
|
||||
for i in 1..self.levels + 1 {
|
||||
let previous_height = (storey * (i as i32 - 1)).max(0);
|
||||
let height = storey * i as i32;
|
||||
let previous_height = (storey * (i as i32 - 1) - 1).max(-1);
|
||||
let height = storey * i as i32 - 1;
|
||||
let window_height = storey - 3;
|
||||
let storey_increase = (i as i32 - 1) * self.overhang;
|
||||
|
||||
@ -1482,7 +1486,7 @@ impl Structure for House {
|
||||
min: Vec2::new(stair_origin.x + 3, stair_origin.y).with_z(alt + previous_floor_height),
|
||||
max: Vec2::new(stair_origin.x + 10, stair_origin.y + stair_width).with_z(alt + previous_height + 1),
|
||||
},
|
||||
inset: storey + 1,
|
||||
inset: storey,
|
||||
dir: 0,
|
||||
})
|
||||
/*},
|
||||
@ -1492,7 +1496,7 @@ impl Structure for House {
|
||||
min: Vec2::new(stair_origin.x, stair_origin.y + 3).with_z(alt + previous_floor_height),
|
||||
max: Vec2::new(stair_origin.x + stair_width, stair_origin.y + 10).with_z(alt + previous_height + 1),
|
||||
},
|
||||
inset: storey + 1,
|
||||
inset: storey,
|
||||
dir: 0,
|
||||
})
|
||||
},
|
||||
@ -1502,7 +1506,7 @@ impl Structure for House {
|
||||
min: Vec2::new(stair_origin.x + 3, stair_origin.y).with_z(alt + previous_floor_height),
|
||||
max: Vec2::new(stair_origin.x + 10, stair_origin.y + stair_width).with_z(alt + previous_height + 1),
|
||||
},
|
||||
inset: storey + 1,
|
||||
inset: storey,
|
||||
dir: 0,
|
||||
})
|
||||
},
|
||||
@ -1512,7 +1516,7 @@ impl Structure for House {
|
||||
min: Vec2::new(stair_origin.x, stair_origin.y + 3).with_z(alt + previous_floor_height),
|
||||
max: Vec2::new(stair_origin.x + stair_width, stair_origin.y + 10).with_z(alt + previous_height + 1),
|
||||
},
|
||||
inset: storey + 1,
|
||||
inset: storey,
|
||||
dir: 0,
|
||||
})
|
||||
}*/
|
||||
@ -1561,7 +1565,7 @@ impl Structure for House {
|
||||
min: Vec2::new(stair_origin.x + 1, stair_origin.y + stair_width).with_z(alt + previous_floor_height),
|
||||
max: Vec2::new(stair_origin.x + 8, stair_origin.y + 2 * stair_width).with_z(alt + previous_height + 1),
|
||||
},
|
||||
inset: storey + 1,
|
||||
inset: storey,
|
||||
dir: 1,
|
||||
})
|
||||
/*},
|
||||
@ -1571,7 +1575,7 @@ impl Structure for House {
|
||||
min: Vec2::new(stair_origin.x + stair_width, stair_origin.y + 1).with_z(alt + previous_floor_height),
|
||||
max: Vec2::new(stair_origin.x + 2 * stair_width, stair_origin.y + 8).with_z(alt + previous_height + 1),
|
||||
},
|
||||
inset: storey + 1,
|
||||
inset: storey,
|
||||
dir: 1,
|
||||
})
|
||||
},
|
||||
@ -1581,7 +1585,7 @@ impl Structure for House {
|
||||
min: Vec2::new(stair_origin.x + 1, stair_origin.y + stair_width).with_z(alt + previous_floor_height),
|
||||
max: Vec2::new(stair_origin.x + 8, stair_origin.y + 2 * stair_width).with_z(alt + previous_height + 1),
|
||||
},
|
||||
inset: storey + 1,
|
||||
inset: storey,
|
||||
dir: 1,
|
||||
})
|
||||
},
|
||||
@ -1591,7 +1595,7 @@ impl Structure for House {
|
||||
min: Vec2::new(stair_origin.x + stair_width, stair_origin.y + 1).with_z(alt + previous_floor_height),
|
||||
max: Vec2::new(stair_origin.x + 2 * stair_width, stair_origin.y + 8).with_z(alt + previous_height + 1),
|
||||
},
|
||||
inset: storey + 1,
|
||||
inset: storey,
|
||||
dir: 1,
|
||||
})
|
||||
},
|
||||
@ -1638,7 +1642,7 @@ impl Structure for House {
|
||||
prim(Primitive::Empty)
|
||||
} else if i % 2 == 0 {
|
||||
prim(Primitive::Aabb(Aabb {
|
||||
min: Vec2::new(stair_origin.x, stair_origin.y)
|
||||
min: Vec2::new(stair_origin.x + 2, stair_origin.y)
|
||||
.with_z(alt + previous_floor_height + 1),
|
||||
max: Vec2::new(stair_origin.x + 9, stair_origin.y + stair_width)
|
||||
.with_z(alt + previous_height + 1),
|
||||
|
@ -207,7 +207,7 @@ impl Tile {
|
||||
|
||||
pub fn is_empty(&self) -> bool { self.kind == TileKind::Empty }
|
||||
|
||||
pub fn is_road(&self) -> bool { matches!(self.kind, TileKind::Road { .. }) }
|
||||
pub fn is_road(&self) -> bool { matches!(self.kind, TileKind::Plaza | TileKind::Road { .. }) }
|
||||
|
||||
pub fn is_obstacle(&self) -> bool {
|
||||
matches!(self.kind, TileKind::Hazard(_)) || self.is_building()
|
||||
|
Loading…
Reference in New Issue
Block a user