From d0828ed06f21afcab5c2e3be60af722d917b0a64 Mon Sep 17 00:00:00 2001 From: Rykka Stormheart Date: Fri, 3 Mar 2023 04:03:02 -0800 Subject: [PATCH] Fixes a looping sound bugs, adds additional options Previously, the pref check on `direct` loops would always fail if pref_check was not enabled, meaning that direct sounds never worked. This is fixed. Modifies how _direct override works. Previously, it was simply doing direct = _direct, which meant that any and all sounds with direct defined would immediately be flipped back to false UNLESS you specified a specific argument. Now, it is an +override+, labeled "disable_direct". If set true, this disables direct and forces it to use local playback. Exclusive mode is added. Enable this on your looping sound to +only+ start one of this soundloop from your object at a time, rather than allowing multiple start() calls to fire and trigger new loops. Skip Start Sound is an argument to start - this allows you to skip the startup and go straight to the mid. Skip Stop Sound is similar to the above, but it skips the stop/end sound, and simply ends the loop. --- 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 5ffbc47f11..de8a28fa38 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 sound_to(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)