diff --git a/assets/voxygen/voxel/sprite/grass/grass_snow_0.vox b/assets/voxygen/voxel/sprite/grass/grass_snow_0.vox new file mode 100644 index 0000000000..f91d3f6f24 --- /dev/null +++ b/assets/voxygen/voxel/sprite/grass/grass_snow_0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45ee10e5805fa443292b063410caa5f5a7b7b6a935731bc9079c4a4fa2693ce5 +size 55651 diff --git a/assets/voxygen/voxel/sprite/grass/grass_snow_1.vox b/assets/voxygen/voxel/sprite/grass/grass_snow_1.vox new file mode 100644 index 0000000000..3d2697d58d --- /dev/null +++ b/assets/voxygen/voxel/sprite/grass/grass_snow_1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89470bacf9a12f6f7473f7b61d4d0a8827d320f1b52d44d26fc199a554c7d53a +size 55663 diff --git a/assets/voxygen/voxel/sprite/grass/grass_snow_2.vox b/assets/voxygen/voxel/sprite/grass/grass_snow_2.vox new file mode 100644 index 0000000000..c501954b89 --- /dev/null +++ b/assets/voxygen/voxel/sprite/grass/grass_snow_2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c89055c2cd7f71975d0ddbfccbc3d5b96b15a158ba3f9f1000f36a4b7217ec3 +size 55663 diff --git a/assets/voxygen/voxel/sprite/grass/grass_snow_3.vox b/assets/voxygen/voxel/sprite/grass/grass_snow_3.vox new file mode 100644 index 0000000000..b1fe51ccbd --- /dev/null +++ b/assets/voxygen/voxel/sprite/grass/grass_snow_3.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acc14c82052df18f96d002ad401722ad53ce4decdb36ad02045346638be2003b +size 55643 diff --git a/assets/voxygen/voxel/sprite/grass/grass_snow_4.vox b/assets/voxygen/voxel/sprite/grass/grass_snow_4.vox new file mode 100644 index 0000000000..25881db9ff --- /dev/null +++ b/assets/voxygen/voxel/sprite/grass/grass_snow_4.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c1cbbd8090fa8e378055ebb191c8d528ab7e70215a3a171246cfa6332eb143c +size 55679 diff --git a/assets/voxygen/voxel/sprite/grass/grass_snow_5.vox b/assets/voxygen/voxel/sprite/grass/grass_snow_5.vox new file mode 100644 index 0000000000..20fd053c82 --- /dev/null +++ b/assets/voxygen/voxel/sprite/grass/grass_snow_5.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9bda5fd9430404feeb8b042e864528f9e9572bc00fb5d454bf546aadac509b5 +size 55767 diff --git a/assets/voxygen/voxel/sprite/grass/grass_snow_6.vox b/assets/voxygen/voxel/sprite/grass/grass_snow_6.vox new file mode 100644 index 0000000000..57ef237bce --- /dev/null +++ b/assets/voxygen/voxel/sprite/grass/grass_snow_6.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f285aebc92333f7d3a0970191ee398d22c850372504b9d38061cd8e07f566171 +size 55823 diff --git a/assets/voxygen/voxel/sprite/grass/grass_snow_7.vox b/assets/voxygen/voxel/sprite/grass/grass_snow_7.vox new file mode 100644 index 0000000000..1d6bab161a --- /dev/null +++ b/assets/voxygen/voxel/sprite/grass/grass_snow_7.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25b79468d0fb6080f41d98cc8db0e8a69aa5eb8fa2e74bdb31a1fa183d9a483b +size 55787 diff --git a/assets/voxygen/voxel/sprite/grass/grass_snow_8.vox b/assets/voxygen/voxel/sprite/grass/grass_snow_8.vox new file mode 100644 index 0000000000..ad5661ceb8 --- /dev/null +++ b/assets/voxygen/voxel/sprite/grass/grass_snow_8.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:803febeaed019bc690af3906a1cbcbaf8409388d265a23ff41d62f074b167ea8 +size 55791 diff --git a/assets/voxygen/voxel/sprite/grass/grass_snow_9.vox b/assets/voxygen/voxel/sprite/grass/grass_snow_9.vox new file mode 100644 index 0000000000..451d4252ea --- /dev/null +++ b/assets/voxygen/voxel/sprite/grass/grass_snow_9.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ffb358971c47cfd6819ea7971117c051dfde09feab2cb59ddc079a3fe6f236b +size 55787 diff --git a/common/src/terrain/block.rs b/common/src/terrain/block.rs index 39e940448b..ad2c551ffc 100644 --- a/common/src/terrain/block.rs +++ b/common/src/terrain/block.rs @@ -90,6 +90,7 @@ pub enum BlockKind { ShinyGem, DropGate, DropGateBottom, + GrassSnow, } impl fmt::Display for BlockKind { @@ -195,6 +196,7 @@ impl BlockKind { BlockKind::ShinyGem => true, BlockKind::DropGate => false, BlockKind::DropGateBottom => false, + BlockKind::GrassSnow => true, _ => false, } } @@ -294,6 +296,7 @@ impl BlockKind { BlockKind::ShinyGem => false, BlockKind::DropGate => false, BlockKind::DropGateBottom => false, + BlockKind::GrassSnow => false, _ => true, } } @@ -370,13 +373,14 @@ impl BlockKind { BlockKind::ShinyGem => false, BlockKind::DropGate => true, BlockKind::DropGateBottom => false, + BlockKind::GrassSnow => false, _ => true, } } pub fn is_explodable(&self) -> bool { match self { - BlockKind::Leaves | BlockKind::Grass | BlockKind::Rock => true, + BlockKind::Leaves | BlockKind::Grass | BlockKind::Rock | BlockKind::GrassSnow => true, _ => false, } } @@ -494,10 +498,9 @@ impl Block { | BlockKind::WardrobeSingle | BlockKind::WardrobeDouble | BlockKind::Pot - | BlockKind::DropGate + | BlockKind::DropGate | BlockKind::DropGateBottom | BlockKind::Door => Some(self.color[0] & 0b111), - _ => None, } } diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index 5f18cd4880..52438575bd 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -19,8 +19,8 @@ use crossbeam::channel; use dot_vox::DotVoxData; use hashbrown::HashMap; use std::{f32, fmt::Debug, i32, marker::PhantomData, time::Duration}; -use treeculler::{BVol, Frustum, AABB}; use tracing::warn; +use treeculler::{BVol, Frustum, AABB}; use vek::*; struct TerrainChunkData { @@ -359,6 +359,10 @@ fn sprite_config_for(kind: BlockKind) -> Option { variations: 1, wind_sway: 0.0, }), + BlockKind::GrassSnow => Some(SpriteConfig { + variations: 10, + wind_sway: 0.2, + }), _ => None, } } @@ -2759,6 +2763,87 @@ impl Terrain { Vec3::one(), ), ), + // Snow covered Grass + ( + (BlockKind::GrassSnow, 0), + make_models( + "voxygen.voxel.sprite.grass.grass_snow_0", + Vec3::new(-2.5, -2.5, 0.0), + Vec3::one(), + ), + ), + ( + (BlockKind::GrassSnow, 1), + make_models( + "voxygen.voxel.sprite.grass.grass_snow_1", + Vec3::new(-2.5, -2.5, 0.0), + Vec3::one(), + ), + ), + ( + (BlockKind::GrassSnow, 2), + make_models( + "voxygen.voxel.sprite.grass.grass_snow_2", + Vec3::new(-2.5, -2.5, 0.0), + Vec3::one(), + ), + ), + ( + (BlockKind::GrassSnow, 3), + make_models( + "voxygen.voxel.sprite.grass.grass_snow_3", + Vec3::new(-2.5, -2.5, 0.0), + Vec3::one(), + ), + ), + ( + (BlockKind::GrassSnow, 4), + make_models( + "voxygen.voxel.sprite.grass.grass_snow_4", + Vec3::new(-2.5, -2.5, 0.0), + Vec3::one(), + ), + ), + ( + (BlockKind::GrassSnow, 5), + make_models( + "voxygen.voxel.sprite.grass.grass_snow_5", + Vec3::new(-2.5, -2.5, 0.0), + Vec3::one(), + ), + ), + ( + (BlockKind::GrassSnow, 6), + make_models( + "voxygen.voxel.sprite.grass.grass_snow_6", + Vec3::new(-2.5, -2.5, 0.0), + Vec3::one(), + ), + ), + ( + (BlockKind::GrassSnow, 7), + make_models( + "voxygen.voxel.sprite.grass.grass_snow_7", + Vec3::new(-2.5, -2.5, 0.0), + Vec3::one(), + ), + ), + ( + (BlockKind::GrassSnow, 8), + make_models( + "voxygen.voxel.sprite.grass.grass_snow_8", + Vec3::new(-2.5, -2.5, 0.0), + Vec3::one(), + ), + ), + ( + (BlockKind::GrassSnow, 9), + make_models( + "voxygen.voxel.sprite.grass.grass_snow_9", + Vec3::new(-2.5, -2.5, 0.0), + Vec3::one(), + ), + ), ] .into_iter() .collect(), @@ -3142,7 +3227,6 @@ impl Terrain { let dist_sqrd = Vec2::from(focus_pos).distance_squared(chunk_center); if dist_sqrd < sprite_render_distance.powf(2.0) { for (kind, instances) in &chunk.sprite_instances { - if let Some(models) = self.sprite_models.get(&kind) { renderer.render_sprites( if dist_sqrd < sprite_high_detail_distance.powf(2.0) { diff --git a/world/src/layer/mod.rs b/world/src/layer/mod.rs index 7cd5ceb449..6d989cb4f6 100644 --- a/world/src/layer/mod.rs +++ b/world/src/layer/mod.rs @@ -1,26 +1,27 @@ use crate::{ column::ColumnSample, - util::{RandomField, Sampler}, sim::SimChunk, + util::{RandomField, Sampler}, Index, }; use common::{ - assets, - comp, + assets, comp, + generation::{ChunkSupplement, EntityInfo}, lottery::Lottery, terrain::{Block, BlockKind}, vol::{BaseVol, ReadVol, RectSizedVol, Vox, WriteVol}, - generation::{ChunkSupplement, EntityInfo}, }; use noise::NoiseFn; +use rand::prelude::*; use std::{ f32, ops::{Mul, Sub}, }; use vek::*; -use rand::prelude::*; -fn close(x: f32, tgt: f32, falloff: f32) -> f32 { (1.0 - (x - tgt).abs() / falloff).max(0.0).powf(0.5) } +fn close(x: f32, tgt: f32, falloff: f32) -> f32 { + (1.0 - (x - tgt).abs() / falloff).max(0.0).powf(0.5) +} pub fn apply_scatter_to<'a>( wpos2d: Vec2, @@ -32,11 +33,50 @@ pub fn apply_scatter_to<'a>( use BlockKind::*; let scatter: &[(_, fn(&SimChunk) -> (f32, Option<(f32, f32)>))] = &[ // (density, Option<(wavelen, threshold)>) - (BlueFlower, |c| (close(c.temp, -0.3, 0.7).min(close(c.humidity, 0.6, 0.35)) * 0.05, Some((48.0, 0.6)))), - (PinkFlower, |c| (close(c.temp, 0.15, 0.5).min(close(c.humidity, 0.6, 0.35)) * 0.05, Some((48.0, 0.6)))), - (DeadBush, |c| (close(c.temp, 0.8, 0.3).min(close(c.humidity, 0.0, 0.4)) * 0.015, None)), + (BlueFlower, |c| { + ( + close(c.temp, -0.3, 0.7).min(close(c.humidity, 0.6, 0.35)) * 0.05, + Some((48.0, 0.6)), + ) + }), + (PinkFlower, |c| { + ( + close(c.temp, 0.15, 0.5).min(close(c.humidity, 0.6, 0.35)) * 0.05, + Some((48.0, 0.6)), + ) + }), + (DeadBush, |c| { + ( + close(c.temp, 0.8, 0.3).min(close(c.humidity, 0.0, 0.4)) * 0.015, + None, + ) + }), (Twigs, |c| ((c.tree_density - 0.5).max(0.0) * 0.0025, None)), (Stones, |c| ((c.rockiness - 0.5).max(0.0) * 0.005, None)), + (ShortGrass, |c| { + ( + close(c.temp, 0.3, 0.4).min(close(c.humidity, 0.6, 0.35)) * 0.05, + Some((48.0, 0.4)), + ) + }), + (MediumGrass, |c| { + ( + close(c.temp, 0.0, 0.6).min(close(c.humidity, 0.6, 0.35)) * 0.05, + Some((48.0, 0.2)), + ) + }), + (LongGrass, |c| { + ( + close(c.temp, 0.4, 0.4).min(close(c.humidity, 0.8, 0.2)) * 0.05, + Some((48.0, 0.1)), + ) + }), + (GrassSnow, |c| { + ( + close(c.temp, -0.4, 0.4).min(close(c.rockiness, 0.0, 0.5)), + Some((48.0, 0.6)), + ) + }), ]; for y in 0..vol.size_xy().y as i32 { @@ -52,29 +92,38 @@ pub fn apply_scatter_to<'a>( continue; }; - let bk = scatter - .iter() - .enumerate() - .find_map(|(i, (bk, f))| { - let (density, patch) = f(chunk); - if density <= 0.0 || patch.map(|(wavelen, threshold)| index - .noise - .scatter_nz - .get(wpos2d.map(|e| e as f64 / wavelen as f64 + i as f64 * 43.0).into_array()) < threshold as f64) + let bk = scatter.iter().enumerate().find_map(|(i, (bk, f))| { + let (density, patch) = f(chunk); + if density <= 0.0 + || patch + .map(|(wavelen, threshold)| { + index.noise.scatter_nz.get( + wpos2d + .map(|e| e as f64 / wavelen as f64 + i as f64 * 43.0) + .into_array(), + ) < threshold as f64 + }) .unwrap_or(false) - || !RandomField::new(i as u32).chance(Vec3::new(wpos2d.x, wpos2d.y, 0), density) - { - None - } else { - Some(*bk) - } - }); + || !RandomField::new(i as u32).chance(Vec3::new(wpos2d.x, wpos2d.y, 0), density) + { + None + } else { + Some(*bk) + } + }); if let Some(bk) = bk { let mut z = col_sample.alt as i32 - 4; for _ in 0..8 { - if vol.get(Vec3::new(offs.x, offs.y, z)).map(|b| !b.is_solid()).unwrap_or(true) { - let _ = vol.set(Vec3::new(offs.x, offs.y, z), Block::new(bk, Rgb::broadcast(0))); + if vol + .get(Vec3::new(offs.x, offs.y, z)) + .map(|b| !b.is_solid()) + .unwrap_or(true) + { + let _ = vol.set( + Vec3::new(offs.x, offs.y, z), + Block::new(bk, Rgb::broadcast(0)), + ); break; } z += 1; @@ -295,57 +344,61 @@ pub fn apply_caves_supplement<'a>( if RandomField::new(index.seed).chance(wpos2d.into(), 0.00005) && cave_base < surface_z as i32 - 40 { - let entity = EntityInfo::at(Vec3::new(wpos2d.x as f32, wpos2d.y as f32, cave_base as f32)) - .with_alignment(comp::Alignment::Enemy) - .with_body(match rng.gen_range(0, 6) { - 0 => { - let species = match rng.gen_range(0, 2) { - 0 => comp::quadruped_small::Species::Truffler, - _ => comp::quadruped_small::Species::Hyena, - }; - comp::quadruped_small::Body::random_with(rng, &species).into() - }, - 1 => { - let species = match rng.gen_range(0, 3) { - 0 => comp::quadruped_medium::Species::Tarasque, - 1 => comp::quadruped_medium::Species::Frostfang, - _ => comp::quadruped_medium::Species::Bonerattler, - }; - comp::quadruped_medium::Body::random_with(rng, &species).into() - }, - 2 => { - let species = match rng.gen_range(0, 3) { - 0 => comp::quadruped_low::Species::Maneater, - 1 => comp::quadruped_low::Species::Rocksnapper, - _ => comp::quadruped_low::Species::Salamander, - }; - comp::quadruped_low::Body::random_with(rng, &species).into() - }, - 3 => { - let species = match rng.gen_range(0, 3) { - 0 => comp::critter::Species::Fungome, - 1 => comp::critter::Species::Axolotl, - _ => comp::critter::Species::Rat, - }; - comp::critter::Body::random_with(rng, &species).into() - }, - 4 => { - let species = match rng.gen_range(0, 1) { - _ => comp::golem::Species::StoneGolem, - }; - comp::golem::Body::random_with(rng, &species).into() - }, - _ => { - let species = match rng.gen_range(0, 4) { - 0 => comp::biped_large::Species::Ogre, - 1 => comp::biped_large::Species::Cyclops, - 2 => comp::biped_large::Species::Wendigo, - _ => comp::biped_large::Species::Troll, - }; - comp::biped_large::Body::random_with(rng, &species).into() - }, - }) - .with_automatic_name(); + let entity = EntityInfo::at(Vec3::new( + wpos2d.x as f32, + wpos2d.y as f32, + cave_base as f32, + )) + .with_alignment(comp::Alignment::Enemy) + .with_body(match rng.gen_range(0, 6) { + 0 => { + let species = match rng.gen_range(0, 2) { + 0 => comp::quadruped_small::Species::Truffler, + _ => comp::quadruped_small::Species::Hyena, + }; + comp::quadruped_small::Body::random_with(rng, &species).into() + }, + 1 => { + let species = match rng.gen_range(0, 3) { + 0 => comp::quadruped_medium::Species::Tarasque, + 1 => comp::quadruped_medium::Species::Frostfang, + _ => comp::quadruped_medium::Species::Bonerattler, + }; + comp::quadruped_medium::Body::random_with(rng, &species).into() + }, + 2 => { + let species = match rng.gen_range(0, 3) { + 0 => comp::quadruped_low::Species::Maneater, + 1 => comp::quadruped_low::Species::Rocksnapper, + _ => comp::quadruped_low::Species::Salamander, + }; + comp::quadruped_low::Body::random_with(rng, &species).into() + }, + 3 => { + let species = match rng.gen_range(0, 3) { + 0 => comp::critter::Species::Fungome, + 1 => comp::critter::Species::Axolotl, + _ => comp::critter::Species::Rat, + }; + comp::critter::Body::random_with(rng, &species).into() + }, + 4 => { + let species = match rng.gen_range(0, 1) { + _ => comp::golem::Species::StoneGolem, + }; + comp::golem::Body::random_with(rng, &species).into() + }, + _ => { + let species = match rng.gen_range(0, 4) { + 0 => comp::biped_large::Species::Ogre, + 1 => comp::biped_large::Species::Cyclops, + 2 => comp::biped_large::Species::Wendigo, + _ => comp::biped_large::Species::Troll, + }; + comp::biped_large::Body::random_with(rng, &species).into() + }, + }) + .with_automatic_name(); supplement.add_entity(entity); }