Added floating scatter

This commit is contained in:
Joshua Barretto 2021-10-27 21:46:17 +01:00 committed by DemonicOnPc
parent 7438252560
commit 6b4abddc4e

View File

@ -1,5 +1,5 @@
use crate::{column::ColumnSample, sim::SimChunk, Canvas, CONFIG};
use common::terrain::SpriteKind;
use common::terrain::{Block, SpriteKind};
use noise::NoiseFn;
use rand::prelude::*;
use std::f32;
@ -13,17 +13,24 @@ const MUSH_FACT: f32 = 1.0e-4; // To balance things around the mushroom spawning
const GRASS_FACT: f32 = 1.0e-3; // To balance things around the grass spawning rate
const DEPTH_WATER_NORM: f32 = 15.0; // Water depth at which regular underwater sprites start spawning
pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
enum WaterMode {
Underwater,
Floating,
Surface,
}
use WaterMode::*;
use SpriteKind::*;
#[allow(clippy::type_complexity)]
// TODO: Add back all sprites we had before
let scatter: &[(
_,
bool,
WaterMode,
fn(&SimChunk, &ColumnSample) -> (f32, Option<(f32, f32, f32)>),
)] = &[
// (density, Option<(base_density_proportion, wavelen, threshold)>)
// Flowers
(BlueFlower, false, |_, col| {
(BlueFlower, Surface, |_, col| {
(
close(col.temp, CONFIG.temperate_temp, 0.7).min(close(
col.humidity,
@ -35,7 +42,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.0, 256.0, 0.25)),
)
}),
(PinkFlower, false, |_, col| {
(PinkFlower, Surface, |_, col| {
(
close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density
@ -44,7 +51,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.0, 100.0, 0.1)),
)
}),
(PurpleFlower, false, |_, col| {
(PurpleFlower, Surface, |_, col| {
(
close(col.temp, CONFIG.temperate_temp, 0.7).min(close(
col.humidity,
@ -56,7 +63,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.0, 100.0, 0.1)),
)
}),
(RedFlower, false, |_, col| {
(RedFlower, Surface, |_, col| {
(
close(col.temp, CONFIG.tropical_temp, 0.7).min(close(
col.humidity,
@ -68,7 +75,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.0, 100.0, 0.1)),
)
}),
(WhiteFlower, false, |_, col| {
(WhiteFlower, Surface, |_, col| {
(
close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density
@ -77,7 +84,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.0, 100.0, 0.1)),
)
}),
(YellowFlower, false, |_, col| {
(YellowFlower, Surface, |_, col| {
(
close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density
@ -86,7 +93,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.0, 100.0, 0.1)),
)
}),
(Cotton, false, |_, col| {
(Cotton, Surface, |_, col| {
(
close(col.temp, CONFIG.temperate_temp, 0.7).min(close(
col.humidity,
@ -98,7 +105,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.0, 256.0, 0.25)),
)
}),
(Sunflower, false, |_, col| {
(Sunflower, Surface, |_, col| {
(
close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density
@ -107,7 +114,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.0, 100.0, 0.15)),
)
}),
(WildFlax, false, |_, col| {
(WildFlax, Surface, |_, col| {
(
close(col.temp, 0.0, 0.7).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* col.tree_density
@ -117,7 +124,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Herbs and Spices
(LingonBerry, false, |_, col| {
(LingonBerry, Surface, |_, col| {
(
close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.5))
* MUSH_FACT
@ -125,7 +132,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
None,
)
}),
(LeafyPlant, false, |_, col| {
(LeafyPlant, Surface, |_, col| {
(
close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.jungle_hum, 0.3))
* GRASS_FACT
@ -133,7 +140,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
None,
)
}),
(Fern, false, |_, col| {
(Fern, Surface, |_, col| {
(
close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.forest_hum, 0.5))
* GRASS_FACT
@ -141,7 +148,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.0, 64.0, 0.2)),
)
}),
(Blueberry, false, |_, col| {
(Blueberry, Surface, |_, col| {
(
close(col.temp, CONFIG.temperate_temp, 0.5).min(close(
col.humidity,
@ -152,7 +159,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
None,
)
}),
(Pumpkin, false, |_, col| {
(Pumpkin, Surface, |_, col| {
(
close(col.temp, CONFIG.temperate_temp, 0.5).min(close(
col.humidity,
@ -165,23 +172,23 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
}),
// Collectable Objects
// Only spawn twigs in temperate forests
(Twigs, false, |_, col| {
(Twigs, Surface, |_, col| {
(
(col.tree_density * 1.25 - 0.25).powf(0.5).max(0.0) * 0.75e-3,
None,
)
}),
(Stones, false, |chunk, _| {
(Stones, Surface, |chunk, _| {
((chunk.rockiness - 0.5).max(0.025) * 1.0e-3, None)
}),
(Copper, false, |chunk, _| {
(Copper, Surface, |chunk, _| {
((chunk.rockiness - 0.5).max(0.0) * 1.5e-3, None)
}),
(Tin, false, |chunk, _| {
(Tin, Surface, |chunk, _| {
((chunk.rockiness - 0.5).max(0.0) * 1.5e-3, None)
}),
// Don't spawn Mushrooms in snowy regions
(Mushroom, false, |_, col| {
(Mushroom, Surface, |_, col| {
(
close(col.temp, 0.3, 0.4).min(close(col.humidity, CONFIG.forest_hum, 0.35))
* MUSH_FACT,
@ -189,7 +196,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Grass
(ShortGrass, false, |_, col| {
(ShortGrass, Surface, |_, col| {
(
close(col.temp, 0.2, 0.75).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* GRASS_FACT
@ -197,7 +204,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.3, 64.0, 0.3)),
)
}),
(MediumGrass, false, |_, col| {
(MediumGrass, Surface, |_, col| {
(
close(col.temp, 0.2, 0.6).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* GRASS_FACT
@ -205,7 +212,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.3, 64.0, 0.3)),
)
}),
(LongGrass, false, |_, col| {
(LongGrass, Surface, |_, col| {
(
close(col.temp, 0.3, 0.35).min(close(col.humidity, CONFIG.jungle_hum, 0.3))
* GRASS_FACT
@ -214,7 +221,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Jungle Sprites
// (LongGrass, false, |c, col| {
// (LongGrass, Surface, |c, col| {
// (
// close(col.temp, CONFIG.tropical_temp, 0.4).min(close(
// col.humidity,
@ -224,7 +231,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
// Some((0.0, 60.0, 5.0)),
// )
// }),
/*(WheatGreen, false, |c, col| {
/*(WheatGreen, Surface, |c, col| {
(
close(col.temp, 0.4, 0.2).min(close(col.humidity, CONFIG.forest_hum, 0.1))
* MUSH_FACT
@ -232,7 +239,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
None,
)
}),*/
(GrassSnow, false, |_, col| {
(GrassSnow, Surface, |_, col| {
(
close(col.temp, CONFIG.snow_temp - 0.2, 0.4).min(close(
col.humidity,
@ -243,7 +250,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.0, 48.0, 0.2)),
)
}),
(Moonbell, false, |_, col| {
(Moonbell, Surface, |_, col| {
(
close(col.temp, CONFIG.snow_temp - 0.2, 0.4).min(close(
col.humidity,
@ -254,7 +261,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Savanna Plants
(SavannaGrass, false, |_, col| {
(SavannaGrass, Surface, |_, col| {
(
{
let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25);
@ -264,7 +271,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.15, 64.0, 0.2)),
)
}),
(TallSavannaGrass, false, |_, col| {
(TallSavannaGrass, Surface, |_, col| {
(
{
let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25);
@ -274,7 +281,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.1, 48.0, 0.2)),
)
}),
(RedSavannaGrass, false, |_, col| {
(RedSavannaGrass, Surface, |_, col| {
(
{
let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25);
@ -284,7 +291,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
Some((0.15, 48.0, 0.25)),
)
}),
(SavannaBush, false, |_, col| {
(SavannaBush, Surface, |_, col| {
(
{
let savanna = close(col.temp, 1.0, 0.4) * close(col.humidity, 0.2, 0.25);
@ -295,49 +302,49 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Desert Plants
(DeadBush, false, |_, col| {
(DeadBush, Surface, |_, col| {
(
close(col.temp, 1.0, 0.95).min(close(col.humidity, 0.0, 0.3)) * MUSH_FACT * 7.5,
None,
)
}),
(Pyrebloom, false, |_, col| {
(Pyrebloom, Surface, |_, col| {
(
close(col.temp, 1.0, 0.95).min(close(col.humidity, 0.0, 0.3)) * MUSH_FACT * 0.35,
None,
)
}),
(LargeCactus, false, |_, col| {
(LargeCactus, Surface, |_, col| {
(
close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 1.5,
None,
)
}),
(RoundCactus, false, |_, col| {
(RoundCactus, Surface, |_, col| {
(
close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5,
None,
)
}),
(ShortCactus, false, |_, col| {
(ShortCactus, Surface, |_, col| {
(
close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5,
None,
)
}),
(MedFlatCactus, false, |_, col| {
(MedFlatCactus, Surface, |_, col| {
(
close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5,
None,
)
}),
(ShortFlatCactus, false, |_, col| {
(ShortFlatCactus, Surface, |_, col| {
(
close(col.temp, 1.0, 0.25).min(close(col.humidity, 0.0, 0.1)) * MUSH_FACT * 2.5,
None,
)
}),
(Reed, false, |_, col| {
(Reed, Surface, |_, col| {
(
close(col.humidity, CONFIG.jungle_hum, 0.9)
* col
@ -349,7 +356,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Underwater chests
(ChestBuried, true, |_, col| {
(ChestBuried, Underwater, |_, col| {
(
MUSH_FACT
* 1.0e-6
@ -362,7 +369,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Underwater mud piles
(Mud, true, |_, col| {
(Mud, Underwater, |_, col| {
(
MUSH_FACT
* 1.0e-3
@ -375,7 +382,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Underwater grass
(GrassBlue, true, |_, col| {
(GrassBlue, Underwater, |_, col| {
(
MUSH_FACT
* 250.0
@ -388,7 +395,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// seagrass
(Seagrass, true, |_, col| {
(Seagrass, Underwater, |_, col| {
(
close(col.temp, CONFIG.temperate_temp, 0.8)
* MUSH_FACT
@ -404,7 +411,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// seagrass, coastal patches
(Seagrass, true, |_, col| {
(Seagrass, Underwater, |_, col| {
(
MUSH_FACT
* 600.0
@ -417,7 +424,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// scattered seaweed (temperate species)
(SeaweedTemperate, true, |_, col| {
(SeaweedTemperate, Underwater, |_, col| {
(
close(col.temp, CONFIG.temperate_temp, 0.8)
* MUSH_FACT
@ -433,7 +440,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// scattered seaweed (tropical species)
(SeaweedTropical, true, |_, col| {
(SeaweedTropical, Underwater, |_, col| {
(
close(col.temp, 1.0, 0.95)
* MUSH_FACT
@ -449,7 +456,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Caulerpa lentillifera algae patch
(SeaGrapes, true, |_, col| {
(SeaGrapes, Underwater, |_, col| {
(
MUSH_FACT
* 250.0
@ -464,7 +471,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Caulerpa prolifera algae patch
(WavyAlgae, true, |_, col| {
(WavyAlgae, Underwater, |_, col| {
(
MUSH_FACT
* 250.0
@ -479,7 +486,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Mermaids' fan algae patch
(MermaidsFan, true, |_, col| {
(MermaidsFan, Underwater, |_, col| {
(
close(col.temp, 1.0, 0.95)
* MUSH_FACT
@ -495,7 +502,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Sea anemones
(SeaAnemone, true, |_, col| {
(SeaAnemone, Underwater, |_, col| {
(
close(col.temp, CONFIG.temperate_temp, 0.8)
* MUSH_FACT
@ -511,7 +518,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Giant Kelp
(GiantKelp, true, |_, col| {
(GiantKelp, Underwater, |_, col| {
(
close(col.temp, CONFIG.temperate_temp, 0.8)
* MUSH_FACT
@ -527,7 +534,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Bull Kelp
(BullKelp, true, |_, col| {
(BullKelp, Underwater, |_, col| {
(
close(col.temp, CONFIG.temperate_temp, 0.7)
* MUSH_FACT
@ -543,7 +550,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Stony Corals
(StonyCoral, true, |_, col| {
(StonyCoral, Underwater, |_, col| {
(
close(col.temp, 1.0, 0.9)
* MUSH_FACT
@ -559,7 +566,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Soft Corals
(SoftCoral, true, |_, col| {
(SoftCoral, Underwater, |_, col| {
(
close(col.temp, 1.0, 0.9)
* MUSH_FACT
@ -575,7 +582,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
)
}),
// Seashells
(Seashells, true, |c, col| {
(Seashells, Underwater, |c, col| {
(
(c.rockiness - 0.5).max(0.0)
* 1.0e-3
@ -589,7 +596,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
None,
)
}),
(Stones, true, |c, col| {
(Stones, Underwater, |c, col| {
(
(c.rockiness - 0.5).max(0.0)
* 1.0e-3
@ -601,6 +608,15 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
None,
)
}),
(CavernLillypadBlue, Floating, |_, col| {
(
close(col.temp, 0.2, 0.6).min(close(col.humidity, CONFIG.jungle_hum, 0.4))
* GRASS_FACT
* 120.0
* ((col.alt - CONFIG.sea_level) / 12.0).clamped(0.0, 1.0),
Some((0.0, 256.0, 0.25)),
)
}),
];
canvas.foreach_col(|canvas, wpos2d, col| {
@ -609,7 +625,7 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
let kind = scatter
.iter()
.enumerate()
.find_map(|(i, (kind, is_underwater, f))| {
.find_map(|(i, (kind, water_mode, f))| {
let (density, patch) = f(canvas.chunk(), col);
let density = patch
.map(|(base_density_prop, wavelen, threshold)| {
@ -633,30 +649,29 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
.unwrap_or(density);
if density > 0.0
&& rng.gen::<f32>() < density //RandomField::new(i as u32).chance(Vec3::new(wpos2d.x, wpos2d.y, 0), density)
&& underwater == *is_underwater
&& matches!(&water_mode, Underwater | Floating) == underwater
{
Some(*kind)
Some((*kind, water_mode))
} else {
None
}
});
if let Some(kind) = kind {
let alt = col.alt as i32;
if let Some((kind, water_mode)) = kind {
let (alt, is_under): (_, fn(Block) -> bool) = match water_mode {
Surface | Underwater => (col.alt as i32, |block| block.is_solid()),
Floating => (col.water_level as i32, |block| !block.is_air()),
};
// Find the intersection between ground and air, if there is one near the
// surface
if let Some(solid_end) = (-4..8)
.find(|z| {
canvas
.get(Vec3::new(wpos2d.x, wpos2d.y, alt + z))
.is_solid()
is_under(canvas.get(Vec3::new(wpos2d.x, wpos2d.y, alt + z)))
})
.and_then(|solid_start| {
(1..8).map(|z| solid_start + z).find(|z| {
!canvas
.get(Vec3::new(wpos2d.x, wpos2d.y, alt + z))
.is_solid()
!is_under(canvas.get(Vec3::new(wpos2d.x, wpos2d.y, alt + z)))
})
})
{