mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Remove an unwrap and move outcome sfx to ron
This commit is contained in:
parent
ffd3ef3f14
commit
2f00af83d8
@ -710,17 +710,87 @@
|
|||||||
],
|
],
|
||||||
threshold: 0.3,
|
threshold: 0.3,
|
||||||
),
|
),
|
||||||
//Explosion: (
|
Explosion: (
|
||||||
// files: [
|
files: [
|
||||||
// // in code
|
"voxygen.audio.sfx.abilities.explosion",
|
||||||
// ],
|
],
|
||||||
// threshold: 0.2,
|
threshold: 0.2,
|
||||||
//),
|
),
|
||||||
//ProjectileShot: (
|
ArrowShot: (
|
||||||
// files: [
|
files: [
|
||||||
// // in code
|
"voxygen.audio.sfx.abilities.arrow_shot_1",
|
||||||
// ],
|
"voxygen.audio.sfx.abilities.arrow_shot_2",
|
||||||
// threshold: 0.5,
|
"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 sfx::{SfxEvent, SfxTriggerItem};
|
||||||
use soundcache::OggSound;
|
use soundcache::OggSound;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error, warn};
|
||||||
|
|
||||||
use common::assets::{AssetExt, AssetHandle};
|
use common::assets::{AssetExt, AssetHandle};
|
||||||
use rodio::{source::Source, OutputStream, OutputStreamHandle, StreamError};
|
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 {
|
} else {
|
||||||
debug!("Missing sfx trigger config for external sfx event.",);
|
debug!("Missing sfx trigger config for external sfx event.",);
|
||||||
}
|
}
|
||||||
@ -238,10 +242,9 @@ impl AudioFrontend {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if underwater {
|
match self.play_sfx(sfx_file, position, volume, underwater) {
|
||||||
self.play_underwater_sfx(sfx_file, position, volume);
|
Ok(_) => {},
|
||||||
} else {
|
Err(e) => warn!("Failed to play sfx. {}", e),
|
||||||
self.play_sfx(sfx_file, position, volume);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!(
|
debug!(
|
||||||
@ -251,40 +254,33 @@ impl AudioFrontend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Play (once) an sfx file by file path at the give position and volume
|
/// Play (once) an sfx file by file path at the given position and volume.
|
||||||
pub fn play_sfx(&mut self, sound: &str, pos: Vec3<f32>, vol: Option<f32>) {
|
/// 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() {
|
if self.audio_stream.is_some() {
|
||||||
let sound = OggSound::load_expect(sound)
|
let sound = OggSound::load_expect(sound)
|
||||||
.cloned()
|
.cloned()
|
||||||
.decoder()
|
.decoder()?
|
||||||
.amplify(vol.unwrap_or(1.0));
|
.amplify(vol.unwrap_or(1.0));
|
||||||
|
|
||||||
let listener = self.listener.clone();
|
let listener = self.listener.clone();
|
||||||
if let Some(channel) = self.get_sfx_channel() {
|
if let Some(channel) = self.get_sfx_channel() {
|
||||||
channel.set_pos(pos);
|
channel.set_pos(pos);
|
||||||
channel.update(&listener);
|
channel.update(&listener);
|
||||||
|
if underwater {
|
||||||
|
channel.play_with_low_pass_filter(sound.convert_samples());
|
||||||
|
} else {
|
||||||
channel.play(sound);
|
channel.play(sound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
/// 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn play_ambient(
|
fn play_ambient(
|
||||||
@ -295,11 +291,12 @@ impl AudioFrontend {
|
|||||||
) {
|
) {
|
||||||
if self.audio_stream.is_some() {
|
if self.audio_stream.is_some() {
|
||||||
if let Some(channel) = self.get_ambient_channel(channel_tag, volume_multiplier) {
|
if let Some(channel) = self.get_ambient_channel(channel_tag, volume_multiplier) {
|
||||||
let sound = OggSound::load_expect(sound).cloned().decoder();
|
if let Ok(sound) = OggSound::load_expect(sound).cloned().decoder() {
|
||||||
channel.play(sound);
|
channel.play(sound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_ambient_channel(
|
fn get_ambient_channel(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -352,11 +349,12 @@ impl AudioFrontend {
|
|||||||
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() {
|
||||||
if let Some(channel) = self.get_music_channel(channel_tag) {
|
if let Some(channel) = self.get_music_channel(channel_tag) {
|
||||||
let sound = OggSound::load_expect(sound).cloned().decoder();
|
if let Ok(sound) = OggSound::load_expect(sound).cloned().decoder() {
|
||||||
channel.play(sound, channel_tag);
|
channel.play(sound, channel_tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* These functions are saved for if we want music playback control at some
|
/* These functions are saved for if we want music playback control at some
|
||||||
* point. They are not used currently but may be useful for later work.
|
* point. They are not used currently but may be useful for later work.
|
||||||
|
@ -92,7 +92,7 @@ use common::{
|
|||||||
assets::{self, AssetExt, AssetHandle},
|
assets::{self, AssetExt, AssetHandle},
|
||||||
comp::{
|
comp::{
|
||||||
beam,
|
beam,
|
||||||
item::{ItemKind, Reagent, ToolKind},
|
item::{ItemKind, ToolKind},
|
||||||
object, Body, CharacterAbilityType, InventoryUpdateEvent,
|
object, Body, CharacterAbilityType, InventoryUpdateEvent,
|
||||||
},
|
},
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
@ -167,8 +167,17 @@ pub enum SfxEvent {
|
|||||||
Unwield(ToolKind),
|
Unwield(ToolKind),
|
||||||
Inventory(SfxInventoryEvent),
|
Inventory(SfxInventoryEvent),
|
||||||
Explosion,
|
Explosion,
|
||||||
ProjectileShot,
|
|
||||||
Damage,
|
Damage,
|
||||||
|
Parry,
|
||||||
|
Block,
|
||||||
|
BreakBlock,
|
||||||
|
HealingBeam,
|
||||||
|
SkillPointGain,
|
||||||
|
ArrowHit,
|
||||||
|
ArrowMiss,
|
||||||
|
ArrowShot,
|
||||||
|
FireShot,
|
||||||
|
FlameThrower,
|
||||||
// Poise(StunState),
|
// Poise(StunState),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,30 +310,20 @@ impl SfxMgr {
|
|||||||
if !audio.sfx_enabled() {
|
if !audio.sfx_enabled() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let triggers = self.triggers.read();
|
||||||
|
|
||||||
|
// TODO handle underwater
|
||||||
match outcome {
|
match outcome {
|
||||||
Outcome::Explosion {
|
Outcome::Explosion { pos, power, .. } => {
|
||||||
pos,
|
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Explosion);
|
||||||
power,
|
audio.emit_sfx(
|
||||||
is_attack,
|
sfx_trigger_item,
|
||||||
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,
|
|
||||||
*pos,
|
*pos,
|
||||||
Some((power.abs() / 2.5).min(1.5)),
|
Some((power.abs() / 2.5).min(1.5)),
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Outcome::ProjectileShot { pos, body, .. } => {
|
Outcome::ProjectileShot { pos, body, .. } => {
|
||||||
// TODO: from sfx config?
|
|
||||||
match body {
|
match body {
|
||||||
Body::Object(
|
Body::Object(
|
||||||
object::Body::Arrow
|
object::Body::Arrow
|
||||||
@ -332,26 +331,16 @@ impl SfxMgr {
|
|||||||
| object::Body::ArrowSnake
|
| object::Body::ArrowSnake
|
||||||
| object::Body::ArrowTurret,
|
| object::Body::ArrowTurret,
|
||||||
) => {
|
) => {
|
||||||
let file_ref = vec![
|
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::ArrowShot);
|
||||||
"voxygen.audio.sfx.abilities.arrow_shot_1",
|
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
|
||||||
"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);
|
|
||||||
},
|
},
|
||||||
Body::Object(
|
Body::Object(
|
||||||
object::Body::BoltFire
|
object::Body::BoltFire
|
||||||
| object::Body::BoltFireBig
|
| object::Body::BoltFireBig
|
||||||
| object::Body::BoltNature,
|
| object::Body::BoltNature,
|
||||||
) => {
|
) => {
|
||||||
let file_ref = vec![
|
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::FireShot);
|
||||||
"voxygen.audio.sfx.abilities.fire_shot_1",
|
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
|
||||||
"voxygen.audio.sfx.abilities.fire_shot_2",
|
|
||||||
][rand::thread_rng().gen_range(1..2)];
|
|
||||||
|
|
||||||
audio.play_sfx(file_ref, *pos, None);
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
// not mapped to sfx file
|
// not mapped to sfx file
|
||||||
@ -372,66 +361,61 @@ impl SfxMgr {
|
|||||||
| object::Body::ArrowTurret,
|
| object::Body::ArrowTurret,
|
||||||
) => {
|
) => {
|
||||||
if target.is_none() {
|
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() {
|
} else if *source == client.uid() {
|
||||||
audio.play_sfx(
|
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::ArrowHit);
|
||||||
"voxygen.audio.sfx.character.arrow_hit",
|
audio.emit_sfx(
|
||||||
|
sfx_trigger_item,
|
||||||
client.position().unwrap_or(*pos),
|
client.position().unwrap_or(*pos),
|
||||||
Some(2.0),
|
Some(2.0),
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
} else {
|
} 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, .. } => {
|
Outcome::SkillPointGain { pos, .. } => {
|
||||||
let file_ref = "voxygen.audio.sfx.character.level_up_sound_-_shorter_wind_up";
|
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::SkillPointGain);
|
||||||
audio.play_sfx(file_ref, *pos, None);
|
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
|
||||||
},
|
},
|
||||||
Outcome::Beam { pos, specifier } => match specifier {
|
Outcome::Beam { pos, specifier } => match specifier {
|
||||||
beam::FrontendSpecifier::LifestealBeam | beam::FrontendSpecifier::HealingBeam => {
|
beam::FrontendSpecifier::LifestealBeam | beam::FrontendSpecifier::HealingBeam => {
|
||||||
let file_ref = "voxygen.audio.sfx.abilities.sceptre_channeling";
|
|
||||||
if thread_rng().gen_bool(0.5) {
|
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 => {
|
beam::FrontendSpecifier::Flamethrower | beam::FrontendSpecifier::Cultist => {
|
||||||
let file_ref = "voxygen.audio.sfx.abilities.flame_thrower";
|
|
||||||
if thread_rng().gen_bool(0.5) {
|
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, .. } => {
|
Outcome::BreakBlock { pos, .. } => {
|
||||||
let file_ref = "voxygen.audio.sfx.footsteps.stone_step_1";
|
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::BreakBlock);
|
||||||
audio.play_sfx(file_ref, pos.map(|e| e as f32 + 0.5), Some(3.0));
|
audio.emit_sfx(
|
||||||
|
sfx_trigger_item,
|
||||||
|
pos.map(|e| e as f32 + 0.5),
|
||||||
|
Some(3.0),
|
||||||
|
false,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
Outcome::Damage { pos, .. } => {
|
Outcome::Damage { pos, .. } => {
|
||||||
let file_ref = vec![
|
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Damage);
|
||||||
"voxygen.audio.sfx.character.hit_1",
|
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
|
||||||
"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);
|
|
||||||
},
|
},
|
||||||
Outcome::Block { pos, parry, .. } => {
|
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 {
|
if *parry {
|
||||||
let file_ref = parry_sfx[rand::thread_rng().gen_range(1..parry_sfx.len())];
|
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Parry);
|
||||||
audio.play_sfx(file_ref, *pos, Some(2.0));
|
audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), false);
|
||||||
} else {
|
} else {
|
||||||
let file_ref = block_sfx[rand::thread_rng().gen_range(1..block_sfx.len())];
|
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Block);
|
||||||
audio.play_sfx(file_ref, *pos, Some(2.0));
|
audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Outcome::ExpChange { .. }
|
Outcome::ExpChange { .. }
|
||||||
|
@ -37,9 +37,11 @@ impl assets::Asset for OggSound {
|
|||||||
|
|
||||||
/// Wrapper for decoded audio data
|
/// Wrapper for decoded audio data
|
||||||
impl OggSound {
|
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);
|
let cursor = io::Cursor::new(self);
|
||||||
rodio::Decoder::new(cursor).unwrap()
|
rodio::Decoder::new(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty() -> OggSound {
|
pub fn empty() -> OggSound {
|
||||||
|
Loading…
Reference in New Issue
Block a user