mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added crickets blocktype, added 3 new cricket sounds, made crickets chirp consistently, made frogs more sporadic
This commit is contained in:
parent
44a9d8dc71
commit
ebbb06a400
@ -28,11 +28,24 @@
|
|||||||
],
|
],
|
||||||
threshold: 14.0,
|
threshold: 14.0,
|
||||||
),
|
),
|
||||||
Cricket: (
|
//Crickets: -20dB
|
||||||
|
Cricket1: (
|
||||||
files: [
|
files: [
|
||||||
"voxygen.audio.sfx.ambient.crickets_1",
|
"voxygen.audio.sfx.ambient.crickets_1",
|
||||||
],
|
],
|
||||||
threshold: 1.0,
|
threshold: 0.0,
|
||||||
|
),
|
||||||
|
Cricket2: (
|
||||||
|
files: [
|
||||||
|
"voxygen.audio.sfx.ambient.crickets_2",
|
||||||
|
],
|
||||||
|
threshold: 0.0,
|
||||||
|
),
|
||||||
|
Cricket3: (
|
||||||
|
files: [
|
||||||
|
"voxygen.audio.sfx.ambient.crickets_3",
|
||||||
|
],
|
||||||
|
threshold: 0.0,
|
||||||
),
|
),
|
||||||
Frog: (
|
Frog: (
|
||||||
files: [
|
files: [
|
||||||
|
BIN
assets/voxygen/audio/sfx/ambient/crickets_1.wav
(Stored with Git LFS)
BIN
assets/voxygen/audio/sfx/ambient/crickets_1.wav
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/audio/sfx/ambient/crickets_2.wav
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/sfx/ambient/crickets_2.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/sfx/ambient/crickets_3.wav
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/sfx/ambient/crickets_3.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -59,6 +59,7 @@ pub struct TerrainChunkMeta {
|
|||||||
tree_density: f32,
|
tree_density: f32,
|
||||||
contains_cave: bool,
|
contains_cave: bool,
|
||||||
contains_river: bool,
|
contains_river: bool,
|
||||||
|
temp: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TerrainChunkMeta {
|
impl TerrainChunkMeta {
|
||||||
@ -69,6 +70,7 @@ impl TerrainChunkMeta {
|
|||||||
tree_density: f32,
|
tree_density: f32,
|
||||||
contains_cave: bool,
|
contains_cave: bool,
|
||||||
contains_river: bool,
|
contains_river: bool,
|
||||||
|
temp: f32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
@ -77,6 +79,7 @@ impl TerrainChunkMeta {
|
|||||||
tree_density,
|
tree_density,
|
||||||
contains_cave,
|
contains_cave,
|
||||||
contains_river,
|
contains_river,
|
||||||
|
temp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +91,7 @@ impl TerrainChunkMeta {
|
|||||||
tree_density: 0.0,
|
tree_density: 0.0,
|
||||||
contains_cave: false,
|
contains_cave: false,
|
||||||
contains_river: false,
|
contains_river: false,
|
||||||
|
temp: 0.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +106,8 @@ impl TerrainChunkMeta {
|
|||||||
pub fn contains_cave(&self) -> bool { self.contains_cave }
|
pub fn contains_cave(&self) -> bool { self.contains_cave }
|
||||||
|
|
||||||
pub fn contains_river(&self) -> bool { self.contains_river }
|
pub fn contains_river(&self) -> bool { self.contains_river }
|
||||||
|
|
||||||
|
pub fn temp(&self) -> f32 { self.temp }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Terrain type aliases
|
// Terrain type aliases
|
||||||
|
@ -17,7 +17,7 @@ use common::{
|
|||||||
use common_sys::state::State;
|
use common_sys::state::State;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use std::time::Instant;
|
use std::time::{Duration, Instant};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
@ -30,7 +30,9 @@ impl Default for PreviousBlockState {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
event: SfxEvent::Idle,
|
event: SfxEvent::Idle,
|
||||||
time: Instant::now(),
|
time: Instant::now()
|
||||||
|
.checked_add(Duration::from_millis(thread_rng().gen_range(0..500)))
|
||||||
|
.unwrap_or_else(Instant::now),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,10 +63,10 @@ impl EventMapper for BlockEventMapper {
|
|||||||
(e.floor() as i32).div_euclid(sz as i32)
|
(e.floor() as i32).div_euclid(sz as i32)
|
||||||
});
|
});
|
||||||
|
|
||||||
// For determining if underground
|
// For determining if underground/crickets should chirp
|
||||||
let terrain_alt = match client.current_chunk() {
|
let (terrain_alt, temp) = match client.current_chunk() {
|
||||||
Some(chunk) => chunk.meta().alt(),
|
Some(chunk) => (chunk.meta().alt(), chunk.meta().temp()),
|
||||||
None => 0.0,
|
None => (0.0, 0.0),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlockSounds<'a> {
|
struct BlockSounds<'a> {
|
||||||
@ -112,7 +114,7 @@ impl EventMapper for BlockEventMapper {
|
|||||||
// //cond: |st| st.get_day_period().is_dark(),
|
// //cond: |st| st.get_day_period().is_dark(),
|
||||||
//},
|
//},
|
||||||
BlockSounds {
|
BlockSounds {
|
||||||
blocks: |boi| &boi.reeds,
|
blocks: |boi| &boi.frogs,
|
||||||
range: 1,
|
range: 1,
|
||||||
sfx: SfxEvent::Frog,
|
sfx: SfxEvent::Frog,
|
||||||
volume: 0.8,
|
volume: 0.8,
|
||||||
@ -126,10 +128,24 @@ impl EventMapper for BlockEventMapper {
|
|||||||
// cond: |st| st.get_day_period().is_dark(),
|
// cond: |st| st.get_day_period().is_dark(),
|
||||||
//},
|
//},
|
||||||
BlockSounds {
|
BlockSounds {
|
||||||
blocks: |boi| &boi.grass,
|
blocks: |boi| &boi.cricket1,
|
||||||
range: 1,
|
range: 1,
|
||||||
sfx: SfxEvent::Cricket,
|
sfx: SfxEvent::Cricket1,
|
||||||
volume: 0.5,
|
volume: 0.33,
|
||||||
|
cond: |st| st.get_day_period().is_dark(),
|
||||||
|
},
|
||||||
|
BlockSounds {
|
||||||
|
blocks: |boi| &boi.cricket2,
|
||||||
|
range: 1,
|
||||||
|
sfx: SfxEvent::Cricket2,
|
||||||
|
volume: 0.33,
|
||||||
|
cond: |st| st.get_day_period().is_dark(),
|
||||||
|
},
|
||||||
|
BlockSounds {
|
||||||
|
blocks: |boi| &boi.cricket3,
|
||||||
|
range: 1,
|
||||||
|
sfx: SfxEvent::Cricket3,
|
||||||
|
volume: 0.33,
|
||||||
cond: |st| st.get_day_period().is_dark(),
|
cond: |st| st.get_day_period().is_dark(),
|
||||||
},
|
},
|
||||||
BlockSounds {
|
BlockSounds {
|
||||||
@ -145,12 +161,12 @@ impl EventMapper for BlockEventMapper {
|
|||||||
for sounds in sounds.iter() {
|
for sounds in sounds.iter() {
|
||||||
// If the timing condition is false, continue
|
// If the timing condition is false, continue
|
||||||
// or if the player is far enough underground, continue
|
// or if the player is far enough underground, continue
|
||||||
// TODO Address bird hack properly. See TODO on line 171
|
// TODO Address bird hack properly. See TODO on line 190
|
||||||
if !(sounds.cond)(state)
|
if !(sounds.cond)(state)
|
||||||
|| player_pos.0.z < (terrain_alt - 30.0)
|
|| player_pos.0.z < (terrain_alt - 30.0)
|
||||||
|| (sounds.sfx == SfxEvent::Birdcall && thread_rng().gen_bool(0.995))
|
|| (sounds.sfx == SfxEvent::Birdcall && thread_rng().gen_bool(0.995))
|
||||||
|| (sounds.sfx == SfxEvent::Owl && thread_rng().gen_bool(0.998))
|
|| (sounds.sfx == SfxEvent::Owl && thread_rng().gen_bool(0.998))
|
||||||
|| (sounds.sfx == SfxEvent::Cricket && thread_rng().gen_bool(0.99))
|
|| (sounds.sfx == SfxEvent::Frog && thread_rng().gen_bool(0.9))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -172,9 +188,9 @@ impl EventMapper for BlockEventMapper {
|
|||||||
// TODO Address this hack properly, potentially by making a new
|
// TODO Address this hack properly, potentially by making a new
|
||||||
// block of interest type which picks fewer leaf blocks
|
// block of interest type which picks fewer leaf blocks
|
||||||
// Hack to reduce the number of bird sounds (too many leaf blocks)
|
// Hack to reduce the number of bird sounds (too many leaf blocks)
|
||||||
if (sounds.sfx == SfxEvent::Birdcall || sounds.sfx == SfxEvent::Owl)
|
if ((sounds.sfx == SfxEvent::Birdcall || sounds.sfx == SfxEvent::Owl)
|
||||||
&& thread_rng().gen_bool(0.999)
|
&& thread_rng().gen_bool(0.999))
|
||||||
|| (sounds.sfx == SfxEvent::Cricket && thread_rng().gen_bool(0.999))
|
|| (sounds.sfx == SfxEvent::Frog && thread_rng().gen_bool(0.75))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -183,7 +199,11 @@ impl EventMapper for BlockEventMapper {
|
|||||||
|
|
||||||
let block_pos = block_pos.map(|x| x as f32);
|
let block_pos = block_pos.map(|x| x as f32);
|
||||||
|
|
||||||
if Self::should_emit(internal_state, triggers.get_key_value(&sounds.sfx)) {
|
if Self::should_emit(
|
||||||
|
internal_state,
|
||||||
|
triggers.get_key_value(&sounds.sfx),
|
||||||
|
temp,
|
||||||
|
) {
|
||||||
// If the camera is within SFX distance
|
// If the camera is within SFX distance
|
||||||
if (block_pos.distance_squared(cam_pos)) < SFX_DIST_LIMIT_SQR {
|
if (block_pos.distance_squared(cam_pos)) < SFX_DIST_LIMIT_SQR {
|
||||||
let underwater = state
|
let underwater = state
|
||||||
@ -228,12 +248,42 @@ impl BlockEventMapper {
|
|||||||
fn should_emit(
|
fn should_emit(
|
||||||
previous_state: &PreviousBlockState,
|
previous_state: &PreviousBlockState,
|
||||||
sfx_trigger_item: Option<(&SfxEvent, &SfxTriggerItem)>,
|
sfx_trigger_item: Option<(&SfxEvent, &SfxTriggerItem)>,
|
||||||
|
temp: f32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if let Some((event, item)) = sfx_trigger_item {
|
if let Some((event, item)) = sfx_trigger_item {
|
||||||
|
//The interval between cricket chirps calculated by converting chunk
|
||||||
|
// temperature to centigrade (we should create a function for this) and applying
|
||||||
|
// the "cricket formula" to it
|
||||||
|
let cricket_interval = (25.0 / (3.0 * ((temp * 30.0) + 15.0))).max(0.5);
|
||||||
if &previous_state.event == event {
|
if &previous_state.event == event {
|
||||||
//In case certain sounds need modification to their threshold,
|
//In case certain sounds need modification to their threshold,
|
||||||
//use match event
|
//use match event
|
||||||
previous_state.time.elapsed().as_secs_f32() >= item.threshold
|
match event {
|
||||||
|
//Crickets' threshold is 0.0 by default
|
||||||
|
SfxEvent::Cricket1 => {
|
||||||
|
previous_state.time.elapsed().as_secs_f32()
|
||||||
|
>= cricket_interval + thread_rng().gen_range(-0.1..0.1)
|
||||||
|
},
|
||||||
|
SfxEvent::Cricket2 => {
|
||||||
|
//the length and manner of this sound is quite different
|
||||||
|
if cricket_interval < 0.75 {
|
||||||
|
previous_state.time.elapsed().as_secs_f32() >= 0.75
|
||||||
|
} else {
|
||||||
|
previous_state.time.elapsed().as_secs_f32()
|
||||||
|
>= cricket_interval + thread_rng().gen_range(-0.1..0.1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
SfxEvent::Cricket3 => {
|
||||||
|
previous_state.time.elapsed().as_secs_f32()
|
||||||
|
>= cricket_interval + thread_rng().gen_range(-0.1..0.1)
|
||||||
|
},
|
||||||
|
//Adds random factor to frogs
|
||||||
|
SfxEvent::Frog => {
|
||||||
|
previous_state.time.elapsed().as_secs_f32()
|
||||||
|
>= thread_rng().gen_range(-2.0..2.0)
|
||||||
|
},
|
||||||
|
_ => previous_state.time.elapsed().as_secs_f32() >= item.threshold,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,9 @@ pub enum SfxEvent {
|
|||||||
Embers,
|
Embers,
|
||||||
Birdcall,
|
Birdcall,
|
||||||
Owl,
|
Owl,
|
||||||
Cricket,
|
Cricket1,
|
||||||
|
Cricket2,
|
||||||
|
Cricket3,
|
||||||
Frog,
|
Frog,
|
||||||
Bees,
|
Bees,
|
||||||
RunningWater,
|
RunningWater,
|
||||||
|
@ -18,6 +18,11 @@ pub struct BlocksOfInterest {
|
|||||||
pub flowers: Vec<Vec3<i32>>,
|
pub flowers: Vec<Vec3<i32>>,
|
||||||
pub fire_bowls: Vec<Vec3<i32>>,
|
pub fire_bowls: Vec<Vec3<i32>>,
|
||||||
pub snow: Vec<Vec3<i32>>,
|
pub snow: Vec<Vec3<i32>>,
|
||||||
|
//This is so crickets stay in place and don't randomly change sounds
|
||||||
|
pub cricket1: Vec<Vec3<i32>>,
|
||||||
|
pub cricket2: Vec<Vec3<i32>>,
|
||||||
|
pub cricket3: Vec<Vec3<i32>>,
|
||||||
|
pub frogs: Vec<Vec3<i32>>,
|
||||||
// Note: these are only needed for chunks within the iteraction range so this is a potential
|
// Note: these are only needed for chunks within the iteraction range so this is a potential
|
||||||
// area for optimization
|
// area for optimization
|
||||||
pub interactables: Vec<Vec3<i32>>,
|
pub interactables: Vec<Vec3<i32>>,
|
||||||
@ -39,6 +44,10 @@ impl BlocksOfInterest {
|
|||||||
let mut lights = Vec::new();
|
let mut lights = Vec::new();
|
||||||
let mut fire_bowls = Vec::new();
|
let mut fire_bowls = Vec::new();
|
||||||
let mut snow = Vec::new();
|
let mut snow = Vec::new();
|
||||||
|
let mut cricket1 = Vec::new();
|
||||||
|
let mut cricket2 = Vec::new();
|
||||||
|
let mut cricket3 = Vec::new();
|
||||||
|
let mut frogs = Vec::new();
|
||||||
|
|
||||||
chunk
|
chunk
|
||||||
.vol_iter(
|
.vol_iter(
|
||||||
@ -52,7 +61,17 @@ impl BlocksOfInterest {
|
|||||||
.for_each(|(pos, block)| {
|
.for_each(|(pos, block)| {
|
||||||
match block.kind() {
|
match block.kind() {
|
||||||
BlockKind::Leaves if thread_rng().gen_range(0..16) == 0 => leaves.push(pos),
|
BlockKind::Leaves if thread_rng().gen_range(0..16) == 0 => leaves.push(pos),
|
||||||
BlockKind::Grass if thread_rng().gen_range(0..16) == 0 => grass.push(pos),
|
BlockKind::Grass => {
|
||||||
|
if thread_rng().gen_range(0..16) == 0 {
|
||||||
|
grass.push(pos);
|
||||||
|
}
|
||||||
|
match thread_rng().gen_range(0..8192) {
|
||||||
|
1 => cricket1.push(pos),
|
||||||
|
2 => cricket2.push(pos),
|
||||||
|
3 => cricket3.push(pos),
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
},
|
||||||
BlockKind::Water
|
BlockKind::Water
|
||||||
if chunk.meta().contains_river() && thread_rng().gen_range(0..16) == 0 =>
|
if chunk.meta().contains_river() && thread_rng().gen_range(0..16) == 0 =>
|
||||||
{
|
{
|
||||||
@ -73,7 +92,12 @@ impl BlocksOfInterest {
|
|||||||
},
|
},
|
||||||
Some(SpriteKind::WallSconce) => fire_bowls.push(pos + Vec3::unit_z()),
|
Some(SpriteKind::WallSconce) => fire_bowls.push(pos + Vec3::unit_z()),
|
||||||
Some(SpriteKind::Beehive) => beehives.push(pos),
|
Some(SpriteKind::Beehive) => beehives.push(pos),
|
||||||
Some(SpriteKind::Reed) => reeds.push(pos),
|
Some(SpriteKind::Reed) => {
|
||||||
|
reeds.push(pos);
|
||||||
|
if thread_rng().gen_range(0..12) == 0 {
|
||||||
|
frogs.push(pos)
|
||||||
|
}
|
||||||
|
},
|
||||||
Some(SpriteKind::PinkFlower) => flowers.push(pos),
|
Some(SpriteKind::PinkFlower) => flowers.push(pos),
|
||||||
Some(SpriteKind::PurpleFlower) => flowers.push(pos),
|
Some(SpriteKind::PurpleFlower) => flowers.push(pos),
|
||||||
Some(SpriteKind::RedFlower) => flowers.push(pos),
|
Some(SpriteKind::RedFlower) => flowers.push(pos),
|
||||||
@ -104,6 +128,10 @@ impl BlocksOfInterest {
|
|||||||
lights,
|
lights,
|
||||||
fire_bowls,
|
fire_bowls,
|
||||||
snow,
|
snow,
|
||||||
|
cricket1,
|
||||||
|
cricket2,
|
||||||
|
cricket3,
|
||||||
|
frogs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,7 @@ impl World {
|
|||||||
sim_chunk.tree_density,
|
sim_chunk.tree_density,
|
||||||
sim_chunk.cave.1.alt != 0.0,
|
sim_chunk.cave.1.alt != 0.0,
|
||||||
sim_chunk.river.is_river(),
|
sim_chunk.river.is_river(),
|
||||||
|
sim_chunk.temp,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut chunk = TerrainChunk::new(base_z, stone, air, meta);
|
let mut chunk = TerrainChunk::new(base_z, stone, air, meta);
|
||||||
|
Loading…
Reference in New Issue
Block a user