refactor sfx mgr outcome useage

This commit is contained in:
scott-c 2020-08-04 23:24:58 +08:00
parent cc36e9c300
commit bf025df204
3 changed files with 67 additions and 48 deletions

View File

@ -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<Self, Self::Error> {
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<String>,
@ -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::<EventBus<SfxEventItem>>().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) {

View File

@ -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::<Vec<_>>();
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);
}

View File

@ -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<Outcome>) -> Result<TickAction, Error> {
fn tick(
&mut self,
dt: Duration,
global_state: &mut GlobalState,
outcomes: &mut Vec<Outcome>,
) -> Result<TickAction, Error> {
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::<EventBus<SfxEventItem>>()
.emit_now(sfx_event_item);
}
self.scene.handle_outcome(&outcome, &scene_data);
self.scene.handle_outcome(&outcome, &scene_data, &mut global_state.audio);
}
}
}