mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Completely redoing ambient sound again.
This commit is contained in:
parent
16ca1410be
commit
aafd13508d
@ -111,7 +111,9 @@ impl Outcome {
|
||||
| Outcome::Utterance { pos, .. }
|
||||
| Outcome::Glider { pos, .. } => Some(*pos),
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
//! Handles ambient non-positional sounds
|
||||
use crate::{
|
||||
audio::{channel::AmbientChannelTag, AudioFrontend},
|
||||
audio::{
|
||||
channel::{AmbientChannel, AmbientChannelTag},
|
||||
AudioFrontend,
|
||||
},
|
||||
scene::Camera,
|
||||
};
|
||||
use client::Client;
|
||||
@ -10,12 +13,13 @@ use common::{
|
||||
};
|
||||
use common_state::State;
|
||||
use serde::Deserialize;
|
||||
use strum::IntoEnumIterator;
|
||||
use std::time::Instant;
|
||||
use tracing::warn;
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
struct AmbientCollection {
|
||||
pub struct AmbientCollection {
|
||||
tracks: Vec<AmbientItem>,
|
||||
}
|
||||
|
||||
@ -29,49 +33,11 @@ pub struct AmbientItem {
|
||||
tag: AmbientChannelTag,
|
||||
}
|
||||
|
||||
pub struct AmbientWindMgr {
|
||||
ambience: AssetHandle<AmbientCollection>,
|
||||
began_playing: Instant,
|
||||
next_track_change: f32,
|
||||
volume: f32,
|
||||
tree_multiplier: f32,
|
||||
pub struct AmbientMgr {
|
||||
pub ambience: AssetHandle<AmbientCollection>,
|
||||
}
|
||||
|
||||
pub struct AmbientRainMgr {
|
||||
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
|
||||
impl AmbientMgr {
|
||||
pub fn maintain(
|
||||
&mut self,
|
||||
audio: &mut AudioFrontend,
|
||||
@ -79,157 +45,156 @@ impl AmbientWindMgr {
|
||||
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, tree_density) = if let Some(chunk) = client.current_chunk() {
|
||||
(chunk.meta().alt(), chunk.meta().tree_density())
|
||||
} else {
|
||||
(0.0, 0.0)
|
||||
};
|
||||
|
||||
// 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;
|
||||
let sfx_volume = audio.get_sfx_volume();
|
||||
// iterate through each tag
|
||||
for tag in AmbientChannelTag::iter() {
|
||||
// iterate through the supposed number of channels - one for each tag
|
||||
for index in 0..AmbientChannelTag::iter().len() {
|
||||
// if index would exceed current number of channels, create a new one with
|
||||
// current tag
|
||||
if index >= audio.ambient_channels.len() {
|
||||
audio.new_ambient_channel(tag);
|
||||
}
|
||||
// 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
|
||||
if audio.get_ambient_channel(AmbientChannelTag::Wind).is_none() {
|
||||
audio.new_ambient_channel(AmbientChannelTag::Wind);
|
||||
} else {
|
||||
self.volume = audio.get_ambient_volume(AmbientChannelTag::Wind);
|
||||
audio.set_ambient_volume(
|
||||
AmbientChannelTag::Wind,
|
||||
Lerp::lerp(self.volume, target_volume, 0.01),
|
||||
);
|
||||
}
|
||||
// set the duration of the loop to whatever the current value is (0.0 by
|
||||
// default)
|
||||
let next_track_change = audio.ambient_channels[index].get_next_track_change();
|
||||
|
||||
if self.began_playing.elapsed().as_secs_f32() > self.next_track_change {
|
||||
let ambience = self.ambience.read();
|
||||
let wind_track = &ambience
|
||||
.tracks
|
||||
.iter()
|
||||
.find(|track| track.tag == AmbientChannelTag::Wind);
|
||||
self.began_playing = Instant::now();
|
||||
if let Some(wind_track) = wind_track {
|
||||
self.next_track_change = wind_track.length;
|
||||
audio.play_ambient(AmbientChannelTag::Wind, &wind_track.path, target_volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if the sound should loop at this point:
|
||||
if audio.ambient_channels[index]
|
||||
.get_began_playing()
|
||||
.elapsed()
|
||||
.as_secs_f32()
|
||||
> next_track_change
|
||||
{
|
||||
let ambience = self.ambience.read();
|
||||
let track = ambience.tracks.iter().find(|track| track.tag == tag);
|
||||
// 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 {
|
||||
/// Checks whether the previous track has completed. If so, sends a
|
||||
/// request to play the next (random) track
|
||||
pub fn maintain(
|
||||
&mut self,
|
||||
audio: &mut AudioFrontend,
|
||||
state: &State,
|
||||
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
|
||||
// remove channel if not playing
|
||||
if audio.ambient_channels[index].get_multiplier() == 0.0 {
|
||||
audio.ambient_channels[index].stop();
|
||||
audio.ambient_channels.remove(index);
|
||||
};
|
||||
// move on to next tag
|
||||
break;
|
||||
} else {
|
||||
volume_multiplier
|
||||
}
|
||||
};
|
||||
|
||||
// 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);
|
||||
// channel tag and current tag don't match, move on to next channel
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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| {
|
||||
warn!(
|
||||
"Error reading ambience config file, ambience will not be available: {:#?}",
|
||||
|
@ -22,6 +22,8 @@ use crate::audio::{
|
||||
};
|
||||
use rodio::{OutputStreamHandle, Sample, Sink, Source, SpatialSink};
|
||||
use serde::Deserialize;
|
||||
use strum::EnumIter;
|
||||
use std::time::Instant;
|
||||
use tracing::warn;
|
||||
use vek::*;
|
||||
|
||||
@ -157,7 +159,7 @@ impl MusicChannel {
|
||||
|
||||
/// AmbientChannelTags are used for non-positional sfx. Currently the only use
|
||||
/// is for wind.
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Deserialize, EnumIter)]
|
||||
pub enum AmbientChannelTag {
|
||||
Wind,
|
||||
Rain,
|
||||
@ -168,6 +170,8 @@ pub struct AmbientChannel {
|
||||
tag: AmbientChannelTag,
|
||||
multiplier: f32,
|
||||
sink: Sink,
|
||||
began_playing: Instant,
|
||||
next_track_change: f32,
|
||||
}
|
||||
|
||||
impl AmbientChannel {
|
||||
@ -178,6 +182,8 @@ impl AmbientChannel {
|
||||
tag,
|
||||
multiplier,
|
||||
sink,
|
||||
began_playing: Instant::now(),
|
||||
next_track_change: 0.0,
|
||||
},
|
||||
Err(_) => {
|
||||
warn!("Failed to create rodio sink. May not play ambient sounds.");
|
||||
@ -185,6 +191,8 @@ impl AmbientChannel {
|
||||
tag,
|
||||
multiplier,
|
||||
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_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
|
||||
@ -264,9 +286,8 @@ impl SfxChannel {
|
||||
pub fn update(&mut self, listener: &Listener) {
|
||||
const FALLOFF: f32 = 0.13;
|
||||
|
||||
self.sink.set_emitter_position(
|
||||
((self.pos - listener.pos) * FALLOFF).into_array(),
|
||||
);
|
||||
self.sink
|
||||
.set_emitter_position(((self.pos - listener.pos) * FALLOFF).into_array());
|
||||
self.sink
|
||||
.set_left_ear_position(listener.ear_left_rpos.into_array());
|
||||
self.sink
|
||||
@ -281,7 +302,7 @@ pub struct UIChannel {
|
||||
impl UIChannel {
|
||||
pub fn new(stream: &OutputStreamHandle) -> Self {
|
||||
Self {
|
||||
sink: Sink::try_new(stream).unwrap()
|
||||
sink: Sink::try_new(stream).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,9 @@ pub mod music;
|
||||
pub mod sfx;
|
||||
pub mod soundcache;
|
||||
|
||||
use channel::{AmbientChannel, AmbientChannelTag, MusicChannel, MusicChannelTag, SfxChannel, UIChannel};
|
||||
use channel::{
|
||||
AmbientChannel, AmbientChannelTag, MusicChannel, MusicChannelTag, SfxChannel, UIChannel,
|
||||
};
|
||||
use fader::Fader;
|
||||
use music::MusicTransitionManifest;
|
||||
use sfx::{SfxEvent, SfxTriggerItem};
|
||||
@ -38,16 +40,16 @@ pub struct AudioFrontend {
|
||||
//pub device_list: Vec<String>,
|
||||
//pub audio_device: Option<Device>,
|
||||
pub stream: Option<rodio::OutputStream>,
|
||||
audio_stream: Option<rodio::OutputStreamHandle>,
|
||||
pub audio_stream: Option<rodio::OutputStreamHandle>,
|
||||
|
||||
music_channels: Vec<MusicChannel>,
|
||||
ambient_channels: Vec<AmbientChannel>,
|
||||
sfx_channels: Vec<SfxChannel>,
|
||||
ui_channels: Vec<UIChannel>,
|
||||
sfx_volume: f32,
|
||||
music_volume: f32,
|
||||
master_volume: f32,
|
||||
listener: Listener,
|
||||
pub music_channels: Vec<MusicChannel>,
|
||||
pub ambient_channels: Vec<AmbientChannel>,
|
||||
pub sfx_channels: Vec<SfxChannel>,
|
||||
pub ui_channels: Vec<UIChannel>,
|
||||
pub sfx_volume: f32,
|
||||
pub music_volume: f32,
|
||||
pub master_volume: f32,
|
||||
pub listener: Listener,
|
||||
|
||||
mtm: AssetHandle<MusicTransitionManifest>,
|
||||
}
|
||||
@ -216,7 +218,11 @@ impl AudioFrontend {
|
||||
|
||||
/// Function to play sfx from external places. Useful for UI and
|
||||
/// 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 {
|
||||
let sfx_file = match item.files.len() {
|
||||
0 => {
|
||||
@ -302,7 +308,7 @@ impl AudioFrontend {
|
||||
} else {
|
||||
channel.play(sound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -371,29 +377,29 @@ impl AudioFrontend {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if self.audio_stream.is_some() {
|
||||
let sfx_volume = self.get_sfx_volume();
|
||||
if let Some(channel) = self.get_ambient_channel(channel_tag) {
|
||||
channel.set_multiplier(volume_multiplier);
|
||||
channel.set_volume(sfx_volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
// fn set_ambient_volume(&mut self, channel_tag: AmbientChannelTag,
|
||||
// volume_multiplier: f32) { if self.audio_stream.is_some() {
|
||||
// let sfx_volume = self.get_sfx_volume();
|
||||
// if let Some(channel) = self.get_ambient_channel(channel_tag) {
|
||||
// channel.set_multiplier(volume_multiplier);
|
||||
// channel.set_volume(sfx_volume);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// retrieves volume (pre-sfx-setting) of the channel with a given tag
|
||||
fn get_ambient_volume(&mut self, channel_tag: AmbientChannelTag) -> f32 {
|
||||
if self.audio_stream.is_some() {
|
||||
if let Some(channel) = self.get_ambient_channel(channel_tag) {
|
||||
let channel_multiplier = channel.get_multiplier();
|
||||
channel_multiplier
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
// fn get_ambient_volume(&mut self, channel_tag: AmbientChannelTag) -> f32 {
|
||||
// if self.audio_stream.is_some() {
|
||||
// if let Some(channel) = self.get_ambient_channel(channel_tag) {
|
||||
// let channel_multiplier = channel.get_multiplier();
|
||||
// channel_multiplier
|
||||
// } else {
|
||||
// 0.0
|
||||
// }
|
||||
// } else {
|
||||
// 0.0
|
||||
// }
|
||||
// }
|
||||
|
||||
fn play_music(&mut self, sound: &str, channel_tag: MusicChannelTag) {
|
||||
if self.music_enabled() {
|
||||
|
@ -82,7 +82,7 @@
|
||||
|
||||
mod event_mapper;
|
||||
|
||||
use specs::{WorldExt};
|
||||
use specs::WorldExt;
|
||||
|
||||
use crate::{
|
||||
audio::AudioFrontend,
|
||||
|
@ -223,7 +223,10 @@ fn main() {
|
||||
// Setup audio
|
||||
let mut audio = match settings.audio.output {
|
||||
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()),
|
||||
};
|
||||
|
||||
|
@ -19,12 +19,7 @@ pub use self::{
|
||||
trail::TrailMgr,
|
||||
};
|
||||
use crate::{
|
||||
audio::{
|
||||
ambient::{AmbientRainMgr, AmbientWindMgr},
|
||||
music::MusicMgr,
|
||||
sfx::SfxMgr,
|
||||
AudioFrontend,
|
||||
},
|
||||
audio::{ambient, ambient::AmbientMgr, music::MusicMgr, sfx::SfxMgr, AudioFrontend},
|
||||
render::{
|
||||
create_skybox_mesh, CloudsLocals, Consts, Drawer, GlobalModel, Globals, GlobalsBindGroup,
|
||||
Light, Model, PointLightMatrix, PostProcessLocals, Renderer, Shadow, ShadowLocals,
|
||||
@ -107,8 +102,9 @@ pub struct Scene {
|
||||
figure_mgr: FigureMgr,
|
||||
pub sfx_mgr: SfxMgr,
|
||||
music_mgr: MusicMgr,
|
||||
ambient_wind_mgr: AmbientWindMgr,
|
||||
ambient_rain_mgr: AmbientRainMgr,
|
||||
ambient_mgr: AmbientMgr,
|
||||
// ambient_wind_mgr: AmbientWindMgr,
|
||||
// ambient_rain_mgr: AmbientRainMgr,
|
||||
}
|
||||
|
||||
pub struct SceneData<'a> {
|
||||
@ -320,8 +316,11 @@ impl Scene {
|
||||
figure_mgr: FigureMgr::new(renderer),
|
||||
sfx_mgr: SfxMgr::default(),
|
||||
music_mgr: MusicMgr::default(),
|
||||
ambient_wind_mgr: AmbientWindMgr::default(),
|
||||
ambient_rain_mgr: AmbientRainMgr::default(),
|
||||
ambient_mgr: AmbientMgr {
|
||||
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");
|
||||
let underwater = state
|
||||
.terrain()
|
||||
.get(cam_pos.map(|e| e.floor() as i32))
|
||||
.map(|b| b.is_liquid())
|
||||
.unwrap_or(false);
|
||||
.terrain()
|
||||
.get(cam_pos.map(|e| e.floor() as i32))
|
||||
.map(|b| b.is_liquid())
|
||||
.unwrap_or(false);
|
||||
self.particle_mgr.handle_outcome(outcome, scene_data);
|
||||
self.sfx_mgr
|
||||
.handle_outcome(outcome, audio, scene_data.client, state, underwater);
|
||||
@ -1080,10 +1079,12 @@ impl Scene {
|
||||
client,
|
||||
);
|
||||
self.music_mgr.maintain(audio, scene_data.state, client);
|
||||
self.ambient_wind_mgr
|
||||
.maintain(audio, scene_data.state, client, &self.camera);
|
||||
self.ambient_rain_mgr
|
||||
self.ambient_mgr
|
||||
.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 }
|
||||
|
@ -245,7 +245,9 @@ impl SessionState {
|
||||
let sfx_triggers = self.scene.sfx_mgr.triggers.read();
|
||||
|
||||
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 {
|
||||
InventoryUpdateEvent::BlockCollectFailed { pos, reason } => {
|
||||
@ -358,7 +360,7 @@ impl PlayState for SessionState {
|
||||
let client = self.client.borrow();
|
||||
(client.presence(), client.registered())
|
||||
};
|
||||
|
||||
|
||||
if client_presence.is_some() {
|
||||
let camera = self.scene.camera_mut();
|
||||
|
||||
@ -1577,12 +1579,16 @@ impl PlayState for SessionState {
|
||||
&scene_data,
|
||||
&client,
|
||||
);
|
||||
|
||||
|
||||
// Process outcomes from client
|
||||
for outcome in outcomes {
|
||||
self.scene
|
||||
.handle_outcome(&outcome, &scene_data, &mut global_state.audio, &client.state(), cam_pos);
|
||||
self.scene.handle_outcome(
|
||||
&outcome,
|
||||
&scene_data,
|
||||
&mut global_state.audio,
|
||||
&client.state(),
|
||||
cam_pos,
|
||||
);
|
||||
self.hud
|
||||
.handle_outcome(&outcome, scene_data.client, global_state);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user