From ff5d267535815d8d2a58ff23f664179960a58bc6 Mon Sep 17 00:00:00 2001 From: Snowram Date: Fri, 16 Apr 2021 13:17:15 +0200 Subject: [PATCH] Day period dependant wildlife spawns --- common/src/time.rs | 2 +- server/src/chunk_generator.rs | 7 ++++-- server/src/lib.rs | 2 ++ server/src/state_ext.rs | 3 ++- world/src/layer/wildlife.rs | 43 +++++++++++++++++++++++++++++++++++ world/src/lib.rs | 7 +++++- 6 files changed, 59 insertions(+), 5 deletions(-) diff --git a/common/src/time.rs b/common/src/time.rs index 023c2f5089..a13ba253f4 100644 --- a/common/src/time.rs +++ b/common/src/time.rs @@ -1,4 +1,4 @@ -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum DayPeriod { Night, Morning, diff --git a/server/src/chunk_generator.rs b/server/src/chunk_generator.rs index 06f27de086..0559b4a460 100644 --- a/server/src/chunk_generator.rs +++ b/server/src/chunk_generator.rs @@ -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, 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)); }); diff --git a/server/src/lib.rs b/server/src/lib.rs index acc5d9c254..692ae02c0e 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -725,6 +725,7 @@ impl Server { &slow_jobs, Arc::clone(&world), index.clone(), + *ecs.read_resource::(), ); }); } @@ -930,6 +931,7 @@ impl Server { &slow_jobs, Arc::clone(&self.world), self.index.clone(), + *ecs.read_resource::(), ); } diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index 93dd7cdc77..89a037d95b 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -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::()); } }); } diff --git a/world/src/layer/wildlife.rs b/world/src/layer/wildlife.rs index 062b5900f4..92b4204ed2 100644 --- a/world/src/layer/wildlife.rs +++ b/world/src/layer/wildlife.rs @@ -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, ) { struct Entry { make_entity: fn(Vec3, &mut R) -> EntityInfo, // Entity group_size: Range, // Group size range is_underwater: bool, // Underwater? + day_period: Vec, // 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::() < density * col_sample.spawn_rate && underwater == *is_underwater + && day_period.contains(¤t_day_period) && col_sample.gradient < Some(1.3) { Some((make_entity, group_size.clone())) diff --git a/world/src/lib.rs b/world/src/lib.rs index 87eae3c622..a349e5bf7a 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -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, // TODO: misleading name mut should_continue: impl FnMut() -> bool, + time: Option, ) -> 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