Fixed path irregularities, better bridges

This commit is contained in:
Joshua Barretto 2020-04-13 21:37:47 +01:00
parent e352858c03
commit a51d214c21
7 changed files with 65 additions and 33 deletions

View File

@ -66,6 +66,7 @@ impl<'a> BlockGen<'a> {
// Conservative range of radius: [8, 47]
let radius = RandomField::new(seed + 2).get(cliff_pos3d) % 48 + 8;
if cliff_sample.water_dist.map(|d| d > radius as f32).unwrap_or(true) {
max_height.max(
if cliff_pos.map(|e| e as f32).distance_squared(wpos)
< (radius as f32 + tolerance).powf(2.0)
@ -75,6 +76,9 @@ impl<'a> BlockGen<'a> {
0.0
},
)
} else {
max_height
}
},
_ => max_height,
},

View File

@ -28,6 +28,7 @@ pub fn structure_gen<'a>(
if (st_sample.tree_density as f64) < random_seed
|| st_sample.alt < st_sample.water_level
|| st_sample.spawn_rate < 0.5
|| st_sample.water_dist.map(|d| d < 8.0).unwrap_or(false)
{
return None;
}

View File

@ -95,9 +95,11 @@ impl Civs {
let wpos = site.center * Vec2::from(TerrainChunkSize::RECT_SIZE).map(|e: u32| e as i32);
// Flatten ground
let flatten_radius = 12.0;
let flatten_radius = 10.0;
if let Some(center_alt) = ctx.sim.get_alt_approx(wpos) {
for pos in Spiral2d::new().map(|offs| site.center + offs).take(radius.pow(2) as usize) {
for offs in Spiral2d::new().take(radius.pow(2) as usize) {
let center_alt = center_alt + if offs.magnitude_squared() <= 6i32.pow(2) { 16.0 } else { 0.0 }; // Raise the town centre up a little
let pos = site.center + offs;
let factor = (1.0 - (site.center - pos).map(|e| e as f32).magnitude() / flatten_radius) * 1.15;
ctx.sim
.get_mut(pos)

View File

@ -679,7 +679,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
Some((river_dist - river_width * 0.5) as f32),
alt_for_river.min(lake_water_alt - 1.0 - river_gouge),
lake_water_alt - river_gouge,
alt_for_river.min(lake_water_alt - 1.0),
alt_for_river.max(lake_water_alt),
0.0,
));
}
@ -753,7 +753,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
Some(lake_dist as f32),
alt_for_river.min(lake_water_alt - 1.0 - river_gouge),
lake_water_alt - river_gouge,
alt_for_river.min(lake_water_alt - 1.0),
alt_for_river.max(lake_water_alt),
0.0,
));
}
@ -774,7 +774,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
alt.min(lake_water_alt - 1.0 - river_gouge),
downhill_water_alt.max(lake_water_alt)
- river_gouge,
alt.min(lake_water_alt - 1.0),
alt.max(lake_water_alt),
0.0,
));
} else {

View File

@ -1867,7 +1867,8 @@ impl SimChunk {
)
};
let cliff = gen_ctx.cliff_nz.get((wposf.div(2048.0)).into_array()) as f32 + chaos * 0.2;
//let cliff = gen_ctx.cliff_nz.get((wposf.div(2048.0)).into_array()) as f32 + chaos * 0.2;
let cliff = 0.0; // Disable cliffs
// Logistic regression. Make sure x ∈ (0, 1).
let logit = |x: f64| x.ln() - x.neg().ln_1p();

View File

@ -11,6 +11,20 @@ use super::{
super::skeleton::*,
};
const COLOR_THEMES: [Rgb<u8>; 11] = [
Rgb::new(0x1D, 0x4D, 0x45),
Rgb::new(0xB3, 0x7D, 0x60),
Rgb::new(0xAC, 0x5D, 0x26),
Rgb::new(0x32, 0x46, 0x6B),
Rgb::new(0x2B, 0x19, 0x0F),
Rgb::new(0x93, 0x78, 0x51),
Rgb::new(0x92, 0x57, 0x24),
Rgb::new(0x4A, 0x4E, 0x4E),
Rgb::new(0x2F, 0x32, 0x47),
Rgb::new(0x8F, 0x35, 0x43),
Rgb::new(0x6D, 0x1E, 0x3A),
];
pub struct House {
roof_color: Rgb<u8>,
noise: RandomField,
@ -116,11 +130,10 @@ impl Archetype for House {
};
let this = Self {
roof_color: Rgb::new(
rng.gen_range(50, 200),
rng.gen_range(50, 200),
rng.gen_range(50, 200),
),
roof_color: COLOR_THEMES
.choose(rng)
.unwrap()
.map(|e| e.saturating_add(rng.gen_range(0, 20)) - 10),
noise: RandomField::new(rng.gen()),
roof_ribbing: rng.gen(),
roof_ribbing_diagonal: rng.gen(),
@ -141,7 +154,7 @@ impl Archetype for House {
let make_block = |r, g, b| {
let nz = self.noise.get(Vec3::new(center_offset.x, center_offset.y, z * 8));
BlockMask::new(Block::new(BlockKind::Normal, Rgb::new(r, g, b) + (nz & 0x0F) as u8 - 8), 2)
BlockMask::new(Block::new(BlockKind::Normal, Rgb::new(r, g, b).map(|e: u8| e.saturating_add((nz & 0x0F) as u8).saturating_sub(8))), 2)
};
let facade_layer = 3;

View File

@ -251,7 +251,7 @@ impl Settlement {
}
pub fn place_town(&mut self, ctx: &mut GenCtx<impl Rng>) {
const PLOT_COUNT: usize = 2;
const PLOT_COUNT: usize = 3;
let mut origin = Vec2::new(ctx.rng.gen_range(-2, 3), ctx.rng.gen_range(-2, 3));
@ -273,6 +273,7 @@ impl Settlement {
}
// Boundary wall
/*
let spokes = CARDINALS
.iter()
.filter_map(|dir| {
@ -316,6 +317,7 @@ impl Settlement {
}
self.land
.write_path(&wall_path, WayKind::Wall, buildable, true);
*/
}
pub fn place_buildings(&mut self, ctx: &mut GenCtx<impl Rng>) {
@ -326,10 +328,11 @@ impl Settlement {
};
for tile in Spiral2d::new().map(|offs| town_center + offs).take(16usize.pow(2)) {
for _ in 0..ctx.rng.gen_range(1, 5) {
for _ in 0..10 {
// This is a stupid way to decide how to place buildings
for _ in 0..ctx.rng.gen_range(2, 5) {
for _ in 0..25 {
let house_pos = tile.map(|e| e * AREA_SIZE as i32 + AREA_SIZE as i32 / 2)
+ Vec2::<i32>::zero().map(|_| ctx.rng.gen_range(-(AREA_SIZE as i32) / 2, AREA_SIZE as i32) / 2);
+ Vec2::<i32>::zero().map(|_| ctx.rng.gen_range(-(AREA_SIZE as i32) / 2, AREA_SIZE as i32 / 2));
let tile_pos = house_pos.map(|e| e.div_euclid(AREA_SIZE as i32));
if !matches!(self.land.plot_at(tile_pos), Some(Plot::Town))
@ -481,20 +484,23 @@ impl Settlement {
// Try to use the column at the centre of the path for sampling to make them flatter
let col = get_column(offs + (nearest.floor().map(|e| e as i32) - rpos)).unwrap_or(col_sample);
let bridge_offset = if let Some(water_dist) = col.water_dist {
((water_dist.max(0.0) * 0.2).min(f32::consts::PI).cos() + 1.0) * 5.0
let (bridge_offset, depth) = if let Some(water_dist) = col.water_dist {
(
((water_dist.max(0.0) * 0.2).min(f32::consts::PI).cos() + 1.0) * 5.0,
((1.0 - ((water_dist + 2.0) * 0.3).min(0.0).cos().abs()) * (col.riverless_alt + 5.0 - col.alt).max(0.0) * 1.75 + 3.0) as i32,
)
} else {
0.0
(0.0, 3)
};
let surface_z = (col.riverless_alt + bridge_offset).floor() as i32;
for z in inset - 3..inset {
for z in inset - depth..inset {
vol.set(
Vec3::new(offs.x, offs.y, surface_z + z),
if bridge_offset >= 2.0 {
if bridge_offset >= 2.0 && dist >= 2.5 || z < inset - 1 {
Block::new(BlockKind::Normal, noisy_color(Rgb::new(80, 80, 100), 8))
} else {
Block::new(BlockKind::Normal, noisy_color(Rgb::new(90, 70, 50), 8))
Block::new(BlockKind::Normal, noisy_color(Rgb::new(80, 50, 30), 8))
},
);
}
@ -622,7 +628,10 @@ impl Settlement {
Some(Plot::Dirt) => return Some(Rgb::new(90, 70, 50)),
Some(Plot::Grass) => return Some(Rgb::new(100, 200, 0)),
Some(Plot::Water) => return Some(Rgb::new(100, 150, 250)),
Some(Plot::Town) => return Some(Rgb::new(130, 120, 80)),
Some(Plot::Town) => return Some(Rgb::new(150, 110, 60)
.map2(Rgb::iota(), |e: u8, i: i32| e
.saturating_add((self.noise.get(Vec3::new(pos.x, pos.y, i * 5)) % 16) as u8)
.saturating_sub(8))),
Some(Plot::Field { seed, .. }) => {
let furrow_dirs = [
Vec2::new(1, 0),
@ -760,7 +769,9 @@ impl Land {
let proj_point = line.projected_point(pos.map(|e| e as f32));
let dist = proj_point.distance(pos.map(|e| e as f32));
if dist < way.width() {
sample.way = Some((way, dist, proj_point));
sample.way = sample.way
.filter(|(_, d, _)| *d < dist)
.or(Some((way, dist, proj_point)));
}
}
}