Adds on-hit combat sfx

This commit is contained in:
DaforLynx 2021-04-04 03:04:02 +00:00 committed by Justin Shipsey
parent 4be0f1b02e
commit 6734198104
49 changed files with 176 additions and 97 deletions

View File

@ -17,7 +17,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Admin designated build areas - Admin designated build areas
- Indicator text to collectable terrain sprites - Indicator text to collectable terrain sprites
- You can now autorequest exact change by ctrl-clicking in a trade, and can quick-add individual items with shift-click. - You can now autorequest exact change by ctrl-clicking in a trade, and can quick-add individual items with shift-click.
<<<<<<< HEAD
- Buy and sell prices in tooltips when trading with a merchant now have colors. - Buy and sell prices in tooltips when trading with a merchant now have colors.
=======
- Attacks now emit sound effects from the target on hit.
>>>>>>> e2f8d1d27 (Changelog)
### Changed ### Changed
@ -31,8 +35,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Overhauled clouds for more verticality and performance - Overhauled clouds for more verticality and performance
- New tooltip for items with stats comparison - New tooltip for items with stats comparison
- Improved bow feedback, added arrow particles - Improved bow feedback, added arrow particles
<<<<<<< HEAD
- Retiered most sceptres and staves - Retiered most sceptres and staves
- Loot tables can now recursively reference loot tables - Loot tables can now recursively reference loot tables
=======
- "max_sfx_channels" default now set to 30
>>>>>>> e2f8d1d27 (Changelog)
### Removed ### Removed

View File

@ -194,7 +194,7 @@
//), //),
GliderOpen: ( GliderOpen: (
files: [ files: [
"voxygen.audio.sfx.glider_open", "voxygen.audio.sfx.character.glider_open",
], ],
threshold: 0.5, threshold: 0.5,
), ),
@ -206,7 +206,7 @@
//), //),
GliderClose: ( GliderClose: (
files: [ files: [
"voxygen.audio.sfx.glider_close", "voxygen.audio.sfx.character.glider_close",
], ],
threshold: 0.5, threshold: 0.5,
), ),

BIN
assets/voxygen/audio/sfx/abilities/explosion.wav (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/audio/sfx/ambient/fire.wav (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/audio/sfx/ambient/owl_1.wav (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/audio/sfx/character/glider_open.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/character/hit_1.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/character/hit_2.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/character/hit_3.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/character/hit_4.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/character/interrupted_1.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/character/stunned_1.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/character/stunned_2.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/explosion.wav (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/audio/sfx/glider_open.wav (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,8 +1,7 @@
use crate::comp::buff::BuffKind;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use crate::{ use crate::{
comp::{ comp::{
buff::{Buff, BuffChange, BuffData, BuffSource}, buff::{Buff, BuffChange, BuffData, BuffKind, BuffSource},
inventory::{ inventory::{
item::{ item::{
armor::Protection, armor::Protection,
@ -17,6 +16,7 @@ use crate::{
Inventory, Stats, Inventory, Stats,
}, },
event::ServerEvent, event::ServerEvent,
outcome::Outcome,
uid::Uid, uid::Uid,
util::Dir, util::Dir,
}; };
@ -54,6 +54,7 @@ pub struct TargetInfo<'a> {
pub inventory: Option<&'a Inventory>, pub inventory: Option<&'a Inventory>,
pub stats: Option<&'a Stats>, pub stats: Option<&'a Stats>,
pub health: Option<&'a Health>, pub health: Option<&'a Health>,
pub pos: Vec3<f32>,
} }
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@ -115,6 +116,7 @@ impl Attack {
// Currently just modifies damage, maybe look into modifying strength of other effects? // Currently just modifies damage, maybe look into modifying strength of other effects?
strength_modifier: f32, strength_modifier: f32,
mut emit: impl FnMut(ServerEvent), mut emit: impl FnMut(ServerEvent),
mut emit_outcome: impl FnMut(Outcome),
) { ) {
let is_crit = thread_rng().gen::<f32>() < self.crit_chance; let is_crit = thread_rng().gen::<f32>() < self.crit_chance;
let mut accumulated_damage = 0.0; let mut accumulated_damage = 0.0;
@ -134,6 +136,7 @@ impl Attack {
); );
let applied_damage = -change.amount as f32; let applied_damage = -change.amount as f32;
accumulated_damage += applied_damage; accumulated_damage += applied_damage;
emit_outcome(Outcome::Damage { pos: target.pos });
if change.amount != 0 { if change.amount != 0 {
emit(ServerEvent::Damage { emit(ServerEvent::Damage {
entity: target.entity, entity: target.entity,

View File

@ -56,6 +56,9 @@ pub enum Outcome {
pos: Vec3<f32>, pos: Vec3<f32>,
body: comp::Body, body: comp::Body,
}, },
Damage {
pos: Vec3<f32>,
},
} }
impl Outcome { impl Outcome {
@ -66,7 +69,8 @@ impl Outcome {
| Outcome::ProjectileHit { pos, .. } | Outcome::ProjectileHit { pos, .. }
| Outcome::Beam { pos, .. } | Outcome::Beam { pos, .. }
| Outcome::SkillPointGain { pos, .. } | Outcome::SkillPointGain { pos, .. }
| Outcome::SummonedCreature { pos, .. } => Some(*pos), | Outcome::SummonedCreature { pos, .. }
| Outcome::Damage { pos, .. } => Some(*pos),
Outcome::BreakBlock { pos, .. } => Some(pos.map(|e| e as f32 + 0.5)), Outcome::BreakBlock { pos, .. } => Some(pos.map(|e| e as f32 + 0.5)),
Outcome::ExpChange { .. } | Outcome::ComboChange { .. } => None, Outcome::ExpChange { .. } | Outcome::ComboChange { .. } => None,
} }

View File

@ -5,6 +5,7 @@ use common::{
Scale, Stats, Scale, Stats,
}, },
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
outcome::Outcome,
resources::{DeltaTime, Time}, resources::{DeltaTime, Time},
terrain::TerrainGrid, terrain::TerrainGrid,
uid::{Uid, UidAllocator}, uid::{Uid, UidAllocator},
@ -15,7 +16,7 @@ use common_ecs::{Job, Origin, ParMode, Phase, System};
use rayon::iter::ParallelIterator; use rayon::iter::ParallelIterator;
use specs::{ use specs::{
saveload::MarkerAllocator, shred::ResourceId, Entities, Join, ParJoin, Read, ReadExpect, saveload::MarkerAllocator, shred::ResourceId, Entities, Join, ParJoin, Read, ReadExpect,
ReadStorage, SystemData, World, WriteStorage, ReadStorage, SystemData, World, Write, WriteStorage,
}; };
use std::time::Duration; use std::time::Duration;
use vek::*; use vek::*;
@ -49,13 +50,17 @@ impl<'a> System<'a> for Sys {
ReadData<'a>, ReadData<'a>,
WriteStorage<'a, BeamSegment>, WriteStorage<'a, BeamSegment>,
WriteStorage<'a, Beam>, WriteStorage<'a, Beam>,
Write<'a, Vec<Outcome>>,
); );
const NAME: &'static str = "beam"; const NAME: &'static str = "beam";
const ORIGIN: Origin = Origin::Common; const ORIGIN: Origin = Origin::Common;
const PHASE: Phase = Phase::Create; const PHASE: Phase = Phase::Create;
fn run(job: &mut Job<Self>, (read_data, mut beam_segments, mut beams): Self::SystemData) { fn run(
job: &mut Job<Self>,
(read_data, mut beam_segments, mut beams, mut outcomes): Self::SystemData,
) {
let mut server_emitter = read_data.server_bus.emitter(); let mut server_emitter = read_data.server_bus.emitter();
let time = read_data.time.0; let time = read_data.time.0;
@ -64,24 +69,25 @@ impl<'a> System<'a> for Sys {
job.cpu_stats.measure(ParMode::Rayon); job.cpu_stats.measure(ParMode::Rayon);
// Beams // Beams
let (server_events, add_hit_entities) = ( let (server_events, add_hit_entities, mut new_outcomes) = (
&read_data.entities, &read_data.entities,
&read_data.positions, &read_data.positions,
&read_data.orientations, &read_data.orientations,
&beam_segments, &beam_segments,
) )
.par_join() .par_join()
.fold(|| (Vec::new(), Vec::new()), |(mut server_events, mut add_hit_entities), (entity, pos, ori, beam_segment)| .fold(|| (Vec::new(), Vec::new(), Vec::new()),
|(mut server_events, mut add_hit_entities, mut outcomes),
(entity, pos, ori, beam_segment)|
{ {
let creation_time = match beam_segment.creation { let creation_time = match beam_segment.creation {
Some(time) => time, Some(time) => time,
// Skip newly created beam segments // Skip newly created beam segments
None => return (server_events, add_hit_entities), None => return (server_events, add_hit_entities, outcomes),
}; };
let end_time = creation_time + beam_segment.duration.as_secs_f64(); let end_time = creation_time + beam_segment.duration.as_secs_f64();
// If beam segment is out of time emit destroy event but still continue since it // If beam segment is out of time emit destroy event but still continue since it
// may have traveled and produced effects a bit before reaching it's // may have traveled and produced effects a bit before reaching its
// end point // end point
if end_time < time { if end_time < time {
server_events.push(ServerEvent::Destroy { server_events.push(ServerEvent::Destroy {
@ -93,7 +99,7 @@ impl<'a> System<'a> for Sys {
// Determine area that was covered by the beam in the last tick // Determine area that was covered by the beam in the last tick
let frame_time = dt.min((end_time - time) as f32); let frame_time = dt.min((end_time - time) as f32);
if frame_time <= 0.0 { if frame_time <= 0.0 {
return (server_events, add_hit_entities); return (server_events, add_hit_entities, outcomes);
} }
// Note: min() probably uneeded // Note: min() probably uneeded
let time_since_creation = (time - creation_time) as f32; let time_since_creation = (time - creation_time) as f32;
@ -112,7 +118,7 @@ impl<'a> System<'a> for Sys {
let hit_entities = if let Some(beam) = beam_owner.and_then(|e| beams.get(e)) { let hit_entities = if let Some(beam) = beam_owner.and_then(|e| beams.get(e)) {
&beam.hit_entities &beam.hit_entities
} else { } else {
return (server_events, add_hit_entities); return (server_events, add_hit_entities, outcomes);
}; };
// Go through all other effectable entities // Go through all other effectable entities
@ -181,6 +187,7 @@ impl<'a> System<'a> for Sys {
inventory: read_data.inventories.get(target), inventory: read_data.inventories.get(target),
stats: read_data.stats.get(target), stats: read_data.stats.get(target),
health: read_data.healths.get(target), health: read_data.healths.get(target),
pos: pos.0,
}; };
beam_segment.properties.attack.apply_attack( beam_segment.properties.attack.apply_attack(
@ -191,19 +198,23 @@ impl<'a> System<'a> for Sys {
false, false,
1.0, 1.0,
|e| server_events.push(e), |e| server_events.push(e),
|o| outcomes.push(o),
); );
add_hit_entities.push((beam_owner, *uid_b)); add_hit_entities.push((beam_owner, *uid_b));
} }
} }
(server_events, add_hit_entities) (server_events, add_hit_entities, outcomes)
}).reduce(|| (Vec::new(), Vec::new()), |(mut events_a, mut hit_entities_a), (mut events_b, mut hit_entities_b)| { }).reduce(|| (Vec::new(), Vec::new(), Vec::new()),
|(mut events_a, mut hit_entities_a, mut outcomes_a),
(mut events_b, mut hit_entities_b, mut outcomes_b)| {
events_a.append(&mut events_b); events_a.append(&mut events_b);
hit_entities_a.append(&mut hit_entities_b); hit_entities_a.append(&mut hit_entities_b);
(events_a, hit_entities_a) outcomes_a.append(&mut outcomes_b);
(events_a, hit_entities_a, outcomes_a)
}); });
job.cpu_stats.measure(ParMode::Single); job.cpu_stats.measure(ParMode::Single);
outcomes.append(&mut new_outcomes);
for event in server_events { for event in server_events {
server_emitter.emit(event); server_emitter.emit(event);

View File

@ -11,7 +11,7 @@ pub mod melee;
mod mount; mod mount;
pub mod phys; pub mod phys;
#[cfg(feature = "plugins")] pub mod plugin; #[cfg(feature = "plugins")] pub mod plugin;
mod projectile; pub mod projectile;
mod shockwave; mod shockwave;
pub mod state; pub mod state;
mod stats; mod stats;
@ -34,6 +34,5 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
dispatch::<projectile::Sys>(dispatch_builder, &[&phys::Sys::sys_name()]); dispatch::<projectile::Sys>(dispatch_builder, &[&phys::Sys::sys_name()]);
dispatch::<shockwave::Sys>(dispatch_builder, &[&phys::Sys::sys_name()]); dispatch::<shockwave::Sys>(dispatch_builder, &[&phys::Sys::sys_name()]);
dispatch::<beam::Sys>(dispatch_builder, &[&phys::Sys::sys_name()]); dispatch::<beam::Sys>(dispatch_builder, &[&phys::Sys::sys_name()]);
dispatch::<melee::Sys>(dispatch_builder, &[&projectile::Sys::sys_name()]);
dispatch::<aura::Sys>(dispatch_builder, &[]); dispatch::<aura::Sys>(dispatch_builder, &[]);
} }

View File

@ -5,13 +5,14 @@ use common::{
Stats, Stats,
}, },
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
outcome::Outcome,
uid::Uid, uid::Uid,
util::Dir, util::Dir,
GroupTarget, GroupTarget,
}; };
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use specs::{ use specs::{
shred::ResourceId, Entities, Join, Read, ReadStorage, SystemData, World, WriteStorage, shred::ResourceId, Entities, Join, Read, ReadStorage, SystemData, World, Write, WriteStorage,
}; };
use vek::*; use vek::*;
@ -39,13 +40,17 @@ pub struct ReadData<'a> {
pub struct Sys; pub struct Sys;
impl<'a> System<'a> for Sys { impl<'a> System<'a> for Sys {
type SystemData = (ReadData<'a>, WriteStorage<'a, Melee>); type SystemData = (
ReadData<'a>,
WriteStorage<'a, Melee>,
Write<'a, Vec<Outcome>>,
);
const NAME: &'static str = "melee"; const NAME: &'static str = "melee";
const ORIGIN: Origin = Origin::Common; const ORIGIN: Origin = Origin::Common;
const PHASE: Phase = Phase::Create; const PHASE: Phase = Phase::Create;
fn run(_job: &mut Job<Self>, (read_data, mut melee_attacks): Self::SystemData) { fn run(_job: &mut Job<Self>, (read_data, mut melee_attacks, mut outcomes): Self::SystemData) {
let mut server_emitter = read_data.server_bus.emitter(); let mut server_emitter = read_data.server_bus.emitter();
// Attacks // Attacks
for (attacker, uid, pos, ori, melee_attack, body) in ( for (attacker, uid, pos, ori, melee_attack, body) in (
@ -141,6 +146,7 @@ impl<'a> System<'a> for Sys {
inventory: read_data.inventories.get(target), inventory: read_data.inventories.get(target),
stats: read_data.stats.get(target), stats: read_data.stats.get(target),
health: read_data.healths.get(target), health: read_data.healths.get(target),
pos: pos.0,
}; };
melee_attack.attack.apply_attack( melee_attack.attack.apply_attack(
@ -151,6 +157,7 @@ impl<'a> System<'a> for Sys {
is_dodge, is_dodge,
1.0, 1.0,
|e| server_emitter.emit(e), |e| server_emitter.emit(e),
|o| outcomes.push(o),
); );
melee_attack.hit_count += 1; melee_attack.hit_count += 1;

View File

@ -129,6 +129,7 @@ impl<'a> System<'a> for Sys {
inventory: read_data.inventories.get(target), inventory: read_data.inventories.get(target),
stats: read_data.stats.get(target), stats: read_data.stats.get(target),
health: read_data.healths.get(target), health: read_data.healths.get(target),
pos: pos.0,
}; };
if let Some(&body) = read_data.bodies.get(entity) { if let Some(&body) = read_data.bodies.get(entity) {
@ -152,6 +153,7 @@ impl<'a> System<'a> for Sys {
false, false,
1.0, 1.0,
|e| server_emitter.emit(e), |e| server_emitter.emit(e),
|o| outcomes.push(o),
); );
} }
}, },

View File

@ -5,6 +5,7 @@ use common::{
Shockwave, ShockwaveHitEntities, Stats, Shockwave, ShockwaveHitEntities, Stats,
}, },
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
outcome::Outcome,
resources::{DeltaTime, Time}, resources::{DeltaTime, Time},
uid::{Uid, UidAllocator}, uid::{Uid, UidAllocator},
util::Dir, util::Dir,
@ -13,7 +14,7 @@ use common::{
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use specs::{ use specs::{
saveload::MarkerAllocator, shred::ResourceId, Entities, Join, Read, ReadStorage, SystemData, saveload::MarkerAllocator, shred::ResourceId, Entities, Join, Read, ReadStorage, SystemData,
World, WriteStorage, World, Write, WriteStorage,
}; };
use vek::*; use vek::*;
@ -47,6 +48,7 @@ impl<'a> System<'a> for Sys {
ReadData<'a>, ReadData<'a>,
WriteStorage<'a, Shockwave>, WriteStorage<'a, Shockwave>,
WriteStorage<'a, ShockwaveHitEntities>, WriteStorage<'a, ShockwaveHitEntities>,
Write<'a, Vec<Outcome>>,
); );
const NAME: &'static str = "shockwave"; const NAME: &'static str = "shockwave";
@ -55,7 +57,7 @@ impl<'a> System<'a> for Sys {
fn run( fn run(
_job: &mut Job<Self>, _job: &mut Job<Self>,
(read_data, mut shockwaves, mut shockwave_hit_lists): Self::SystemData, (read_data, mut shockwaves, mut shockwave_hit_lists, mut outcomes): Self::SystemData,
) { ) {
let mut server_emitter = read_data.server_bus.emitter(); let mut server_emitter = read_data.server_bus.emitter();
@ -189,6 +191,7 @@ impl<'a> System<'a> for Sys {
inventory: read_data.inventories.get(target), inventory: read_data.inventories.get(target),
stats: read_data.stats.get(target), stats: read_data.stats.get(target),
health: read_data.healths.get(target), health: read_data.healths.get(target),
pos: pos.0,
}; };
shockwave.properties.attack.apply_attack( shockwave.properties.attack.apply_attack(
@ -199,6 +202,7 @@ impl<'a> System<'a> for Sys {
false, false,
1.0, 1.0,
|e| server_emitter.emit(e), |e| server_emitter.emit(e),
|o| outcomes.push(o),
); );
shockwave_hit_list.hit_entities.push(*uid_b); shockwave_hit_list.hit_entities.push(*uid_b);

View File

@ -544,8 +544,8 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
// Add an outcome // Add an outcome
// Uses radius as outcome power for now // Uses radius as outcome power for now
let outcome_power = explosion.radius; let outcome_power = explosion.radius;
ecs.write_resource::<Vec<Outcome>>() let mut outcomes = ecs.write_resource::<Vec<Outcome>>();
.push(Outcome::Explosion { outcomes.push(Outcome::Explosion {
pos, pos,
power: outcome_power, power: outcome_power,
radius: explosion.radius, radius: explosion.radius,
@ -711,6 +711,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
inventory: inventory_b_maybe, inventory: inventory_b_maybe,
stats: stats_b_maybe, stats: stats_b_maybe,
health: Some(health_b), health: Some(health_b),
pos,
}; };
let server_eventbus = ecs.read_resource::<EventBus<ServerEvent>>(); let server_eventbus = ecs.read_resource::<EventBus<ServerEvent>>();
@ -723,6 +724,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
false, false,
strength, strength,
|e| server_eventbus.emit_now(e), |e| server_eventbus.emit_now(e),
|o| outcomes.push(o),
); );
} }
} }

View File

@ -11,7 +11,8 @@ pub mod terrain;
pub mod terrain_sync; pub mod terrain_sync;
pub mod waypoint; pub mod waypoint;
use common_ecs::{dispatch, run_now}; use common_ecs::{dispatch, run_now, System};
use common_sys::{melee, projectile};
use specs::DispatcherBuilder; use specs::DispatcherBuilder;
use std::{ use std::{
marker::PhantomData, marker::PhantomData,
@ -21,6 +22,7 @@ use std::{
pub type PersistenceScheduler = SysScheduler<persistence::Sys>; pub type PersistenceScheduler = SysScheduler<persistence::Sys>;
pub fn add_server_systems(dispatch_builder: &mut DispatcherBuilder) { pub fn add_server_systems(dispatch_builder: &mut DispatcherBuilder) {
dispatch::<melee::Sys>(dispatch_builder, &[&projectile::Sys::sys_name()]);
dispatch::<agent::Sys>(dispatch_builder, &[]); dispatch::<agent::Sys>(dispatch_builder, &[]);
dispatch::<terrain::Sys>(dispatch_builder, &[]); dispatch::<terrain::Sys>(dispatch_builder, &[]);
dispatch::<waypoint::Sys>(dispatch_builder, &[]); dispatch::<waypoint::Sys>(dispatch_builder, &[]);

View File

@ -97,13 +97,13 @@ impl EventMapper for BlockEventMapper {
volume: 1.0, volume: 1.0,
cond: |st| st.get_day_period().is_dark(), cond: |st| st.get_day_period().is_dark(),
}, },
BlockSounds { // BlockSounds {
blocks: |boi| &boi.river, // blocks: |boi| &boi.river,
range: 1, // range: 1,
sfx: SfxEvent::RunningWater, // sfx: SfxEvent::RunningWater,
volume: 1.0, // volume: 1.0,
cond: |_| true, // cond: |_| true,
}, // },
//BlockSounds { //BlockSounds {
// blocks: |boi| &boi.embers, // blocks: |boi| &boi.embers,
// range: 1, // range: 1,

View File

@ -72,7 +72,7 @@ impl EventMapper for CampfireEventMapper {
.map(|b| b.is_liquid()) .map(|b| b.is_liquid())
.unwrap_or(false); .unwrap_or(false);
let sfx_trigger_item = triggers.get_key_value(&mapped_event); let sfx_trigger_item = triggers.get_key_value(&mapped_event);
const CAMPFIRE_VOLUME: f32 = 0.1; const CAMPFIRE_VOLUME: f32 = 0.9;
audio.emit_sfx(sfx_trigger_item, pos.0, Some(CAMPFIRE_VOLUME), underwater); audio.emit_sfx(sfx_trigger_item, pos.0, Some(CAMPFIRE_VOLUME), underwater);
internal_state.time = Instant::now(); internal_state.time = Instant::now();
} }

View File

@ -168,6 +168,8 @@ pub enum SfxEvent {
Inventory(SfxInventoryEvent), Inventory(SfxInventoryEvent),
Explosion, Explosion,
ProjectileShot, ProjectileShot,
Damage,
// Poise(StunState),
} }
#[derive(Clone, Debug, PartialEq, Deserialize, Hash, Eq)] #[derive(Clone, Debug, PartialEq, Deserialize, Hash, Eq)]
@ -311,7 +313,7 @@ impl SfxMgr {
let file_ref = if *is_attack && matches!(reagent, Some(Reagent::Green)) { let file_ref = if *is_attack && matches!(reagent, Some(Reagent::Green)) {
"voxygen.audio.sfx.abilities.heal_bomb" "voxygen.audio.sfx.abilities.heal_bomb"
} else { } else {
"voxygen.audio.sfx.explosion" "voxygen.audio.sfx.abilities.explosion"
}; };
audio.play_sfx( audio.play_sfx(
@ -370,10 +372,10 @@ impl SfxMgr {
| object::Body::ArrowTurret, | object::Body::ArrowTurret,
) => { ) => {
if target.is_none() { if target.is_none() {
audio.play_sfx("voxygen.audio.sfx.arrow_miss", *pos, Some(2.0)); audio.play_sfx("voxygen.audio.sfx.character.arrow_miss", *pos, Some(2.0));
} else if *source == client.uid() { } else if *source == client.uid() {
audio.play_sfx( audio.play_sfx(
"voxygen.audio.sfx.arrow_hit", "voxygen.audio.sfx.character.arrow_hit",
client.position().unwrap_or(*pos), client.position().unwrap_or(*pos),
Some(2.0), Some(2.0),
); );
@ -389,12 +391,16 @@ impl SfxMgr {
}, },
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.staff_channeling"; let file_ref = "voxygen.audio.sfx.abilities.sceptre_channeling";
if thread_rng().gen_bool(0.5) {
audio.play_sfx(file_ref, *pos, None); audio.play_sfx(file_ref, *pos, None);
};
}, },
beam::FrontendSpecifier::Flamethrower | beam::FrontendSpecifier::Cultist => { beam::FrontendSpecifier::Flamethrower | beam::FrontendSpecifier::Cultist => {
let file_ref = "voxygen.audio.sfx.abilities.flame_thrower"; let file_ref = "voxygen.audio.sfx.abilities.flame_thrower";
if thread_rng().gen_bool(0.5) {
audio.play_sfx(file_ref, *pos, None); audio.play_sfx(file_ref, *pos, None);
}
}, },
}, },
Outcome::BreakBlock { pos, .. } => { Outcome::BreakBlock { pos, .. } => {
@ -404,6 +410,15 @@ impl SfxMgr {
Outcome::ExpChange { .. } Outcome::ExpChange { .. }
| Outcome::ComboChange { .. } | Outcome::ComboChange { .. }
| Outcome::SummonedCreature { .. } => {}, | Outcome::SummonedCreature { .. } => {},
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);
},
} }
} }

View File

@ -208,6 +208,7 @@ impl ParticleMgr {
| Outcome::ExpChange { .. } | Outcome::ExpChange { .. }
| Outcome::SkillPointGain { .. } | Outcome::SkillPointGain { .. }
| Outcome::ComboChange { .. } => {}, | Outcome::ComboChange { .. } => {},
Outcome::Damage { .. } => {},
} }
} }

View File

@ -677,7 +677,7 @@ impl Default for AudioSettings {
master_volume: 1.0, master_volume: 1.0,
music_volume: 0.4, music_volume: 0.4,
sfx_volume: 0.6, sfx_volume: 0.6,
max_sfx_channels: 10, max_sfx_channels: 30,
output: AudioOutput::Automatic, output: AudioOutput::Automatic,
} }
} }