Merge branch 'bd/1455' into 'master'

#1455 | Sprites now only spawn on designated block types

See merge request veloren/veloren!3434
This commit is contained in:
Marcel 2022-06-20 19:24:52 +00:00
commit 4e6e754494

View File

@ -1,5 +1,5 @@
use crate::{column::ColumnSample, sim::SimChunk, Canvas, CONFIG}; use crate::{column::ColumnSample, sim::SimChunk, Canvas, CONFIG};
use common::terrain::{Block, SpriteKind}; use common::terrain::{Block, BlockKind, SpriteKind};
use noise::NoiseFn; use noise::NoiseFn;
use rand::prelude::*; use rand::prelude::*;
use std::f32; use std::f32;
@ -21,15 +21,23 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
use WaterMode::*; use WaterMode::*;
use SpriteKind::*; use SpriteKind::*;
struct ScatterConfig {
kind: SpriteKind,
water_mode: WaterMode,
permit: fn(BlockKind) -> bool,
f: fn(&SimChunk, &ColumnSample) -> (f32, Option<(f32, f32, f32)>),
}
// TODO: Add back all sprites we had before // TODO: Add back all sprites we had before
let scatter: &[( let scatter: &[ScatterConfig] = &[
_,
WaterMode,
fn(&SimChunk, &ColumnSample) -> (f32, Option<(f32, f32, f32)>),
)] = &[
// (density, Option<(base_density_proportion, wavelen, threshold)>) // (density, Option<(base_density_proportion, wavelen, threshold)>)
// Flowers // Flowers
(BlueFlower, Ground, |_, col| { ScatterConfig {
kind: BlueFlower,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, CONFIG.temperate_temp, 0.7).min(close( close(col.temp, CONFIG.temperate_temp, 0.7).min(close(
col.humidity, col.humidity,
@ -40,8 +48,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 256.0, * 256.0,
Some((0.0, 256.0, 0.25)), Some((0.0, 256.0, 0.25)),
) )
}), },
(PinkFlower, Ground, |_, col| { },
ScatterConfig {
kind: PinkFlower,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density * col.tree_density
@ -49,8 +62,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 350.0, * 350.0,
Some((0.0, 100.0, 0.1)), Some((0.0, 100.0, 0.1)),
) )
}), },
(PurpleFlower, Ground, |_, col| { },
ScatterConfig {
kind: PurpleFlower,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, CONFIG.temperate_temp, 0.7).min(close( close(col.temp, CONFIG.temperate_temp, 0.7).min(close(
col.humidity, col.humidity,
@ -61,8 +79,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 350.0, * 350.0,
Some((0.0, 100.0, 0.1)), Some((0.0, 100.0, 0.1)),
) )
}), },
(RedFlower, Ground, |_, col| { },
ScatterConfig {
kind: RedFlower,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, CONFIG.tropical_temp, 0.7).min(close( close(col.temp, CONFIG.tropical_temp, 0.7).min(close(
col.humidity, col.humidity,
@ -73,8 +96,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 350.0, * 350.0,
Some((0.0, 100.0, 0.1)), Some((0.0, 100.0, 0.1)),
) )
}), },
(WhiteFlower, Ground, |_, col| { },
ScatterConfig {
kind: WhiteFlower,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density * col.tree_density
@ -82,8 +110,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 350.0, * 350.0,
Some((0.0, 100.0, 0.1)), Some((0.0, 100.0, 0.1)),
) )
}), },
(YellowFlower, Ground, |_, col| { },
ScatterConfig {
kind: YellowFlower,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density * col.tree_density
@ -91,8 +124,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 350.0, * 350.0,
Some((0.0, 100.0, 0.1)), Some((0.0, 100.0, 0.1)),
) )
}), },
(Cotton, Ground, |_, col| { },
ScatterConfig {
kind: Cotton,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, CONFIG.temperate_temp, 0.7).min(close( close(col.temp, CONFIG.temperate_temp, 0.7).min(close(
col.humidity, col.humidity,
@ -103,8 +141,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 75.0, * 75.0,
Some((0.0, 256.0, 0.25)), Some((0.0, 256.0, 0.25)),
) )
}), },
(Sunflower, Ground, |_, col| { },
ScatterConfig {
kind: Sunflower,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density * col.tree_density
@ -112,8 +155,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 350.0, * 350.0,
Some((0.0, 100.0, 0.15)), Some((0.0, 100.0, 0.15)),
) )
}), },
(WildFlax, Ground, |_, col| { },
ScatterConfig {
kind: WildFlax,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density * col.tree_density
@ -121,41 +169,66 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 600.0, * 600.0,
Some((0.0, 100.0, 0.15)), Some((0.0, 100.0, 0.15)),
) )
}), },
},
// Herbs and Spices // Herbs and Spices
(LingonBerry, Ground, |_, col| { ScatterConfig {
kind: LingonBerry,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.5)) close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.5))
* MUSH_FACT * MUSH_FACT
* 2.5, * 2.5,
None, None,
) )
}), },
(LeafyPlant, Ground, |_, col| { },
ScatterConfig {
kind: LeafyPlant,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.3)) close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.3))
* GRASS_FACT * GRASS_FACT
* 4.0, * 4.0,
None, None,
) )
}), },
(JungleLeafyPlant, Ground, |_, col| { },
ScatterConfig {
kind: JungleLeafyPlant,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* GRASS_FACT * GRASS_FACT
* 32.0, * 32.0,
Some((0.15, 64.0, 0.2)), Some((0.15, 64.0, 0.2)),
) )
}), },
(Fern, Ground, |_, col| { },
ScatterConfig {
kind: Fern,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.forest_hum, 0.5)) close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.forest_hum, 0.5))
* GRASS_FACT * GRASS_FACT
* 0.25, * 0.25,
Some((0.0, 64.0, 0.2)), Some((0.0, 64.0, 0.2)),
) )
}), },
(JungleFern, Ground, |_, col| { },
ScatterConfig {
kind: JungleFern,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density * col.tree_density
@ -163,8 +236,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 200.0, * 200.0,
Some((0.0, 84.0, 0.35)), Some((0.0, 84.0, 0.35)),
) )
}), },
(Blueberry, Ground, |_, col| { },
ScatterConfig {
kind: Blueberry,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, CONFIG.temperate_temp, 0.5).min(close( close(col.temp, CONFIG.temperate_temp, 0.5).min(close(
col.humidity, col.humidity,
@ -174,8 +252,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 0.3, * 0.3,
None, None,
) )
}), },
(Pumpkin, Ground, |_, col| { },
ScatterConfig {
kind: Pumpkin,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, CONFIG.temperate_temp, 0.5).min(close( close(col.temp, CONFIG.temperate_temp, 0.5).min(close(
col.humidity, col.humidity,
@ -185,65 +268,124 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 500.0, * 500.0,
Some((0.0, 512.0, 0.05)), Some((0.0, 512.0, 0.05)),
) )
}), },
},
// Collectable Objects // Collectable Objects
// Only spawn twigs in temperate forests // Only spawn twigs in temperate forests
(Twigs, Ground, |_, col| { ScatterConfig {
kind: Twigs,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
(col.tree_density * 1.25 - 0.25).powf(0.5).max(0.0) * 0.75e-3, (col.tree_density * 1.25 - 0.25).powf(0.5).max(0.0) * 0.75e-3,
None, None,
) )
}), },
},
// Only spawn logs in temperate forests (arbitrarily set to ~20% twig density) // Only spawn logs in temperate forests (arbitrarily set to ~20% twig density)
(Wood, Ground, |_, col| { ScatterConfig {
kind: Wood,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
(col.tree_density * 1.25 - 0.25).powf(0.5).max(0.0) * 0.15e-3, (col.tree_density * 1.25 - 0.25).powf(0.5).max(0.0) * 0.15e-3,
None, None,
) )
}), },
(Stones, Ground, |chunk, _| { },
((chunk.rockiness - 0.5).max(0.025) * 1.0e-3, None) ScatterConfig {
}), kind: Stones,
(Copper, Ground, |chunk, _| { water_mode: Ground,
((chunk.rockiness - 0.5).max(0.0) * 1.5e-3, None) permit: |b| {
}), matches!(
(Tin, Ground, |chunk, _| { b,
((chunk.rockiness - 0.5).max(0.0) * 1.5e-3, None) BlockKind::Earth | BlockKind::Grass | BlockKind::Rock | BlockKind::Sand
}), )
},
f: |chunk, _| ((chunk.rockiness - 0.5).max(0.025) * 1.0e-3, None),
},
ScatterConfig {
kind: Copper,
water_mode: Ground,
permit: |b| {
matches!(
b,
BlockKind::Earth | BlockKind::Grass | BlockKind::Rock | BlockKind::Sand
)
},
f: |chunk, _| ((chunk.rockiness - 0.5).max(0.0) * 1.5e-3, None),
},
ScatterConfig {
kind: Tin,
water_mode: Ground,
permit: |b| {
matches!(
b,
BlockKind::Earth | BlockKind::Grass | BlockKind::Rock | BlockKind::Sand
)
},
f: |chunk, _| ((chunk.rockiness - 0.5).max(0.0) * 1.5e-3, None),
},
// Don't spawn Mushrooms in snowy regions // Don't spawn Mushrooms in snowy regions
(Mushroom, Ground, |_, col| { ScatterConfig {
kind: Mushroom,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.forest_hum, 0.35)) close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.forest_hum, 0.35))
* MUSH_FACT, * MUSH_FACT,
None, None,
) )
}), },
},
// Grass // Grass
(ShortGrass, Ground, |_, col| { ScatterConfig {
kind: ShortGrass,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.2, 0.75).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.2, 0.75).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* GRASS_FACT * GRASS_FACT
* 150.0, * 150.0,
Some((0.3, 64.0, 0.3)), Some((0.3, 64.0, 0.3)),
) )
}), },
(MediumGrass, Ground, |_, col| { },
ScatterConfig {
kind: MediumGrass,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.2, 0.6).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.2, 0.6).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* GRASS_FACT * GRASS_FACT
* 120.0, * 120.0,
Some((0.3, 64.0, 0.3)), Some((0.3, 64.0, 0.3)),
) )
}), },
(LongGrass, Ground, |_, col| { },
ScatterConfig {
kind: LongGrass,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.3, 0.35).min(close(col.humidity, CONFIG.jungle_hum, 0.3)) close(col.temp, 0.3, 0.35).min(close(col.humidity, CONFIG.jungle_hum, 0.3))
* GRASS_FACT * GRASS_FACT
* 150.0, * 150.0,
Some((0.1, 48.0, 0.3)), Some((0.1, 48.0, 0.3)),
) )
}), },
(JungleRedGrass, Ground, |_, col| { },
ScatterConfig {
kind: JungleRedGrass,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density * col.tree_density
@ -251,7 +393,8 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 350.0, * 350.0,
Some((0.0, 128.0, 0.25)), Some((0.0, 128.0, 0.25)),
) )
}), },
},
// Jungle Sprites // Jungle Sprites
// (LongGrass, Ground, |c, col| { // (LongGrass, Ground, |c, col| {
// ( // (
@ -271,7 +414,11 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
None, None,
) )
}),*/ }),*/
(GrassSnow, Ground, |_, col| { ScatterConfig {
kind: GrassSnow,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, CONFIG.snow_temp - 0.2, 0.4).min(close( close(col.temp, CONFIG.snow_temp - 0.2, 0.4).min(close(
col.humidity, col.humidity,
@ -281,8 +428,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* 100.0, * 100.0,
Some((0.0, 48.0, 0.2)), Some((0.0, 48.0, 0.2)),
) )
}), },
(Moonbell, Ground, |_, col| { },
ScatterConfig {
kind: Moonbell,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, CONFIG.snow_temp - 0.2, 0.4).min(close( close(col.temp, CONFIG.snow_temp - 0.2, 0.4).min(close(
col.humidity, col.humidity,
@ -291,9 +443,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)) * 0.003, )) * 0.003,
Some((0.0, 48.0, 0.2)), Some((0.0, 48.0, 0.2)),
) )
}), },
},
// Savanna Plants // Savanna Plants
(SavannaGrass, Ground, |_, col| { ScatterConfig {
kind: SavannaGrass,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
{ {
let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25); let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25);
@ -302,8 +459,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.15, 64.0, 0.2)), Some((0.15, 64.0, 0.2)),
) )
}), },
(TallSavannaGrass, Ground, |_, col| { },
ScatterConfig {
kind: TallSavannaGrass,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
{ {
let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25); let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25);
@ -312,8 +474,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.1, 48.0, 0.2)), Some((0.1, 48.0, 0.2)),
) )
}), },
(RedSavannaGrass, Ground, |_, col| { },
ScatterConfig {
kind: RedSavannaGrass,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
{ {
let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25); let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25);
@ -322,8 +489,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.15, 48.0, 0.25)), Some((0.15, 48.0, 0.25)),
) )
}), },
(SavannaBush, Ground, |_, col| { },
ScatterConfig {
kind: SavannaBush,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
{ {
let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25); let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25);
@ -332,52 +504,94 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.1, 96.0, 0.15)), Some((0.1, 96.0, 0.15)),
) )
}), },
},
// Desert Plants // Desert Plants
(DeadBush, Ground, |_, col| { ScatterConfig {
kind: DeadBush,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 1.0, 0.95).min(close(col.humidity, 0.0, 0.3)) * MUSH_FACT * 7.5, close(col.temp, 1.0, 0.95).min(close(col.humidity, 0.0, 0.3)) * MUSH_FACT * 7.5,
None, None,
) )
}), },
(Pyrebloom, Ground, |_, col| { },
ScatterConfig {
kind: Pyrebloom,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 1.0, 0.95).min(close(col.humidity, 0.0, 0.3)) * MUSH_FACT * 0.35, close(col.temp, 1.0, 0.95).min(close(col.humidity, 0.0, 0.3))
* MUSH_FACT
* 0.35,
None, None,
) )
}), },
(LargeCactus, Ground, |_, col| { },
ScatterConfig {
kind: LargeCactus,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 1.5, close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 1.5,
None, None,
) )
}), },
(RoundCactus, Ground, |_, col| { },
ScatterConfig {
kind: RoundCactus,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5, close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5,
None, None,
) )
}), },
(ShortCactus, Ground, |_, col| { },
ScatterConfig {
kind: ShortCactus,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5, close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5,
None, None,
) )
}), },
(MedFlatCactus, Ground, |_, col| { },
ScatterConfig {
kind: MedFlatCactus,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5, close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5,
None, None,
) )
}), },
(ShortFlatCactus, Ground, |_, col| { },
ScatterConfig {
kind: ShortFlatCactus,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5, close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5,
None, None,
) )
}), },
},
// Underwater chests // Underwater chests
(ChestBuried, Underwater, |_, col| { ScatterConfig {
kind: ChestBuried,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth | BlockKind::Sand),
f: |_, col| {
( (
MUSH_FACT MUSH_FACT
* 1.0e-6 * 1.0e-6
@ -388,9 +602,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
None, None,
) )
}), },
},
// Underwater mud piles // Underwater mud piles
(Mud, Underwater, |_, col| { ScatterConfig {
kind: Mud,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth),
f: |_, col| {
( (
MUSH_FACT MUSH_FACT
* 1.0e-3 * 1.0e-3
@ -401,9 +620,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
None, None,
) )
}), },
},
// Underwater grass // Underwater grass
(GrassBlue, Underwater, |_, col| { ScatterConfig {
kind: GrassBlue,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
MUSH_FACT MUSH_FACT
* 250.0 * 250.0
@ -414,9 +638,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 100.0, 0.15)), Some((0.0, 100.0, 0.15)),
) )
}), },
},
// seagrass // seagrass
(Seagrass, Underwater, |_, col| { ScatterConfig {
kind: Seagrass,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, CONFIG.temperate_temp, 0.8) close(col.temp, CONFIG.temperate_temp, 0.8)
* MUSH_FACT * MUSH_FACT
@ -430,22 +659,34 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 150.0, 0.3)), Some((0.0, 150.0, 0.3)),
) )
}), },
},
// seagrass, coastal patches // seagrass, coastal patches
(Seagrass, Underwater, |_, col| { ScatterConfig {
kind: Seagrass,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
MUSH_FACT MUSH_FACT
* 600.0 * 600.0
* if col.water_level <= CONFIG.sea_level && (col.water_level - col.alt) < 3.0 { * if col.water_level <= CONFIG.sea_level
&& (col.water_level - col.alt) < 3.0
{
1.0 1.0
} else { } else {
0.0 0.0
}, },
Some((0.0, 150.0, 0.4)), Some((0.0, 150.0, 0.4)),
) )
}), },
},
// scattered seaweed (temperate species) // scattered seaweed (temperate species)
(SeaweedTemperate, Underwater, |_, col| { ScatterConfig {
kind: SeaweedTemperate,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, CONFIG.temperate_temp, 0.8) close(col.temp, CONFIG.temperate_temp, 0.8)
* MUSH_FACT * MUSH_FACT
@ -459,9 +700,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 500.0, 0.75)), Some((0.0, 500.0, 0.75)),
) )
}), },
},
// scattered seaweed (tropical species) // scattered seaweed (tropical species)
(SeaweedTropical, Underwater, |_, col| { ScatterConfig {
kind: SeaweedTropical,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 1.0, 0.95) close(col.temp, 1.0, 0.95)
* MUSH_FACT * MUSH_FACT
@ -475,9 +721,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 500.0, 0.75)), Some((0.0, 500.0, 0.75)),
) )
}), },
},
// Caulerpa lentillifera algae patch // Caulerpa lentillifera algae patch
(SeaGrapes, Underwater, |_, col| { ScatterConfig {
kind: SeaGrapes,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth),
f: |_, col| {
( (
MUSH_FACT MUSH_FACT
* 250.0 * 250.0
@ -490,9 +741,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 100.0, 0.15)), Some((0.0, 100.0, 0.15)),
) )
}), },
},
// Caulerpa prolifera algae patch // Caulerpa prolifera algae patch
(WavyAlgae, Underwater, |_, col| { ScatterConfig {
kind: WavyAlgae,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth),
f: |_, col| {
( (
MUSH_FACT MUSH_FACT
* 250.0 * 250.0
@ -505,9 +761,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 100.0, 0.15)), Some((0.0, 100.0, 0.15)),
) )
}), },
},
// Mermaids' fan algae patch // Mermaids' fan algae patch
(MermaidsFan, Underwater, |_, col| { ScatterConfig {
kind: MermaidsFan,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth),
f: |_, col| {
( (
close(col.temp, 1.0, 0.95) close(col.temp, 1.0, 0.95)
* MUSH_FACT * MUSH_FACT
@ -521,9 +782,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 50.0, 0.10)), Some((0.0, 50.0, 0.10)),
) )
}), },
},
// Sea anemones // Sea anemones
(SeaAnemone, Underwater, |_, col| { ScatterConfig {
kind: SeaAnemone,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth),
f: |_, col| {
( (
close(col.temp, CONFIG.temperate_temp, 0.8) close(col.temp, CONFIG.temperate_temp, 0.8)
* MUSH_FACT * MUSH_FACT
@ -537,9 +803,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 100.0, 0.3)), Some((0.0, 100.0, 0.3)),
) )
}), },
},
// Giant Kelp // Giant Kelp
(GiantKelp, Underwater, |_, col| { ScatterConfig {
kind: GiantKelp,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth),
f: |_, col| {
( (
close(col.temp, CONFIG.temperate_temp, 0.8) close(col.temp, CONFIG.temperate_temp, 0.8)
* MUSH_FACT * MUSH_FACT
@ -553,9 +824,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 200.0, 0.4)), Some((0.0, 200.0, 0.4)),
) )
}), },
},
// Bull Kelp // Bull Kelp
(BullKelp, Underwater, |_, col| { ScatterConfig {
kind: BullKelp,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth),
f: |_, col| {
( (
close(col.temp, CONFIG.temperate_temp, 0.7) close(col.temp, CONFIG.temperate_temp, 0.7)
* MUSH_FACT * MUSH_FACT
@ -569,9 +845,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 75.0, 0.3)), Some((0.0, 75.0, 0.3)),
) )
}), },
},
// Stony Corals // Stony Corals
(StonyCoral, Underwater, |_, col| { ScatterConfig {
kind: StonyCoral,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth),
f: |_, col| {
( (
close(col.temp, 1.0, 0.9) close(col.temp, 1.0, 0.9)
* MUSH_FACT * MUSH_FACT
@ -585,9 +866,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 120.0, 0.4)), Some((0.0, 120.0, 0.4)),
) )
}), },
},
// Soft Corals // Soft Corals
(SoftCoral, Underwater, |_, col| { ScatterConfig {
kind: SoftCoral,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth),
f: |_, col| {
( (
close(col.temp, 1.0, 0.9) close(col.temp, 1.0, 0.9)
* MUSH_FACT * MUSH_FACT
@ -601,9 +887,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
Some((0.0, 120.0, 0.4)), Some((0.0, 120.0, 0.4)),
) )
}), },
},
// Seashells // Seashells
(Seashells, Underwater, |c, col| { ScatterConfig {
kind: Seashells,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth),
f: |c, col| {
( (
(c.rockiness - 0.5).max(0.0) (c.rockiness - 0.5).max(0.0)
* 1.0e-3 * 1.0e-3
@ -616,8 +907,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
None, None,
) )
}), },
(Stones, Underwater, |c, col| { },
ScatterConfig {
kind: Stones,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Earth),
f: |c, col| {
( (
(c.rockiness - 0.5).max(0.0) (c.rockiness - 0.5).max(0.0)
* 1.0e-3 * 1.0e-3
@ -628,9 +924,14 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}, },
None, None,
) )
}), },
},
//River-related scatter //River-related scatter
(LillyPads, Floating, |_, col| { ScatterConfig {
kind: LillyPads,
water_mode: Floating,
permit: |_| true,
f: |_, col| {
( (
close(col.temp, 0.2, 0.6).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.2, 0.6).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* GRASS_FACT * GRASS_FACT
@ -641,8 +942,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
.map_or(0.0, |d| 1.0 / (1.0 + (d.abs() * 0.4).powi(2))), .map_or(0.0, |d| 1.0 / (1.0 + (d.abs() * 0.4).powi(2))),
Some((0.0, 128.0, 0.35)), Some((0.0, 128.0, 0.35)),
) )
}), },
(Reed, Underwater, |_, col| { },
ScatterConfig {
kind: Reed,
water_mode: Underwater,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.temp, 0.2, 0.6).min(close(col.humidity, CONFIG.jungle_hum, 0.4)) close(col.temp, 0.2, 0.6).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* GRASS_FACT * GRASS_FACT
@ -653,8 +959,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
.map_or(0.0, |d| 1.0 / (1.0 + (d.abs() * 0.40).powi(2))), .map_or(0.0, |d| 1.0 / (1.0 + (d.abs() * 0.40).powi(2))),
Some((0.2, 128.0, 0.5)), Some((0.2, 128.0, 0.5)),
) )
}), },
(Reed, Ground, |_, col| { },
ScatterConfig {
kind: Reed,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
close(col.humidity, CONFIG.jungle_hum, 0.9) close(col.humidity, CONFIG.jungle_hum, 0.9)
* col * col
@ -664,8 +975,13 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* ((col.alt - CONFIG.sea_level) / 12.0).clamped(0.0, 1.0), * ((col.alt - CONFIG.sea_level) / 12.0).clamped(0.0, 1.0),
Some((0.2, 128.0, 0.5)), Some((0.2, 128.0, 0.5)),
) )
}), },
(Bamboo, Ground, |_, col| { },
ScatterConfig {
kind: Bamboo,
water_mode: Ground,
permit: |b| matches!(b, BlockKind::Grass),
f: |_, col| {
( (
0.014 0.014
* close(col.humidity, CONFIG.jungle_hum, 0.9) * close(col.humidity, CONFIG.jungle_hum, 0.9)
@ -676,16 +992,29 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
* ((col.alt - CONFIG.sea_level) / 12.0).clamped(0.0, 1.0), * ((col.alt - CONFIG.sea_level) / 12.0).clamped(0.0, 1.0),
Some((0.2, 128.0, 0.5)), Some((0.2, 128.0, 0.5)),
) )
}), },
},
]; ];
canvas.foreach_col(|canvas, wpos2d, col| { canvas.foreach_col(|canvas, wpos2d, col| {
let underwater = col.water_level.floor() > col.alt; let underwater = col.water_level.floor() > col.alt;
let kind = scatter let kind = scatter.iter().enumerate().find_map(
.iter() |(
.enumerate() i,
.find_map(|(i, (kind, water_mode, f))| { ScatterConfig {
kind,
water_mode,
permit,
f,
},
)| {
let block_kind = canvas
.get(Vec3::new(wpos2d.x, wpos2d.y, col.alt as i32))
.kind();
if !permit(block_kind) {
return None;
}
let (density, patch) = f(canvas.chunk(), col); let (density, patch) = f(canvas.chunk(), col);
let density = patch let density = patch
.map(|(base_density_prop, wavelen, threshold)| { .map(|(base_density_prop, wavelen, threshold)| {
@ -715,7 +1044,8 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
} else { } else {
None None
} }
}); },
);
if let Some((kind, water_mode)) = kind { if let Some((kind, water_mode)) = kind {
let (alt, is_under): (_, fn(Block) -> bool) = match water_mode { let (alt, is_under): (_, fn(Block) -> bool) = match water_mode {