diff --git a/CHANGELOG.md b/CHANGELOG.md index a556f9bff8..6ad28d3149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added a skill tree for mining, which gains xp from mining ores and gems. - Added debug line info to release builds, enhancing the usefulness of panic backtraces +- NPCs and animals can now make sounds in response to certain events +- Players can press H to greet others ### Changed - Entity-entity pushback is no longer applied in forced movement states like rolling and leaping. @@ -18,7 +20,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed ### Fixed + - Cases where no audio output could be produced before. +- Significantly improved the performance of playing sound effects ## [0.10.0] - 2021-06-12 diff --git a/assets/voxygen/audio/sfx.ron b/assets/voxygen/audio/sfx.ron index 1f6ae01af3..81bca564d1 100644 --- a/assets/voxygen/audio/sfx.ron +++ b/assets/voxygen/audio/sfx.ron @@ -5,7 +5,7 @@ // Campfire: ( files: [ - "voxygen.audio.sfx.ambient.fire", + "voxygen.audio.sfx.ambient.fire", ], threshold: 21.835, ), @@ -831,54 +831,56 @@ ], threshold: 0.2, ), - Utterance(Angry, Wendigo): ( - files: [ - "voxygen.audio.sfx.utterance.wendigo_angry", - ], - threshold: 4.0, - ), - Utterance(Angry, BipedLarge): ( - files: [ - "voxygen.audio.sfx.utterance.ogre_angry", - "voxygen.audio.sfx.utterance.ogre_angry2", - ], - threshold: 4.0, - ), - Utterance(Angry, Reptile): ( - files: [ - "voxygen.audio.sfx.utterance.saurok_angry", - ], - threshold: 4.0, - ), - Utterance(Angry, Bird): ( - files: [ - "voxygen.audio.sfx.utterance.bird_angry", - ], - threshold: 4.0, - ), - Utterance(Calm, Pig): ( - files: [ - "voxygen.audio.sfx.utterance.pig_calm", - ], - threshold: 4.0, - ), - Utterance(Calm, Cow): ( - files: [ - "voxygen.audio.sfx.utterance.cow_calm", - ], - threshold: 4.0, - ), - Utterance(Calm, Sheep): ( - files: [ - "voxygen.audio.sfx.utterance.sheep_calm", - ], - threshold: 4.0, - ), - Utterance(Greeting, HumanMale): ( - files: [ - "voxygen.audio.sfx.utterance.humanmale_greeting", - ], - threshold: 4.0, - ), + Utterance(Angry, Wendigo): ( + files: [ + "voxygen.audio.sfx.utterance.wendigo_angry", + ], + threshold: 0.2, + ), + Utterance(Angry, BipedLarge): ( + files: [ + "voxygen.audio.sfx.utterance.ogre_angry", + "voxygen.audio.sfx.utterance.ogre_angry2", + ], + threshold: 0.2, + ), + Utterance(Angry, Reptile): ( + files: [ + "voxygen.audio.sfx.utterance.saurok_angry", + ], + threshold: 0.2, + ), + Utterance(Angry, Bird): ( + files: [ + "voxygen.audio.sfx.utterance.bird_angry", + ], + threshold: 0.2, + ), + Utterance(Calm, Pig): ( + files: [ + "voxygen.audio.sfx.utterance.pig_calm", + ], + threshold: 0.2, + ), + Utterance(Calm, Cow): ( + files: [ + "voxygen.audio.sfx.utterance.cow_calm", + "voxygen.audio.sfx.utterance.cow_calm2", + "voxygen.audio.sfx.utterance.cow_calm3", + ], + threshold: 0.2, + ), + Utterance(Calm, Sheep): ( + files: [ + "voxygen.audio.sfx.utterance.sheep_calm", + ], + threshold: 0.2, + ), + Utterance(Greeting, HumanMale): ( + files: [ + "voxygen.audio.sfx.utterance.humanmale_greeting", + ], + threshold: 0.2, + ), } ) diff --git a/assets/voxygen/audio/sfx/utterance/cow_calm2.ogg b/assets/voxygen/audio/sfx/utterance/cow_calm2.ogg new file mode 100644 index 0000000000..f060217fe4 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/cow_calm2.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:581a6c86eb6f06ed2694d0cdfa08691fa8bf38fd7fffb57680b41ed5dc1060ed +size 23328 diff --git a/assets/voxygen/audio/sfx/utterance/cow_calm3.ogg b/assets/voxygen/audio/sfx/utterance/cow_calm3.ogg new file mode 100644 index 0000000000..59ae620508 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/cow_calm3.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb77a69af59eb015c20de58bad181f7e02bc82649d33c274302018c8baf4b85a +size 14690 diff --git a/client/src/lib.rs b/client/src/lib.rs index 661c2ad5f7..9f09ffb9d0 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -28,7 +28,7 @@ use common::{ skills::Skill, slot::Slot, ChatMode, ControlAction, ControlEvent, Controller, ControllerInputs, GroupManip, InputKind, - InventoryAction, InventoryEvent, InventoryUpdateEvent, + InventoryAction, InventoryEvent, InventoryUpdateEvent, UtteranceKind, }, event::{EventBus, LocalEvent}, grid::Grid, @@ -1224,6 +1224,10 @@ impl Client { } } + pub fn utter(&mut self, kind: UtteranceKind) { + self.send_msg(ClientGeneral::ControlEvent(ControlEvent::Utterance(kind))); + } + pub fn toggle_sneak(&mut self) { let is_sneaking = self .state diff --git a/server/src/events/interaction.rs b/server/src/events/interaction.rs index 3a04f63aec..acd935f9a6 100644 --- a/server/src/events/interaction.rs +++ b/server/src/events/interaction.rs @@ -404,17 +404,17 @@ pub fn handle_sound(server: &mut Server, sound: &Sound) { .inbox .push_back(AgentEvent::ServerSound(propagated_sound)); } + } - // Attempt to turn this sound into an outcome to be received by frontends. - if let Some(outcome) = match sound.kind { - SoundKind::Utterance(kind, body) => Some(Outcome::Utterance { - kind, - pos: sound.pos, - body, - }), - _ => None, - } { - ecs.write_resource::>().push(outcome); - } + // Attempt to turn this sound into an outcome to be received by frontends. + if let Some(outcome) = match sound.kind { + SoundKind::Utterance(kind, body) => Some(Outcome::Utterance { + kind, + pos: sound.pos, + body, + }), + _ => None, + } { + ecs.write_resource::>().push(outcome); } } diff --git a/voxygen/src/audio/sfx/mod.rs b/voxygen/src/audio/sfx/mod.rs index 99193012be..1f5fe7ab89 100644 --- a/voxygen/src/audio/sfx/mod.rs +++ b/voxygen/src/audio/sfx/mod.rs @@ -106,7 +106,7 @@ use event_mapper::SfxEventMapper; use hashbrown::HashMap; use rand::prelude::*; use serde::Deserialize; -use tracing::warn; +use tracing::{debug, warn}; use vek::*; /// We watch the states of nearby entities in order to emit SFX at their @@ -186,9 +186,8 @@ pub enum SfxEvent { Utterance(UtteranceKind, VoiceKind), } -#[derive(Clone, Debug, PartialEq, Deserialize, Hash, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Deserialize, Hash, Eq)] pub enum VoiceKind { - Mute, HumanFemale, HumanMale, BipedLarge, @@ -203,8 +202,8 @@ pub enum VoiceKind { BigCat, } -fn body_to_voice(body: &Body) -> VoiceKind { - match body { +fn body_to_voice(body: &Body) -> Option { + Some(match body { Body::Humanoid(body) => match &body.body_type { humanoid::BodyType::Female => VoiceKind::HumanFemale, humanoid::BodyType::Male => VoiceKind::HumanMale, @@ -232,7 +231,7 @@ fn body_to_voice(body: &Body) -> VoiceKind { | quadruped_medium::Species::Yak | quadruped_medium::Species::Moose | quadruped_medium::Species::Dreadhorn => VoiceKind::Cow, - _ => VoiceKind::Mute, + _ => return None, }, Body::BirdMedium(_) | Body::BirdLarge(_) => VoiceKind::Bird, Body::BipedLarge(body) => match body.species { @@ -243,8 +242,8 @@ fn body_to_voice(body: &Body) -> VoiceKind { _ => VoiceKind::BipedLarge, }, Body::Theropod(_) | Body::Dragon(_) => VoiceKind::Reptile, - _ => VoiceKind::Mute, - } + _ => return None, + }) } #[derive(Clone, Debug, PartialEq, Deserialize, Hash, Eq)] @@ -516,9 +515,18 @@ impl SfxMgr { }, }, Outcome::Utterance { pos, kind, body } => { - let sfx_trigger_item = - triggers.get_key_value(&SfxEvent::Utterance(*kind, body_to_voice(body))); - audio.emit_sfx(sfx_trigger_item, *pos, Some(2.5), false); + if let Some(voice) = body_to_voice(body) { + let sfx_trigger_item = + triggers.get_key_value(&SfxEvent::Utterance(*kind, voice)); + if let Some(sfx_trigger_item) = sfx_trigger_item { + audio.emit_sfx(Some(sfx_trigger_item), *pos, Some(2.5), false); + } else { + debug!( + "No utterance sound effect exists for ({:?}, {:?})", + kind, voice + ); + } + } }, Outcome::ExpChange { .. } | Outcome::ComboChange { .. } diff --git a/voxygen/src/audio/soundcache.rs b/voxygen/src/audio/soundcache.rs index 7fcdae187f..f08a4bdab6 100644 --- a/voxygen/src/audio/soundcache.rs +++ b/voxygen/src/audio/soundcache.rs @@ -2,7 +2,7 @@ //! the need to decode files on each playback use common::assets::{self, Loader}; use rodio::{source::Buffered, Decoder, Source}; -use std::{borrow::Cow, io, sync::Arc}; +use std::{borrow::Cow, io}; use tracing::warn; // Implementation of sound taken from this github issue: @@ -13,10 +13,6 @@ pub struct SoundLoader; #[derive(Clone)] pub struct OggSound(Buffered>>>); -// impl AsRef<[u8]> for OggSound { -// fn as_ref(&self) -> &[u8] { &self.0 } -// } - impl Loader for SoundLoader { fn load(content: Cow<[u8]>, _: &str) -> Result { let source = Decoder::new(io::Cursor::new(content.into_owned()))?.buffered(); diff --git a/voxygen/src/session/mod.rs b/voxygen/src/session/mod.rs index 9abef76774..104459f2b8 100644 --- a/voxygen/src/session/mod.rs +++ b/voxygen/src/session/mod.rs @@ -15,7 +15,7 @@ use common::{ inventory::slot::{EquipSlot, Slot}, invite::InviteKind, item::{tool::ToolKind, ItemDef, ItemDesc}, - ChatMsg, ChatType, InputKind, InventoryUpdateEvent, Pos, Vel, + ChatMsg, ChatType, InputKind, InventoryUpdateEvent, Pos, UtteranceKind, Vel, }, consts::{MAX_MOUNT_RANGE, MAX_PICKUP_RANGE}, outcome::Outcome, @@ -525,6 +525,11 @@ impl PlayState for SessionState { self.client.borrow_mut().toggle_dance(); } }, + GameInput::Greet => { + if state { + self.client.borrow_mut().utter(UtteranceKind::Greeting); + } + }, GameInput::Sneak => { if state { self.stop_auto_walk(); diff --git a/voxygen/src/settings/control.rs b/voxygen/src/settings/control.rs index 67b4defb63..c0b9eb1bd6 100644 --- a/voxygen/src/settings/control.rs +++ b/voxygen/src/settings/control.rs @@ -123,6 +123,7 @@ impl ControlSettings { GameInput::Jump => KeyMouse::Key(VirtualKeyCode::Space), GameInput::Sit => KeyMouse::Key(VirtualKeyCode::K), GameInput::Dance => KeyMouse::Key(VirtualKeyCode::J), + GameInput::Greet => KeyMouse::Key(VirtualKeyCode::H), GameInput::Glide => KeyMouse::Key(VirtualKeyCode::LShift), GameInput::Climb => KeyMouse::Key(VirtualKeyCode::Space), GameInput::ClimbDown => KeyMouse::Key(VirtualKeyCode::LControl), diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index 2dfe0a9c85..118fe109e9 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -39,6 +39,7 @@ pub enum GameInput { Jump, Sit, Dance, + Greet, Glide, Climb, ClimbDown, @@ -94,6 +95,7 @@ impl GameInput { GameInput::Jump => "gameinput.jump", GameInput::Sit => "gameinput.sit", GameInput::Dance => "gameinput.dance", + GameInput::Greet => "gameinput.greet", GameInput::Glide => "gameinput.glide", GameInput::Climb => "gameinput.climb", GameInput::ClimbDown => "gameinput.climbdown", @@ -159,6 +161,7 @@ impl GameInput { GameInput::Jump, GameInput::Sit, GameInput::Dance, + GameInput::Greet, GameInput::Glide, GameInput::Climb, GameInput::ClimbDown,