Files
CHOMPStation2/code/datums/looping_sounds/_looping_sound.dm
CHOMPStation2 f37f844f5a [MIRROR] de-reference save_data lists (#9067)
Co-authored-by: Heroman3003 <31296024+Heroman3003@users.noreply.github.com>
Co-authored-by: Kashargul <KashL@t-online.de>
2024-09-28 05:05:23 +02:00

132 lines
4.3 KiB
Plaintext

/*
output_atoms (list of atoms) The destination(s) for the sounds
mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end.
mid_length (num) The length to wait between playing mid_sounds
start_sound (soundfile) Played before starting the mid_sounds loop
start_length (num) How long to wait before starting the main loop after playing start_sound
end_sound (soundfile) The sound played after the main loop has concluded
chance (num) Chance per loop to play a mid_sound
volume (num) Sound output volume
muted (bool) Private. Used to stop the sound loop.
max_loops (num) The max amount of loops to run for.
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.
volume_chan (type) If set to a specific volume channel via the incoming argument, we tell the playsound proc to modulate volume based on that channel //CHOMPedit
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
var/mid_sounds
var/mid_length
var/start_sound
var/start_length
var/end_sound
var/chance
var/volume = 100
var/max_loops
var/direct
var/vary
var/extra_range
var/opacity_check
var/pref_check
var/volume_chan //CHOMPedit
var/exclusive
var/falloff // CHOMPEdit: Add Falloff
var/timerid
var/started
/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
if(disable_direct)
direct = FALSE
if(start_immediately)
start()
/datum/looping_sound/Destroy()
stop()
output_atoms = null
return ..()
/datum/looping_sound/proc/start(atom/add_thing, skip_start_sound = FALSE)
if(QDELETED(src)) //Chomp runtime
return //Chomp runtime
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, skip_stop_sound = FALSE)
if(remove_thing)
output_atoms -= remove_thing
if(!timerid)
return
if(!skip_stop_sound)
on_stop()
deltimer(timerid)
timerid = null
started = FALSE
/datum/looping_sound/proc/sound_loop(starttime)
if(QDELETED(src) || (max_loops && world.time >= starttime + mid_length * max_loops)) //ChompEDIT - runtime
stop()
return
if(!chance || prob(chance))
play(get_sound(starttime))
if(!timerid)
timerid = addtimer(CALLBACK(src, PROC_REF(sound_loop), world.time), mid_length, TIMER_STOPPABLE | TIMER_LOOP)
/datum/looping_sound/proc/play(soundfile)
var/list/atoms_cache = output_atoms
var/sound/S = sound(soundfile)
if(direct)
S.channel = SSsounds.random_available_channel()
S.volume = volume
for(var/i in 1 to atoms_cache?.len) //Chomp - runtime
var/atom/thing = atoms_cache[i]
if(direct)
if(ismob(thing))
var/mob/M = thing
if(!M.check_sound_preference(pref_check))
continue
SEND_SOUND(thing, S)
else
playsound(thing, S, volume, vary, extra_range, falloff = falloff, ignore_walls = !opacity_check, preference = pref_check, volume_channel = volume_chan) // CHOMPEdit - Weather volume channel CHOMPEdit again: falloff
/datum/looping_sound/proc/get_sound(starttime, _mid_sounds)
if(!_mid_sounds)
. = mid_sounds
else
. = _mid_sounds
while(!isfile(.) && !isnull(.))
. = pickweight(.)
/datum/looping_sound/proc/on_start()
var/start_wait = 1 // On TG this is 0, however it needs to be 1 to work around an issue.
if(start_sound)
play(start_sound)
start_wait = start_length
addtimer(CALLBACK(src, PROC_REF(sound_loop)), start_wait)
/datum/looping_sound/proc/on_stop()
if(end_sound)
play(end_sound)