From 4550a77b3fe926bd47613317fcfadc0ee2bef691 Mon Sep 17 00:00:00 2001 From: Atermonera Date: Sun, 12 Mar 2023 12:23:52 -0800 Subject: [PATCH 1/2] Merge pull request #9018 from Rykka-Stormheart/shep-dev-direct-sound-fix Fixes a looping sound bug, adds additional options --- code/datums/looping_sounds/_looping_sound.dm | 27 +++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/code/datums/looping_sounds/_looping_sound.dm b/code/datums/looping_sounds/_looping_sound.dm index be6ccd4fa54..e60fa3ad19d 100644 --- a/code/datums/looping_sounds/_looping_sound.dm +++ b/code/datums/looping_sounds/_looping_sound.dm @@ -16,6 +16,7 @@ direct (bool) If true plays directly to provided atoms instead of from them opacity_check (bool) If true, things behind walls/opaque things won't hear the sounds. pref_check (type) If set to a /datum/client_preference type, will check if the hearer has that preference active before playing it to them. + exclusive (bool) If true, only one of this sound is allowed to play. Relies on if started is true or not. If true, it will not start another loop until it is false. */ /datum/looping_sound var/list/atom/output_atoms @@ -32,16 +33,19 @@ var/extra_range var/opacity_check var/pref_check + var/exclusive var/timerid + var/started -/datum/looping_sound/New(list/_output_atoms=list(), start_immediately=FALSE, _direct=FALSE) +/datum/looping_sound/New(list/_output_atoms=list(), start_immediately=FALSE, disable_direct=FALSE) if(!mid_sounds) WARNING("A looping sound datum was created without sounds to play.") return output_atoms = _output_atoms - direct = _direct + if(disable_direct) + direct = FALSE if(start_immediately) start() @@ -51,21 +55,30 @@ output_atoms = null return ..() -/datum/looping_sound/proc/start(atom/add_thing) +/datum/looping_sound/proc/start(atom/add_thing, skip_start_sound = FALSE) if(add_thing) output_atoms |= add_thing if(timerid) return + if(skip_start_sound && (!exclusive && !started)) // Skip start sounds optionally, check if we're exclusive AND started already + sound_loop() + started = TRUE + return + if(exclusive && started) // Prevents a sound from starting multiple times + return // Don't start this loop. on_start() + started = TRUE -/datum/looping_sound/proc/stop(atom/remove_thing) +/datum/looping_sound/proc/stop(atom/remove_thing, skip_stop_sound = FALSE) if(remove_thing) output_atoms -= remove_thing if(!timerid) return - on_stop() + if(!skip_stop_sound) + on_stop() deltimer(timerid) timerid = null + started = FALSE /datum/looping_sound/proc/sound_loop(starttime) if(max_loops && world.time >= starttime + mid_length * max_loops) @@ -87,7 +100,7 @@ if(direct) if(ismob(thing)) var/mob/M = thing - if(!M.is_preference_enabled(pref_check)) + if(pref_check && !M.is_preference_enabled(pref_check)) continue SEND_SOUND(thing, S) else @@ -110,4 +123,4 @@ /datum/looping_sound/proc/on_stop() if(end_sound) - play(end_sound) \ No newline at end of file + play(end_sound)