From b6f2d39f6bfabf924ef22b60962c52e6114644cb Mon Sep 17 00:00:00 2001 From: Graham Lloyd Date: Thu, 27 Mar 2014 14:49:49 -0400 Subject: [PATCH] 3d Sound from /tg/ --- code/game/objects/explosion.dm | 34 +++++- code/game/objects/structures/musician.dm | 6 +- code/game/sound.dm | 140 +++++++++++------------ 3 files changed, 103 insertions(+), 77 deletions(-) diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index c024b49831..c48d062e9e 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -26,9 +26,37 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa epicenter = get_turf(epicenter) if(!epicenter) return + var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flash_range) + //playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(devastation_range*2,1) ) + //playsound(epicenter, "explosion", 100, 1, round(devastation_range,1) ) - playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(devastation_range*2,1) ) - playsound(epicenter, "explosion", 100, 1, round(devastation_range,1) ) +// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves. + +// Stereo users will also hear the direction of the explosion! + +// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions. + +// 3/7/14 will calculate to 80 + 35 + var/far_dist = 0 + far_dist += heavy_impact_range * 5 + far_dist += devastation_range * 20 + var/frequency = get_rand_frequency() + for(var/mob/M in player_list) + // Double check for client + if(M && M.client) + var/turf/M_turf = get_turf(M) + if(M_turf && M_turf.z == epicenter.z) + var/dist = get_dist(M_turf, epicenter) + // If inside the blast radius + world.view - 2 + if(dist <= round(max_range + world.view - 2, 1)) + M.playsound_local(epicenter, get_sfx("explosion"), 100, 1, frequency, falloff = 5) // get_sfx() is so that everyone gets the same sound + + //You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. + + else if(dist <= far_dist) + var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist + far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion + M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5) var/close = range(world.view+round(devastation_range,1), epicenter) // to all distanced mobs play a different sound @@ -55,7 +83,7 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa var/y0 = epicenter.y var/z0 = epicenter.z - for(var/turf/T in range(epicenter, max(devastation_range, heavy_impact_range, light_impact_range))) + for(var/turf/T in range(epicenter, max_range)) var/dist = cheap_pythag(T.x - x0,T.y - y0) if(dist < devastation_range) dist = 1 diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index c9bcbda3e5..425c03ad8c 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -204,7 +204,11 @@ if("Cn9") soundfile = 'sound/piano/Cn9.ogg' else return - hearers(15, src) << sound(soundfile) + //hearers(15, src) << sound(soundfile) + var/turf/source = get_turf(src) + for(var/mob/M in hearers(15, source)) + M.playsound_local(source, file(soundfile), 100, falloff = 5) + /obj/structure/device/piano/proc/playsong() do diff --git a/code/game/sound.dm b/code/game/sound.dm index 67062e64f3..b79504bf1d 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -1,79 +1,41 @@ -/proc/playsound(var/atom/source, soundin, vol as num, vary, extrarange as num) - //Frequency stuff only works with 45kbps oggs. +var/list/shatter_sound = list('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg') +var/list/explosion_sound = list('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg') +var/list/spark_sound = list('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks4.ogg') +var/list/rustle_sound = list('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg') +var/list/punch_sound = list('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg') +var/list/clown_sound = list('sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg') +var/list/swing_hit_sound = list('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg') +var/list/hiss_sound = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg') +var/list/page_sound = list('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg') +//var/list/gun_sound = list('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg') - switch(soundin) - if ("shatter") soundin = pick('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg') - if ("explosion") soundin = pick('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg') - if ("sparks") soundin = pick('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks4.ogg') - if ("rustle") soundin = pick('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg') - if ("punch") soundin = pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg') - if ("clownstep") soundin = pick('sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg') - if ("swing_hit") soundin = pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg') - if ("hiss") soundin = pick('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg') - if ("pageturn") soundin = pick('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg') +/proc/playsound(var/atom/source, soundin, vol as num, vary, extrarange as num, falloff) - var/sound/S = sound(soundin) - S.wait = 0 //No queue - S.channel = 0 //Any channel - S.volume = vol + soundin = get_sfx(soundin) // same sound for everyone - if (vary) - S.frequency = rand(32000, 55000) + if(isarea(source)) + error("[source] is an area and is trying to make the sound: [soundin]") + return - for (var/A in range(world.view+extrarange, source)) // Plays for people in range. + var/frequency = get_rand_frequency() // Same frequency for everybody + var/turf/turf_source = get_turf(source) - if(ismob(A)) - var/mob/M = A - var/mob/M2 = locate(/mob/, M) - if (M2 && M2.client) - if(M2.ear_deaf <= 0 || !M.ear_deaf) - if(isturf(source)) - var/dx = source.x - M2.x - S.pan = max(-100, min(100, dx/8.0 * 100)) + // Looping through the player list has the added bonus of working for mobs inside containers + for (var/P in player_list) + var/mob/M = P + if(!M || !M.client) + continue + if(get_dist(M, turf_source) <= world.view + extrarange) + var/turf/T = get_turf(M) + if(T && T.z == turf_source.z) + M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff) - M2 << S +var/const/FALLOFF_SOUNDS = 1 +var/const/SURROUND_CAP = 7 - if (M.client) - if(M.ear_deaf <= 0 || !M.ear_deaf) - if(isturf(source)) - var/dx = source.x - M.x - S.pan = max(-100, min(100, dx/8.0 * 100)) - - M << S - - if(istype(A, /obj/structure/closet)) - var/obj/O = A - for(var/mob/M in O) - if (M.client) - if(M.ear_deaf <= 0 || !M.ear_deaf) - if(isturf(source)) - var/dx = source.x - M.x - S.pan = max(-100, min(100, dx/8.0 * 100)) - - M << S - - for(var/obj/mecha/mech in range(world.view+extrarange, source)) - var/mob/M = mech.occupant - if (M && M.client) - if(M.ear_deaf <= 0 || !M.ear_deaf) - if(isturf(source)) - var/dx = source.x - M.x - S.pan = max(-100, min(100, dx/8.0 * 100)) - - M << S - // Now plays for people in lockers! -- Polymorph - -/mob/proc/playsound_local(var/atom/source, soundin, vol as num, vary, extrarange as num) +/mob/proc/playsound_local(var/turf/turf_source, soundin, vol as num, vary, frequency, falloff) if(!src.client || ear_deaf > 0) return - switch(soundin) - if ("shatter") soundin = pick('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg') - if ("explosion") soundin = pick('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg') - if ("sparks") soundin = pick('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks4.ogg') - if ("rustle") soundin = pick('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg') - if ("punch") soundin = pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg') - if ("clownstep") soundin = pick('sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg') - if ("swing_hit") soundin = pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg') - if ("hiss") soundin = pick('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg') + soundin = get_sfx(soundin) var/sound/S = sound(soundin) S.wait = 0 //No queue @@ -81,14 +43,46 @@ S.volume = vol if (vary) - S.frequency = rand(32000, 55000) - if(isturf(source)) - var/dx = source.x - src.x - S.pan = max(-100, min(100, dx/8.0 * 100)) + if(frequency) + S.frequency = frequency + else + S.frequency = get_rand_frequency() + + if(isturf(turf_source)) + // 3D sounds, the technology is here! + var/turf/T = get_turf(src) + var/dx = turf_source.x - T.x // Hearing from the right/left + + S.x = round(max(-SURROUND_CAP, min(SURROUND_CAP, dx)), 1) + + var/dz = turf_source.y - T.y // Hearing from infront/behind + S.z = round(max(-SURROUND_CAP, min(SURROUND_CAP, dz)), 1) + + // The y value is for above your head, but there is no ceiling in 2d spessmens. + S.y = 1 + S.falloff = (falloff ? falloff : FALLOFF_SOUNDS) src << S /client/proc/playtitlemusic() if(!ticker || !ticker.login_music) return if(prefs.toggles & SOUND_LOBBY) - src << sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS \ No newline at end of file + src << sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS + +/proc/get_rand_frequency() + return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. + +/proc/get_sfx(soundin) + if(istext(soundin)) + switch(soundin) + if ("shatter") soundin = pick(shatter_sound) + if ("explosion") soundin = pick(explosion_sound) + if ("sparks") soundin = pick(spark_sound) + if ("rustle") soundin = pick(rustle_sound) + if ("punch") soundin = pick(punch_sound) + if ("clownstep") soundin = pick(clown_sound) + if ("swing_hit") soundin = pick(swing_hit_sound) + if ("hiss") soundin = pick(hiss_sound) + if ("pageturn") soundin = pick(page_sound) + //if ("gunshot") soundin = pick(gun_sound) + return soundin \ No newline at end of file