Completely redoing ambient sound again.

This commit is contained in:
DaforLynx 2022-03-19 02:14:54 -07:00 committed by IsseW
parent 16ca1410be
commit aafd13508d
8 changed files with 249 additions and 245 deletions

View File

@ -111,7 +111,9 @@ impl Outcome {
| Outcome::Utterance { pos, .. } | Outcome::Utterance { pos, .. }
| Outcome::Glider { pos, .. } => Some(*pos), | Outcome::Glider { pos, .. } => Some(*pos),
Outcome::BreakBlock { pos, .. } => Some(pos.map(|e| e as f32 + 0.5)), Outcome::BreakBlock { pos, .. } => Some(pos.map(|e| e as f32 + 0.5)),
Outcome::ExpChange { .. } | Outcome::ComboChange { .. } | Outcome::SkillPointGain { .. } => None, Outcome::ExpChange { .. }
| Outcome::ComboChange { .. }
| Outcome::SkillPointGain { .. } => None,
} }
} }
} }

View File

@ -1,6 +1,9 @@
//! Handles ambient non-positional sounds //! Handles ambient non-positional sounds
use crate::{ use crate::{
audio::{channel::AmbientChannelTag, AudioFrontend}, audio::{
channel::{AmbientChannel, AmbientChannelTag},
AudioFrontend,
},
scene::Camera, scene::Camera,
}; };
use client::Client; use client::Client;
@ -10,12 +13,13 @@ use common::{
}; };
use common_state::State; use common_state::State;
use serde::Deserialize; use serde::Deserialize;
use strum::IntoEnumIterator;
use std::time::Instant; use std::time::Instant;
use tracing::warn; use tracing::warn;
use vek::*; use vek::*;
#[derive(Debug, Default, Deserialize)] #[derive(Debug, Default, Deserialize)]
struct AmbientCollection { pub struct AmbientCollection {
tracks: Vec<AmbientItem>, tracks: Vec<AmbientItem>,
} }
@ -29,49 +33,11 @@ pub struct AmbientItem {
tag: AmbientChannelTag, tag: AmbientChannelTag,
} }
pub struct AmbientWindMgr { pub struct AmbientMgr {
ambience: AssetHandle<AmbientCollection>, pub ambience: AssetHandle<AmbientCollection>,
began_playing: Instant,
next_track_change: f32,
volume: f32,
tree_multiplier: f32,
} }
pub struct AmbientRainMgr { impl AmbientMgr {
ambience: AssetHandle<AmbientCollection>,
began_playing: Instant,
next_track_change: f32,
volume: f32,
rain_intensity: f32,
}
impl Default for AmbientWindMgr {
fn default() -> Self {
Self {
ambience: load_ambience_items(),
began_playing: Instant::now(),
next_track_change: 0.0,
volume: 0.0,
tree_multiplier: 0.0,
}
}
}
impl Default for AmbientRainMgr {
fn default() -> Self {
Self {
ambience: load_ambience_items(),
began_playing: Instant::now(),
next_track_change: 0.0,
volume: 0.0,
rain_intensity: 0.0,
}
}
}
impl AmbientWindMgr {
/// Checks whether the previous track has completed. If so, sends a
/// request to play the next (random) track
pub fn maintain( pub fn maintain(
&mut self, &mut self,
audio: &mut AudioFrontend, audio: &mut AudioFrontend,
@ -79,157 +45,156 @@ impl AmbientWindMgr {
client: &Client, client: &Client,
camera: &Camera, camera: &Camera,
) { ) {
if audio.sfx_enabled() && !self.ambience.read().tracks.is_empty() { let sfx_volume = audio.get_sfx_volume();
let focus_off = camera.get_focus_pos().map(f32::trunc); // iterate through each tag
let cam_pos = camera.dependents().cam_pos + focus_off; for tag in AmbientChannelTag::iter() {
// iterate through the supposed number of channels - one for each tag
let (terrain_alt, tree_density) = if let Some(chunk) = client.current_chunk() { for index in 0..AmbientChannelTag::iter().len() {
(chunk.meta().alt(), chunk.meta().tree_density()) // if index would exceed current number of channels, create a new one with
} else { // current tag
(0.0, 0.0) if index >= audio.ambient_channels.len() {
}; audio.new_ambient_channel(tag);
// The following code is specifically for wind, as it is the only
// non-positional ambient sound in the game. Others can be added
// as seen fit.
let target_volume = {
// Wind volume increases with altitude
let alt_multiplier = (cam_pos.z / 1200.0).abs();
// Tree density factors into wind volume. The more trees,
// the lower wind volume. The trees make more of an impact
// the closer the camera is to the ground.
self.tree_multiplier = ((1.0 - tree_density)
+ ((cam_pos.z - terrain_alt).abs() / 150.0).powi(2))
.min(1.0);
let mut volume_multiplier = alt_multiplier * self.tree_multiplier;
// Checks if the camera is underwater to stop ambient sounds
if state
.terrain()
.get((cam_pos).map(|e| e.floor() as i32))
.map(|b| b.is_liquid())
.unwrap_or(false)
{
volume_multiplier *= 0.1;
}
// Is the camera roughly under the terrain?
if cam_pos.z < terrain_alt - 10.0 {
volume_multiplier = 0.0;
} }
// update with sfx volume
audio.ambient_channels[index].set_volume(sfx_volume);
// if current channel's tag is not the current tag, move on to next channel
if audio.ambient_channels[index].get_tag() == tag {
// maintain: get the correct multiplier of whatever the tag of the current
// channel is
let target_volume =
audio.ambient_channels[index].maintain(state, client, camera);
// get multiplier of the current channel
let initial_volume = audio.ambient_channels[index].get_multiplier();
volume_multiplier.clamped(0.0, 1.0) // lerp multiplier of current channel
}; audio.ambient_channels[index].set_multiplier(Lerp::lerp(
initial_volume,
target_volume,
0.01,
));
// Transitions the ambient sounds (more) smoothly // set the duration of the loop to whatever the current value is (0.0 by
if audio.get_ambient_channel(AmbientChannelTag::Wind).is_none() { // default)
audio.new_ambient_channel(AmbientChannelTag::Wind); let next_track_change = audio.ambient_channels[index].get_next_track_change();
} else {
self.volume = audio.get_ambient_volume(AmbientChannelTag::Wind);
audio.set_ambient_volume(
AmbientChannelTag::Wind,
Lerp::lerp(self.volume, target_volume, 0.01),
);
}
if self.began_playing.elapsed().as_secs_f32() > self.next_track_change { // if the sound should loop at this point:
let ambience = self.ambience.read(); if audio.ambient_channels[index]
let wind_track = &ambience .get_began_playing()
.tracks .elapsed()
.iter() .as_secs_f32()
.find(|track| track.tag == AmbientChannelTag::Wind); > next_track_change
self.began_playing = Instant::now(); {
if let Some(wind_track) = wind_track { let ambience = self.ambience.read();
self.next_track_change = wind_track.length; let track = ambience.tracks.iter().find(|track| track.tag == tag);
audio.play_ambient(AmbientChannelTag::Wind, &wind_track.path, target_volume); // set the track's start point at this instant
} audio.ambient_channels[index].set_began_playing(Instant::now());
} if let Some(track) = track {
} // set loop duration to the one specified in the ron
} audio.ambient_channels[index].set_next_track_change(track.length);
} // play the file of the current tag at the current multiplier
let current_multiplier = audio.ambient_channels[index].get_multiplier();
audio.play_ambient(tag, &track.path, current_multiplier);
}
};
impl AmbientRainMgr { // remove channel if not playing
/// Checks whether the previous track has completed. If so, sends a if audio.ambient_channels[index].get_multiplier() == 0.0 {
/// request to play the next (random) track audio.ambient_channels[index].stop();
pub fn maintain( audio.ambient_channels.remove(index);
&mut self, };
audio: &mut AudioFrontend, // move on to next tag
state: &State, break;
client: &Client,
camera: &Camera,
) {
if audio.sfx_enabled() && !self.ambience.read().tracks.is_empty() {
let focus_off = camera.get_focus_pos().map(f32::trunc);
let cam_pos = camera.dependents().cam_pos + focus_off;
let terrain_alt = if let Some(chunk) = client.current_chunk() {
chunk.meta().alt()
} else {
0.0
};
// multipler at end will have to change depending on how intense rain normally
// is
self.rain_intensity = client.current_weather().rain * 5.0;
let mut volume_multiplier = self.rain_intensity;
// TODO: make rain diminish with distance above terrain
let target_volume = {
// Checks if the camera is underwater to stop ambient sounds
if state
.terrain()
.get((cam_pos).map(|e| e.floor() as i32))
.map(|b| b.is_liquid())
.unwrap_or(false)
{
volume_multiplier *= 0.1;
}
// Is the camera roughly under the terrain?
if cam_pos.z < terrain_alt - 10.0 {
volume_multiplier = 0.0;
}
volume_multiplier = volume_multiplier.clamped(0.0, 1.0);
// possibly remove noise
if volume_multiplier < 0.05 {
0.0
} else { } else {
volume_multiplier // channel tag and current tag don't match, move on to next channel
} continue;
};
// Transitions the ambient sounds (more) smoothly
if audio.get_ambient_channel(AmbientChannelTag::Rain).is_none() {
audio.new_ambient_channel(AmbientChannelTag::Rain);
} else {
self.volume = audio.get_ambient_volume(AmbientChannelTag::Rain);
audio.set_ambient_volume(
AmbientChannelTag::Rain,
Lerp::lerp(self.volume, target_volume, 0.01),
);
}
if self.began_playing.elapsed().as_secs_f32() > self.next_track_change {
let ambience = self.ambience.read();
let rain_track = &ambience
.tracks
.iter()
.find(|track| track.tag == AmbientChannelTag::Rain);
self.began_playing = Instant::now();
if let Some(rain_track) = rain_track {
self.next_track_change = rain_track.length;
audio.play_ambient(AmbientChannelTag::Rain, &rain_track.path, target_volume);
} }
} }
} }
} }
} }
fn load_ambience_items() -> AssetHandle<AmbientCollection> { impl AmbientChannel {
pub fn maintain(&mut self, state: &State, client: &Client, camera: &Camera) -> f32 {
let tag = self.get_tag();
let focus_off = camera.get_focus_pos().map(f32::trunc);
let cam_pos = camera.dependents().cam_pos + focus_off;
let mut target_volume: f32 = match tag {
// Get target volume of wind
AmbientChannelTag::Wind => self.get_wind_volume(client, camera),
// get target volume of rain
AmbientChannelTag::Rain => self.get_rain_volume(client),
};
// TODO: make rain diminish with distance above terrain
target_volume = self.check_camera(state, client, cam_pos, target_volume);
return target_volume;
}
fn check_camera(
&mut self,
state: &State,
client: &Client,
cam_pos: Vec3<f32>,
initial_volume: f32,
) -> f32 {
let mut volume_multiplier = initial_volume;
let terrain_alt = if let Some(chunk) = client.current_chunk() {
chunk.meta().alt()
} else {
0.0
};
// Checks if the camera is underwater to stop ambient sounds
if state
.terrain()
.get((cam_pos).map(|e| e.floor() as i32))
.map(|b| b.is_liquid())
.unwrap_or(false)
{
volume_multiplier *= 0.1;
}
// Is the camera roughly under the terrain?
if cam_pos.z < terrain_alt - 10.0 {
volume_multiplier = 0.0;
}
volume_multiplier.clamped(0.0, 1.0)
}
fn get_wind_volume(&mut self, client: &Client, camera: &Camera) -> f32 {
let focus_off = camera.get_focus_pos().map(f32::trunc);
let cam_pos = camera.dependents().cam_pos + focus_off;
let (terrain_alt, tree_density) = if let Some(chunk) = client.current_chunk() {
(chunk.meta().alt(), chunk.meta().tree_density())
} else {
(0.0, 0.0)
};
// Wind volume increases with altitude
let alt_multiplier = (cam_pos.z / 1200.0).abs();
// Tree density factors into wind volume. The more trees,
// the lower wind volume. The trees make more of an impact
// the closer the camera is to the ground.
let tree_multiplier =
((1.0 - tree_density) + ((cam_pos.z - terrain_alt).abs() / 150.0).powi(2)).min(1.0);
return alt_multiplier * tree_multiplier;
}
fn get_rain_volume(&mut self, client: &Client) -> f32 {
// multipler at end will have to change depending on how intense rain normally
// is
let rain_intensity = client.current_weather().rain * 5.0;
return rain_intensity;
}
}
pub fn load_ambience_items() -> AssetHandle<AmbientCollection> {
AmbientCollection::load_or_insert_with("voxygen.audio.ambient", |error| { AmbientCollection::load_or_insert_with("voxygen.audio.ambient", |error| {
warn!( warn!(
"Error reading ambience config file, ambience will not be available: {:#?}", "Error reading ambience config file, ambience will not be available: {:#?}",

View File

@ -22,6 +22,8 @@ use crate::audio::{
}; };
use rodio::{OutputStreamHandle, Sample, Sink, Source, SpatialSink}; use rodio::{OutputStreamHandle, Sample, Sink, Source, SpatialSink};
use serde::Deserialize; use serde::Deserialize;
use strum::EnumIter;
use std::time::Instant;
use tracing::warn; use tracing::warn;
use vek::*; use vek::*;
@ -157,7 +159,7 @@ impl MusicChannel {
/// AmbientChannelTags are used for non-positional sfx. Currently the only use /// AmbientChannelTags are used for non-positional sfx. Currently the only use
/// is for wind. /// is for wind.
#[derive(Debug, PartialEq, Clone, Copy, Deserialize)] #[derive(Debug, PartialEq, Clone, Copy, Deserialize, EnumIter)]
pub enum AmbientChannelTag { pub enum AmbientChannelTag {
Wind, Wind,
Rain, Rain,
@ -168,6 +170,8 @@ pub struct AmbientChannel {
tag: AmbientChannelTag, tag: AmbientChannelTag,
multiplier: f32, multiplier: f32,
sink: Sink, sink: Sink,
began_playing: Instant,
next_track_change: f32,
} }
impl AmbientChannel { impl AmbientChannel {
@ -178,6 +182,8 @@ impl AmbientChannel {
tag, tag,
multiplier, multiplier,
sink, sink,
began_playing: Instant::now(),
next_track_change: 0.0,
}, },
Err(_) => { Err(_) => {
warn!("Failed to create rodio sink. May not play ambient sounds."); warn!("Failed to create rodio sink. May not play ambient sounds.");
@ -185,6 +191,8 @@ impl AmbientChannel {
tag, tag,
multiplier, multiplier,
sink: Sink::new_idle().0, sink: Sink::new_idle().0,
began_playing: Instant::now(),
next_track_change: 0.0,
} }
}, },
} }
@ -211,6 +219,20 @@ impl AmbientChannel {
pub fn get_multiplier(&mut self) -> f32 { self.multiplier } pub fn get_multiplier(&mut self) -> f32 { self.multiplier }
pub fn get_tag(&self) -> AmbientChannelTag { self.tag } pub fn get_tag(&self) -> AmbientChannelTag { self.tag }
pub fn set_tag(&mut self, tag: AmbientChannelTag) { self.tag = tag }
pub fn get_began_playing(&self) -> Instant { self.began_playing }
pub fn get_next_track_change(&self) -> f32 { self.next_track_change }
pub fn set_began_playing(&mut self, began_playing: Instant) {
self.began_playing = began_playing
}
pub fn set_next_track_change(&mut self, next_track_change: f32) {
self.next_track_change = next_track_change
}
} }
/// An SfxChannel uses a positional audio sink, and is designed for short-lived /// An SfxChannel uses a positional audio sink, and is designed for short-lived
@ -264,9 +286,8 @@ impl SfxChannel {
pub fn update(&mut self, listener: &Listener) { pub fn update(&mut self, listener: &Listener) {
const FALLOFF: f32 = 0.13; const FALLOFF: f32 = 0.13;
self.sink.set_emitter_position( self.sink
((self.pos - listener.pos) * FALLOFF).into_array(), .set_emitter_position(((self.pos - listener.pos) * FALLOFF).into_array());
);
self.sink self.sink
.set_left_ear_position(listener.ear_left_rpos.into_array()); .set_left_ear_position(listener.ear_left_rpos.into_array());
self.sink self.sink
@ -281,7 +302,7 @@ pub struct UIChannel {
impl UIChannel { impl UIChannel {
pub fn new(stream: &OutputStreamHandle) -> Self { pub fn new(stream: &OutputStreamHandle) -> Self {
Self { Self {
sink: Sink::try_new(stream).unwrap() sink: Sink::try_new(stream).unwrap(),
} }
} }

View File

@ -7,7 +7,9 @@ pub mod music;
pub mod sfx; pub mod sfx;
pub mod soundcache; pub mod soundcache;
use channel::{AmbientChannel, AmbientChannelTag, MusicChannel, MusicChannelTag, SfxChannel, UIChannel}; use channel::{
AmbientChannel, AmbientChannelTag, MusicChannel, MusicChannelTag, SfxChannel, UIChannel,
};
use fader::Fader; use fader::Fader;
use music::MusicTransitionManifest; use music::MusicTransitionManifest;
use sfx::{SfxEvent, SfxTriggerItem}; use sfx::{SfxEvent, SfxTriggerItem};
@ -38,16 +40,16 @@ pub struct AudioFrontend {
//pub device_list: Vec<String>, //pub device_list: Vec<String>,
//pub audio_device: Option<Device>, //pub audio_device: Option<Device>,
pub stream: Option<rodio::OutputStream>, pub stream: Option<rodio::OutputStream>,
audio_stream: Option<rodio::OutputStreamHandle>, pub audio_stream: Option<rodio::OutputStreamHandle>,
music_channels: Vec<MusicChannel>, pub music_channels: Vec<MusicChannel>,
ambient_channels: Vec<AmbientChannel>, pub ambient_channels: Vec<AmbientChannel>,
sfx_channels: Vec<SfxChannel>, pub sfx_channels: Vec<SfxChannel>,
ui_channels: Vec<UIChannel>, pub ui_channels: Vec<UIChannel>,
sfx_volume: f32, pub sfx_volume: f32,
music_volume: f32, pub music_volume: f32,
master_volume: f32, pub master_volume: f32,
listener: Listener, pub listener: Listener,
mtm: AssetHandle<MusicTransitionManifest>, mtm: AssetHandle<MusicTransitionManifest>,
} }
@ -216,7 +218,11 @@ impl AudioFrontend {
/// Function to play sfx from external places. Useful for UI and /// Function to play sfx from external places. Useful for UI and
/// inventory events /// inventory events
pub fn emit_sfx_item(&mut self, trigger_item: Option<(&SfxEvent, &SfxTriggerItem)>, vol: Option<f32>) { pub fn emit_sfx_item(
&mut self,
trigger_item: Option<(&SfxEvent, &SfxTriggerItem)>,
vol: Option<f32>,
) {
if let Some((event, item)) = trigger_item { if let Some((event, item)) = trigger_item {
let sfx_file = match item.files.len() { let sfx_file = match item.files.len() {
0 => { 0 => {
@ -302,7 +308,7 @@ impl AudioFrontend {
} else { } else {
channel.play(sound); channel.play(sound);
} }
} }
} }
Ok(()) Ok(())
} }
@ -371,29 +377,29 @@ impl AudioFrontend {
} }
// sets the volume of the channel with the given tag to the given volume // sets the volume of the channel with the given tag to the given volume
fn set_ambient_volume(&mut self, channel_tag: AmbientChannelTag, volume_multiplier: f32) { // fn set_ambient_volume(&mut self, channel_tag: AmbientChannelTag,
if self.audio_stream.is_some() { // volume_multiplier: f32) { if self.audio_stream.is_some() {
let sfx_volume = self.get_sfx_volume(); // let sfx_volume = self.get_sfx_volume();
if let Some(channel) = self.get_ambient_channel(channel_tag) { // if let Some(channel) = self.get_ambient_channel(channel_tag) {
channel.set_multiplier(volume_multiplier); // channel.set_multiplier(volume_multiplier);
channel.set_volume(sfx_volume); // channel.set_volume(sfx_volume);
} // }
} // }
} // }
// retrieves volume (pre-sfx-setting) of the channel with a given tag // retrieves volume (pre-sfx-setting) of the channel with a given tag
fn get_ambient_volume(&mut self, channel_tag: AmbientChannelTag) -> f32 { // fn get_ambient_volume(&mut self, channel_tag: AmbientChannelTag) -> f32 {
if self.audio_stream.is_some() { // if self.audio_stream.is_some() {
if let Some(channel) = self.get_ambient_channel(channel_tag) { // if let Some(channel) = self.get_ambient_channel(channel_tag) {
let channel_multiplier = channel.get_multiplier(); // let channel_multiplier = channel.get_multiplier();
channel_multiplier // channel_multiplier
} else { // } else {
0.0 // 0.0
} // }
} else { // } else {
0.0 // 0.0
} // }
} // }
fn play_music(&mut self, sound: &str, channel_tag: MusicChannelTag) { fn play_music(&mut self, sound: &str, channel_tag: MusicChannelTag) {
if self.music_enabled() { if self.music_enabled() {

View File

@ -82,7 +82,7 @@
mod event_mapper; mod event_mapper;
use specs::{WorldExt}; use specs::WorldExt;
use crate::{ use crate::{
audio::AudioFrontend, audio::AudioFrontend,

View File

@ -223,7 +223,10 @@ fn main() {
// Setup audio // Setup audio
let mut audio = match settings.audio.output { let mut audio = match settings.audio.output {
AudioOutput::Off => AudioFrontend::no_audio(), AudioOutput::Off => AudioFrontend::no_audio(),
AudioOutput::Automatic => AudioFrontend::new(settings.audio.num_sfx_channels, settings.audio.num_ui_channels), AudioOutput::Automatic => AudioFrontend::new(
settings.audio.num_sfx_channels,
settings.audio.num_ui_channels,
),
// AudioOutput::Device(ref dev) => Some(dev.clone()), // AudioOutput::Device(ref dev) => Some(dev.clone()),
}; };

View File

@ -19,12 +19,7 @@ pub use self::{
trail::TrailMgr, trail::TrailMgr,
}; };
use crate::{ use crate::{
audio::{ audio::{ambient, ambient::AmbientMgr, music::MusicMgr, sfx::SfxMgr, AudioFrontend},
ambient::{AmbientRainMgr, AmbientWindMgr},
music::MusicMgr,
sfx::SfxMgr,
AudioFrontend,
},
render::{ render::{
create_skybox_mesh, CloudsLocals, Consts, Drawer, GlobalModel, Globals, GlobalsBindGroup, create_skybox_mesh, CloudsLocals, Consts, Drawer, GlobalModel, Globals, GlobalsBindGroup,
Light, Model, PointLightMatrix, PostProcessLocals, Renderer, Shadow, ShadowLocals, Light, Model, PointLightMatrix, PostProcessLocals, Renderer, Shadow, ShadowLocals,
@ -107,8 +102,9 @@ pub struct Scene {
figure_mgr: FigureMgr, figure_mgr: FigureMgr,
pub sfx_mgr: SfxMgr, pub sfx_mgr: SfxMgr,
music_mgr: MusicMgr, music_mgr: MusicMgr,
ambient_wind_mgr: AmbientWindMgr, ambient_mgr: AmbientMgr,
ambient_rain_mgr: AmbientRainMgr, // ambient_wind_mgr: AmbientWindMgr,
// ambient_rain_mgr: AmbientRainMgr,
} }
pub struct SceneData<'a> { pub struct SceneData<'a> {
@ -320,8 +316,11 @@ impl Scene {
figure_mgr: FigureMgr::new(renderer), figure_mgr: FigureMgr::new(renderer),
sfx_mgr: SfxMgr::default(), sfx_mgr: SfxMgr::default(),
music_mgr: MusicMgr::default(), music_mgr: MusicMgr::default(),
ambient_wind_mgr: AmbientWindMgr::default(), ambient_mgr: AmbientMgr {
ambient_rain_mgr: AmbientRainMgr::default(), ambience: ambient::load_ambience_items(),
},
// ambient_wind_mgr: AmbientWindMgr::default(),
// ambient_rain_mgr: AmbientRainMgr::default(),
} }
} }
@ -414,10 +413,10 @@ impl Scene {
) { ) {
span!(_guard, "handle_outcome", "Scene::handle_outcome"); span!(_guard, "handle_outcome", "Scene::handle_outcome");
let underwater = state let underwater = state
.terrain() .terrain()
.get(cam_pos.map(|e| e.floor() as i32)) .get(cam_pos.map(|e| e.floor() as i32))
.map(|b| b.is_liquid()) .map(|b| b.is_liquid())
.unwrap_or(false); .unwrap_or(false);
self.particle_mgr.handle_outcome(outcome, scene_data); self.particle_mgr.handle_outcome(outcome, scene_data);
self.sfx_mgr self.sfx_mgr
.handle_outcome(outcome, audio, scene_data.client, state, underwater); .handle_outcome(outcome, audio, scene_data.client, state, underwater);
@ -1080,10 +1079,12 @@ impl Scene {
client, client,
); );
self.music_mgr.maintain(audio, scene_data.state, client); self.music_mgr.maintain(audio, scene_data.state, client);
self.ambient_wind_mgr self.ambient_mgr
.maintain(audio, scene_data.state, client, &self.camera);
self.ambient_rain_mgr
.maintain(audio, scene_data.state, client, &self.camera); .maintain(audio, scene_data.state, client, &self.camera);
// self.ambient_wind_mgr
// .maintain(audio, scene_data.state, client, &self.camera);
// self.ambient_rain_mgr
// .maintain(audio, scene_data.state, client, &self.camera);
} }
pub fn global_bind_group(&self) -> &GlobalsBindGroup { &self.globals_bind_group } pub fn global_bind_group(&self) -> &GlobalsBindGroup { &self.globals_bind_group }

View File

@ -245,7 +245,9 @@ impl SessionState {
let sfx_triggers = self.scene.sfx_mgr.triggers.read(); let sfx_triggers = self.scene.sfx_mgr.triggers.read();
let sfx_trigger_item = sfx_triggers.get_key_value(&SfxEvent::from(&inv_event)); let sfx_trigger_item = sfx_triggers.get_key_value(&SfxEvent::from(&inv_event));
global_state.audio.emit_sfx_item(sfx_trigger_item, Some(1.0)); global_state
.audio
.emit_sfx_item(sfx_trigger_item, Some(1.0));
match inv_event { match inv_event {
InventoryUpdateEvent::BlockCollectFailed { pos, reason } => { InventoryUpdateEvent::BlockCollectFailed { pos, reason } => {
@ -358,7 +360,7 @@ impl PlayState for SessionState {
let client = self.client.borrow(); let client = self.client.borrow();
(client.presence(), client.registered()) (client.presence(), client.registered())
}; };
if client_presence.is_some() { if client_presence.is_some() {
let camera = self.scene.camera_mut(); let camera = self.scene.camera_mut();
@ -1577,12 +1579,16 @@ impl PlayState for SessionState {
&scene_data, &scene_data,
&client, &client,
); );
// Process outcomes from client // Process outcomes from client
for outcome in outcomes { for outcome in outcomes {
self.scene self.scene.handle_outcome(
.handle_outcome(&outcome, &scene_data, &mut global_state.audio, &client.state(), cam_pos); &outcome,
&scene_data,
&mut global_state.audio,
&client.state(),
cam_pos,
);
self.hud self.hud
.handle_outcome(&outcome, scene_data.client, global_state); .handle_outcome(&outcome, scene_data.client, global_state);
} }