More granular entity spawning. Tweak biome distribution to not favour hot biomes

This commit is contained in:
Syniis 2024-02-22 17:23:33 +01:00
parent 059cdebb48
commit 6979a1beca

View File

@ -17,6 +17,7 @@ use common::{
vol::RectVolSize, vol::RectVolSize,
}; };
use inline_tweak::tweak_fn; use inline_tweak::tweak_fn;
use itertools::Itertools;
use noise::NoiseFn; use noise::NoiseFn;
use rand::prelude::*; use rand::prelude::*;
use std::{ use std::{
@ -210,7 +211,7 @@ impl Tunnel {
.mul(2.0) .mul(2.0)
.sub(1.0) .sub(1.0)
.add( .add(
((col.alt - wpos.z as f32) / (AVG_LEVEL_DEPTH as f32 * LAYERS as f32 * 0.5)) ((col.alt - wpos.z as f32) / (AVG_LEVEL_DEPTH as f32 * LAYERS as f32 * 0.75))
.clamped(0.0, 2.5), .clamped(0.0, 2.5),
), ),
below, below,
@ -247,27 +248,27 @@ impl Tunnel {
// Extremely hot and dry areas deep underground // Extremely hot and dry areas deep underground
let fire = underground let fire = underground
* close(humidity, 0.0, 0.6) * close(humidity, 0.0, 0.6)
* close(temp, 2.5, 1.4) * close(temp, 2.0, 1.3)
* close(depth, 1.0, 0.5); * close(depth, 1.0, 0.5);
// Overgrown with plants that need a moderate climate to survive // Overgrown with plants that need a moderate climate to survive
let leafy = underground let leafy = underground
* close(humidity, 0.8, 0.8) * close(humidity, 0.8, 0.8)
* close(temp, 0.85, 0.9) * close(temp, 0.95, 0.85)
* close(depth, 0.0, 0.6); * close(depth, 0.0, 0.6);
// Cool temperature, dry and devoid of value // Cool temperature, dry and devoid of value
let dusty = close(humidity, 0.0, 0.5) * close(temp, -0.1, 0.6); let dusty = close(humidity, 0.0, 0.5) * close(temp, -0.1, 0.6);
// Deep underground and freezing cold // Deep underground and freezing cold
let icy = underground let icy = underground
* close(temp, -1.0, 0.6) * close(temp, -1.5, 1.3)
* close(depth, 1.0, 0.5) * close(depth, 1.0, 0.65)
* close(humidity, 1.0, 0.7); * close(humidity, 1.0, 0.7);
// Rocky cold cave that appear near the surface // Rocky cold cave that appear near the surface
let snowy = close(temp, -0.5, 0.3) * close(depth, 0.0, 0.4); let snowy = close(temp, -0.5, 0.3) * close(depth, 0.0, 0.4);
// Crystals grow deep underground in areas rich with minerals. They are present // Crystals grow deep underground in areas rich with minerals. They are present
// in areas with colder temperatures and low humidity // in areas with colder temperatures and low humidity
let crystal = underground let crystal = underground
* close(humidity, 0.0, 0.7) * close(humidity, 0.0, 0.5)
* close(temp, -0.5, 0.8) * close(temp, -0.6, 0.75)
* close(depth, 1.0, 0.55) * close(depth, 1.0, 0.55)
* close(mineral, 1.5, 1.0); * close(mineral, 1.5, 1.0);
// Hot, dry and shallow // Hot, dry and shallow
@ -583,9 +584,10 @@ fn write_column<R: Rng>(
let ceiling_cover = if biome.leafy > 0.3 let ceiling_cover = if biome.leafy > 0.3
|| biome.mushroom > 0.5 || biome.mushroom > 0.5
|| biome.icy > 0.7 || biome.icy > 0.6
|| biome.sandy > 0.5 || biome.sandy > 0.4
|| biome.fire > 0.5 || biome.fire > 0.4
|| biome.crystal > 0.75
{ {
// 1.0 because at some point we maybe want to use some noise value here instead // 1.0 because at some point we maybe want to use some noise value here instead
1.0.mul(((col.alt - z_range.end as f32) / 32.0).clamped(0.0, 1.0)) 1.0.mul(((col.alt - z_range.end as f32) / 32.0).clamped(0.0, 1.0))
@ -599,6 +601,7 @@ fn write_column<R: Rng>(
.max(biome.sandy - 0.3) .max(biome.sandy - 0.3)
.max(biome.leafy - 0.4) .max(biome.leafy - 0.4)
.max(biome.mushroom - 0.4) .max(biome.mushroom - 0.4)
.max(biome.crystal - 0.5)
{ {
max_height * col.marble_mid max_height * col.marble_mid
} else { } else {
@ -1177,6 +1180,7 @@ fn write_column<R: Rng>(
let stalactite: Rgb<i16> = Lerp::lerp_unclamped( let stalactite: Rgb<i16> = Lerp::lerp_unclamped(
Lerp::lerp_unclamped( Lerp::lerp_unclamped(
Lerp::lerp_unclamped( Lerp::lerp_unclamped(
Lerp::lerp_unclamped(
Lerp::lerp_unclamped( Lerp::lerp_unclamped(
Lerp::lerp_unclamped( Lerp::lerp_unclamped(
Rgb::new(80, 100, 150), Rgb::new(80, 100, 150),
@ -1210,9 +1214,21 @@ fn write_column<R: Rng>(
col.marble, col.marble,
), ),
biome.icy, biome.icy,
),
Lerp::lerp_unclamped(
Rgb::new(105, 25, 131),
Rgb::new(251, 238, 255),
col.marble_mid,
),
biome.crystal,
); );
Block::new( Block::new(
if rand.chance(wpos, (biome.mushroom * 0.01).max(biome.icy * 0.1)) { if rand.chance(
wpos,
(biome.mushroom * 0.01)
.max(biome.icy * 0.1)
.max(biome.crystal * 0.005),
) {
BlockKind::GlowingWeakRock BlockKind::GlowingWeakRock
} else if rand.chance(wpos, biome.sandy) { } else if rand.chance(wpos, biome.sandy) {
BlockKind::Sand BlockKind::Sand
@ -1556,175 +1572,220 @@ fn write_column<R: Rng>(
} }
fn apply_entity_spawns<R: Rng>(canvas: &mut Canvas, wpos: Vec3<i32>, biome: &Biome, rng: &mut R) { fn apply_entity_spawns<R: Rng>(canvas: &mut Canvas, wpos: Vec3<i32>, biome: &Biome, rng: &mut R) {
if RandomField::new(canvas.info().index().seed).chance(wpos, 0.05) { if RandomField::new(canvas.info().index().seed).chance(wpos, 0.025) {
if let Some(entity_asset) = [ if let Some(entity_asset) = [
// Mushroom biome // Mushroom biome
( (
Some("common.entity.wild.peaceful.truffler"), Some("common.entity.wild.peaceful.truffler"),
(biome.mushroom + 0.02) * 0.35, biome.mushroom + 0.02,
0.35,
0.5,
), ),
( (
Some("common.entity.wild.peaceful.fungome"), Some("common.entity.wild.peaceful.fungome"),
(biome.mushroom + 0.02) * 0.5, biome.mushroom + 0.02,
0.5,
0.5,
), ),
( (
Some("common.entity.wild.peaceful.bat"), Some("common.entity.wild.aggressive.bat"),
(biome.mushroom + 0.1) * 0.25, biome.mushroom + 0.1,
0.25,
0.5,
), ),
// Leafy biome // Leafy biome
( (
Some("common.entity.wild.peaceful.holladon"), Some("common.entity.wild.peaceful.holladon"),
(biome.leafy.max(biome.dusty) + 0.05) * 0.3, biome.leafy + 0.05,
0.5,
0.5,
), ),
( (
Some("common.entity.dungeon.gnarling.mandragora"), Some("common.entity.wild.peaceful.turtle"),
(biome.leafy + 0.05) * 0.2, biome.leafy + 0.05,
0.5,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.rootsnapper"), Some("common.entity.wild.aggressive.rootsnapper"),
(biome.leafy + 0.05) * 0.1, biome.leafy + 0.05,
0.05,
0.5,
),
(
Some("common.entity.wild.peaceful.axolotl"),
biome.leafy + 0.05,
0.5,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.maneater"), Some("common.entity.wild.aggressive.maneater"),
(biome.leafy + 0.0) * 0.05, biome.leafy + 0.05,
0.1,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.batfox"), Some("common.entity.wild.aggressive.batfox"),
(biome biome
.leafy .leafy
.max(biome.barren) .max(biome.barren)
.max(biome.sandy) .max(biome.sandy)
.max(biome.snowy) .max(biome.snowy)
+ 0.3) + 0.3,
* 0.35, 0.35,
0.5,
),
(
Some("common.entity.wild.aggressive.cave_salamander"),
biome.leafy + 0.0,
0.3,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.asp"), Some("common.entity.wild.aggressive.asp"),
(biome.leafy + 0.1) * 0.2, biome.leafy + 0.1,
0.25,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.swamp_troll"), Some("common.entity.wild.aggressive.swamp_troll"),
(biome.leafy + 0.0) * 0.05, biome.leafy + 0.0,
0.1,
0.5,
), ),
( (
Some("common.entity.wild.peaceful.bat"), Some("common.entity.wild.aggressive.bat"),
(biome.leafy + 0.1) * 0.25, biome.leafy + 0.1,
), 0.25,
( 0.5,
Some("common.entity.wild.peaceful.crawler_moss"),
(biome.leafy + 0.05) * 0.25,
), ),
// Dusty biome // Dusty biome
( (
Some("common.entity.wild.aggressive.dodarock"), Some("common.entity.wild.aggressive.dodarock"),
(biome biome.dusty.max(biome.barren).max(biome.snowy) + 0.05,
.dusty 0.05,
.max(biome.barren) 0.5,
.max(biome.crystal)
.max(biome.snowy)
+ 0.05)
* 0.05,
), ),
( (
Some("common.entity.wild.aggressive.cave_spider"), Some("common.entity.wild.aggressive.cave_spider"),
(biome.dusty + 0.0) * 0.05, biome.dusty + 0.0,
0.4,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.cave_troll"), Some("common.entity.wild.aggressive.cave_troll"),
(biome.dusty + 0.1) * 0.05, biome.dusty + 0.1,
0.05,
0.5,
), ),
( (
Some("common.entity.wild.peaceful.rat"), Some("common.entity.wild.peaceful.rat"),
(biome.dusty.max(biome.barren) + 0.15) * 0.3, biome.dusty + 0.1,
0.3,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.bat"), Some("common.entity.wild.aggressive.bat"),
(biome.dusty.max(biome.sandy).max(biome.snowy) + 0.1) * 0.25, biome.dusty.max(biome.sandy).max(biome.snowy) + 0.1,
0.25,
0.5,
), ),
// Icy biome // Icy biome
( (
Some("common.entity.wild.aggressive.icedrake"), Some("common.entity.wild.aggressive.blue_oni"),
(biome.icy + 0.0) * 0.04, biome.icy + 0.0,
0.03,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.roshwalr"), Some("common.entity.wild.aggressive.icedrake"),
(biome.icy + 0.0) * 0.1, biome.icy + 0.0,
0.1,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.wendigo"), Some("common.entity.wild.aggressive.wendigo"),
(biome.icy.min(biome.depth) + 0.0) * 0.02, biome.icy.min(biome.depth) + 0.0,
), 0.02,
( 0.5,
Some("common.entity.wild.aggressive.frostfang"),
(biome.icy + 0.0) * 0.2,
),
(
Some("common.entity.wild.aggressive.tursus"),
(biome.icy + 0.0) * 0.03,
), ),
// Lava biome // Lava biome
( (
Some("common.entity.wild.aggressive.lavadrake"), Some("common.entity.wild.aggressive.lavadrake"),
(biome.fire + 0.0) * 0.25, biome.fire + 0.0,
0.5,
0.5,
), ),
( (
Some("common.entity.wild.peaceful.crawler_molten"), Some("common.entity.wild.peaceful.crawler_molten"),
(biome.fire + 0.0) * 0.5, biome.fire + 0.0,
), 0.75,
( 0.5,
Some("common.entity.wild.aggressive.cave_salamander"),
(biome.fire + 0.0) * 0.5,
), ),
( (
Some("common.entity.wild.aggressive.red_oni"), Some("common.entity.wild.aggressive.red_oni"),
(biome.fire + 0.0) * 0.03, biome.fire + 0.0,
0.05,
0.5,
), ),
// Crystal biome // Crystal biome
( (
Some("common.entity.wild.aggressive.basilisk"), Some("common.entity.wild.aggressive.basilisk"),
(biome.crystal + 0.1) * 0.1, biome.crystal + 0.1,
), 0.1,
( 0.5,
Some("common.entity.wild.aggressive.blue_oni"),
(biome.crystal + 0.0) * 0.03,
), ),
// Sandy biome // Sandy biome
( (
Some("common.entity.wild.aggressive.antlion"), Some("common.entity.wild.aggressive.antlion"),
(biome.sandy.max(biome.dusty) + 0.1) * 0.050, biome.sandy.max(biome.dusty) + 0.1,
0.025,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.sandshark"), Some("common.entity.wild.aggressive.sandshark"),
(biome.sandy + 0.1) * 0.050, biome.sandy + 0.1,
), 0.025,
( 0.5,
Some("common.entity.wild.peaceful.crawler_sand"),
(biome.sandy + 0.1) * 0.2,
), ),
// Snowy biome // Snowy biome
( (
Some("common.entity.wild.aggressive.akhlut"), Some("common.entity.wild.aggressive.akhlut"),
(biome.snowy.max(biome.icy) + 0.1) * 0.03, biome.snowy.max(biome.icy) + 0.1,
0.05,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.rocksnapper"), Some("common.entity.wild.aggressive.rocksnapper"),
(biome.barren.max(biome.crystal).max(biome.snowy) + 0.1) * 0.1, biome.barren.max(biome.snowy) + 0.1,
0.1,
0.5,
), ),
// With depth // With depth
( (
Some("common.entity.wild.aggressive.black_widow"), Some("common.entity.wild.aggressive.black_widow"),
(biome.depth + 0.0) * 0.01, biome.depth + 0.0,
0.02,
0.5,
), ),
( (
Some("common.entity.wild.aggressive.ogre"), Some("common.entity.wild.aggressive.ogre"),
(biome.depth + 0.0) * 0.02, biome.depth + 0.0,
0.02,
0.5,
), ),
( (None, 100.0, 0.0, 0.0),
Some("common.entity.wild.aggressive.basilisk"),
(biome.depth + 0.1) * 0.005,
),
(None, 100.0),
] ]
.iter()
.filter_map(|(entity, biome_modifier, chance, cutoff)| {
if let Some(entity) = entity {
let close = close_fast(1.0, *biome_modifier, *cutoff, 2);
(close > 0.0).then(|| (Some(entity), close * chance))
} else {
Some((None, 100.0))
}
})
.collect_vec()
.choose_weighted(rng, |(_, w)| *w) .choose_weighted(rng, |(_, w)| *w)
.ok() .ok()
.and_then(|s| s.0) .and_then(|s| s.0)