471d69fcf7
This requires a 508 beta version to use. If Travis fails this he's a bitch Exceptions will generate a stack trace, which is way easier to see and more helpful in actually solving this kind of crap. Also logs all the arguments, src, line, and file automatically. Removed any dubiously helpful information in the exception names so the runtime condenser won't see each one as a different runtime. If the information is critical to solve these bugs (camera one maybe?), then I'll just make these warnings. Thrown exceptions crash the currently running proc. Yes that means there's useless returns in a bunch of these, sue me. spawn()'s are to let the proc continue. Almost all of these are difficult to trigger, but I did test playsound. And frankly even if they do cause bugs by crashing procs, big whoop
107 lines
4.3 KiB
Plaintext
107 lines
4.3 KiB
Plaintext
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, surround = 1)
|
|
|
|
soundin = get_sfx(soundin) // same sound for everyone
|
|
|
|
if(isarea(source))
|
|
throw EXCEPTION("playsound(): source is an area")
|
|
return
|
|
|
|
var/frequency = get_rand_frequency() // Same frequency for everybody
|
|
var/turf/turf_source = get_turf(source)
|
|
|
|
// 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, surround)
|
|
|
|
|
|
/atom/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, surround = 1)
|
|
soundin = get_sfx(soundin)
|
|
|
|
var/sound/S = sound(soundin)
|
|
S.wait = 0 //No queue
|
|
S.channel = 0 //Any channel
|
|
S.volume = vol
|
|
|
|
if (vary)
|
|
if(frequency)
|
|
S.frequency = frequency
|
|
else
|
|
S.frequency = get_rand_frequency()
|
|
|
|
if(isturf(turf_source))
|
|
var/turf/T = get_turf(src)
|
|
|
|
//Atmosphere affects sound
|
|
var/pressure_factor = 1
|
|
var/datum/gas_mixture/hearer_env = T.return_air()
|
|
var/datum/gas_mixture/source_env = turf_source.return_air()
|
|
|
|
if(hearer_env && source_env)
|
|
var/pressure = min(hearer_env.return_pressure(), source_env.return_pressure())
|
|
if(pressure < ONE_ATMOSPHERE)
|
|
pressure_factor = max((pressure - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 0)
|
|
else //space
|
|
pressure_factor = 0
|
|
|
|
var/distance = get_dist(T, turf_source)
|
|
if(distance <= 1)
|
|
pressure_factor = max(pressure_factor, 0.15) //touching the source of the sound
|
|
|
|
S.volume *= pressure_factor
|
|
//End Atmosphere affecting sound
|
|
|
|
if(S.volume <= 0)
|
|
return //No sound
|
|
|
|
// 3D sounds, the technology is here!
|
|
if (surround)
|
|
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
|
|
|
|
/mob/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, surround = 1)
|
|
if(!client || ear_deaf > 0)
|
|
return
|
|
..()
|
|
|
|
/mob/proc/stopLobbySound()
|
|
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1)
|
|
|
|
/client/proc/playtitlemusic()
|
|
if(!ticker || !ticker.login_music) return
|
|
if(prefs && (prefs.toggles & SOUND_LOBBY))
|
|
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('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 ("bodyfall") soundin = pick('sound/effects/bodyfall1.ogg','sound/effects/bodyfall2.ogg','sound/effects/bodyfall3.ogg','sound/effects/bodyfall4.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')
|
|
if ("gunshot") soundin = pick('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg')
|
|
return soundin
|