From bf025df204a112687ceb0a493dcb6cc92e55ece6 Mon Sep 17 00:00:00 2001 From: scott-c Date: Tue, 4 Aug 2020 23:24:58 +0800 Subject: [PATCH] refactor sfx mgr outcome useage --- voxygen/src/audio/sfx/mod.rs | 51 +++++++++++++++++++++--------------- voxygen/src/scene/mod.rs | 38 ++++++++++++++++----------- voxygen/src/session.rs | 26 +++++++++--------- 3 files changed, 67 insertions(+), 48 deletions(-) diff --git a/voxygen/src/audio/sfx/mod.rs b/voxygen/src/audio/sfx/mod.rs index c823c0f648..143e2820c1 100644 --- a/voxygen/src/audio/sfx/mod.rs +++ b/voxygen/src/audio/sfx/mod.rs @@ -191,24 +191,6 @@ impl From<&InventoryUpdateEvent> for SfxEvent { } } -impl<'a> TryFrom<&'a Outcome> for SfxEventItem { - type Error = (); - - fn try_from(outcome: &'a Outcome) -> Result { - match outcome { - Outcome::Explosion { pos, power } => Ok(Self::new( - SfxEvent::Explosion, - Some(*pos), - Some((*power / 2.5).min(1.5)), - )), - Outcome::ProjectileShot { pos, .. } => { - Ok(Self::new(SfxEvent::ProjectileShot, Some(*pos), None)) - }, - // _ => Err(()), - } - } -} - #[derive(Deserialize)] pub struct SfxTriggerItem { pub files: Vec, @@ -251,13 +233,15 @@ impl SfxMgr { return; } - self.event_mapper - .maintain(state, player_entity, camera, &self.triggers); - let ecs = state.ecs(); audio.set_listener_pos(camera.dependents().cam_pos, camera.dependents().cam_dir); + // deprecated in favor of outcomes + self.event_mapper + .maintain(state, player_entity, camera, &self.triggers); + + // deprecated in favor of outcomes let events = ecs.read_resource::>().recv_all(); for event in events { @@ -283,6 +267,31 @@ impl SfxMgr { } } + pub fn handle_outcome(&mut self, outcome: &Outcome, audio: &mut AudioFrontend) { + if !audio.sfx_enabled() { + return; + } + + match outcome { + Outcome::Explosion { pos, power } => { + audio.play_sfx( + // TODO: from sfx triggers config + "voxygen.audio.sfx.explosion", + *pos, + Some((*power / 2.5).min(1.5)), + ); + }, + Outcome::ProjectileShot { pos, body, .. } => { + audio.play_sfx( + // TODO: from sfx triggers config + "voxygen.audio.sfx.glider_open", + *pos, + None, + ); + }, + } + } + fn load_sfx_items() -> SfxTriggers { match assets::load_file("voxygen.audio.sfx", &["ron"]) { Ok(file) => match ron::de::from_reader(file) { diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 5ee7f0257b..c635c02c83 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -21,10 +21,10 @@ use crate::{ use anim::character::SkeletonAttr; use common::{ comp, - state::{State, DeltaTime}, + outcome::Outcome, + state::{DeltaTime, State}, terrain::{BlockKind, TerrainChunk}, vol::ReadVol, - outcome::Outcome, }; use specs::{Entity as EcsEntity, Join, WorldExt}; use vek::*; @@ -193,21 +193,23 @@ impl Scene { } } - pub fn handle_outcome(&mut self, outcome: &Outcome, scene_data: &SceneData) { + pub fn handle_outcome( + &mut self, + outcome: &Outcome, + scene_data: &SceneData, + audio: &mut AudioFrontend, + ) { + self.particle_mgr.handle_outcome(&outcome, &scene_data); + self.sfx_mgr.handle_outcome(&outcome, audio); + match outcome { Outcome::Explosion { pos, power, .. } => self.event_lights.push(EventLight { - light: Light::new( - *pos, - Rgb::new(1.0, 0.5, 0.0), - *power * 2.5, - ), + light: Light::new(*pos, Rgb::new(1.0, 0.5, 0.0), *power * 2.5), timeout: 0.5, fadeout: |timeout| timeout * 2.0, }), _ => {}, } - - self.particle_mgr.handle_outcome(&outcome, &scene_data); } /// Maintain data such as GPU constant buffers, models, etc. To be called @@ -342,9 +344,11 @@ impl Scene { light_anim.strength, ) }) - .chain(self.event_lights - .iter() - .map(|el| el.light.with_strength((el.fadeout)(el.timeout)))) + .chain( + self.event_lights + .iter() + .map(|el| el.light.with_strength((el.fadeout)(el.timeout))), + ) .collect::>(); lights.sort_by_key(|light| light.get_pos().distance_squared(player_pos) as i32); lights.truncate(MAX_LIGHT_COUNT); @@ -437,8 +441,12 @@ impl Scene { self.particle_mgr.maintain(renderer, &scene_data); // Maintain audio - self.sfx_mgr - .maintain(audio, scene_data.state, scene_data.player_entity, &self.camera); + self.sfx_mgr.maintain( + audio, + scene_data.state, + scene_data.player_entity, + &self.camera, + ); self.music_mgr.maintain(audio, scene_data.state); } diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 15570db133..83bf35eb24 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -21,13 +21,13 @@ use common::{ }, event::EventBus, msg::ClientState, + outcome::Outcome, terrain::{Block, BlockKind}, util::Dir, vol::ReadVol, - outcome::Outcome, }; use specs::{Join, WorldExt}; -use std::{cell::RefCell, rc::Rc, time::Duration, convert::TryFrom}; +use std::{cell::RefCell, rc::Rc, time::Duration}; use tracing::{error, info}; use vek::*; @@ -101,7 +101,12 @@ impl SessionState { } /// Tick the session (and the client attached to it). - fn tick(&mut self, dt: Duration, global_state: &mut GlobalState, outcomes: &mut Vec) -> Result { + fn tick( + &mut self, + dt: Duration, + global_state: &mut GlobalState, + outcomes: &mut Vec, + ) -> Result { self.inputs.tick(dt); let mut client = self.client.borrow_mut(); @@ -638,7 +643,11 @@ impl PlayState for SessionState { // Runs if either in a multiplayer server or the singleplayer server is unpaused if !global_state.paused() { // Perform an in-game tick. - match self.tick(global_state.clock.get_avg_delta(), global_state, &mut outcomes) { + match self.tick( + global_state.clock.get_avg_delta(), + global_state, + &mut outcomes, + ) { Ok(TickAction::Continue) => {}, // Do nothing Ok(TickAction::Disconnect) => return PlayStateResult::Pop, // Go to main menu Err(err) => { @@ -1026,14 +1035,7 @@ impl PlayState for SessionState { // Process outcomes from client for outcome in outcomes { - if let Ok(sfx_event_item) = SfxEventItem::try_from(&outcome) { - client - .state() - .ecs() - .read_resource::>() - .emit_now(sfx_event_item); - } - self.scene.handle_outcome(&outcome, &scene_data); + self.scene.handle_outcome(&outcome, &scene_data, &mut global_state.audio); } } }