diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index e253ec43b1..6ab3d3eb71 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -44,6 +44,8 @@ impl<'a> SamplerMut for BlockGen<'a> { let ColumnSample { alt, chaos, + water_level, + river, surface_color, tree_density, forest_kind, @@ -107,6 +109,7 @@ impl<'a> SamplerMut for BlockGen<'a> { }; let height = alt + warp + cliff; + let water_height = water_level + warp; // Sample blocks @@ -138,7 +141,7 @@ impl<'a> SamplerMut for BlockGen<'a> { ); // Surface Some(Block::new(1, col.map(|e| (e * 255.0) as u8))) - } else if (wposf.z as f32) < CONFIG.sea_level { + } else if (wposf.z as f32) < water_height { // Ocean Some(water) } else { @@ -233,7 +236,8 @@ impl<'a> SamplerMut for BlockGen<'a> { match self.sample_column(Vec2::from(*tree_pos)) { Some(tree_sample) if tree_sample.tree_density - > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 => + > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 + && tree_sample.alt > tree_sample.water_level => { let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, tree_sample.alt as i32); diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 269dc2a3ff..f3c0591bdc 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -5,6 +5,7 @@ use common::{ }; use noise::NoiseFn; use std::{ + f32, ops::{Add, Div, Mul, Neg, Sub}, sync::Arc, }; @@ -42,12 +43,31 @@ impl<'a> Sampler for ColumnGen<'a> { let sim_chunk = sim.get(chunk_pos)?; - let alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? + const RIVER_PROPORTION: f32 = 0.025; + + let river = dryness + .abs() + .neg() + .add(RIVER_PROPORTION) + .div(RIVER_PROPORTION) + .max(0.0) + .mul((1.0 - (chaos - 0.15) * 20.0).max(0.0).min(1.0)); + + let riverless_alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? + (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32) .abs() .mul(chaos.max(0.2)) - .mul(64.0) - - dryness.abs().neg().add(0.03).max(0.0).mul(3000.0); + .mul(64.0); + + let alt = riverless_alt + - (1.0 - river) + .mul(f32::consts::PI) + .cos() + .add(1.0) + .mul(0.5) + .mul(24.0); + + let water_level = (riverless_alt - 4.0 - 5.0 * chaos).max(CONFIG.sea_level); let rock = (sim.gen_ctx.small_nz.get( Vec3::new(wposf.x, wposf.y, alt as f64) @@ -123,6 +143,8 @@ impl<'a> Sampler for ColumnGen<'a> { Some(ColumnSample { alt, chaos, + water_level, + river, surface_color: Rgb::lerp( sand, // Land @@ -142,7 +164,7 @@ impl<'a> Sampler for ColumnGen<'a> { (alt - CONFIG.sea_level - 0.2 * CONFIG.mountain_scale) / 180.0, ), // Beach - (alt - CONFIG.sea_level - 2.0) / 5.0, + ((alt - CONFIG.sea_level - 2.0) / 5.0).min(1.0 - river * 2.0), ), tree_density, forest_kind: sim_chunk.forest_kind, @@ -161,6 +183,8 @@ impl<'a> Sampler for ColumnGen<'a> { pub struct ColumnSample<'a> { pub alt: f32, pub chaos: f32, + pub water_level: f32, + pub river: f32, pub surface_color: Rgb, pub tree_density: f32, pub forest_kind: ForestKind, diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index c8c05bc9d2..60d0abcec2 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -25,6 +25,7 @@ pub(crate) struct GenCtx { pub alt_nz: HybridMulti, pub hill_nz: SuperSimplex, pub temp_nz: SuperSimplex, + pub dry_nz: BasicMulti, pub small_nz: BasicMulti, pub rock_nz: HybridMulti, pub cliff_nz: HybridMulti, @@ -56,16 +57,17 @@ impl WorldSim { .set_persistence(0.1) .set_seed(seed + 4), temp_nz: SuperSimplex::new().set_seed(seed + 5), - small_nz: BasicMulti::new().set_octaves(2).set_seed(seed + 6), - rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 7), - cliff_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 7), - warp_nz: BasicMulti::new().set_octaves(3).set_seed(seed + 8), + dry_nz: BasicMulti::new().set_seed(seed + 6), + small_nz: BasicMulti::new().set_octaves(2).set_seed(seed + 7), + rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 8), + cliff_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 9), + warp_nz: BasicMulti::new().set_octaves(3).set_seed(seed + 10), tree_nz: BasicMulti::new() .set_octaves(12) .set_persistence(0.75) - .set_seed(seed + 9), - cave_0_nz: SuperSimplex::new().set_seed(seed + 10), - cave_1_nz: SuperSimplex::new().set_seed(seed + 11), + .set_seed(seed + 12), + cave_0_nz: SuperSimplex::new().set_seed(seed + 13), + cave_1_nz: SuperSimplex::new().set_seed(seed + 14), tree_gen: StructureGen2d::new(seed, 32, 24), }; @@ -256,7 +258,18 @@ impl SimChunk { .add(0.3) .max(0.0); - let dryness = (gen_ctx.chaos_nz.get((wposf.div(1_000.0)).into_array()) as f32); + let dryness = (gen_ctx.dry_nz.get( + (wposf + .add(Vec2::new( + gen_ctx + .dry_nz + .get((wposf.add(10000.0).div(500.0)).into_array()) + * 150.0, + gen_ctx.dry_nz.get((wposf.add(0.0).div(500.0)).into_array()) * 150.0, + )) + .div(2_000.0)) + .into_array(), + ) as f32); let chaos = (gen_ctx.chaos_nz.get((wposf.div(4_000.0)).into_array()) as f32) .add(1.0) @@ -345,7 +358,7 @@ impl SimChunk { } pub fn get_min_z(&self) -> f32 { - self.alt - Z_TOLERANCE.0 * (self.chaos + 0.3) + self.alt - Z_TOLERANCE.0 * (self.chaos * 1.2 + 0.3) } pub fn get_max_z(&self) -> f32 {