Merge branch 'james/sound-unwraps' into 'master'

Remove an unwrap and move outcome sfx to ron

See merge request veloren/veloren!2206
This commit is contained in:
Marcel 2021-04-27 21:01:06 +00:00
commit aa963493e8
4 changed files with 166 additions and 112 deletions

View File

@ -710,17 +710,87 @@
],
threshold: 0.3,
),
//Explosion: (
// files: [
// // in code
// ],
// threshold: 0.2,
//),
//ProjectileShot: (
// files: [
// // in code
// ],
// threshold: 0.5,
//),
Explosion: (
files: [
"voxygen.audio.sfx.abilities.explosion",
],
threshold: 0.2,
),
ArrowShot: (
files: [
"voxygen.audio.sfx.abilities.arrow_shot_1",
"voxygen.audio.sfx.abilities.arrow_shot_2",
"voxygen.audio.sfx.abilities.arrow_shot_3",
"voxygen.audio.sfx.abilities.arrow_shot_4",
],
threshold: 0.2,
),
FireShot: (
files: [
"voxygen.audio.sfx.abilities.fire_shot_1",
"voxygen.audio.sfx.abilities.fire_shot_2",
],
threshold: 0.2,
),
ArrowMiss: (
files: [
"voxygen.audio.sfx.character.arrow_miss",
],
threshold: 0.2,
),
ArrowHit: (
files: [
"voxygen.audio.sfx.character.arrow_hit",
],
threshold: 0.2,
),
SkillPointGain: (
files: [
"voxygen.audio.sfx.character.level_up_sound_-_shorter_wind_up",
],
threshold: 0.2,
),
HealingBeam: (
files: [
"voxygen.audio.sfx.abilities.sceptre_channeling",
],
threshold: 0.2,
),
FlameThrower: (
files: [
"voxygen.audio.sfx.abilities.flame_thrower",
],
threshold: 0.2,
),
BreakBlock: (
files: [
"voxygen.audio.sfx.footsteps.stone_step_1",
],
threshold: 0.2,
),
Damage: (
files: [
"voxygen.audio.sfx.character.hit_1",
"voxygen.audio.sfx.character.hit_2",
"voxygen.audio.sfx.character.hit_3",
"voxygen.audio.sfx.character.hit_4",
],
threshold: 0.2,
),
Block: (
files: [
"voxygen.audio.sfx.character.block_1",
"voxygen.audio.sfx.character.block_2",
"voxygen.audio.sfx.character.block_3",
],
threshold: 0.2,
),
Parry: (
files: [
"voxygen.audio.sfx.character.parry_1",
"voxygen.audio.sfx.character.parry_2",
],
threshold: 0.2,
),
}
)

View File

@ -13,7 +13,7 @@ use music::MusicTransitionManifest;
use sfx::{SfxEvent, SfxTriggerItem};
use soundcache::OggSound;
use std::time::Duration;
use tracing::{debug, error};
use tracing::{debug, error, warn};
use common::assets::{AssetExt, AssetHandle};
use rodio::{source::Source, OutputStream, OutputStreamHandle, StreamError};
@ -206,7 +206,11 @@ impl AudioFrontend {
},
};
self.play_sfx(sfx_file, self.listener.pos, None);
// TODO: Should this take `underwater` into consideration?
match self.play_sfx(sfx_file, self.listener.pos, None, false) {
Ok(_) => {},
Err(e) => warn!("Failed to play sfx. {}", e),
}
} else {
debug!("Missing sfx trigger config for external sfx event.",);
}
@ -238,10 +242,9 @@ impl AudioFrontend {
},
};
if underwater {
self.play_underwater_sfx(sfx_file, position, volume);
} else {
self.play_sfx(sfx_file, position, volume);
match self.play_sfx(sfx_file, position, volume, underwater) {
Ok(_) => {},
Err(e) => warn!("Failed to play sfx. {}", e),
}
} else {
debug!(
@ -251,40 +254,33 @@ impl AudioFrontend {
}
}
/// Play (once) an sfx file by file path at the give position and volume
pub fn play_sfx(&mut self, sound: &str, pos: Vec3<f32>, vol: Option<f32>) {
/// Play (once) an sfx file by file path at the given position and volume.
/// If `underwater` is true, the sound is played with a low pass filter
pub fn play_sfx(
&mut self,
sound: &str,
pos: Vec3<f32>,
vol: Option<f32>,
underwater: bool,
) -> Result<(), rodio::decoder::DecoderError> {
if self.audio_stream.is_some() {
let sound = OggSound::load_expect(sound)
.cloned()
.decoder()
.decoder()?
.amplify(vol.unwrap_or(1.0));
let listener = self.listener.clone();
if let Some(channel) = self.get_sfx_channel() {
channel.set_pos(pos);
channel.update(&listener);
channel.play(sound);
}
}
}
/// Play (once) an sfx file by file path at the give position and volume
/// but with the sound passed through a low pass filter to simulate
/// being underwater
pub fn play_underwater_sfx(&mut self, sound: &str, pos: Vec3<f32>, vol: Option<f32>) {
if self.audio_stream.is_some() {
let sound = OggSound::load_expect(sound)
.cloned()
.decoder()
.amplify(vol.unwrap_or(1.0));
let listener = self.listener.clone();
if let Some(channel) = self.get_sfx_channel() {
channel.set_pos(pos);
channel.update(&listener);
channel.play_with_low_pass_filter(sound.convert_samples());
if underwater {
channel.play_with_low_pass_filter(sound.convert_samples());
} else {
channel.play(sound);
}
}
}
Ok(())
}
fn play_ambient(
@ -295,8 +291,9 @@ impl AudioFrontend {
) {
if self.audio_stream.is_some() {
if let Some(channel) = self.get_ambient_channel(channel_tag, volume_multiplier) {
let sound = OggSound::load_expect(sound).cloned().decoder();
channel.play(sound);
if let Ok(sound) = OggSound::load_expect(sound).cloned().decoder() {
channel.play(sound);
}
}
}
}
@ -352,8 +349,9 @@ impl AudioFrontend {
fn play_music(&mut self, sound: &str, channel_tag: MusicChannelTag) {
if self.music_enabled() {
if let Some(channel) = self.get_music_channel(channel_tag) {
let sound = OggSound::load_expect(sound).cloned().decoder();
channel.play(sound, channel_tag);
if let Ok(sound) = OggSound::load_expect(sound).cloned().decoder() {
channel.play(sound, channel_tag);
}
}
}
}

View File

@ -92,7 +92,7 @@ use common::{
assets::{self, AssetExt, AssetHandle},
comp::{
beam,
item::{ItemKind, Reagent, ToolKind},
item::{ItemKind, ToolKind},
object, Body, CharacterAbilityType, InventoryUpdateEvent,
},
outcome::Outcome,
@ -167,8 +167,17 @@ pub enum SfxEvent {
Unwield(ToolKind),
Inventory(SfxInventoryEvent),
Explosion,
ProjectileShot,
Damage,
Parry,
Block,
BreakBlock,
HealingBeam,
SkillPointGain,
ArrowHit,
ArrowMiss,
ArrowShot,
FireShot,
FlameThrower,
// Poise(StunState),
}
@ -301,30 +310,20 @@ impl SfxMgr {
if !audio.sfx_enabled() {
return;
}
let triggers = self.triggers.read();
// TODO handle underwater
match outcome {
Outcome::Explosion {
pos,
power,
is_attack,
reagent,
..
} => {
let file_ref = if *is_attack && matches!(reagent, Some(Reagent::Green)) {
"voxygen.audio.sfx.abilities.heal_bomb"
} else {
"voxygen.audio.sfx.abilities.explosion"
};
audio.play_sfx(
// TODO: from sfx config?
file_ref,
Outcome::Explosion { pos, power, .. } => {
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Explosion);
audio.emit_sfx(
sfx_trigger_item,
*pos,
Some((power.abs() / 2.5).min(1.5)),
false,
);
},
Outcome::ProjectileShot { pos, body, .. } => {
// TODO: from sfx config?
match body {
Body::Object(
object::Body::Arrow
@ -332,26 +331,16 @@ impl SfxMgr {
| object::Body::ArrowSnake
| object::Body::ArrowTurret,
) => {
let file_ref = vec![
"voxygen.audio.sfx.abilities.arrow_shot_1",
"voxygen.audio.sfx.abilities.arrow_shot_2",
"voxygen.audio.sfx.abilities.arrow_shot_3",
"voxygen.audio.sfx.abilities.arrow_shot_4",
][rand::thread_rng().gen_range(1..4)];
audio.play_sfx(file_ref, *pos, None);
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::ArrowShot);
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
},
Body::Object(
object::Body::BoltFire
| object::Body::BoltFireBig
| object::Body::BoltNature,
) => {
let file_ref = vec![
"voxygen.audio.sfx.abilities.fire_shot_1",
"voxygen.audio.sfx.abilities.fire_shot_2",
][rand::thread_rng().gen_range(1..2)];
audio.play_sfx(file_ref, *pos, None);
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::FireShot);
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
},
_ => {
// not mapped to sfx file
@ -372,66 +361,61 @@ impl SfxMgr {
| object::Body::ArrowTurret,
) => {
if target.is_none() {
audio.play_sfx("voxygen.audio.sfx.character.arrow_miss", *pos, Some(2.0));
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::ArrowMiss);
audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), false);
} else if *source == client.uid() {
audio.play_sfx(
"voxygen.audio.sfx.character.arrow_hit",
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::ArrowHit);
audio.emit_sfx(
sfx_trigger_item,
client.position().unwrap_or(*pos),
Some(2.0),
false,
);
} else {
audio.play_sfx("voxygen.audio.sfx.character.arrow_hit", *pos, Some(2.0));
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::ArrowHit);
audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), false);
}
},
_ => {},
},
Outcome::SkillPointGain { pos, .. } => {
let file_ref = "voxygen.audio.sfx.character.level_up_sound_-_shorter_wind_up";
audio.play_sfx(file_ref, *pos, None);
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::SkillPointGain);
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
},
Outcome::Beam { pos, specifier } => match specifier {
beam::FrontendSpecifier::LifestealBeam | beam::FrontendSpecifier::HealingBeam => {
let file_ref = "voxygen.audio.sfx.abilities.sceptre_channeling";
if thread_rng().gen_bool(0.5) {
audio.play_sfx(file_ref, *pos, None);
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::HealingBeam);
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
};
},
beam::FrontendSpecifier::Flamethrower | beam::FrontendSpecifier::Cultist => {
let file_ref = "voxygen.audio.sfx.abilities.flame_thrower";
if thread_rng().gen_bool(0.5) {
audio.play_sfx(file_ref, *pos, None);
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::FlameThrower);
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
}
},
},
Outcome::BreakBlock { pos, .. } => {
let file_ref = "voxygen.audio.sfx.footsteps.stone_step_1";
audio.play_sfx(file_ref, pos.map(|e| e as f32 + 0.5), Some(3.0));
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::BreakBlock);
audio.emit_sfx(
sfx_trigger_item,
pos.map(|e| e as f32 + 0.5),
Some(3.0),
false,
);
},
Outcome::Damage { pos, .. } => {
let file_ref = vec![
"voxygen.audio.sfx.character.hit_1",
"voxygen.audio.sfx.character.hit_2",
"voxygen.audio.sfx.character.hit_3",
"voxygen.audio.sfx.character.hit_4",
][rand::thread_rng().gen_range(1..4)];
audio.play_sfx(file_ref, *pos, None);
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Damage);
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
},
Outcome::Block { pos, parry, .. } => {
let block_sfx = vec![
"voxygen.audio.sfx.character.block_1",
"voxygen.audio.sfx.character.block_2",
"voxygen.audio.sfx.character.block_3",
];
let parry_sfx = vec![
"voxygen.audio.sfx.character.parry_1",
"voxygen.audio.sfx.character.parry_2",
];
if *parry {
let file_ref = parry_sfx[rand::thread_rng().gen_range(1..parry_sfx.len())];
audio.play_sfx(file_ref, *pos, Some(2.0));
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Parry);
audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), false);
} else {
let file_ref = block_sfx[rand::thread_rng().gen_range(1..block_sfx.len())];
audio.play_sfx(file_ref, *pos, Some(2.0));
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Block);
audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), false);
}
},
Outcome::ExpChange { .. }

View File

@ -37,9 +37,11 @@ impl assets::Asset for OggSound {
/// Wrapper for decoded audio data
impl OggSound {
pub fn decoder(self) -> rodio::Decoder<io::Cursor<OggSound>> {
pub fn decoder(
self,
) -> Result<rodio::Decoder<io::Cursor<OggSound>>, rodio::decoder::DecoderError> {
let cursor = io::Cursor::new(self);
rodio::Decoder::new(cursor).unwrap()
rodio::Decoder::new(cursor)
}
pub fn empty() -> OggSound {