diff --git a/code/datums/looping_sounds/looping_sound.dm b/code/datums/looping_sounds/looping_sound.dm new file mode 100644 index 00000000000..4a5af0010e9 --- /dev/null +++ b/code/datums/looping_sounds/looping_sound.dm @@ -0,0 +1,100 @@ +/* + 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 +*/ +/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/muted = TRUE + var/max_loops + var/direct + +/datum/looping_sound/New(list/_output_atoms = list(), start_immediately = FALSE, _direct = FALSE) + if(!mid_sounds) + WARNING("A looping sound datum was created without sounds to play.") + return + + output_atoms = _output_atoms + direct = _direct + + if(start_immediately) + start() + +/datum/looping_sound/Destroy() + stop() + output_atoms = null + return ..() + +/datum/looping_sound/proc/start(atom/add_thing) + if(add_thing) + output_atoms |= add_thing + if(!muted) + return + muted = FALSE + on_start() + +/datum/looping_sound/proc/stop(atom/remove_thing) + if(remove_thing) + output_atoms -= remove_thing + if(muted) + return + muted = TRUE + +/datum/looping_sound/proc/sound_loop(looped = 0) + if(muted || (max_loops && looped > max_loops)) + on_stop(looped) + return + if(!chance || prob(chance)) + play(get_sound(looped)) + addtimer(src, "sound_loop", mid_length, FALSE, ++looped) + +/datum/looping_sound/proc/play(soundfile) + var/list/atoms_cache = output_atoms + var/sound/S = sound(soundfile) + if(direct) + S.channel = open_sound_channel() + S.volume = volume + for(var/i in 1 to atoms_cache.len) + var/atom/thing = atoms_cache[i] + if(direct) + SEND_SOUND(thing, S) + else + playsound(thing, S, volume) + +/datum/looping_sound/proc/get_sound(looped, _mid_sounds) + if(!_mid_sounds) + . = mid_sounds + else + . = _mid_sounds + while(!isfile(.) && !isnull(.)) + . = pickweight(.) + +/datum/looping_sound/proc/on_start() + var/start_wait = 0 + if(start_sound) + play(start_sound) + start_wait = start_length + addtimer(src, "sound_loop", start_wait) + +/datum/looping_sound/proc/on_stop(looped) + if(end_sound) + play(end_sound) \ No newline at end of file diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm new file mode 100644 index 00000000000..b1f5bdc6908 --- /dev/null +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -0,0 +1,7 @@ +/datum/looping_sound/showering + start_sound = 'sound/machines/shower/shower_start.ogg' + start_length = 2 + mid_sounds = list('sound/machines/shower/shower_mid1.ogg' = 1,'sound/machines/shower/shower_mid2.ogg' = 1,'sound/machines/shower/shower_mid3.ogg' = 1) + mid_length = 10 + end_sound = 'sound/machines/shower/shower_end.ogg' + volume = 20 \ No newline at end of file diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 7cc9c97dfdd..8c473eab9e8 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -249,9 +249,11 @@ var/ismist = 0 //needs a var so we can make it linger~ var/watertemp = "normal" //freezing, normal, or boiling var/mobpresent = 0 //true if there is a mob on the shower's loc, this is to ease process() + var/datum/looping_sound/showering/soundloop /obj/machinery/shower/New(turf/T, newdir = SOUTH, building = FALSE) ..() + soundloop = new(list(src), FALSE) if(building) dir = newdir pixel_x = 0 @@ -264,8 +266,8 @@ layer = FLY_LAYER /obj/machinery/shower/Destroy() - if(mymist) - QDEL_NULL(mymist) + QDEL_NULL(mymist) + QDEL_NULL(soundloop) return ..() //add heat controls? when emagged, you can freeze to death in it? @@ -282,6 +284,7 @@ on = !on update_icon() if(on) + soundloop.start() if(M.loc == loc) wash(M) check_heat(M) @@ -289,6 +292,8 @@ for(var/atom/movable/G in src.loc) G.clean_blood() G.water_act(100, convertHeat(), src) + else + soundloop.stop() /obj/machinery/shower/attackby(obj/item/I as obj, mob/user as mob, params) if(I.type == /obj/item/analyzer) diff --git a/code/game/sound.dm b/code/game/sound.dm index 39bf16bc697..66746ece0ae 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -1,4 +1,4 @@ -/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE) +/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE) if(isarea(source)) error("[source] is an area and is trying to make the sound: [soundin]") return @@ -11,7 +11,10 @@ // Looping through the player list has the added bonus of working for mobs inside containers var/sound/S = sound(get_sfx(soundin)) var/maxdistance = (world.view + extrarange) * 3 - for(var/P in player_list) + var/list/listeners = player_list + if(!ignore_walls) //these sounds don't carry through walls + listeners = listeners & hearers(maxdistance, turf_source) + for(var/P in listeners) var/mob/M = P if(!M || !M.client) continue @@ -78,13 +81,15 @@ S.y = 1 S.falloff = (falloff ? falloff : FALLOFF_SOUNDS) - src << S + SEND_SOUND(src, S) -/client/proc/playtitlemusic() - if(!ticker || !ticker.login_music || config.disable_lobby_music) - return - if(prefs.sound & SOUND_LOBBY) - src << sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = CHANNEL_LOBBYMUSIC) // MAD JAMS +/proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, falloff = FALSE, channel = 0, pressure_affected = FALSE, sound/S) + if(!S) + S = sound(get_sfx(soundin)) + for(var/m in player_list) + if(ismob(m) && !isnewplayer(m)) + var/mob/M = m + M.playsound_local(M, null, volume, vary, frequency, falloff, channel, pressure_affected, S) /proc/open_sound_channel() var/static/next_channel = 1 //loop through the available 1024 - (the ones we reserve) channels and pray that its not still being used @@ -93,7 +98,13 @@ next_channel = 1 /mob/proc/stop_sound_channel(chan) - src << sound(null, repeat = 0, wait = 0, channel = chan) + SEND_SOUND(src, sound(null, repeat = 0, wait = 0, channel = chan)) + +/client/proc/playtitlemusic() + if(!ticker || !ticker.login_music || config.disable_lobby_music) + return + if(prefs.sound & SOUND_LOBBY) + SEND_SOUND(src, sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = CHANNEL_LOBBYMUSIC)) // MAD JAMS /proc/get_rand_frequency() return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. diff --git a/paradise.dme b/paradise.dme index 438cb2acaae..a61f6237b46 100644 --- a/paradise.dme +++ b/paradise.dme @@ -311,6 +311,8 @@ #include "code\datums\helper_datums\map_template.dm" #include "code\datums\helper_datums\teleport.dm" #include "code\datums\helper_datums\topic_input.dm" +#include "code\datums\looping_sounds\looping_sound.dm" +#include "code\datums\looping_sounds\machinery_sounds.dm" #include "code\datums\outfits\outfit.dm" #include "code\datums\outfits\outfit_admin.dm" #include "code\datums\ruins\space.dm" diff --git a/sound/machines/shower/shower_end.ogg b/sound/machines/shower/shower_end.ogg new file mode 100644 index 00000000000..80b93af39eb Binary files /dev/null and b/sound/machines/shower/shower_end.ogg differ diff --git a/sound/machines/shower/shower_mid1.ogg b/sound/machines/shower/shower_mid1.ogg new file mode 100644 index 00000000000..e1ae5a0c456 Binary files /dev/null and b/sound/machines/shower/shower_mid1.ogg differ diff --git a/sound/machines/shower/shower_mid2.ogg b/sound/machines/shower/shower_mid2.ogg new file mode 100644 index 00000000000..4a54acd3524 Binary files /dev/null and b/sound/machines/shower/shower_mid2.ogg differ diff --git a/sound/machines/shower/shower_mid3.ogg b/sound/machines/shower/shower_mid3.ogg new file mode 100644 index 00000000000..8b4776a9b97 Binary files /dev/null and b/sound/machines/shower/shower_mid3.ogg differ diff --git a/sound/machines/shower/shower_start.ogg b/sound/machines/shower/shower_start.ogg new file mode 100644 index 00000000000..e5529f401bb Binary files /dev/null and b/sound/machines/shower/shower_start.ogg differ