From 3f02aa513460f0d003f0e078854bba13794afe07 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 8 Nov 2020 23:19:07 +0000 Subject: [PATCH] Removed more redundant code, desert dunes, better bridges --- assets/voxygen/item_image_manifest.ron | 4 +- world/src/block/mod.rs | 6 +- world/src/civ/mod.rs | 6 +- world/src/column/mod.rs | 118 +++++++++++++------------ world/src/layer/mod.rs | 4 +- world/src/layer/scatter.rs | 2 +- world/src/layer/tree.rs | 22 ++--- world/src/sim/mod.rs | 27 +++--- world/src/site/settlement/mod.rs | 2 +- 9 files changed, 96 insertions(+), 95 deletions(-) diff --git a/assets/voxygen/item_image_manifest.ron b/assets/voxygen/item_image_manifest.ron index 8646e88f5a..d461084197 100644 --- a/assets/voxygen/item_image_manifest.ron +++ b/assets/voxygen/item_image_manifest.ron @@ -1264,7 +1264,7 @@ ), Consumable("SunflowerTea"): Png( "element.icons.item_sunflower_tea", - ), + ), // Throwables Throwable(Bomb): VoxTrans( "voxel.object.bomb", @@ -1344,7 +1344,7 @@ "voxel.object.potion_empty", (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8, ), - // Gliders + // Gliders Glider("Starter"): VoxTrans( "voxel.glider.glider_starter", (-2.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.9, diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index d19ab5569f..53ddc1cc73 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -107,7 +107,7 @@ impl<'a> BlockGen<'a> { let water = Block::new(BlockKind::Water, Rgb::zero()); let grass_depth = (1.5 + 2.0 * chaos).min(height - basement_height); - let block = if (wposf.z as f32) < height - grass_depth { + if (wposf.z as f32) < height - grass_depth { let stone_factor = (height - grass_depth - wposf.z as f32) * 0.15; let col = Lerp::lerp( sub_surface_color, @@ -169,9 +169,7 @@ impl<'a> BlockGen<'a> { } else { None } - }); - - block + }) } } diff --git a/world/src/civ/mod.rs b/world/src/civ/mod.rs index d49f610d4f..af33cfef87 100644 --- a/world/src/civ/mod.rs +++ b/world/src/civ/mod.rs @@ -646,16 +646,16 @@ fn walk_in_dir(sim: &WorldSim, a: Vec2, dir: Vec2) -> Option { let a_chunk = sim.get(a)?; let b_chunk = sim.get(a + dir)?; - let hill_cost = ((b_chunk.alt - a_chunk.alt).abs() / 2.5).powf(2.0); + let hill_cost = ((b_chunk.alt - a_chunk.alt).abs() / 5.0).powf(2.0); let water_cost = if b_chunk.river.near_water() { 50.0 } else { 0.0 - }; + } + (b_chunk.water_alt - b_chunk.alt + 8.0).clamped(0.0, 8.0) * 3.0; // Try not to path swamps / tidal areas let wild_cost = if b_chunk.path.0.is_way() { 0.0 // Traversing existing paths has no additional cost! } else { - 2.0 + 3.0 // + (1.0 - b_chunk.tree_density) * 20.0 // Prefer going through forests, for aesthetics }; Some(1.0 + hill_cost + water_cost + wild_cost) } else { diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 73bdd597ce..62c21f5b48 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -405,12 +405,6 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { river_overlap_distance_product / overlap_count } as f32; - let cliff_hill = (sim - .gen_ctx - .small_nz - .get((wposf_turb.div(128.0)).into_array()) as f32) - .mul(4.0); - let riverless_alt_delta = (sim.gen_ctx.small_nz.get( (wposf_turb.div(200.0 * (32.0 / TerrainChunkSize::RECT_SIZE.x as f64))).into_array(), ) as f32) @@ -440,9 +434,6 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { }) .unwrap_or(CONFIG.sea_level); - let is_cliffs = sim_chunk.is_cliffs; - let near_cliffs = sim_chunk.near_cliffs; - let river_gouge = 0.5; let (_in_water, water_dist, alt_, water_level, riverless_alt, warp_factor) = if let Some( (max_border_river_pos, river_chunk, max_border_river, max_border_river_dist), @@ -457,43 +448,44 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { max_border_river .river_kind .and_then(|river_kind| { - if let RiverKind::River { cross_section } = river_kind { - if max_border_river_dist.map(|(_, dist, _, _)| dist) - != Some(Vec2::zero()) - { - return None; - } - let ( - _, - _, - river_width, - (river_t, (river_pos, _), downhill_river_chunk), - ) = max_border_river_dist.unwrap(); - let river_alt = Lerp::lerp( - river_chunk.alt.max(river_chunk.water_alt), - downhill_river_chunk.alt.max(downhill_river_chunk.water_alt), - river_t as f32, - ); - let new_alt = river_alt - river_gouge; - let river_dist = wposf.distance(river_pos); - let river_height_factor = river_dist / (river_width * 0.5); + match river_kind { + RiverKind::River { cross_section } => { + if max_border_river_dist.map(|(_, dist, _, _)| dist) + != Some(Vec2::zero()) + { + return None; + } + let ( + _, + _, + river_width, + (river_t, (river_pos, _), downhill_river_chunk), + ) = max_border_river_dist.unwrap(); + let river_alt = Lerp::lerp( + river_chunk.alt.max(river_chunk.water_alt), + downhill_river_chunk.alt.max(downhill_river_chunk.water_alt), + river_t as f32, + ); + let new_alt = river_alt - river_gouge; + let river_dist = wposf.distance(river_pos); + let river_height_factor = river_dist / (river_width * 0.5); - let valley_alt = Lerp::lerp( - new_alt - cross_section.y.max(1.0), - new_alt - 1.0, - (river_height_factor * river_height_factor) as f32, - ); + let valley_alt = Lerp::lerp( + new_alt - cross_section.y.max(1.0), + new_alt - 1.0, + (river_height_factor * river_height_factor) as f32, + ); - Some(( - true, - Some((river_dist - river_width * 0.5) as f32), - valley_alt, - new_alt, - river_alt, - 0.0, - )) - } else { - None + Some(( + true, + Some((river_dist - river_width * 0.5) as f32), + valley_alt, + new_alt, + alt, //river_alt + cross_section.y.max(1.0), + 0.0, + )) + }, + _ => None, } }) .unwrap_or_else(|| { @@ -642,7 +634,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { } else { return ( true, - None, + Some(lake_dist as f32), alt_for_river, if in_bounds_ { downhill_water_alt.max(lake_water_alt) @@ -675,7 +667,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { Some((river_dist - river_width * 0.5) as f32), alt_for_river, downhill_water_alt, - alt_for_river, + alt, //alt_for_river, river_scale_factor as f32, ) }, @@ -686,7 +678,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { None, alt_for_river, downhill_water_alt, - alt_for_river, + alt, //alt_for_river, river_scale_factor as f32, )) }); @@ -704,7 +696,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { None, alt_for_river, downhill_water_alt, - alt_for_river, + alt, //alt_for_river, 1.0, ) }; @@ -729,6 +721,26 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { .max(0.0) .mul(8.0); + // Columns near water have a more stable temperature and so get pushed towards + // the average (0) + let temp = Lerp::lerp( + Lerp::lerp(temp, 0.0, 0.1), + temp, + water_dist + .map(|water_dist| water_dist / 20.0) + .unwrap_or(1.0) + .clamped(0.0, 1.0), + ); + // Columns near water get a humidity boost + let humidity = Lerp::lerp( + Lerp::lerp(humidity, 1.0, 0.1), + humidity, + water_dist + .map(|water_dist| water_dist / 20.0) + .unwrap_or(1.0) + .clamped(0.0, 1.0), + ); + let wposf3d = Vec3::new(wposf.x, wposf.y, alt as f64); let marble_small = (sim.gen_ctx.hill_nz.get((wposf3d.div(3.0)).into_array()) as f32) @@ -953,7 +965,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { let near_ocean = max_river.and_then(|(_, _, river_data, _)| { if (river_data.is_lake() || river_data.river_kind == Some(RiverKind::Ocean)) - && ((alt <= water_level.max(CONFIG.sea_level + 5.0) && !is_cliffs) || !near_cliffs) + && alt <= water_level.max(CONFIG.sea_level + 5.0) { Some(water_level) } else { @@ -1005,10 +1017,6 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { marble, marble_small, rock, - is_cliffs, - near_cliffs, - cliff_hill, - close_cliffs: sim.gen_ctx.cliff_gen.get(wpos), temp, humidity, spawn_rate, @@ -1037,10 +1045,6 @@ pub struct ColumnSample<'a> { pub marble: f32, pub marble_small: f32, pub rock: f32, - pub is_cliffs: bool, - pub near_cliffs: bool, - pub cliff_hill: f32, - pub close_cliffs: [(Vec2, u32); 9], pub temp: f32, pub humidity: f32, pub spawn_rate: f32, diff --git a/world/src/layer/mod.rs b/world/src/layer/mod.rs index 652bea0df0..77b9b1e1e0 100644 --- a/world/src/layer/mod.rs +++ b/world/src/layer/mod.rs @@ -33,7 +33,7 @@ pub struct Colors { const EMPTY_AIR: Block = Block::air(SpriteKind::Empty); -pub fn apply_paths_to<'a>(canvas: &mut Canvas) { +pub fn apply_paths_to(canvas: &mut Canvas) { let info = canvas.info(); canvas.foreach_col(|canvas, wpos2d, col| { let surface_z = col.riverless_alt.floor() as i32; @@ -106,7 +106,7 @@ pub fn apply_paths_to<'a>(canvas: &mut Canvas) { }); } -pub fn apply_caves_to<'a>(canvas: &mut Canvas) { +pub fn apply_caves_to(canvas: &mut Canvas) { let info = canvas.info(); canvas.foreach_col(|canvas, wpos2d, col| { let surface_z = col.riverless_alt.floor() as i32; diff --git a/world/src/layer/scatter.rs b/world/src/layer/scatter.rs index d5a533b7f8..d5e74015d3 100644 --- a/world/src/layer/scatter.rs +++ b/world/src/layer/scatter.rs @@ -8,7 +8,7 @@ fn close(x: f32, tgt: f32, falloff: f32) -> f32 { (1.0 - (x - tgt).abs() / falloff).max(0.0).powf(0.125) } const MUSH_FACT: f32 = 1.0e-4; // To balance everything around the mushroom spawning rate -pub fn apply_scatter_to<'a>(canvas: &mut Canvas) { +pub fn apply_scatter_to(canvas: &mut Canvas) { use SpriteKind::*; #[allow(clippy::type_complexity)] // TODO: Add back all sprites we had before diff --git a/world/src/layer/tree.rs b/world/src/layer/tree.rs index 520d2690c6..66f64def68 100644 --- a/world/src/layer/tree.rs +++ b/world/src/layer/tree.rs @@ -6,10 +6,7 @@ use crate::{ Canvas, CONFIG, }; use common::{ - terrain::{ - structure::Structure, - Block, - }, + terrain::{structure::Structure, Block}, vol::ReadVol, }; use lazy_static::lazy_static; @@ -34,7 +31,7 @@ static MODEL_RAND: RandomPerm = RandomPerm::new(0xDB21C052); static UNIT_CHOOSER: UnitChooser = UnitChooser::new(0x700F4EC7); static QUIRKY_RAND: RandomPerm = RandomPerm::new(0xA634460F); -pub fn apply_trees_to<'a>(canvas: &mut Canvas) { +pub fn apply_trees_to(canvas: &mut Canvas) { struct Tree { pos: Vec3, model: Arc, @@ -84,8 +81,10 @@ pub fn apply_trees_to<'a>(canvas: &mut Canvas) { ForestKind::Mangrove => &MANGROVE_TREES, } }; - models[(MODEL_RAND.get(seed.wrapping_mul(17)) / 13) as usize % models.len()] - .clone() + Arc::clone( + &models[(MODEL_RAND.get(seed.wrapping_mul(17)) / 13) as usize + % models.len()], + ) }, seed, units: UNIT_CHOOSER.get(seed), @@ -109,14 +108,11 @@ pub fn apply_trees_to<'a>(canvas: &mut Canvas) { ) + Vec3::unit_z() * (wpos.z - tree.pos.z); block_from_structure( info.index(), - if let Some(block) = tree.model - .get(model_pos) - .ok() - .copied() - { + if let Some(block) = tree.model.get(model_pos).ok().copied() { block } else { - // If we hit an inaccessible block, we're probably outside the model bounds. Skip this column. + // If we hit an inaccessible block, we're probably outside the model bounds. + // Skip this column. break; }, wpos, diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 5adf44d64d..fb5696f748 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -103,7 +103,6 @@ pub(crate) struct GenCtx { // Small amounts of noise for simulating rough terrain. pub small_nz: BasicMulti, pub rock_nz: HybridMulti, - pub cliff_nz: HybridMulti, pub warp_nz: FastNoise, pub tree_nz: BasicMulti, @@ -112,7 +111,6 @@ pub(crate) struct GenCtx { pub structure_gen: StructureGen2d, pub region_gen: StructureGen2d, - pub cliff_gen: StructureGen2d, pub fast_turb_x_nz: FastNoise, pub fast_turb_y_nz: FastNoise, @@ -503,7 +501,6 @@ impl WorldSim { small_nz: BasicMulti::new().set_octaves(2).set_seed(rng.gen()), rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(rng.gen()), - cliff_nz: HybridMulti::new().set_persistence(0.3).set_seed(rng.gen()), warp_nz: FastNoise::new(rng.gen()), tree_nz: BasicMulti::new() .set_octaves(12) @@ -514,7 +511,6 @@ impl WorldSim { structure_gen: StructureGen2d::new(rng.gen(), 32, 16), region_gen: StructureGen2d::new(rng.gen(), 400, 96), - cliff_gen: StructureGen2d::new(rng.gen(), 80, 56), humid_nz: Billow::new() .set_octaves(9) .set_persistence(0.4) @@ -2004,8 +2000,6 @@ pub struct SimChunk { pub temp: f32, pub humidity: f32, pub rockiness: f32, - pub is_cliffs: bool, - pub near_cliffs: bool, pub tree_density: f32, pub forest_kind: ForestKind, pub spawn_rate: f32, @@ -2095,10 +2089,6 @@ impl SimChunk { ) }; - //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(); // 0.5 + 0.5 * tanh(ln(1 / (1 - 0.1) - 1) / (2 * (sqrt(3)/pi))) @@ -2165,8 +2155,23 @@ impl SimChunk { .sub(0.5) .mul(0.95) .add(0.5) + * (1.0 - temp as f64) } as f32; + // Sand dunes (formed over a short period of time) + let alt = alt + + if river.near_water() { + 0.0 + } else { + let warp = Vec2::new( + gen_ctx.turb_x_nz.get(wposf.div(256.0).into_array()) as f32, + gen_ctx.turb_y_nz.get(wposf.div(256.0).into_array()) as f32, + ) * 192.0; + let dune_nz = (wposf.map(|e| e as f32) + warp).sum().div(100.0).sin() * 0.5 + 0.5; + let dune_scale = 16.0; + dune_nz * dune_scale * (temp - 0.75).clamped(0.0, 0.25) * 4.0 + }; + Self { chaos, flux, @@ -2185,8 +2190,6 @@ impl SimChunk { } else { 0.0 }, - is_cliffs: cliff > 0.5 && !is_underwater, - near_cliffs: cliff > 0.2, tree_density, forest_kind: if temp > CONFIG.temperate_temp { if temp > CONFIG.desert_temp { diff --git a/world/src/site/settlement/mod.rs b/world/src/site/settlement/mod.rs index 022f33bfb4..7142469469 100644 --- a/world/src/site/settlement/mod.rs +++ b/world/src/site/settlement/mod.rs @@ -93,7 +93,7 @@ pub fn center_of(p: [Vec2; 3]) -> Vec2 { impl WorldSim { fn can_host_settlement(&self, pos: Vec2) -> bool { self.get(pos) - .map(|chunk| !chunk.near_cliffs && !chunk.river.is_river() && !chunk.river.is_lake()) + .map(|chunk| !chunk.river.is_river() && !chunk.river.is_lake()) .unwrap_or(false) && self .get_gradient_approx(pos)