From a684bc90fd28a9633e3d9fa3c61735a44e0bf6c7 Mon Sep 17 00:00:00 2001 From: jiminycrick Date: Wed, 11 Nov 2020 00:51:14 -0800 Subject: [PATCH] Quadraped footsteps and songs in biomes --- CHANGELOG.md | 4 + assets/voxygen/audio/ambient/wind.ogg | 4 +- assets/voxygen/audio/sfx.ron | 29 +- assets/voxygen/audio/soundtrack.ron | 313 ++++++++++-------- client/src/lib.rs | 8 +- common/src/terrain/site.rs | 2 +- voxygen/src/audio/mod.rs | 15 +- voxygen/src/audio/music.rs | 16 +- .../audio/sfx/event_mapper/movement/mod.rs | 28 +- voxygen/src/audio/sfx/mod.rs | 2 + voxygen/src/audio/wind.rs | 2 +- world/src/sim/mod.rs | 2 +- 12 files changed, 262 insertions(+), 163 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d709f84974..fd21d91c17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Upscaling support - Added "Persist Combo from Combo Melee State" when rolling mid-combo - You can no longer spam hammer and bow special when stamina is 0 +- Biome and site specific music system +- Ambient SFX emitted from terrain blocks +- Campfire SFX +- Wind SFX system ### Changed diff --git a/assets/voxygen/audio/ambient/wind.ogg b/assets/voxygen/audio/ambient/wind.ogg index 66a0bcf6be..37cac9eb05 100644 --- a/assets/voxygen/audio/ambient/wind.ogg +++ b/assets/voxygen/audio/ambient/wind.ogg @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d4e34c87ebbad553857788a44c14715388edab227069a23cd8d6409458b343f8 -size 107555 +oid sha256:c28c1067d78474057c8a5b4608bb0a6026f90377074e287bb87fbd3e8fa39098 +size 94292 diff --git a/assets/voxygen/audio/sfx.ron b/assets/voxygen/audio/sfx.ron index 9b7701454e..9feadcc507 100644 --- a/assets/voxygen/audio/sfx.ron +++ b/assets/voxygen/audio/sfx.ron @@ -75,6 +75,17 @@ ], threshold: 0.25, ), + QuadRun: ( + files: [ + "voxygen.audio.sfx.footsteps.stepgrass_1", + "voxygen.audio.sfx.footsteps.stepgrass_2", + "voxygen.audio.sfx.footsteps.stepgrass_3", + "voxygen.audio.sfx.footsteps.stepgrass_4", + "voxygen.audio.sfx.footsteps.stepgrass_5", + "voxygen.audio.sfx.footsteps.stepgrass_6", + ], + threshold: 0.12, + ), SnowRun: ( files: [ "voxygen.audio.sfx.footsteps.snow_step_1", @@ -83,6 +94,14 @@ ], threshold: 0.25, ), + QuadSnowRun: ( + files: [ + "voxygen.audio.sfx.footsteps.snow_step_1", + "voxygen.audio.sfx.footsteps.snow_step_2", + "voxygen.audio.sfx.footsteps.snow_step_3", + ], + threshold: 0.12, + ), ExperienceGained: ( files: [ // "voxygen.audio.sfx.character.experience_gained_1", @@ -214,7 +233,7 @@ ], threshold: 0.5, ), - Attack(BasicMelee, Hammer): ( + Attack(ComboMelee(Swing, 1), Hammer): ( files: [ "voxygen.audio.sfx.abilities.swing", ], @@ -254,7 +273,13 @@ ], threshold: 0.5, ), - Attack(BasicMelee, Axe): ( + Attack(ComboMelee(Swing, 1), Axe): ( + files: [ + "voxygen.audio.sfx.abilities.swing", + ], + threshold: 0.7, + ), + Attack(ComboMelee(Swing, 2), Axe): ( files: [ "voxygen.audio.sfx.abilities.swing", ], diff --git a/assets/voxygen/audio/soundtrack.ron b/assets/voxygen/audio/soundtrack.ron index e642d24873..5abdb84d9b 100644 --- a/assets/voxygen/audio/soundtrack.ron +++ b/assets/voxygen/audio/soundtrack.ron @@ -1,139 +1,174 @@ -// TODO: Re-add tunes that are not fitting general outside day/night situations -// TODO: Add an ambient-soundtrack that runs independently from the musical soundtrack - -( - tracks: [ - ( - title: "A Solemn Quest", - path: "voxygen.audio.soundtrack.a_solemn_quest", - length: 206.0, - timing: Some(Day), - biomes: [ - (Lake, 1), - (Grassland, 1), - ], - site: None, - artist: "Eden", - ), - ( - title: "Into The Dark Forest", - path: "voxygen.audio.soundtrack.into_the_dark_forest", - length: 184.0, - timing: Some(Day), - biomes: [ - (Forest, 1), - (Jungle, 1), - ], - site: None, - artist: "Aeronic", - ), - ( - title: "Field Grazing", - path: "voxygen.audio.soundtrack.field_grazing", - length: 154.0, - timing: Some(Day), - biomes: [], - site: None, - artist: "Aeronic", - ), - //( - // title: "Wandering Voices", - // path: "voxygen.audio.soundtrack.wandering_voices", - // length: 137.0, - // timing: Some(Day), - // biome: Some(Desert), - // site: None, - // artist: "Aeronic", - //), - //( - // title: "Snowtop Volume", //Snow Region - // path: "voxygen.audio.soundtrack.snowtop_volume", - // length: 89.0, - // timing: Some(Day), - // biome: Some(Desert), - // site: None, - // artist: "Aeronic", - //), - //( - // title: "Mineral Deposits", - // path: "voxygen.audio.soundtrack.mineral_deposits", - // length: 148.0, - // timing: Some(Day), - // biome: Some(Desert), - // site: None, - // artist: "Aeronic", - //), - //( - // title: "Moonbeams", - // path: "voxygen.audio.soundtrack.moonbeams", - // length: 158.0, - // timing: Some(Night), - // biome: Some(Desert), - // site: None, - // artist: "Aeronic", - //), - //( - // title: "Serene Meadows", - // path: "voxygen.audio.soundtrack.serene_meadows", - // length: 173.0, - // timing: Some(Night), - // biome: Some(Desert), - // site: None, - // artist: "Aeronic", - //), - ///*( - // title: "Rest Assured", // Town/Shop - // path: "voxygen.audio.soundtrack.rest_assured", - // length: 185.0, - // timing: Some(Day), - // biome: Some(Desert), - // site: None, - // artist: "badbbad", - //),*/ - //( - // title: "Just The Beginning", - // path: "voxygen.audio.soundtrack.just_the_beginning", - // length: 188.0, - // timing: Some(Day), - // biome: Some(Desert), - // site: None, - // artist: "badbbad", - //), - //( - // title: "Campfire Stories", - // path: "voxygen.audio.soundtrack.campfire_stories", - // length: 100.0, - // timing: Some(Night), - // biome: Some(Desert), - // site: None, - // artist: "badbbad", - //), - ( - title: "Limits", - path: "voxygen.audio.soundtrack.limits", - length: 203.0, - timing: None, - biomes: [], - site: Some(Dungeon), - artist: "badbbad", - ), - ( // Dungeon - title: "Down The Rabbit Hole", - path: "voxygen.audio.soundtrack.down_the_rabbit_hole", - length: 244.0, - timing: None, - biomes: [], - site: Some(Cave), - artist: "badbbad", - ), - //( - // title: "Between The Fairies", - // path: "voxygen.audio.soundtrack.between_the_fairies", - // length: 175.0, - // timing: None, - // biomes: [], - // site: Some(Cave), - // artist: "badbbad", - //), - ] -) +// TODO: Re-add tunes that are not fitting general outside day/night situations +// TODO: Add an ambient-soundtrack that runs independently from the musical soundtrack +//Times: Some(Day), Some(Night), None +//List of biomes currently: Grassland, Forest, Jungle, Desert, Snowland, Lake, Mountain +//Sites: Cave, Dungeon + +( + tracks: [ + ( + title: "A Solemn Quest", + path: "voxygen.audio.soundtrack.a_solemn_quest", + length: 206.0, + timing: Some(Night), + biomes: [ + (Jungle, 1), + (Desert, 1), + (Grassland, 1), + (Snowland, 1), + (Mountain, 1), + (Lake, 1), + ], + site: Some(Void), + artist: "Eden", + ), + ( + title: "Into The Dark Forest", + path: "voxygen.audio.soundtrack.into_the_dark_forest", + length: 184.0, + timing: Some(Night), + biomes: [ + (Forest, 1), + (Jungle, 1), + ], + site: Some(Void), + artist: "Aeronic", + ), + ( + title: "Field Grazing", + path: "voxygen.audio.soundtrack.field_grazing", + length: 154.0, + timing: Some(Day), + biomes: [ + (Grassland, 1), + ], + site: Some(Void), + artist: "Aeronic", + ), + ( + title: "Wandering Voices", + path: "voxygen.audio.soundtrack.wandering_voices", + length: 137.0, + timing: Some(Night), + biomes: [], + site: Some(Void), + artist: "Aeronic", + ), + ( + title: "Snowtop Volume", + path: "voxygen.audio.soundtrack.snowtop_volume", + length: 89.0, + timing: None, + biomes: [ + (Snowland, 1), + (Mountain, 1), + ], + site: Some(Void), + artist: "Aeronic", + ), + ( + title: "Mineral Deposits", + path: "voxygen.audio.soundtrack.mineral_deposits", + length: 148.0, + timing: None, + biomes: [], + site: Some(Cave), + artist: "Aeronic", + ), + ( + title: "Moonbeams", + path: "voxygen.audio.soundtrack.moonbeams", + length: 158.0, + timing: Some(Night), + biomes: [], + site: Some(Void), + artist: "Aeronic", + ), + ( + title: "Serene Meadows", + path: "voxygen.audio.soundtrack.serene_meadows", + length: 173.0, + timing: Some(Night), + biomes: [ + (Forest, 1), + (Grassland, 1), + ], + site: Some(Void), + artist: "Aeronic", + ), + //( + // title: "Rest Assured", // Town/Shop + // path: "voxygen.audio.soundtrack.rest_assured", + // length: 185.0, + // timing: Some(Day), + // biomes: [], + // site: Some(Void), + // artist: "badbbad", + //), + ( + title: "Just The Beginning", + path: "voxygen.audio.soundtrack.just_the_beginning", + length: 188.0, + timing: Some(Day), + biomes: [ + (Grassland, 1), + (Snowland, 1), + (Mountain, 1), + ], + site: Some(Void), + artist: "badbbad", + ), + ( + title: "Campfire Stories", + path: "voxygen.audio.soundtrack.campfire_stories", + length: 100.0, + timing: Some(Night), + biomes: [], + site: Some(Void), + artist: "badbbad", + ), + ( + title: "Limits", + path: "voxygen.audio.soundtrack.limits", + length: 203.0, + timing: None, + biomes: [ + (Desert, 1), + (Lake, 1) + ], + site: Some(Void), + artist: "badbbad", + ), + ( + title: "Down The Rabbit Hole", + path: "voxygen.audio.soundtrack.down_the_rabbit_hole", + length: 244.0, + timing: None, + biomes: [], + site: Some(Cave), + artist: "badbbad", + ), + ( //Repeat for other site + title: "Down The Rabbit Hole", + path: "voxygen.audio.soundtrack.down_the_rabbit_hole", + length: 244.0, + timing: None, + biomes: [], + site: Some(Dungeon), + artist: "badbbad", + ), + ( + title: "Between The Fairies", + path: "voxygen.audio.soundtrack.between_the_fairies", + length: 175.0, + timing: Some(Night), + biomes: [ + (Forest, 1), + (Lake, 1), + (Snowland, 1), + ], + site: Some(Void), + artist: "badbbad", + ) + ] +) diff --git a/client/src/lib.rs b/client/src/lib.rs index 16c1db3747..dc176b8f15 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -858,7 +858,13 @@ impl Client { } pub fn current_position(&self) -> Option> { - Some(self.state.read_storage::().get(self.entity).cloned()?.0) + Some( + self.state + .read_storage::() + .get(self.entity) + .cloned()? + .0, + ) } pub fn inventories(&self) -> ReadStorage { self.state.read_storage() } diff --git a/common/src/terrain/site.rs b/common/src/terrain/site.rs index eaf69b9d86..2156de3664 100644 --- a/common/src/terrain/site.rs +++ b/common/src/terrain/site.rs @@ -6,5 +6,5 @@ pub enum SitesKind { Cave, Settlement, Castle, - None, + Void, } diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 0d9d9d0e71..9ec556affc 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -11,10 +11,9 @@ use channel::{MusicChannel, MusicChannelTag, SfxChannel, WindChannel}; use fader::Fader; use soundcache::SoundCache; use std::time::Duration; -use tracing::warn; +//use tracing::warn; use common::assets; -//use cpal::traits::{DeviceTrait, HostTrait}; use rodio::{source::Source, Decoder, OutputStream, OutputStreamHandle, StreamError}; use vek::*; @@ -32,6 +31,7 @@ pub struct Listener { /// Voxygen's [`GlobalState`](../struct.GlobalState.html#structfield.audio) to /// provide access to devices and playback control in-game pub struct AudioFrontend { + // The following is for the disabled device switcher //pub device: String, //pub device_list: Vec, //pub audio_device: Option, @@ -70,6 +70,7 @@ impl AudioFrontend { }; Self { + // The following is for the disabled device switcher //device, //device_list: list_devices(), //audio_device, @@ -88,6 +89,7 @@ impl AudioFrontend { /// Construct in `no-audio` mode for debugging pub fn no_audio() -> Self { Self { + // The following is for the disabled device switcher //device: "".to_string(), //device_list: Vec::new(), //audio_device: None, @@ -211,7 +213,7 @@ impl AudioFrontend { fn get_wind_channel(&mut self, volume_multiplier: f32) -> Option<&mut WindChannel> { if self.audio_stream.is_some() { - if let Some(channel) = self.wind_channels.iter_mut().find(|_c| true) { + if let Some(channel) = self.wind_channels.iter_mut().last() { channel.set_volume(self.sfx_volume * volume_multiplier); return Some(channel); @@ -223,7 +225,7 @@ impl AudioFrontend { fn set_wind_volume(&mut self, volume_multiplier: f32) { if self.audio_stream.is_some() { - if let Some(channel) = self.wind_channels.iter_mut().find(|_c| true) { + if let Some(channel) = self.wind_channels.iter_mut().last() { channel.set_volume(self.sfx_volume * volume_multiplier); } } @@ -231,7 +233,7 @@ impl AudioFrontend { fn get_wind_volume(&mut self) -> f32 { if self.audio_stream.is_some() { - if let Some(channel) = self.wind_channels.iter_mut().find(|_c| true) { + if let Some(channel) = self.wind_channels.iter_mut().last() { channel.get_volume() / self.sfx_volume } else { 0.0 @@ -344,6 +346,7 @@ impl AudioFrontend { } } + // The following is for the disabled device switcher //// TODO: figure out how badly this will break things when it is called //pub fn set_device(&mut self, name: String) { // self.device = name.clone(); @@ -351,6 +354,7 @@ impl AudioFrontend { //} } +// The following is for the disabled device switcher ///// Returns the default audio device. ///// Does not return rodio Device struct in case our audio backend changes. //pub fn get_default_device() -> Option { @@ -365,6 +369,7 @@ pub fn get_default_stream() -> Result<(OutputStream, OutputStreamHandle), Stream rodio::OutputStream::try_default() } +// The following is for the disabled device switcher ///// Returns a stream on the specified device //pub fn get_stream( // device: &rodio::Device, diff --git a/voxygen/src/audio/music.rs b/voxygen/src/audio/music.rs index e1ae49daf0..8130b7d438 100644 --- a/voxygen/src/audio/music.rs +++ b/voxygen/src/audio/music.rs @@ -26,7 +26,11 @@ //! path: "voxygen.audio.soundtrack.sleepy", //! length: 400.0, //! timing: Some(Night), -//! biome: Some(Forest), +//! biome: [ +//! (Forest, 1), +//! (Grassland, 2), +//! ], +//! site: None, //! artist: "Elvis", //! ), //! ``` @@ -129,8 +133,9 @@ impl MusicMgr { //println!("chaos: {}", current_chunk.meta().chaos()); //println!("alt: {}", current_chunk.meta().alt()); //println!("temp: {}", current_chunk.meta().temp()); - //println!("tree_density: {}", current_chunk.meta().tree_density()); - //println!("humidity: {}", current_chunk.meta().humidity()); + //println!("tree_density: {}", + // current_chunk.meta().tree_density()); + // println!("humidity: {}", current_chunk.meta().humidity()); //println!("cave_alt: {}", current_chunk.meta().cave_alt()); //if let Some(position) = client.current_position() { // println!("player_pos: {:?}", position); @@ -163,7 +168,7 @@ impl MusicMgr { let mut rng = thread_rng(); // Adds a bit of randomness between plays - let silence_between_tracks_seconds: f32 = rng.gen_range(30.0, 60.0); + let silence_between_tracks_seconds: f32 = rng.gen_range(15.0, 60.0); let game_time = (state.get_time_of_day() as u64 % 86400) as u32; let current_period_of_day = Self::get_current_day_period(game_time); @@ -221,6 +226,7 @@ impl MusicMgr { }); if let Ok(track) = new_maybe_track { + println!("Now playing {:?}", track.title); self.last_track = String::from(&track.title); self.began_playing = Instant::now(); self.next_track_change = track.length + silence_between_tracks_seconds; @@ -260,7 +266,7 @@ impl MusicMgr { } else if player_alt < (terrain_alt - 20.0) { SitesKind::Dungeon } else { - SitesKind::None + SitesKind::Void } } diff --git a/voxygen/src/audio/sfx/event_mapper/movement/mod.rs b/voxygen/src/audio/sfx/event_mapper/movement/mod.rs index 2a61a87d28..df9d33366e 100644 --- a/voxygen/src/audio/sfx/event_mapper/movement/mod.rs +++ b/voxygen/src/audio/sfx/event_mapper/movement/mod.rs @@ -88,12 +88,10 @@ impl EventMapper for MovementEventMapper { vel.0, underfoot_block_kind, ), - Body::QuadrupedMedium(_) - | Body::QuadrupedSmall(_) - | Body::QuadrupedLow(_) - | Body::BirdMedium(_) - | Body::BirdSmall(_) - | Body::BipedLarge(_) => { + Body::QuadrupedMedium(_) | Body::QuadrupedSmall(_) | Body::QuadrupedLow(_) => { + Self::map_quadruped_movement_event(physics, vel.0, underfoot_block_kind) + }, + Body::BirdMedium(_) | Body::BirdSmall(_) | Body::BipedLarge(_) => { Self::map_non_humanoid_movement_event(physics, vel.0, underfoot_block_kind) }, _ => SfxEvent::Idle, // Ignore fish, etc... @@ -234,6 +232,24 @@ impl MovementEventMapper { } } + /// Maps a limited set of movements for quadruped entities + fn map_quadruped_movement_event( + physics_state: &PhysicsState, + vel: Vec3, + underfoot_block_kind: BlockKind, + ) -> SfxEvent { + if physics_state.in_liquid.is_some() && vel.magnitude() > 0.1 { + SfxEvent::Swim + } else if physics_state.on_ground && vel.magnitude() > 0.1 { + match underfoot_block_kind { + BlockKind::Snow => SfxEvent::QuadSnowRun, + _ => SfxEvent::QuadRun, + } + } else { + SfxEvent::Idle + } + } + /// Returns a relative volume value for a body type. This helps us emit sfx /// at a volume appropriate fot the entity we are emitting the event for fn get_volume_for_body_type(body: &Body) -> f32 { diff --git a/voxygen/src/audio/sfx/mod.rs b/voxygen/src/audio/sfx/mod.rs index 5f9e004719..55d40531cc 100644 --- a/voxygen/src/audio/sfx/mod.rs +++ b/voxygen/src/audio/sfx/mod.rs @@ -151,7 +151,9 @@ pub enum SfxEvent { Idle, Swim, Run, + QuadRun, SnowRun, + QuadSnowRun, Roll, Sneak, Climb, diff --git a/voxygen/src/audio/wind.rs b/voxygen/src/audio/wind.rs index 1c5f31ad7d..2544dceaf5 100644 --- a/voxygen/src/audio/wind.rs +++ b/voxygen/src/audio/wind.rs @@ -101,7 +101,7 @@ impl WindMgr { { volume_multiplier *= volume_multiplier; } - if cam_pos.z < Self::get_current_terrain_alt(client) - 20.0 { + if cam_pos.z < Self::get_current_terrain_alt(client) - 10.0 { volume_multiplier = 0.0; } diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 2ec204b473..d587ba4106 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -2303,7 +2303,7 @@ impl SimChunk { pub fn get_biome(&self) -> BiomeKind { if self.alt < CONFIG.sea_level { BiomeKind::Ocean - } else if self.humidity == 0.0 { + } else if self.humidity == 0.5 { BiomeKind::Lake } else if self.temp < CONFIG.snow_temp { BiomeKind::Snowland