mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
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:
commit
aa963493e8
@ -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,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 { .. }
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user