Files
Yogstation/code/controllers/subsystem/sound.dm
azzzertyy 2b4079d1e5 Ports Bees ambience, reverb & sound system (#19559)
* ambience part 1

* almost there

* p3

* 420blazeit

* jesus christ im sorry

* virofix

* hm

* increase max time
2023-07-12 14:36:22 -05:00

128 lines
3.3 KiB
Plaintext

/*
* Sound subsystem:
* Used for things that need constant updating (sound fading in / out)
*/
SUBSYSTEM_DEF(sound_effects)
name = "Sound"
wait = 1
priority = FIRE_PRIORITY_AMBIENCE
flags = SS_NO_INIT
//Note: Make sure you update this if you use sound fading pre-game
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/acting_effects = list() //key = sound, value = datum
var/list/currentrun = list()
/datum/controller/subsystem/sound_effects/fire(resumed = 0)
if (!resumed)
src.currentrun = acting_effects.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(LAZYLEN(currentrun))
var/datum/sound_effect/sound_effect = currentrun[currentrun[currentrun.len]]
currentrun.len--
sound_effect.update_effect()
if(world.time > sound_effect.end_tick)
sound_effect.end_effect()
acting_effects -= sound_effect.effect_id
if (MC_TICK_CHECK)
return
// ===== Sound effect procs =====
/proc/sound_fade(sound/S, start_volume = 100, end_volume = 0, time = 10, var/listeners)
//Check basics
if(!S)
CRASH("sound_fade called without a sound file.")
if(!listeners)
return
//Check in list format
var/listeners_list = listeners
if(!islist(listeners_list))
listeners_list = list(listeners)
//Create datum
new /datum/sound_effect/fade(S, listeners_list, time, start_volume, end_volume)
// ===== Sound effect datum =====
/datum/sound_effect
var/name = "null"
var/sound/sound
var/list/listeners
var/start_tick
var/end_tick
var/effect_id
/datum/sound_effect/New(S, list/_listeners, time)
. = ..()
sound = S
listeners = _listeners
start_tick = world.time
end_tick = world.time + time
effect_id = generate_id()
start_sound()
/datum/sound_effect/proc/generate_id()
var/id = "[name][sound.file]"
for(var/A in listeners)
id = "[id][REF(A)]"
return id
/datum/sound_effect/proc/send_sound()
for(var/receiver in listeners)
SEND_SOUND(receiver, sound)
/datum/sound_effect/proc/update_effect()
return //Not implemented
/datum/sound_effect/proc/end_effect()
return //Not implemented
// Send the sound to the person it's affecting and add it to the sound subsystem.
// Should be overridden to account for if an effect is already playing for that sound.
/datum/sound_effect/proc/start_sound()
send_sound()
SSsound_effects.acting_effects[effect_id] = src
//============== Fade =============
/datum/sound_effect/fade
name = "fade"
var/in_vol
var/out_vol
//Calculated
var/current_vol
/datum/sound_effect/fade/New(S, list/_listeners, time, start_vol, end_vol)
in_vol = start_vol
out_vol = end_vol
. = ..(S, _listeners, time)
/datum/sound_effect/fade/start_sound()
//If the sound is already playing, make it fade from the current point
if(SSsound_effects.acting_effects[effect_id])
var/datum/sound_effect/fade/old_sound = SSsound_effects.acting_effects[effect_id]
in_vol = old_sound.current_vol
else
send_sound()
SSsound_effects.acting_effects[effect_id] = src
/datum/sound_effect/fade/update_effect()
var/time_multiplier = clamp((world.time - start_tick) / (end_tick - start_tick), 0, 1)
current_vol = (time_multiplier * out_vol) + ((1-time_multiplier) * in_vol)
sound.status = SOUND_UPDATE
sound.volume = current_vol
for(var/receiver in listeners)
SEND_SOUND(receiver, sound)
/datum/sound_effect/fade/end_effect()
if(!out_vol)
sound.repeat = FALSE