diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index f7cb9002c996..23c2da40b3ca 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -5,13 +5,25 @@ #define CHANNEL_JUKEBOX 1021 #define CHANNEL_JUSTICAR_ARK 1020 #define CHANNEL_HEARTBEAT 1019 //sound channel for heartbeats -#define CHANNEL_AMBIENCE 1018 +#define CHANNEL_AMBIENT_EFFECTS 1018 +#define CHANNEL_AMBIENT_MUSIC 1017 #define CHANNEL_BUZZ 1017 #define CHANNEL_BICYCLE 1016 #define CHANNEL_VOICE_ANNOUNCE 1015 #define CHANNEL_MEGAFAUNA 1014 // battle music #define CHANNEL_CHARGED_SPELL 1013 +///Default range of a sound. +#define SOUND_RANGE 17 +///default extra range for sounds considered to be quieter +#define SHORT_RANGE_SOUND_EXTRARANGE -9 +///The range deducted from sound range for things that are considered silent / sneaky +#define SILENCED_SOUND_EXTRARANGE -11 +///Percentage of sound's range where no falloff is applied +#define SOUND_DEFAULT_FALLOFF_DISTANCE 1 //For a normal sound this would be 1 tile of no falloff +///The default exponent of sound falloff +#define SOUND_FALLOFF_EXPONENT 6 + //THIS SHOULD ALWAYS BE THE LOWEST ONE! //KEEP IT UPDATED @@ -22,69 +34,71 @@ #define SOUND_MINIMUM_PRESSURE 10 #define FALLOFF_SOUNDS 1 - -//Ambience types - -#define GENERIC list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg',\ - 'sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg',\ - 'sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg',\ - 'sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg',\ - 'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\ - 'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg','sound/ambience/ambigen15.ogg') - -#define HOLY list('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg',\ - 'sound/ambience/ambicha4.ogg', 'sound/ambience/ambiholy.ogg', 'sound/ambience/ambiholy2.ogg',\ - 'sound/ambience/ambiholy3.ogg') - -#define HIGHSEC list('sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg') - -#define RUINS list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\ - 'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\ - 'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\ - 'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambitech3.ogg',\ - 'sound/ambience/ambimystery.ogg', 'sound/ambience/ambimaint1.ogg') - -#define ENGINEERING list('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg',\ - 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg') - -#define MINING list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\ - 'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\ - 'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\ - 'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint1.ogg',\ - 'sound/ambience/ambilava1.ogg', 'sound/ambience/ambilava2.ogg', 'sound/ambience/ambilava3.ogg') - -#define MEDICAL list('sound/ambience/ambinice.ogg') - -#define SPOOKY list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg','sound/ambience/ambiruin7.ogg','sound/ambience/ambiruin6.ogg',\ - 'sound/ambience/ambiodd.ogg', 'sound/ambience/ambimystery.ogg') - -#define SPACE list('sound/ambience/ambispace.ogg', 'sound/ambience/ambispace2.ogg', 'sound/ambience/title2.ogg', 'sound/ambience/ambiatmos.ogg') - -#define MAINTENANCE list('sound/ambience/ambimaint1.ogg', 'sound/ambience/ambimaint2.ogg', 'sound/ambience/ambimaint3.ogg', 'sound/ambience/ambimaint4.ogg',\ - 'sound/ambience/ambimaint5.ogg', 'sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg', 'sound/ambience/ambitech2.ogg' ) - -#define AWAY_MISSION list('sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiruin.ogg',\ - 'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\ - 'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\ - 'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint.ogg',\ - 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambiodd.ogg') - -#define REEBE list('sound/ambience/ambireebe1.ogg', 'sound/ambience/ambireebe2.ogg', 'sound/ambience/ambireebe3.ogg') - - - -#define CREEPY_SOUNDS list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/screech.ogg',\ - 'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\ - 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\ - 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\ - 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg') - #define INTERACTION_SOUND_RANGE_MODIFIER -3 #define EQUIP_SOUND_VOLUME 30 #define PICKUP_SOUND_VOLUME 40 #define DROP_SOUND_VOLUME 50 #define YEET_SOUND_VOLUME 90 + +#define AMBIENCE_GENERIC "generic" +#define AMBIENCE_HOLY "holy" +#define AMBIENCE_DANGER "danger" +#define AMBIENCE_RUINS "ruins" +#define AMBIENCE_ENGI "engi" +#define AMBIENCE_MINING "mining" +#define AMBIENCE_MEDICAL "med" +#define AMBIENCE_SPOOKY "spooky" +#define AMBIENCE_SPACE "space" +#define AMBIENCE_MAINT "maint" +#define AMBIENCE_AWAY "away" +#define AMBIENCE_REEBE "reebe" +#define AMBIENCE_AI "ai" +#define AMBIENCE_CREEPY "creepy" //not to be confused with spooky + +//default byond sound environments +#define SOUND_ENVIRONMENT_NONE -1 +#define SOUND_ENVIRONMENT_GENERIC 0 +#define SOUND_ENVIRONMENT_PADDED_CELL 1 +#define SOUND_ENVIRONMENT_ROOM 2 +#define SOUND_ENVIRONMENT_BATHROOM 3 +#define SOUND_ENVIRONMENT_LIVINGROOM 4 +#define SOUND_ENVIRONMENT_STONEROOM 5 +#define SOUND_ENVIRONMENT_AUDITORIUM 6 +#define SOUND_ENVIRONMENT_CONCERT_HALL 7 +#define SOUND_ENVIRONMENT_CAVE 8 +#define SOUND_ENVIRONMENT_ARENA 9 +#define SOUND_ENVIRONMENT_HANGAR 10 +#define SOUND_ENVIRONMENT_CARPETED_HALLWAY 11 +#define SOUND_ENVIRONMENT_HALLWAY 12 +#define SOUND_ENVIRONMENT_STONE_CORRIDOR 13 +#define SOUND_ENVIRONMENT_ALLEY 14 +#define SOUND_ENVIRONMENT_FOREST 15 +#define SOUND_ENVIRONMENT_CITY 16 +#define SOUND_ENVIRONMENT_MOUNTAINS 17 +#define SOUND_ENVIRONMENT_QUARRY 18 +#define SOUND_ENVIRONMENT_PLAIN 19 +#define SOUND_ENVIRONMENT_PARKING_LOT 20 +#define SOUND_ENVIRONMENT_SEWER_PIPE 21 +#define SOUND_ENVIRONMENT_UNDERWATER 22 +#define SOUND_ENVIRONMENT_DRUGGED 23 +#define SOUND_ENVIRONMENT_DIZZY 24 +#define SOUND_ENVIRONMENT_PSYCHOTIC 25 +//If we ever make custom ones add them here + +//"sound areas": easy way of keeping different types of areas consistent. +#define SOUND_AREA_STANDARD_STATION SOUND_ENVIRONMENT_PARKING_LOT +#define SOUND_AREA_LARGE_ENCLOSED SOUND_ENVIRONMENT_QUARRY +#define SOUND_AREA_SMALL_ENCLOSED SOUND_ENVIRONMENT_BATHROOM +#define SOUND_AREA_TUNNEL_ENCLOSED SOUND_ENVIRONMENT_STONEROOM +#define SOUND_AREA_LARGE_SOFTFLOOR SOUND_ENVIRONMENT_CARPETED_HALLWAY +#define SOUND_AREA_MEDIUM_SOFTFLOOR SOUND_ENVIRONMENT_LIVINGROOM +#define SOUND_AREA_SMALL_SOFTFLOOR SOUND_ENVIRONMENT_ROOM +#define SOUND_AREA_ASTEROID SOUND_ENVIRONMENT_CAVE +#define SOUND_AREA_SPACE SOUND_ENVIRONMENT_UNDERWATER +#define SOUND_AREA_LAVALAND SOUND_ENVIRONMENT_MOUNTAINS +#define SOUND_AREA_WOODFLOOR SOUND_ENVIRONMENT_CITY + ///Announcer audio keys #define ANNOUNCER_AIMALF "announcer_aimalf" #define ANNOUNCER_ALIENS "announcer_aliens" diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 3bbf6a8b540c..79e8989aaa5f 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -172,6 +172,7 @@ // Subsystem fire priority, from lowest to highest priority // If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child) +#define FIRE_PRIORITY_AMBIENCE 10 #define FIRE_PRIORITY_IDLE_NPC 10 #define FIRE_PRIORITY_SERVER_MAINT 10 #define FIRE_PRIORITY_RESEARCH 10 diff --git a/code/_globalvars/lists/ambience.dm b/code/_globalvars/lists/ambience.dm new file mode 100644 index 000000000000..3ee06f7491ed --- /dev/null +++ b/code/_globalvars/lists/ambience.dm @@ -0,0 +1,184 @@ +GLOBAL_LIST_INIT(generic_ambience,list( + 'sound/ambience/ambigen1.ogg', + 'sound/ambience/ambigen3.ogg', + 'sound/ambience/ambigen4.ogg', + 'sound/ambience/ambigen5.ogg', + 'sound/ambience/ambigen6.ogg', + 'sound/ambience/ambigen7.ogg', + 'sound/ambience/ambigen8.ogg', + 'sound/ambience/ambigen9.ogg', + 'sound/ambience/ambigen10.ogg', + 'sound/ambience/ambigen11.ogg', + 'sound/ambience/ambigen12.ogg', + 'sound/ambience/ambigen14.ogg', + 'sound/ambience/ambigen15.ogg')) + +GLOBAL_LIST_INIT(holy_ambience,list( + 'sound/ambience/ambicha1.ogg', + 'sound/ambience/ambicha2.ogg', + 'sound/ambience/ambicha3.ogg', + 'sound/ambience/ambicha4.ogg', + 'sound/ambience/ambiholy.ogg', + 'sound/ambience/ambiholy2.ogg', + 'sound/ambience/ambiholy3.ogg')) + +GLOBAL_LIST_INIT(danger_ambience,list( + 'sound/ambience/ambidanger.ogg', + 'sound/ambience/ambidanger2.ogg')) + +GLOBAL_LIST_INIT(ruins_ambience,list( + 'sound/ambience/ambimine.ogg', + 'sound/ambience/ambicave.ogg', + 'sound/ambience/ambiruin.ogg', + 'sound/ambience/ambiruin2.ogg', + 'sound/ambience/ambiruin3.ogg', + 'sound/ambience/ambiruin4.ogg', + 'sound/ambience/ambiruin5.ogg', + 'sound/ambience/ambiruin6.ogg', + 'sound/ambience/ambiruin7.ogg', + 'sound/ambience/ambidanger.ogg', + 'sound/ambience/ambidanger2.ogg', + 'sound/ambience/ambitech3.ogg', + 'sound/ambience/ambimystery.ogg', + 'sound/ambience/ambimaint1.ogg')) + +GLOBAL_LIST_INIT(engi_ambience,list( + 'sound/ambience/ambisin1.ogg', + 'sound/ambience/ambisin2.ogg', + 'sound/ambience/ambisin3.ogg', + 'sound/ambience/ambisin4.ogg', + 'sound/ambience/ambiatmos.ogg', + 'sound/ambience/ambiatmos2.ogg', + 'sound/ambience/ambitech.ogg', + 'sound/ambience/ambitech2.ogg', + 'sound/ambience/ambitech3.ogg')) + +GLOBAL_LIST_INIT(mining_ambience,list( + 'sound/ambience/ambimine.ogg', + 'sound/ambience/ambicave.ogg', + 'sound/ambience/ambiruin.ogg', + 'sound/ambience/ambiruin2.ogg', + 'sound/ambience/ambiruin3.ogg', + 'sound/ambience/ambiruin4.ogg', + 'sound/ambience/ambiruin5.ogg', + 'sound/ambience/ambiruin6.ogg', + 'sound/ambience/ambiruin7.ogg', + 'sound/ambience/ambidanger.ogg', + 'sound/ambience/ambidanger2.ogg', + 'sound/ambience/ambimaint1.ogg', + 'sound/ambience/ambilava1.ogg', + 'sound/ambience/ambilava2.ogg', + 'sound/ambience/ambilava3.ogg')) + +GLOBAL_LIST_INIT(medical_ambience,list( + 'sound/ambience/ambinice.ogg', + 'sound/ambience/ambiruin2.ogg', + 'sound/ambience/ambiodd.ogg', + 'sound/ambience/ambiviro.ogg', + 'sound/ambience/ambiviro1.ogg', + 'sound/ambience/ambiviro2.ogg', + 'sound/ambience/cavesound3.ogg')) + +GLOBAL_LIST_INIT(spooky_ambience,list( + 'sound/ambience/ambimo1.ogg', + 'sound/ambience/ambimo2.ogg', + 'sound/ambience/ambiruin7.ogg', + 'sound/ambience/ambiruin6.ogg', + 'sound/ambience/ambiodd.ogg', + 'sound/ambience/ambimystery.ogg', + 'sound/ambience/maintambience.ogg', + 'sound/voice/lowHiss1.ogg')) + +GLOBAL_LIST_INIT(space_ambient_music,list( + 'sound/ambience/ambispace.ogg', + 'sound/ambience/ambispace2.ogg', + 'sound/ambience/title2.ogg', + 'sound/ambience/ambiatmos.ogg')) + +GLOBAL_LIST_INIT(maint_ambience,list( + 'sound/ambience/ambimaint1.ogg', + 'sound/ambience/ambimaint2.ogg', + 'sound/ambience/ambimaint3.ogg', + 'sound/ambience/ambimaint4.ogg', + 'sound/ambience/ambimaint5.ogg', + 'sound/voice/lowHiss2.ogg', + 'sound/voice/lowHiss3.ogg', + 'sound/voice/lowHiss4.ogg', + 'sound/ambience/ambitech2.ogg', + 'sound/ambience/maintambience.ogg')) + +GLOBAL_LIST_INIT(away_ambience,list( + 'sound/ambience/ambitech.ogg', + 'sound/ambience/ambitech2.ogg', + 'sound/ambience/ambiruin.ogg', + 'sound/ambience/ambiruin2.ogg', + 'sound/ambience/ambiruin3.ogg', + 'sound/ambience/ambiruin4.ogg', + 'sound/ambience/ambiruin5.ogg', + 'sound/ambience/ambiruin6.ogg', + 'sound/ambience/ambiruin7.ogg', + 'sound/ambience/ambidanger.ogg', + 'sound/ambience/ambidanger2.ogg', + 'sound/ambience/ambimaint.ogg', + 'sound/ambience/ambiatmos.ogg', + 'sound/ambience/ambiatmos2.ogg', + 'sound/ambience/ambiodd.ogg')) + +GLOBAL_LIST_INIT(reebe_ambience,list( + 'sound/ambience/ambireebe1.ogg', + 'sound/ambience/ambireebe2.ogg', + 'sound/ambience/ambireebe3.ogg')) + +GLOBAL_LIST_INIT(ai_ambience, list( + 'sound/ambience/ambimalf.ogg', + 'sound/ambience/ambitech.ogg', + 'sound/ambience/ambitech2.ogg', + 'sound/ambience/ambiatmos.ogg', + 'sound/ambience/ambiatmos2.ogg', + 'sound/ambience/ambimalf2.ogg')) + +GLOBAL_LIST_INIT(creepy_ambience,list( + 'sound/effects/ghost.ogg', + 'sound/effects/ghost2.ogg', + 'sound/effects/heart_beat.ogg', + 'sound/effects/screech.ogg', + 'sound/hallucinations/behind_you1.ogg', + 'sound/hallucinations/behind_you2.ogg', + 'sound/hallucinations/far_noise.ogg', + 'sound/hallucinations/growl1.ogg', + 'sound/hallucinations/growl2.ogg', + 'sound/hallucinations/growl3.ogg', + 'sound/hallucinations/im_here1.ogg', + 'sound/hallucinations/im_here2.ogg', + 'sound/hallucinations/i_see_you1.ogg', + 'sound/hallucinations/i_see_you2.ogg', + 'sound/hallucinations/look_up1.ogg', + 'sound/hallucinations/look_up2.ogg', + 'sound/hallucinations/over_here1.ogg', + 'sound/hallucinations/over_here2.ogg', + 'sound/hallucinations/over_here3.ogg', + 'sound/hallucinations/turn_around1.ogg', + 'sound/hallucinations/turn_around2.ogg', + 'sound/hallucinations/veryfar_noise.ogg', + 'sound/hallucinations/wail.ogg')) + +GLOBAL_LIST_INIT(ambience_assoc,list( + AMBIENCE_GENERIC = GLOB.generic_ambience, + AMBIENCE_HOLY = GLOB.holy_ambience, + AMBIENCE_DANGER = GLOB.danger_ambience, + AMBIENCE_RUINS = GLOB.ruins_ambience, + AMBIENCE_ENGI = GLOB.engi_ambience, + AMBIENCE_MINING = GLOB.mining_ambience, + AMBIENCE_MEDICAL = GLOB.medical_ambience, + AMBIENCE_SPOOKY = GLOB.spooky_ambience, + AMBIENCE_MAINT = GLOB.maint_ambience, + AMBIENCE_AWAY = GLOB.away_ambience, + AMBIENCE_REEBE = GLOB.reebe_ambience, + AMBIENCE_CREEPY = GLOB.creepy_ambience, + AMBIENCE_AI = GLOB.ai_ambience, + AMBIENCE_NONE = list())) + + +GLOBAL_LIST_INIT(ambient_music_assoc, list( + AMBIENCE_SPACE = GLOB.space_ambient_music +)) diff --git a/code/controllers/subsystem/ambience.dm b/code/controllers/subsystem/ambience.dm new file mode 100644 index 000000000000..91fbd1a9d2dc --- /dev/null +++ b/code/controllers/subsystem/ambience.dm @@ -0,0 +1,82 @@ +/// The subsystem used to play ambience to users every now and then, makes them real excited. +SUBSYSTEM_DEF(ambience) + name = "Ambience" + flags = SS_BACKGROUND|SS_NO_INIT + priority = FIRE_PRIORITY_AMBIENCE + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + wait = 2 + ///Assoc list of listening client - next ambience time + var/list/ambience_listening_clients = list() + var/list/currentrun = list() + +/datum/controller/subsystem/ambience/fire(resumed) + if(!resumed) + currentrun = ambience_listening_clients.Copy() + var/list/cached_clients = currentrun + for(var/client/client_iterator as anything in cached_clients) + if(isnull(client_iterator)) + continue + + if(isnewplayer(client_iterator.mob)) + continue + + process_ambience_client(client_iterator) + + if(MC_TICK_CHECK) + return + +/datum/controller/subsystem/ambience/proc/process_ambience_client(client/to_process) + var/mob/current_mob = to_process.mob + var/area/current_area = get_area(current_mob) + if(!current_area) //Something's gone horribly wrong + stack_trace("[key_name(to_process)] has somehow ended up in nullspace. WTF did you do -xoxo ambience subsystem") + ambience_listening_clients -= to_process + return + + if(current_area.ambient_buzz) + play_buzz(current_mob, current_area) + + if(ambience_listening_clients[to_process] > world.time) + return //Not ready for the next sound + + if(current_area.ambientsounds && length(current_area.ambientsounds)) + var/ambi_fx = pick(current_area.ambientsounds) + + play_ambience_effects(current_mob, ambi_fx, current_area) + + if(current_area.ambientmusic && length(current_area.ambientmusic)) + var/ambi_music = pick(current_area.ambientmusic) + play_ambience_music(current_mob, ambi_music, current_area) + + ambience_listening_clients[to_process] = world.time + rand(current_area.min_ambience_cooldown, current_area.max_ambience_cooldown) + +/datum/controller/subsystem/ambience/proc/add_ambience_client(client/to_add) + if(SSambience.ambience_listening_clients[to_add] > world.time) + return // If already properly set we don't want to reset the timer. + SSambience.ambience_listening_clients[to_add] = world.time + 10 SECONDS //Just wait 10 seconds before the next one aight mate? cheers. + +/datum/controller/subsystem/ambience/proc/remove_ambience_client(client/to_remove) + ambience_listening_clients -= to_remove + currentrun -= to_remove + +///Buzzing sound, the low ship drone that plays constantly, IC (requires the user to be able to hear) +/datum/controller/subsystem/ambience/proc/play_buzz(mob/M, area/A) + if (A.ambient_buzz && (M.client.prefs.toggles & SOUND_SHIP_AMBIENCE) && M.can_hear_ambience()) + if (!M.client.buzz_playing || (A.ambient_buzz != M.client.buzz_playing)) + SEND_SOUND(M, sound(A.ambient_buzz, repeat = 1, wait = 0, volume = A.ambient_buzz_vol, channel = CHANNEL_BUZZ)) + M.client.buzz_playing = A.ambient_buzz // It's done this way so I can tell when the user switches to an area that has a different buzz effect, so we can seamlessly swap over to that one + return + + if(M.client.buzz_playing) // If it's playing, and it shouldn't be, stop it + M.stop_sound_channel(CHANNEL_BUZZ) + M.client.buzz_playing = null + +///Effect, random sounds that will play at random times, IC (requires the user to be able to hear) +/datum/controller/subsystem/ambience/proc/play_ambience_effects(mob/M, _ambi_fx, area/A) + if(M.can_hear_ambience() && !M.client?.channel_in_use(CHANNEL_AMBIENT_EFFECTS)) + SEND_SOUND(M, sound(_ambi_fx, repeat = 0, wait = 0, volume = 45, channel = CHANNEL_AMBIENT_EFFECTS)) + +///Play background music, the more OOC ambience, like eerie space music +/datum/controller/subsystem/ambience/proc/play_ambience_music(mob/M, _ambi_music, area/A) + if(!M.client?.channel_in_use(CHANNEL_AMBIENT_MUSIC)) + SEND_SOUND(M, sound(_ambi_music, repeat = 0, wait = 0, volume = 75, channel = CHANNEL_AMBIENT_MUSIC)) diff --git a/code/controllers/subsystem/sound.dm b/code/controllers/subsystem/sound.dm new file mode 100644 index 000000000000..376f1faa746f --- /dev/null +++ b/code/controllers/subsystem/sound.dm @@ -0,0 +1,127 @@ +/* + * 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 diff --git a/code/datums/diseases/heart_failure.dm b/code/datums/diseases/heart_failure.dm index f6dadf5ddaca..173aaa1765bd 100644 --- a/code/datums/diseases/heart_failure.dm +++ b/code/datums/diseases/heart_failure.dm @@ -41,7 +41,7 @@ to_chat(H, span_warning("You feel [pick("full", "nauseated", "sweaty", "weak", "tired", "short on breath", "uneasy")].")) if(3 to 4) if(!sound) - H.playsound_local(H, 'sound/health/slowbeat.ogg',40,0, channel = CHANNEL_HEARTBEAT) + H.playsound_local(H, 'sound/health/slowbeat.ogg',40,0, channel = CHANNEL_HEARTBEAT, use_reverb = FALSE) sound = TRUE if(prob(3)) to_chat(H, span_danger("You feel a sharp pain in your chest!")) diff --git a/code/datums/wounds/pierce.dm b/code/datums/wounds/pierce.dm index e9abeeec6648..402c023423dd 100644 --- a/code/datums/wounds/pierce.dm +++ b/code/datums/wounds/pierce.dm @@ -134,12 +134,12 @@ self_penalty_mult = 0.5 user.visible_message(span_danger("[user] begins cauterizing [victim]'s [limb.name] with [I]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")) - playsound(I, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff = 1) + playsound(I, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff_exponent = 1) if(!do_after(user, base_treat_time * self_penalty_mult * improv_penalty_mult * I.toolspeed, victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) return - playsound(I, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff = 1) + playsound(I, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff_exponent = 1) user.visible_message(span_green("[user] cauterizes some of the bleeding on [victim]."), span_green("You cauterize some of the bleeding on [victim].")) limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND) if(prob(30)) diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index f1c4fce4d714..f4dc664e1b5c 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -165,12 +165,12 @@ if(LAZYLEN(user.mind?.antag_datums) && severity > WOUND_SEVERITY_MODERATE) //antagonists can heal wounds better with ghetto alternatives, since they don't have as much access to proper medical treatment self_penalty_mult = 1 user.visible_message(span_warning("[user] begins aiming [lasgun] directly at [victim]'s [limb.name]..."), span_userdanger("You begin aiming [lasgun] directly at [user == victim ? "your" : "[victim]'s"] [limb.name]...")) - playsound(lasgun, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff = 1) + playsound(lasgun, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff_exponent = 1) if(!do_after(user, base_treat_time * self_penalty_mult, victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) return - playsound(lasgun, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff = 1) + playsound(lasgun, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff_exponent = 1) var/damage = lasgun.chambered.BB.damage lasgun.chambered.BB.bare_wound_bonus = 0 lasgun.chambered.BB.wound_bonus -= 30 @@ -189,12 +189,12 @@ self_penalty_mult = 0.5 improv_penalty_mult = 1 user.visible_message(span_danger("[user] begins cauterizing [victim]'s [limb.name] with [I]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")) - playsound(I, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff = 1) + playsound(I, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff_exponent = 1) if(!do_after(user, base_treat_time * self_penalty_mult * improv_penalty_mult * I.toolspeed, victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) return - playsound(I, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff = 1) + playsound(I, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff_exponent = 1) user.visible_message(span_green("[user] cauterizes some of the bleeding on [victim]."), span_green("You cauterize some of the bleeding on [victim].")) limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND) if(prob(30)) diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm index aab2714427f0..83fcaa7d6a25 100644 --- a/code/game/area/Space_Station_13_areas.dm +++ b/code/game/area/Space_Station_13_areas.dm @@ -28,8 +28,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station power_environ = FALSE valid_territory = FALSE outdoors = TRUE - ambientsounds = SPACE blob_allowed = FALSE //Eating up space doesn't count for victory as a blob. + ambience_index = null + ambient_music_index = AMBIENCE_SPACE + ambient_buzz = null + sound_environment = SOUND_AREA_SPACE /area/space/nearstation icon_state = "space_near" @@ -41,7 +44,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station requires_power = FALSE dynamic_lighting = DYNAMIC_LIGHTING_DISABLED has_gravity = STANDARD_GRAVITY - + ambience_index = null + ambient_buzz = null /area/testroom requires_power = FALSE @@ -58,11 +62,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station has_gravity = STANDARD_GRAVITY blob_allowed = FALSE //Nope, no winning on the asteroid as a blob. Gotta eat the station. valid_territory = FALSE - ambientsounds = MINING + ambience_index = AMBIENCE_MINING + sound_environment = SOUND_AREA_ASTEROID /area/asteroid/nearstation dynamic_lighting = DYNAMIC_LIGHTING_FORCED - ambientsounds = RUINS + ambience_index = AMBIENCE_RUINS always_unpowered = FALSE requires_power = TRUE blob_allowed = TRUE @@ -75,11 +80,15 @@ NOTE: there are two lists of areas in the end of this file: centcom and station //Maintenance /area/maintenance - ambientsounds = MAINTENANCE + ambience_index = AMBIENCE_MAINT + sound_environment = SOUND_AREA_TUNNEL_ENCLOSED valid_territory = FALSE minimap_color = "#4f4e3a" - airlock_wires = /datum/wires/airlock/maint + ambient_buzz = 'sound/ambience/source_corridor2.ogg' + ambient_buzz_vol = 20 + min_ambience_cooldown = 20 SECONDS + max_ambience_cooldown = 35 SECONDS //Departments @@ -95,6 +104,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/maintenance/department/crew_quarters/bar name = "Bar Maintenance" icon_state = "maint_bar" + sound_environment = SOUND_AREA_WOODFLOOR /area/maintenance/department/crew_quarters/dorms name = "Dormitory Maintenance" @@ -242,6 +252,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway minimap_color = "#8d8c68" + sound_environment = SOUND_AREA_STANDARD_STATION /area/hallway/primary/aft name = "Aft (S) Primary Hallway" @@ -299,14 +310,17 @@ NOTE: there are two lists of areas in the end of this file: centcom and station ambientsounds = list('sound/ambience/signal.ogg') minimap_color = "#0400a2" airlock_wires = /datum/wires/airlock/command + sound_environment = SOUND_AREA_STANDARD_STATION /area/bridge/meeting_room name = "Heads of Staff Meeting Room" icon_state = "meeting" + sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR /area/bridge/meeting_room/council name = "Council Chamber" icon_state = "meeting" + sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR /area/bridge/showroom/corporate name = "Corporate Showroom" @@ -320,10 +334,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Captain's Office" icon_state = "captain" minimap_color = "#2900d8" + sound_environment = SOUND_AREA_WOODFLOOR /area/crew_quarters/heads/captain/private name = "Captain's Quarters" icon_state = "captain" + sound_environment = SOUND_ENVIRONMENT_ROOM /area/crew_quarters/heads/chief name = "Chief Engineer's Office" @@ -353,15 +369,18 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/comms name = "Communications Relay" icon_state = "tcomsatcham" + sound_environment = SOUND_AREA_STANDARD_STATION /area/server name = "Messaging Server Room" icon_state = "server" + sound_environment = SOUND_AREA_STANDARD_STATION //Crew /area/crew_quarters minimap_color = "#b0e1ff" + sound_environment = SOUND_AREA_STANDARD_STATION /area/crew_quarters/dorms name = "Dormitories" @@ -378,6 +397,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Dormitory Toilets" icon_state = "toilet" minimap_color = "#b0e1ff" + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/crew_quarters/toilet/auxiliary name = "Auxiliary Restrooms" @@ -400,6 +420,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/crew_quarters/lounge name = "Lounge" icon_state = "yellow" + sound_environment = SOUND_AREA_SMALL_SOFTFLOOR /area/crew_quarters/fitness name = "Fitness Room" @@ -427,6 +448,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/crew_quarters/kitchen/coldroom name = "Kitchen Cold Room" icon_state = "kitchen_cold" + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/crew_quarters/bar name = "Bar" @@ -435,6 +457,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station mood_bonus = 5 mood_message = span_nicegreen("I love being in the bar!\n") airlock_wires = /datum/wires/airlock/service + sound_environment = SOUND_AREA_WOODFLOOR /area/crew_quarters/bar/Initialize(mapload) . = ..() @@ -443,6 +466,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/crew_quarters/bar/atrium name = "Atrium" icon_state = "bar" + sound_environment = SOUND_AREA_WOODFLOOR /area/crew_quarters/electronic_marketing_den name = "Electronic Marketing Den" @@ -459,6 +483,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Theatre" icon_state = "Theatre" minimap_color = "#5ac866" + sound_environment = SOUND_AREA_WOODFLOOR /area/crew_quarters/theatre/abandoned name = "Abandoned Theatre" @@ -473,6 +498,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/library/lounge name = "Library Lounge" icon_state = "library" + sound_environment = SOUND_AREA_LARGE_SOFTFLOOR /area/library/abandoned name = "Abandoned Library" @@ -481,7 +507,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/chapel icon_state = "chapel" - ambientsounds = HOLY + ambience_index = AMBIENCE_HOLY + sound_environment = SOUND_AREA_LARGE_ENCLOSED flags_1 = NONE clockwork_warp_allowed = FALSE clockwork_warp_fail = "The consecration here prevents you from warping in." @@ -500,6 +527,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/chapel/asteroid name = "Chapel Asteroid" icon_state = "explored" + sound_environment = SOUND_AREA_ASTEROID /area/chapel/asteroid/monastery name = "Monastery Asteroid" @@ -512,12 +540,14 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Law Office" icon_state = "law" minimap_color = "#b12527" + sound_environment = SOUND_AREA_SMALL_SOFTFLOOR //Engineering /area/engine - ambientsounds = ENGINEERING + ambience_index = AMBIENCE_ENGI + sound_environment = SOUND_AREA_LARGE_ENCLOSED minimap_color = "#edea00" airlock_wires = /datum/wires/airlock/engineering @@ -546,6 +576,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/engine/atmos/engine name = "\improper Atmospherics Engine" icon_state = "atmos_engine" + sound_environment = SOUND_AREA_LARGE_ENCLOSED /area/engine/atmos/pumproom name = "\improper Atmospherics Pumping Room" @@ -566,18 +597,22 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/engine/atmos/hfr name = "\improper Atmospherics HFR Room" icon_state = "atmos_hfr" + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/engine/supermatter name = "Supermatter Engine" icon_state = "engine_sm" + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/engine/foyer name = "Engineering Foyer" icon_state = "engine_foyer" + sound_environment = SOUND_AREA_STANDARD_STATION /area/engine/break_room name = "Engineering Break Room" icon_state = "engine_foyer" + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/engine/gravity_generator name = "Gravity Generator Room" @@ -588,6 +623,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/engine/storage name = "Engineering Storage" icon_state = "engi_storage" + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/engine/storage_shared name = "Shared Engineering Storage" @@ -606,13 +642,15 @@ NOTE: there are two lists of areas in the end of this file: centcom and station valid_territory = FALSE blob_allowed = FALSE flags_1 = NONE - ambientsounds = ENGINEERING + ambience_index = AMBIENCE_ENGI + sound_environment = SOUND_AREA_SPACE minimap_color = "#6b6b6b" airlock_wires = /datum/wires/airlock/engineering /area/solar/fore name = "Fore (N) Solar Array" icon_state = "yellow" + sound_environment = SOUND_AREA_STANDARD_STATION /area/solar/aft name = "Aft (S) Solar Array" @@ -686,14 +724,16 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/teleporter name = "Teleporter Room" icon_state = "teleporter" - ambientsounds = ENGINEERING + ambience_index = AMBIENCE_ENGI + sound_environment = SOUND_AREA_STANDARD_STATION minimap_color = "#6b6b6b" airlock_wires = /datum/wires/airlock/command /area/gateway name = "Gateway" icon_state = "gateway" - ambientsounds = ENGINEERING + ambience_index = AMBIENCE_ENGI + sound_environment = SOUND_AREA_STANDARD_STATION minimap_color = "#5d57a5" airlock_wires = /datum/wires/airlock/command @@ -702,7 +742,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/medical name = "Medical" icon_state = "medbay3" - ambientsounds = MEDICAL + ambience_index = AMBIENCE_MEDICAL + sound_environment = SOUND_AREA_STANDARD_STATION minimap_color = "#5d57a5" airlock_wires = /datum/wires/airlock/medbay @@ -710,6 +751,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Abandoned Medbay" icon_state = "medbay3" ambientsounds = list('sound/ambience/signal.ogg') + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/medical/medbay/central name = "Medbay Central" @@ -744,6 +786,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/medical/patients_rooms name = "Patients' Rooms" icon_state = "patients" + sound_environment = SOUND_AREA_SMALL_SOFTFLOOR /area/medical/patients_rooms/room_a name = "Patient Room A" @@ -762,11 +805,14 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon_state = "virology" flags_1 = NONE minimap_color = "#01f5b3" + ambience_index = AMBIENCE_MEDICAL + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/medical/morgue name = "Morgue" icon_state = "morgue" - ambientsounds = SPOOKY + ambience_index = AMBIENCE_SPOOKY + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/medical/chemistry name = "Chemistry" @@ -803,7 +849,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/security name = "Security" icon_state = "security" - ambientsounds = HIGHSEC + ambience_index = AMBIENCE_DANGER + sound_environment = SOUND_AREA_STANDARD_STATION minimap_color = "#b12527" airlock_wires = /datum/wires/airlock/security @@ -822,6 +869,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/security/courtroom name = "Courtroom" icon_state = "courtroom" + sound_environment = SOUND_AREA_LARGE_ENCLOSED /area/security/prison name = "Prison Wing" @@ -838,10 +886,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/security/processing/cremation name = "Security Crematorium" icon_state = "sec_prison" + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/security/warden name = "Brig Control" icon_state = "Warden" + sound_environment = SOUND_AREA_SMALL_SOFTFLOOR /area/security/detectives_office name = "Detective's Office" @@ -851,6 +901,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/security/detectives_office/private_investigators_office name = "Private Investigator's Office" icon_state = "detective" + sound_environment = SOUND_AREA_SMALL_SOFTFLOOR /area/security/range name = "Firing Range" @@ -928,14 +979,17 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon_state = "quart" minimap_color = "#936f3c" airlock_wires = /datum/wires/airlock/service + sound_environment = SOUND_AREA_STANDARD_STATION /area/quartermaster/sorting name = "Delivery Office" icon_state = "cargo_delivery" + sound_environment = SOUND_AREA_STANDARD_STATION /area/quartermaster/warehouse name = "Warehouse" icon_state = "cargo_warehouse" + sound_environment = SOUND_AREA_LARGE_ENCLOSED /area/quartermaster/office name = "Cargo Office" @@ -945,6 +999,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/quartermaster/storage name = "Cargo Bay" icon_state = "cargo_bay" + sound_environment = SOUND_AREA_LARGE_ENCLOSED /area/quartermaster/qm name = "Quartermaster's Office" @@ -964,6 +1019,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station flags_1 = NONE minimap_color = "#cc00ff" airlock_wires = /datum/wires/airlock/service + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/janitor/a //yogs start added two new areas name = "Custodial Closet A" @@ -980,6 +1036,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon_state = "hydro" minimap_color = "#5ac866" airlock_wires = /datum/wires/airlock/service + sound_environment = SOUND_AREA_STANDARD_STATION /area/hydroponics/upper name = "Upper Hydroponics" @@ -993,6 +1050,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hydroponics/garden/abandoned name = "Abandoned Garden" icon_state = "abandoned_garden" + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/hydroponics/garden/monastery name = "Monastery Garden" @@ -1006,6 +1064,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon_state = "toxlab" minimap_color = "#75009b" airlock_wires = /datum/wires/airlock/science + sound_environment = SOUND_AREA_STANDARD_STATION /area/science/lab name = "Research and Development" @@ -1068,6 +1127,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/science/research/abandoned name = "Abandoned Research Lab" icon_state = "medresearch" + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/science/nanite name = "Nanite Lab" @@ -1077,6 +1137,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/storage minimap_color = "#f8ff83" + sound_environment = SOUND_AREA_STANDARD_STATION /area/storage/tools name = "Auxiliary Tool Storage" @@ -1119,12 +1180,14 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/construction name = "Construction Area" icon_state = "yellow" - ambientsounds = ENGINEERING + ambience_index = AMBIENCE_ENGI + sound_environment = SOUND_AREA_STANDARD_STATION minimap_color = "#4f4e3a" /area/construction/mining/aux_base name = "Auxiliary Base Construction" icon_state = "aux_base_construction" + sound_environment = SOUND_AREA_LARGE_ENCLOSED /area/construction/storage_wing name = "Storage Wing" @@ -1134,7 +1197,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/vacant_room name = "Vacant Room" icon_state = "yellow" - ambientsounds = MAINTENANCE + ambience_index = AMBIENCE_MAINT + sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR icon_state = "vacant_room" minimap_color = "#4f4e3a" @@ -1151,7 +1215,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/ai_monitored/security/armory name = "Armory" icon_state = "armory" - ambientsounds = HIGHSEC + ambience_index = AMBIENCE_DANGER minimap_color = "#b12527" airlock_wires = /datum/wires/airlock/security @@ -1161,20 +1225,20 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/ai_monitored/storage/eva name = "EVA Storage" icon_state = "eva" - ambientsounds = HIGHSEC + ambience_index = AMBIENCE_DANGER minimap_color = "#c8c0ff" /area/ai_monitored/storage/satellite name = "AI Satellite Maint" icon_state = "storage" - ambientsounds = HIGHSEC + ambience_index = AMBIENCE_DANGER minimap_color = "#4f4e3a" airlock_wires = /datum/wires/airlock/ai /area/ai_monitored/storage/satellite/teleporter name = "AI Satellite Access Teleporter" icon_state = "storage" - ambientsounds = HIGHSEC + ambience_index = AMBIENCE_DANGER minimap_color = "#4f4e3a" airlock_wires = /datum/wires/airlock/ai @@ -1182,16 +1246,18 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "AI Secondary Datacore Monitoring" icon_state = "ai" minimap_color = "#00fff6" + ambience_index = AMBIENCE_DANGER /area/ai_monitored/secondarydatacoreserver name = "AI Secondary Datacore Servers" icon_state = "ai" minimap_color = "#00fff6" + ambience_index = AMBIENCE_DANGER //Turret_protected /area/ai_monitored/turret_protected - ambientsounds = list('sound/ambience/ambimalf.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambimalf2.ogg') + ambience_index = AMBIENCE_AI minimap_color = "#00fff6" airlock_wires = /datum/wires/airlock/ai @@ -1199,10 +1265,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "AI Upload Chamber" icon_state = "ai_upload" minimap_color = "#4f4e3a" + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/ai_monitored/turret_protected/ai_upload_foyer name = "AI Upload Access" icon_state = "ai_foyer" + sound_environment = SOUND_AREA_SMALL_ENCLOSED /area/ai_monitored/turret_protected/ai name = "AI Chamber" @@ -1211,7 +1279,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/ai_monitored/turret_protected/aisat name = "AI Satellite" icon_state = "ai" - + sound_environment = SOUND_ENVIRONMENT_ROOM /area/ai_monitored/turret_protected/aisat/atmos name = "AI Satellite Atmos" icon_state = "ai" @@ -1237,6 +1305,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/ai_monitored/turret_protected/aisat_interior name = "AI Satellite Antechamber" icon_state = "ai" + sound_environment = SOUND_AREA_LARGE_ENCLOSED /area/ai_monitored/turret_protected/AIsatextAS name = "AI Sat Ext" @@ -1260,6 +1329,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/tcommsat/computer name = "Telecomms Control Room" icon_state = "tcomsatcomp" + sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR /area/tcommsat/server name = "Telecomms Server Room" diff --git a/code/game/area/ai_monitored.dm b/code/game/area/ai_monitored.dm index 87b44291f56e..2448b15d8f38 100644 --- a/code/game/area/ai_monitored.dm +++ b/code/game/area/ai_monitored.dm @@ -3,6 +3,7 @@ clockwork_warp_allowed = FALSE var/list/obj/machinery/camera/motioncameras = list() var/list/datum/weakref/motionTargets = list() + sound_environment = SOUND_AREA_STANDARD_STATION /area/ai_monitored/Initialize(mapload) . = ..() @@ -28,4 +29,4 @@ for(var/X in motioncameras) var/obj/machinery/camera/cam = X cam.lostTargetRef(WEAKREF(O)) - return \ No newline at end of file + return diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index c269471969de..659fba236175 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -79,7 +79,25 @@ var/global/global_uid = 0 var/uid - var/list/ambientsounds = GENERIC + + var/ambience_index = AMBIENCE_GENERIC + var/list/ambientsounds + + ///Ambient buzz of the station, plays repeatedly, also IC + var/ambient_buzz = 'sound/ambience/shipambience.ogg' + ///The volume of the ambient buzz + var/ambient_buzz_vol = 30 + ///Used to decide what the minimum time between ambience is + var/min_ambience_cooldown = 30 SECONDS + ///Used to decide what the maximum time between ambience is + var/max_ambience_cooldown = 240 SECONDS + ///Used to decide what kind of reverb the area makes sound have + var/sound_environment = SOUND_ENVIRONMENT_NONE + + var/ambient_music_index + var/list/ambientmusic + + flags_1 = CAN_BE_DIRTY_1 var/list/firedoors @@ -165,6 +183,13 @@ GLOBAL_LIST_EMPTY(teleportlocs) map_name = name // Save the initial (the name set in the map) name of the area. canSmoothWithAreas = typecacheof(canSmoothWithAreas) + + if(!ambientsounds && ambience_index) + ambientsounds = GLOB.ambience_assoc[ambience_index] + + if(!ambientmusic && ambient_music_index) + ambientmusic = GLOB.ambient_music_assoc[ambient_music_index] + if(requires_power) luminosity = 0 else @@ -652,28 +677,6 @@ GLOBAL_LIST_EMPTY(teleportlocs) set waitfor = FALSE SEND_SIGNAL(src, COMSIG_AREA_ENTERED, M) SEND_SIGNAL(M, COMSIG_ENTER_AREA, src) //The atom that enters the area - if(!isliving(M)) - return - - var/mob/living/L = M - if(!L.ckey) - return - - // Ambience goes down here -- make sure to list each area separately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch - if(L.client && !L.client.ambience_playing && L.client.prefs.toggles & SOUND_SHIP_AMBIENCE) - L.client.ambience_playing = 1 - SEND_SOUND(L, sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = CHANNEL_BUZZ)) - - if(!(L.client && (L.client.prefs.toggles & SOUND_AMBIENCE))) - return //General ambience check is below the ship ambience so one can play without the other - - if(prob(35)) - var/sound = pick(ambientsounds) - - if(!L.client.played) - SEND_SOUND(L, sound(sound, repeat = 0, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE)) - L.client.played = TRUE - addtimer(CALLBACK(L.client, /client/proc/ResetAmbiencePlayed), 1 MINUTES) /** * Called when an atom exits an area @@ -684,12 +687,6 @@ GLOBAL_LIST_EMPTY(teleportlocs) SEND_SIGNAL(src, COMSIG_AREA_EXITED, M) SEND_SIGNAL(M, COMSIG_EXIT_AREA, src) //The atom that exits the area -/** - * Reset the played var to false on the client - */ -/client/proc/ResetAmbiencePlayed() - played = FALSE - /** * Returns true if this atom has gravity for the passed in turf * diff --git a/code/game/area/areas/away_content.dm b/code/game/area/areas/away_content.dm index c0a7fd868096..76347393408e 100644 --- a/code/game/area/areas/away_content.dm +++ b/code/game/area/areas/away_content.dm @@ -8,7 +8,8 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30" name = "Strange Location" icon_state = "away" has_gravity = STANDARD_GRAVITY - ambientsounds = AWAY_MISSION + ambience_index = AMBIENCE_AWAY + sound_environment = SOUND_ENVIRONMENT_ROOM unique = TRUE diff --git a/code/game/area/areas/centcom.dm b/code/game/area/areas/centcom.dm index 4472083a4983..b2b918760cf0 100644 --- a/code/game/area/areas/centcom.dm +++ b/code/game/area/areas/centcom.dm @@ -145,7 +145,7 @@ noteleport = TRUE blob_allowed = FALSE //Not... entirely sure this will ever come up... but if the bus makes blobs AND ops, it shouldn't aim for the ops to win. flags_1 = NONE - ambientsounds = HIGHSEC + ambience_index = AMBIENCE_DANGER /area/syndicate_mothership/control name = "Syndicate Control Room" @@ -208,7 +208,7 @@ has_gravity = STANDARD_GRAVITY noteleport = TRUE hidden = TRUE - ambientsounds = REEBE + ambience_index = AMBIENCE_REEBE /area/reebe/city_of_cogs name = "City of Cogs" diff --git a/code/game/area/areas/mining.dm b/code/game/area/areas/mining.dm index 40003384a486..d962cebd22d6 100644 --- a/code/game/area/areas/mining.dm +++ b/code/game/area/areas/mining.dm @@ -4,6 +4,9 @@ icon_state = "mining" has_gravity = STANDARD_GRAVITY area_flags = FLORA_ALLOWED + ambient_buzz = 'sound/ambience/magma.ogg' + + ambient_buzz_vol = 10 /area/mine/explored name = "Mine" @@ -16,8 +19,10 @@ power_light = FALSE outdoors = TRUE flags_1 = NONE - ambientsounds = MINING + ambience_index = AMBIENCE_MINING area_flags = NONE + ambient_buzz = 'sound/ambience/magma.ogg' + ambient_buzz_vol = 20 /area/mine/unexplored name = "Mine" @@ -30,8 +35,9 @@ power_light = FALSE outdoors = TRUE flags_1 = NONE - ambientsounds = MINING + ambience_index = AMBIENCE_MINING area_flags = CAVES_ALLOWED | FLORA_ALLOWED | MOB_SPAWN_ALLOWED | MEGAFAUNA_SPAWN_ALLOWED + ambient_buzz = 'sound/ambience/magma.ogg' map_generator = /datum/map_generator/cave_generator /area/mine/lobby @@ -91,7 +97,7 @@ /area/mine/laborcamp/security name = "Labor Camp Security" icon_state = "security" - ambientsounds = HIGHSEC + ambience_index = AMBIENCE_DANGER @@ -103,6 +109,7 @@ has_gravity = STANDARD_GRAVITY flags_1 = NONE area_flags = FLORA_ALLOWED + ambient_buzz = 'sound/ambience/magma.ogg' /area/lavaland/surface name = "Lavaland" @@ -113,7 +120,8 @@ power_equip = FALSE power_light = FALSE requires_power = TRUE - ambientsounds = MINING + ambience_index = AMBIENCE_MINING + ambient_buzz = 'sound/ambience/magma.ogg' /area/lavaland/underground name = "Lavaland Caves" @@ -124,7 +132,8 @@ power_environ = FALSE power_equip = FALSE power_light = FALSE - ambientsounds = MINING + ambience_index = AMBIENCE_MINING + ambient_buzz = 'sound/ambience/magma.ogg' /area/lavaland/surface/outdoors @@ -163,7 +172,7 @@ power_equip = FALSE power_light = FALSE requires_power = TRUE - ambientsounds = MINING + ambience_index = AMBIENCE_MINING /area/icemoon/surface/outdoors name = "Icemoon Wastes" @@ -190,7 +199,7 @@ power_environ = FALSE power_equip = FALSE power_light = FALSE - ambientsounds = MINING + ambience_index = AMBIENCE_MINING /area/icemoon/underground/unexplored // mobs and megafauna and ruins spawn here name = "Icemoon Caves" diff --git a/code/game/area/areas/ruins/_ruins.dm b/code/game/area/areas/ruins/_ruins.dm index a944609a1aee..2d8b7bf2f47c 100644 --- a/code/game/area/areas/ruins/_ruins.dm +++ b/code/game/area/areas/ruins/_ruins.dm @@ -6,7 +6,7 @@ has_gravity = STANDARD_GRAVITY hidden = FALSE dynamic_lighting = DYNAMIC_LIGHTING_FORCED - ambientsounds = RUINS + ambience_index = AMBIENCE_RUINS /area/ruin/unpowered diff --git a/code/game/area/areas/ruins/lavaland.dm b/code/game/area/areas/ruins/lavaland.dm index 169c74eeca0c..3b2f2d7b73b9 100644 --- a/code/game/area/areas/ruins/lavaland.dm +++ b/code/game/area/areas/ruins/lavaland.dm @@ -80,7 +80,9 @@ /area/ruin/powered/syndicate_lava_base name = "Syndicate Lavaland" icon_state = "syndie-control" - ambientsounds = HIGHSEC + ambience_index = AMBIENCE_DANGER + ambient_buzz = 'sound/ambience/magma.ogg' + ambient_buzz_vol = 10 hidden = FALSE requires_power = TRUE @@ -138,3 +140,4 @@ //ash walker nest /area/ruin/unpowered/ash_walkers icon_state = "red" + ambient_buzz = 'sound/ambience/magma.ogg' diff --git a/code/game/area/areas/ruins/space.dm b/code/game/area/areas/ruins/space.dm index 9e43b6f5b101..7c7957045002 100644 --- a/code/game/area/areas/ruins/space.dm +++ b/code/game/area/areas/ruins/space.dm @@ -22,8 +22,11 @@ power_environ = FALSE valid_territory = FALSE outdoors = TRUE - ambientsounds = SPACE blob_allowed = FALSE + ambience_index = null + ambient_music_index = AMBIENCE_SPACE + ambient_buzz = null + sound_environment = SOUND_AREA_SPACE ///////////// diff --git a/code/game/area/areas/shuttles.dm b/code/game/area/areas/shuttles.dm index 5646cdfe9ee7..b4d2878b1680 100644 --- a/code/game/area/areas/shuttles.dm +++ b/code/game/area/areas/shuttles.dm @@ -33,7 +33,7 @@ /area/shuttle/syndicate name = "Syndicate Infiltrator" blob_allowed = FALSE - ambientsounds = HIGHSEC + ambience_index = AMBIENCE_DANGER canSmoothWithAreas = /area/shuttle/syndicate /area/shuttle/syndicate/bridge diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index b5ca55cbf96c..8947fdef0a61 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -206,7 +206,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( blocked = TRUE var/attackamt = rand(2,6) temp = "You attack for [attackamt] damage!" - playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10) + playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) updateUsrDialog() if(turtle > 0) turtle-- @@ -220,7 +220,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( var/pointamt = rand(1,3) var/healamt = rand(6,8) temp = "You use [pointamt] magic to heal for [healamt] damage!" - playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10) + playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) updateUsrDialog() turtle++ @@ -235,7 +235,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( blocked = TRUE var/chargeamt = rand(4,7) temp = "You regain [chargeamt] points" - playsound(loc, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 10) + playsound(loc, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) player_mp += chargeamt if(turtle > 0) turtle-- @@ -270,7 +270,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( if(!gameover) gameover = TRUE temp = "[enemy_name] has fallen! Rejoice!" - playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10) + playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) if(obj_flags & EMAGGED) new /obj/effect/spawner/newbomb/timer/syndicate(loc) @@ -287,13 +287,13 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( else if ((obj_flags & EMAGGED) && (turtle >= 4)) var/boomamt = rand(5,10) temp = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!" - playsound(loc, 'sound/arcade/boom.ogg', 50, 1, extrarange = -3, falloff = 10) + playsound(loc, 'sound/arcade/boom.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) player_hp -= boomamt else if ((enemy_mp <= 5) && (prob(70))) var/stealamt = rand(2,3) temp = "[enemy_name] steals [stealamt] of your power!" - playsound(loc, 'sound/arcade/steal.ogg', 50, 1, extrarange = -3, falloff = 10) + playsound(loc, 'sound/arcade/steal.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) player_mp -= stealamt updateUsrDialog() @@ -301,27 +301,27 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( gameover = TRUE sleep(1 SECONDS) temp = "You have been drained! GAME OVER" - playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10) + playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) if(obj_flags & EMAGGED) usr.gib() SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "mana", (obj_flags & EMAGGED ? "emagged":"normal"))) else if ((enemy_hp <= 10) && (enemy_mp > 4)) temp = "[enemy_name] heals for 4 health!" - playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10) + playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) enemy_hp += 4 enemy_mp -= 4 else var/attackamt = rand(3,6) temp = "[enemy_name] attacks for [attackamt] damage!" - playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10) + playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) player_hp -= attackamt if ((player_mp <= 0) || (player_hp <= 0)) gameover = TRUE temp = "You have been crushed! GAME OVER" - playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10) + playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) if(obj_flags & EMAGGED) usr.gib() SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (obj_flags & EMAGGED ? "emagged":"normal"))) @@ -1165,7 +1165,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( var/obj/item/bodypart/chopchop = c_user.get_bodypart(which_hand) chopchop.dismember() qdel(chopchop) - playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10) + playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) for(var/i=1; i<=rand(3,5); i++) prizevend(user) else diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm index 36eb9632c135..2ceaa4804956 100644 --- a/code/game/machinery/quantum_pad.dm +++ b/code/game/machinery/quantum_pad.dm @@ -161,9 +161,9 @@ //target_pad.sparks() flick("qpad-beam", src) - playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5) + playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff_exponent = 5) flick("qpad-beam", target_pad) - playsound(get_turf(target_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5) + playsound(get_turf(target_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff_exponent = 5) for(var/atom/movable/ROI in get_turf(src)) if(QDELETED(ROI)) continue //sleeps in CHECK_TICK diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 96fdddb814c8..479be91dafcc 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -526,7 +526,7 @@ . = ..() if(world.time >= music_time) SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "motivation", /datum/mood_event/motivation) //lets refresh the moodlet - M.stop_sound_channel(CHANNEL_AMBIENCE) + M.stop_sound_channel(CHANNEL_AMBIENT_EFFECTS) music_time = 0 /obj/structure/chair/comfy/plastic/proc/motivate(mob/living/M) @@ -534,5 +534,5 @@ return SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "motivation", /datum/mood_event/motivation) if(M.client && (M.client.prefs.toggles & SOUND_JUKEBOX)) - M.stop_sound_channel(CHANNEL_AMBIENCE) - M.playsound_local(M, 'sound/ambience/burythelight.ogg',60,0, channel = CHANNEL_AMBIENCE) + M.stop_sound_channel(CHANNEL_AMBIENT_EFFECTS) + M.playsound_local(M, 'sound/ambience/burythelight.ogg',60,0, channel = CHANNEL_AMBIENT_EFFECTS) diff --git a/code/game/sound.dm b/code/game/sound.dm index 69bb6ebb588b..6487f4aaab84 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -5,7 +5,50 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list( 'sound/items/pshoom_2.ogg' = 'sound/items/pshoom.ogg', )) -/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE) + +///Default override for echo +/sound + echo = list( + 0, // Direct + 0, // DirectHF + -10000, // Room, -10000 means no low frequency sound reverb + -10000, // RoomHF, -10000 means no high frequency sound reverb + 0, // Obstruction + 0, // ObstructionLFRatio + 0, // Occlusion + 0.25, // OcclusionLFRatio + 1.5, // OcclusionRoomRatio + 1.0, // OcclusionDirectRatio + 0, // Exclusion + 1.0, // ExclusionLFRatio + 0, // OutsideVolumeHF + 0, // DopplerFactor + 0, // RolloffFactor + 0, // RoomRolloffFactor + 1.0, // AirAbsorptionFactor + 0, // Flags (1 = Auto Direct, 2 = Auto Room, 4 = Auto RoomHF) + ) + environment = SOUND_ENVIRONMENT_NONE //Default to none so sounds without overrides dont get reverb + +/*! playsound + +playsound is a proc used to play a 3D sound in a specific range. This uses SOUND_RANGE + extra_range to determine that. + +source - Origin of sound +soundin - Either a file, or a string that can be used to get an SFX +vol - The volume of the sound, excluding falloff and pressure affection. +vary - bool that determines if the sound changes pitch every time it plays +extrarange - modifier for sound range. This gets added on top of SOUND_RANGE +falloff_exponent - Rate of falloff for the audio. Higher means quicker drop to low volume. Should generally be over 1 to indicate a quick dive to 0 rather than a slow dive. +frequency - playback speed of audio +channel - The channel the sound is played at +pressure_affected - Whether or not difference in pressure affects the sound (E.g. if you can hear in space) +ignore_walls - Whether or not the sound can pass through walls. +falloff_distance - Distance at which falloff begins. Sound is at peak volume (in regards to falloff) aslong as it is in this range. + +*/ + +/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff_exponent = SOUND_FALLOFF_EXPONENT, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, use_reverb = TRUE) if(isarea(source)) CRASH("playsound(): source is an area") @@ -19,7 +62,7 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list( // 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) + var/maxdistance = (SOUND_RANGE + extrarange) var/z = turf_source.z var/list/listeners = SSmobs.clients_by_zlevel[z] if(!ignore_walls) //these sounds don't carry through walls @@ -27,13 +70,30 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list( for(var/P in listeners) var/mob/M = P if(get_dist(M, turf_source) <= maxdistance) - M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S) + M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, maxdistance, falloff_distance, 1, use_reverb) for(var/P in SSmobs.dead_players_by_zlevel[z]) var/mob/M = P if(get_dist(M, turf_source) <= maxdistance) - M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S) + M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, maxdistance, falloff_distance, 1, use_reverb) -/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, channel = 0, pressure_affected = TRUE, sound/S, distance_multiplier = 1) + +/*! playsound +playsound_local is a proc used to play a sound directly on a mob from a specific turf. +This is called by playsound to send sounds to players, in which case it also gets the max_distance of that sound. +turf_source - Origin of sound +soundin - Either a file, or a string that can be used to get an SFX +vol - The volume of the sound, excluding falloff +vary - bool that determines if the sound changes pitch every time it plays +frequency - playback speed of audio +falloff_exponent - Rate of falloff for the audio. Higher means quicker drop to low volume. Should generally be over 1 to indicate a quick dive to 0 rather than a slow dive. +channel - The channel the sound is played at +pressure_affected - Whether or not difference in pressure affects the sound (E.g. if you can hear in space) +max_distance - The peak distance of the sound, if this is a 3D sound +falloff_distance - Distance at which falloff begins, if this is a 3D sound +distance_multiplier - Can be used to multiply the distance at which the sound is heard +*/ + +/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/S, max_distance, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = 1, use_reverb = TRUE) if(!client || !can_hear()) return @@ -61,7 +121,9 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list( distance *= distance_multiplier - S.volume -= max(distance - world.view, 0) * 2 //multiplicative falloff to add on top of natural audio falloff. + if(max_distance) //If theres no max_distance we're not a 3D sound, so no falloff. + S.volume -= (max(distance - falloff_distance, 0) ** (1 / falloff_exponent)) / ((max(max_distance, distance) - falloff_distance) ** (1 / falloff_exponent)) * S.volume + //https://www.desmos.com/calculator/sqdfl8ipgf if(pressure_affected) //Atmosphere affects sound @@ -92,17 +154,30 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list( var/dy = (turf_source.z - T.z) * 5 * distance_multiplier // Hearing from above / below, multiplied by 5 because we assume height is further along coords. S.y = dy - S.falloff = (falloff ? falloff : FALLOFF_SOUNDS) + S.falloff = max_distance || 1 //use max_distance, else just use 1 as we are a direct sound so falloff isnt relevant. + + // Sounds can't have their own environment. A sound's environment will be: + // 1. the mob's + // 2. the area's (defaults to SOUND_ENVRIONMENT_NONE) + if(sound_environment_override != SOUND_ENVIRONMENT_NONE) + S.environment = sound_environment_override + else + var/area/A = get_area(src) + S.environment = A.sound_environment + + if(use_reverb && S.environment != SOUND_ENVIRONMENT_NONE) //We have reverb, reset our echo setting + S.echo[3] = 0 //Room setting, 0 means normal reverb + S.echo[4] = 0 //RoomHF setting, 0 means normal reverb. SEND_SOUND(src, S) -/proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, falloff = FALSE, channel = 0, pressure_affected = FALSE, sound/S) +/proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, channel = 0, pressure_affected = FALSE, sound/S) if(!S) S = sound(get_sfx(soundin)) for(var/m in GLOB.player_list) if(ismob(m) && !isnewplayer(m)) var/mob/M = m - M.playsound_local(M, null, volume, vary, frequency, falloff, channel, pressure_affected, S) + M.playsound_local(M, null, volume, vary, frequency, null, channel, pressure_affected, S) /mob/proc/stop_sound_channel(chan) SEND_SOUND(src, sound(null, repeat = 0, wait = 0, channel = chan)) @@ -205,3 +280,22 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list( if("switch") //stolen from nsv soundin = pick('sound/machines/switch1.ogg','sound/machines/switch2.ogg','sound/machines/switch3.ogg') return soundin + +/client/proc/channel_in_use(channel) + for (var/sound/S in src.SoundQuery()) + if (S.channel == channel) + return TRUE + + return FALSE + +/mob/proc/can_hear_ambience() + if (!src.can_hear()) // If they can't hear they can't hear + return FALSE + + var/turf/T = get_turf(src) + var/datum/gas_mixture/hearer_env = T.return_air() + + if (!hearer_env || hearer_env.return_pressure() < SOUND_MINIMUM_PRESSURE) // They can't hear ambience if there isn't enough pressure + return FALSE + + return TRUE diff --git a/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm b/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm index e4f8df2114bc..1dc1aec8b4d4 100644 --- a/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm +++ b/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm @@ -22,7 +22,7 @@ for(var/mob/M in GLOB.player_list) if(M.z == z) if(get_dist(src, M) >= 7) - M.playsound_local(src, 'sound/magic/blink.ogg', 10, FALSE, falloff = 10) + M.playsound_local(src, 'sound/magic/blink.ogg', 10, FALSE, falloff_exponent = 10) else M.playsound_local(src, 'sound/magic/blink.ogg', 50, FALSE) diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm index d3c98bc979c2..c74e4f4f6f87 100644 --- a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm +++ b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm @@ -207,9 +207,9 @@ if(last_accent_sound < world.time && prob(20)) var/aggression = min(((critical_threshold_proximity / 800) * ((power_level) / 5)), 1.0) * 100 if(critical_threshold_proximity >= 300) - playsound(src, "hypertorusmelting", max(50, aggression), FALSE, 40, 30, falloff = 10) + playsound(src, "hypertorusmelting", max(50, aggression), FALSE, 40, 30, falloff_exponent = 10) else - playsound(src, "hypertoruscalm", max(50, aggression), FALSE, 25, 25, falloff = 10) + playsound(src, "hypertoruscalm", max(50, aggression), FALSE, 25, 25, falloff_exponent = 10) var/next_sound = round((100 - aggression) * 5) + 5 last_accent_sound = world.time + max(HYPERTORUS_ACCENT_SOUND_MIN_COOLDOWN, next_sound) @@ -291,11 +291,11 @@ /obj/machinery/atmospherics/components/unary/hypertorus/core/proc/alarm() switch(get_status()) if(HYPERTORUS_MELTING) - playsound(src, 'sound/misc/bloblarm.ogg', 100, FALSE, 40, 30, falloff = 10) + playsound(src, 'sound/misc/bloblarm.ogg', 100, FALSE, 40, 30, falloff_exponent = 10) if(HYPERTORUS_EMERGENCY) - playsound(src, 'sound/machines/engine_alert1.ogg', 100, FALSE, 30, 30, falloff = 10) + playsound(src, 'sound/machines/engine_alert1.ogg', 100, FALSE, 30, 30, falloff_exponent = 10) if(HYPERTORUS_DANGER) - playsound(src, 'sound/machines/engine_alert2.ogg', 100, FALSE, 30, 30, falloff = 10) + playsound(src, 'sound/machines/engine_alert2.ogg', 100, FALSE, 30, 30, falloff_exponent = 10) if(HYPERTORUS_WARNING) playsound(src, 'sound/machines/terminal_alert.ogg', 75) diff --git a/code/modules/chatter/chatter.dm b/code/modules/chatter/chatter.dm index 3cca56dc6dd8..d7d248f48904 100644 --- a/code/modules/chatter/chatter.dm +++ b/code/modules/chatter/chatter.dm @@ -38,7 +38,7 @@ var/path = "sound/chatter/[phomeme]_[length].ogg" playsound(loc, path, - vol = 40, vary = 0, extrarange = 3, falloff = FALSE) + vol = 40, vary = 0, extrarange = 3, falloff_exponent = FALSE) sleep((length + 1) * chatter_get_sleep_multiplier(phomeme)) diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 31cf29b4876b..9f876156b699 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -49,10 +49,9 @@ /////////////// //SOUND STUFF// /////////////// - ///Currently playing ambience sound - var/ambience_playing = null - ///Whether an ambience sound has been played and one shouldn't be played again, unset by a callback - var/played = FALSE + + var/buzz_playing = null + //////////// //SECURITY// //////////// diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 9e0bda883d31..ec4717a9367b 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -436,7 +436,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them. to_chat(src, span_warning("Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.")) - + update_ambience_pref() //This is down here because of the browse() calls in tooltip/New() if(!tooltips) tooltips = new /datum/tooltip(src) @@ -508,6 +508,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( GLOB.directory -= ckey GLOB.clients -= src + SSambience.remove_ambience_client(src) + var/datum/connection_log/CL = GLOB.connection_logs[ckey] if(CL) CL.logout(mob) @@ -1095,3 +1097,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( SEND_SOUND(usr, sound(null)) tgui_panel?.stop_music() SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Stop Self Sounds")) + +/client/proc/update_ambience_pref() + if(prefs.toggles & SOUND_AMBIENCE) + if(SSambience.ambience_listening_clients[src] > world.time) + return // If already properly set we don't want to reset the timer. + SSambience.ambience_listening_clients[src] = world.time + 10 SECONDS //Just wait 10 seconds before the next one aight mate? cheers. + else + SSambience.ambience_listening_clients -= src diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index a89f8d6d2de1..54362e8c863a 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -865,7 +865,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( target.playsound_local(source, pick('sound/voice/human/manlaugh1.ogg', 'sound/voice/human/manlaugh2.ogg'), 50, 1) if("creepy") //These sounds are (mostly) taken from Hidden: Source - target.playsound_local(source, pick(CREEPY_SOUNDS), 50, 1) + target.playsound_local(source, pick(GLOB.creepy_ambience), 50, 1) if("tesla") //Tesla loose! target.playsound_local(source, 'sound/magic/lightningbolt.ogg', 35, 1) sleep(3 SECONDS) diff --git a/code/modules/instruments/songs/play_legacy.dm b/code/modules/instruments/songs/play_legacy.dm index e4f958397358..fbd6b12701a9 100644 --- a/code/modules/instruments/songs/play_legacy.dm +++ b/code/modules/instruments/songs/play_legacy.dm @@ -87,5 +87,5 @@ L.apply_status_effect(STATUS_EFFECT_GOOD_MUSIC) if(!(M?.client?.prefs?.toggles & SOUND_INSTRUMENTS)) continue - M.playsound_local(source, null, volume * using_instrument.volume_multiplier, falloff = 5, S = music_played) + M.playsound_local(source, null, volume * using_instrument.volume_multiplier, falloff_exponent = 5, S = music_played) // Could do environment and echo later but not for now diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index c3c2ca83a065..b3ba9df0a698 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -214,3 +214,5 @@ var/datum/client_interface/mock_client var/create_area_cooldown + + var/sound_environment_override = SOUND_ENVIRONMENT_NONE diff --git a/code/modules/modular_computers/file_system/programs/arcade.dm b/code/modules/modular_computers/file_system/programs/arcade.dm index 3f2fd4639e87..63d6f381d4d8 100644 --- a/code/modules/modular_computers/file_system/programs/arcade.dm +++ b/code/modules/modular_computers/file_system/programs/arcade.dm @@ -24,7 +24,7 @@ sleep(0.5 SECONDS) if(boss_hp <= 0) heads_up = "You have crushed [boss_name]! Rejoice!" - playsound(computer.loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3, falloff = 10) + playsound(computer.loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10) game_active = FALSE program_icon_state = "arcade_off" if(istype(computer)) @@ -34,7 +34,7 @@ return else if(player_hp <= 0 || player_mp <= 0) heads_up = "You have been defeated... how will the station survive?" - playsound(computer.loc, 'sound/arcade/lose.ogg', 50, TRUE, extrarange = -3, falloff = 10) + playsound(computer.loc, 'sound/arcade/lose.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10) game_active = FALSE program_icon_state = "arcade_off" if(istype(computer)) @@ -55,17 +55,17 @@ return if (boss_mp <= 5) heads_up = "[boss_mpamt] magic power has been stolen from you!" - playsound(computer.loc, 'sound/arcade/steal.ogg', 50, TRUE, extrarange = -3, falloff = 10) + playsound(computer.loc, 'sound/arcade/steal.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10) player_mp -= boss_mpamt boss_mp += boss_mpamt else if(boss_mp > 5 && boss_hp <12) heads_up = "[boss_name] heals for [bossheal] health!" - playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3, falloff = 10) + playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10) boss_hp += bossheal boss_mp -= boss_mpamt else heads_up = "[boss_name] attacks you for [boss_attackamt] damage!" - playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3, falloff = 10) + playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10) player_hp -= boss_attackamt pause_state = FALSE @@ -104,7 +104,7 @@ pause_state = TRUE heads_up = "You attack for [attackamt] damage." computer.play_interact_sound() - playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3, falloff = 10) + playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10) boss_hp -= attackamt sleep(1 SECONDS) game_check() @@ -119,7 +119,7 @@ pause_state = TRUE heads_up = "You heal for [healamt] damage." computer.play_interact_sound() - playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3, falloff = 10) + playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10) player_hp += healamt player_mp -= healcost sleep(1 SECONDS) @@ -133,7 +133,7 @@ pause_state = TRUE heads_up = "You regain [rechargeamt] magic power." computer.play_interact_sound() - playsound(computer.loc, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3, falloff = 10) + playsound(computer.loc, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10) player_mp += rechargeamt sleep(1 SECONDS) game_check() diff --git a/code/modules/modular_computers/file_system/programs/minesweeper.dm b/code/modules/modular_computers/file_system/programs/minesweeper.dm index 7730828c62d1..14fd9c0e6de1 100644 --- a/code/modules/modular_computers/file_system/programs/minesweeper.dm +++ b/code/modules/modular_computers/file_system/programs/minesweeper.dm @@ -181,7 +181,7 @@ var/obj/item/modular_computer/comp = host comp.play_computer_sound(sound, 50, 0) else - playsound(get_turf(host), sound, 50, 0, extrarange = -3, falloff = 10) + playsound(get_turf(host), sound, 50, 0, extrarange = -3, falloff_exponent = 10) /datum/minesweeper/proc/vis_msg(msg, local_msg) if(istype(host, /obj/item/modular_computer)) diff --git a/code/modules/projectiles/guns/ballistic/bow.dm b/code/modules/projectiles/guns/ballistic/bow.dm index 39598331ba6c..4e6044bc33c9 100644 --- a/code/modules/projectiles/guns/ballistic/bow.dm +++ b/code/modules/projectiles/guns/ballistic/bow.dm @@ -90,7 +90,7 @@ return TRUE drawing = FALSE to_chat(user, span_notice("You draw back the bowstring.")) - playsound(src, draw_sound, 75, 0, falloff = 3) //gets way too high pitched if the freq varies + playsound(src, draw_sound, 75, 0, falloff_exponent = 3) //gets way too high pitched if the freq varies chamber_round() return TRUE diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 74deabccf35f..d70ab9e77369 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -806,7 +806,7 @@ for(var/mob/M in SSmobs.clients_by_zlevel[z]) var/dist_far = get_dist(M, distant_source) if(dist_far <= long_range && dist_far > range) - M.playsound_local(distant_source, "sound/effects/[selected_sound]_distance.ogg", 100, falloff = 20) + M.playsound_local(distant_source, "sound/effects/[selected_sound]_distance.ogg", 100, falloff_exponent = 20) else if(dist_far <= range) var/source if(engine_list.len == 0) @@ -818,7 +818,7 @@ if(dist_near < closest_dist) source = O closest_dist = dist_near - M.playsound_local(source, "sound/effects/[selected_sound].ogg", 100, falloff = range / 2) + M.playsound_local(source, "sound/effects/[selected_sound].ogg", 100, falloff_exponent = range / 2) // Losing all initial engines should get you 2 // Adding another set of engines at 0.5 time diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index 803604786dd5..d4afbd49b49c 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -79,7 +79,7 @@ var/datum/surgery/procedure = new S.type(M, selected_zone, affecting) user.visible_message("[user] prepares to operate on [M]'s [parse_zone(selected_zone)].", \ span_notice("You prepare to operate on [M]'s [parse_zone(selected_zone)].")) - playsound(get_turf(M), 'sound/items/handling/cloth_drop.ogg', 30, TRUE, falloff = 1) + playsound(get_turf(M), 'sound/items/handling/cloth_drop.ogg', 30, TRUE, falloff_exponent = 1) log_combat(user, M, "operated on", null, "(OPERATION TYPE: [procedure.name]) (TARGET AREA: [selected_zone])") if(S.self_operable || user != M) procedure.next_step(user, user.a_intent) diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index 61804543fb2e..f201f886151e 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -170,7 +170,7 @@ sound_file_use = preop_sound if(!sound_file_use) return - playsound(get_turf(target), sound_file_use, 30, TRUE, falloff = 2) + playsound(get_turf(target), sound_file_use, 30, TRUE, falloff_exponent = 2) /datum/surgery_step/proc/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, span_notice("You succeed."), @@ -191,7 +191,7 @@ sound_file_use = success_sound if(!sound_file_use) return - playsound(get_turf(target), sound_file_use, 30, TRUE, falloff = 2) + playsound(get_turf(target), sound_file_use, 30, TRUE, falloff_exponent = 2) /datum/surgery_step/proc/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, span_warning("You screw up!"), @@ -212,7 +212,7 @@ sound_file_use = failure_sound if(!sound_file_use) return - playsound(get_turf(target), sound_file_use, 30, TRUE, falloff = 2) + playsound(get_turf(target), sound_file_use, 30, TRUE, falloff_exponent = 2) /datum/surgery_step/proc/tool_check(mob/user, obj/item/tool) return TRUE diff --git a/sound/ambience/ambiviro.ogg b/sound/ambience/ambiviro.ogg new file mode 100644 index 000000000000..71b280f7e711 Binary files /dev/null and b/sound/ambience/ambiviro.ogg differ diff --git a/sound/ambience/ambiviro1.ogg b/sound/ambience/ambiviro1.ogg new file mode 100644 index 000000000000..cf05bdc287a7 Binary files /dev/null and b/sound/ambience/ambiviro1.ogg differ diff --git a/sound/ambience/ambiviro2.ogg b/sound/ambience/ambiviro2.ogg new file mode 100644 index 000000000000..b6cc3a247957 Binary files /dev/null and b/sound/ambience/ambiviro2.ogg differ diff --git a/sound/ambience/cavesound3.ogg b/sound/ambience/cavesound3.ogg new file mode 100644 index 000000000000..ca7f9cfe995b Binary files /dev/null and b/sound/ambience/cavesound3.ogg differ diff --git a/sound/ambience/magma.ogg b/sound/ambience/magma.ogg new file mode 100644 index 000000000000..415c62966fcc Binary files /dev/null and b/sound/ambience/magma.ogg differ diff --git a/sound/ambience/maintambience.ogg b/sound/ambience/maintambience.ogg new file mode 100644 index 000000000000..1e98d9db13cb Binary files /dev/null and b/sound/ambience/maintambience.ogg differ diff --git a/sound/ambience/source_corridor2.ogg b/sound/ambience/source_corridor2.ogg new file mode 100644 index 000000000000..1fa9194f4cdd Binary files /dev/null and b/sound/ambience/source_corridor2.ogg differ diff --git a/sound/ambience/source_holehit3.ogg b/sound/ambience/source_holehit3.ogg new file mode 100644 index 000000000000..79cf9c8b4a7a Binary files /dev/null and b/sound/ambience/source_holehit3.ogg differ diff --git a/yogstation.dme b/yogstation.dme index f714e015ac9e..a68117403b71 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -259,6 +259,7 @@ #include "code\_globalvars\lists\objects.dm" #include "code\_globalvars\lists\poll_ignore.dm" #include "code\_globalvars\lists\typecache.dm" +#include "code\_globalvars\lists\ambience.dm" #include "code\_js\byjax.dm" #include "code\_js\menus.dm" #include "code\_onclick\adjacent.dm" @@ -402,6 +403,7 @@ #include "code\controllers\subsystem\processing\slowprocess.dm" #include "code\controllers\subsystem\processing\station.dm" #include "code\controllers\subsystem\processing\wet_floors.dm" +#include "code\controllers\subsystem\ambience.dm" #include "code\datums\ai_laws.dm" #include "code\datums\armor.dm" #include "code\datums\beam.dm" diff --git a/yogstation/code/game/area/areas/centcom.dm b/yogstation/code/game/area/areas/centcom.dm index 60905f1ad182..d6c5303cdac5 100644 --- a/yogstation/code/game/area/areas/centcom.dm +++ b/yogstation/code/game/area/areas/centcom.dm @@ -7,7 +7,7 @@ has_gravity = TRUE noteleport = TRUE flags_1 = NONE - ambientsounds = HIGHSEC + ambience_index = AMBIENCE_DANGER dynamic_lighting = DYNAMIC_LIGHTING_FORCED /area/yogs/infiltrator_base/poweralert(state, obj/source) @@ -32,4 +32,4 @@ has_gravity = TRUE noteleport = TRUE flags_1 = NONE - area_flags = NOTELEPORT \ No newline at end of file + area_flags = NOTELEPORT diff --git a/yogstation/code/game/machinery/computer/arcade.dm b/yogstation/code/game/machinery/computer/arcade.dm index bc76ca248529..dca71e710146 100644 --- a/yogstation/code/game/machinery/computer/arcade.dm +++ b/yogstation/code/game/machinery/computer/arcade.dm @@ -23,9 +23,9 @@ return if(board.game_status == MINESWEEPER_IDLE || board.game_status == MINESWEEPER_DEAD || board.game_status == MINESWEEPER_VICTORY) if(obj_flags & EMAGGED) - playsound(loc, 'yogstation/sound/arcade/minesweeper_emag2.ogg', 50, 0, extrarange = -3, falloff = 10) + playsound(loc, 'yogstation/sound/arcade/minesweeper_emag2.ogg', 50, 0, extrarange = -3, falloff_exponent = 10) else - playsound(loc, 'yogstation/sound/arcade/minesweeper_startup.ogg', 50, 0, extrarange = -3, falloff = 10) + playsound(loc, 'yogstation/sound/arcade/minesweeper_startup.ogg', 50, 0, extrarange = -3, falloff_exponent = 10) if(obj_flags & EMAGGED) do_sparks(5, 1, src) @@ -154,8 +154,8 @@ obj_flags |= EMAGGED if(board.game_status != MINESWEEPER_CONTINUE) to_chat(user, span_warning("An ominous tune plays from the arcade's speakers!")) - playsound(user, 'yogstation/sound/arcade/minesweeper_emag1.ogg', 100, 0, extrarange = 3, falloff = 10) + playsound(user, 'yogstation/sound/arcade/minesweeper_emag1.ogg', 100, 0, extrarange = 3, falloff_exponent = 10) else //Can't let you do that, star fox! to_chat(user, span_warning("The machine buzzes and sparks... the game has been reset!")) - playsound(user, 'sound/machines/buzz-sigh.ogg', 100, 0, extrarange = 3, falloff = 10) //Loud buzz + playsound(user, 'sound/machines/buzz-sigh.ogg', 100, 0, extrarange = 3, falloff_exponent = 10) //Loud buzz board.game_status = MINESWEEPER_IDLE diff --git a/yogstation/code/modules/antagonists/darkspawn/darkspawn_progenitor.dm b/yogstation/code/modules/antagonists/darkspawn/darkspawn_progenitor.dm index 8a1ed48c8e64..7b6d346e107e 100644 --- a/yogstation/code/modules/antagonists/darkspawn/darkspawn_progenitor.dm +++ b/yogstation/code/modules/antagonists/darkspawn/darkspawn_progenitor.dm @@ -71,7 +71,7 @@ playsound(src, 'yogstation/sound/creatures/progenitor_roar.ogg', 50, TRUE) for(var/mob/M in GLOB.player_list) if(get_dist(M, src) > 7) - M.playsound_local(src, 'yogstation/sound/creatures/progenitor_distant.ogg', 25, FALSE, falloff = 5) + M.playsound_local(src, 'yogstation/sound/creatures/progenitor_distant.ogg', 25, FALSE, falloff_exponent = 5) else if(isliving(M)) var/mob/living/L = M if(L != src) //OH GOD OH FUCK I'M SCARING MYSELF diff --git a/yogstation/code/modules/guardian/abilities/special/pocket.dm b/yogstation/code/modules/guardian/abilities/special/pocket.dm index b14b111f6d24..c3fd839c205e 100644 --- a/yogstation/code/modules/guardian/abilities/special/pocket.dm +++ b/yogstation/code/modules/guardian/abilities/special/pocket.dm @@ -16,7 +16,7 @@ GLOBAL_LIST_EMPTY(pocket_mirrors) unique = FALSE requires_power = FALSE show_on_sensors = FALSE - ambientsounds = SPACE + ambience_index = AMBIENCE_SPACE parallax_movedir = EAST /obj/effect/landmark/pocket_dimension_corner