Day period dependant wildlife spawns

This commit is contained in:
Snowram 2021-04-16 13:17:15 +02:00
parent fd177c9669
commit bd84677906
6 changed files with 59 additions and 5 deletions

View File

@ -1,4 +1,4 @@
#[derive(Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum DayPeriod {
Night,
Morning,

View File

@ -1,7 +1,9 @@
use crate::metrics::ChunkGenMetrics;
#[cfg(not(feature = "worldgen"))]
use crate::test_world::{IndexOwned, World};
use common::{generation::ChunkSupplement, slowjob::SlowJobPool, terrain::TerrainChunk};
use common::{
generation::ChunkSupplement, resources::TimeOfDay, slowjob::SlowJobPool, terrain::TerrainChunk,
};
use hashbrown::{hash_map::Entry, HashMap};
use specs::Entity as EcsEntity;
use std::sync::{
@ -42,6 +44,7 @@ impl ChunkGenerator {
slowjob_pool: &SlowJobPool,
world: Arc<World>,
index: IndexOwned,
time: TimeOfDay,
) {
let v = if let Entry::Vacant(v) = self.pending_chunks.entry(key) {
v
@ -55,7 +58,7 @@ impl ChunkGenerator {
slowjob_pool.spawn("CHUNK_GENERATOR", move || {
let index = index.as_index_ref();
let payload = world
.generate_chunk(index, key, || cancel.load(Ordering::Relaxed))
.generate_chunk(index, key, || cancel.load(Ordering::Relaxed), Some(time))
.map_err(|_| entity);
let _ = chunk_tx.send((key, payload));
});

View File

@ -725,6 +725,7 @@ impl Server {
&slow_jobs,
Arc::clone(&world),
index.clone(),
*ecs.read_resource::<TimeOfDay>(),
);
});
}
@ -930,6 +931,7 @@ impl Server {
&slow_jobs,
Arc::clone(&self.world),
self.index.clone(),
*ecs.read_resource::<TimeOfDay>(),
);
}

View File

@ -11,6 +11,7 @@ use common::{
Group, Inventory,
},
effect::Effect,
resources::TimeOfDay,
slowjob::SlowJobPool,
uid::{Uid, UidAllocator},
};
@ -382,7 +383,7 @@ impl StateExt for State {
.for_each(|chunk_key| {
#[cfg(feature = "worldgen")]
{
chunk_generator.generate_chunk(None, chunk_key, &slow_jobs, Arc::clone(world), index.clone());
chunk_generator.generate_chunk(None, chunk_key, &slow_jobs, Arc::clone(world), index.clone(), *ecs.read_resource::<TimeOfDay>());
}
});
}

View File

@ -5,7 +5,9 @@ use common::{
quadruped_medium, quadruped_small, theropod, Alignment,
},
generation::{ChunkSupplement, EntityInfo},
resources::TimeOfDay,
terrain::Block,
time::DayPeriod::{self, Evening, Morning, Night, Noon},
vol::{BaseVol, ReadVol, RectSizedVol, WriteVol},
};
use rand::prelude::*;
@ -28,11 +30,13 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
_index: IndexRef,
chunk: &SimChunk,
supplement: &mut ChunkSupplement,
time: Option<TimeOfDay>,
) {
struct Entry<R> {
make_entity: fn(Vec3<f32>, &mut R) -> EntityInfo, // Entity
group_size: Range<usize>, // Group size range
is_underwater: bool, // Underwater?
day_period: Vec<DayPeriod>, // Period of the day
get_density: fn(&SimChunk, &ColumnSample) -> f32, // Density
}
@ -60,6 +64,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..4,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, col| {
close(c.temp, CONFIG.snow_temp, 0.3)
* BASE_DENSITY
@ -91,6 +96,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, col| {
close(c.temp, CONFIG.snow_temp, 0.3) * col.tree_density * BASE_DENSITY * 1.4
},
@ -106,6 +112,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.5,
},
// Tundra rarer solitary ennemies
@ -119,6 +126,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.1,
},
// Tundra rock solitary ennemies
@ -133,6 +141,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, col| {
close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * col.rock * 1.0
},
@ -154,6 +163,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, col| {
close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * col.tree_density * BASE_DENSITY * 0.4
},
@ -170,6 +180,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 3..8,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, col| {
close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * col.tree_density * BASE_DENSITY * 0.9
},
@ -199,6 +210,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..4,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * BASE_DENSITY * 1.0,
},
// Taiga solitary wild
@ -237,6 +249,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * BASE_DENSITY * 5.0,
},
// Temperate solitary ennemies
@ -271,6 +284,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, col| {
close(c.temp, CONFIG.temperate_temp + 0.1, 0.5)
* col.tree_density
@ -341,6 +355,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..8,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| {
close(c.temp, CONFIG.temperate_temp + 0.1, 0.6)
* close(c.humidity, CONFIG.forest_hum, 0.6)
@ -408,6 +423,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| {
close(c.temp, CONFIG.temperate_temp + 0.1, 0.6)
* BASE_DENSITY
@ -433,6 +449,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| close(c.temp, CONFIG.temperate_temp, 0.8) * BASE_DENSITY * 0.08,
},
// Temperate river wildlife
@ -463,6 +480,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |_c, col| {
close(col.temp, CONFIG.temperate_temp, 0.6)
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
@ -487,6 +505,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |_c, col| {
close(col.temp, CONFIG.temperate_temp, 0.6)
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
@ -508,6 +527,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |_c, col| {
close(col.temp, CONFIG.temperate_temp, 0.6)
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
@ -532,6 +552,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, col| {
close(c.temp, CONFIG.tropical_temp + 0.1, 0.5) * col.rock * BASE_DENSITY * 5.0
},
@ -557,6 +578,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| {
close(c.temp, CONFIG.tropical_temp + 0.2, 0.2)
* close(c.humidity, CONFIG.jungle_hum, 0.2)
@ -585,6 +607,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| {
close(c.temp, CONFIG.tropical_temp + 0.2, 0.2)
* close(c.humidity, CONFIG.jungle_hum, 0.2)
@ -619,6 +642,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| {
close(c.temp, CONFIG.tropical_temp + 0.2, 0.3)
* close(c.humidity, CONFIG.jungle_hum, 0.2)
@ -638,6 +662,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..3,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |_c, col| {
close(col.temp, CONFIG.tropical_temp + 0.2, 0.5)
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
@ -671,6 +696,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..3,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |_c, col| {
close(col.temp, CONFIG.tropical_temp, 0.5)
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
@ -700,6 +726,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..3,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| {
close(c.temp, CONFIG.tropical_temp + 0.1, 0.4)
* close(c.humidity, CONFIG.desert_hum, 0.4)
@ -727,6 +754,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 3..7,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| {
close(c.temp, CONFIG.tropical_temp + 0.1, 0.4)
* close(c.humidity, CONFIG.desert_hum, 0.4)
@ -757,6 +785,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| {
close(c.temp, CONFIG.desert_temp + 0.2, 0.3)
* close(c.humidity, CONFIG.desert_hum, 0.5)
@ -781,6 +810,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| {
close(c.temp, CONFIG.desert_temp + 0.2, 0.3)
* close(c.humidity, CONFIG.desert_hum, 0.5)
@ -800,6 +830,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..3,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |_c, col| {
close(col.temp, CONFIG.desert_temp + 0.2, 0.3)
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
@ -824,6 +855,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..3,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| {
close(c.temp, CONFIG.desert_temp + 0.2, 0.3)
* close(c.humidity, CONFIG.desert_hum, 0.5)
@ -875,6 +907,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..2,
is_underwater: false,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, _col| {
close(c.temp, CONFIG.desert_temp + 0.2, 0.3) * BASE_DENSITY * 5.0
},
@ -896,6 +929,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 3..5,
is_underwater: true,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, col| {
close(c.temp, CONFIG.temperate_temp, 1.0) * col.tree_density * BASE_DENSITY * 5.0
},
@ -911,6 +945,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
},
group_size: 1..3,
is_underwater: true,
day_period: vec![Night, Morning, Noon, Evening],
get_density: |c, col| {
close(c.temp, CONFIG.snow_temp, 0.15) * col.tree_density * BASE_DENSITY * 5.0
},
@ -931,6 +966,12 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
};
let underwater = col_sample.water_level > col_sample.alt;
let current_day_period;
if let Some(time) = time {
current_day_period = DayPeriod::from(time.0)
} else {
current_day_period = Noon
}
let entity_group = scatter.iter().enumerate().find_map(
|(
@ -939,6 +980,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
make_entity,
group_size,
is_underwater,
day_period,
get_density,
},
)| {
@ -946,6 +988,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
if density > 0.0
&& dynamic_rng.gen::<f32>() < density * col_sample.spawn_rate
&& underwater == *is_underwater
&& day_period.contains(&current_day_period)
&& col_sample.gradient < Some(1.3)
{
Some((make_entity, group_size.clone()))

View File

@ -50,6 +50,7 @@ use crate::{
use common::{
assets,
generation::{ChunkSupplement, EntityInfo},
resources::TimeOfDay,
terrain::{Block, BlockKind, SpriteKind, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
vol::{ReadVol, RectVolSize, WriteVol},
};
@ -171,7 +172,9 @@ impl World {
// Unwrapping because generate_chunk only returns err when should_continue evals
// to true
let (tc, _cs) = self.generate_chunk(index, chunk_pos, || false).unwrap();
let (tc, _cs) = self
.generate_chunk(index, chunk_pos, || false, None)
.unwrap();
let min_z = tc.get_min_z();
let max_z = tc.get_max_z();
@ -209,6 +212,7 @@ impl World {
chunk_pos: Vec2<i32>,
// TODO: misleading name
mut should_continue: impl FnMut() -> bool,
time: Option<TimeOfDay>,
) -> Result<(TerrainChunk, ChunkSupplement), ()> {
let mut sampler = self.sample_blocks();
@ -390,6 +394,7 @@ impl World {
index,
sim_chunk,
&mut supplement,
time,
);
// Apply site supplementary information