diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 397b171772d..ed76f6fd3ff 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -94,6 +94,7 @@
#define FIRE_PRIORITY_CLEANUP 10
#define FIRE_PRIORITY_TICKETS 10
#define FIRE_PRIORITY_RESEARCH 10
+#define FIRE_PRIORITY_AMBIENCE 10
#define FIRE_PRIORITY_GARBAGE 15
#define FIRE_PRIORITY_WET_FLOORS 20
#define FIRE_PRIORITY_AIR 20
diff --git a/code/controllers/subsystem/ambience.dm b/code/controllers/subsystem/ambience.dm
new file mode 100644
index 00000000000..f95dc32b807
--- /dev/null
+++ b/code/controllers/subsystem/ambience.dm
@@ -0,0 +1,28 @@
+/// 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 = 1 SECONDS
+ ///Assoc list of listening client - next ambience time
+ var/list/ambience_listening_clients = list()
+
+/datum/controller/subsystem/ambience/fire(resumed)
+ for(var/C in ambience_listening_clients)
+ var/client/client_iterator = C
+
+ if(isnull(client_iterator))
+ ambience_listening_clients -= client_iterator
+ continue
+
+ if(ambience_listening_clients[client_iterator] > world.time)
+ continue //Not ready for the next sound
+
+ var/area/current_area = get_area(client_iterator.mob)
+
+ var/sound = pick(current_area.ambientsounds)
+
+ SEND_SOUND(client_iterator.mob, sound(sound, repeat = 0, wait = 0, volume = 25 * client_iterator.prefs.get_channel_volume(CHANNEL_AMBIENCE), channel = CHANNEL_AMBIENCE))
+
+ ambience_listening_clients[client_iterator] = world.time + rand(current_area.min_ambience_cooldown, current_area.max_ambience_cooldown)
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 3076c4b2c6c..d2485e24357 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -70,6 +70,11 @@
///Used to decide what kind of reverb the area makes sound have
var/sound_environment = SOUND_ENVIRONMENT_NONE
+ ///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 = 90 SECONDS
+
/area/Initialize(mapload)
GLOB.all_areas += src
icon_state = ""
@@ -476,27 +481,13 @@
if((oldarea.has_gravity == 0) && (newarea.has_gravity == 1) && (L.m_intent == MOVE_INTENT_RUN)) // Being ready when you change areas gives you a chance to avoid falling all together.
thunk(L)
- // Ambience goes down here -- make sure to list each area seperately 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 && L.client && !L.client.ambience_playing && (L.client.prefs.sound & SOUND_BUZZ)) //split off the white noise from the rest of the ambience because of annoyance complaints - Kluys
+ //Ship ambience just loops if turned on.
+ if(L && L.client && !L.client.ambience_playing && (L.client.prefs.sound & SOUND_BUZZ))
L.client.ambience_playing = TRUE
SEND_SOUND(L, sound('sound/ambience/shipambience.ogg', repeat = TRUE, wait = FALSE, volume = 35 * L.client.prefs.get_channel_volume(CHANNEL_BUZZ), channel = CHANNEL_BUZZ))
else if(L && L.client && !(L.client.prefs.sound & SOUND_BUZZ))
L.client.ambience_playing = FALSE
- if(prob(35) && L && L.client && (L.client.prefs.sound & SOUND_AMBIENCE))
- var/sound = pick(ambientsounds)
-
- if(!L.client.played)
- SEND_SOUND(L, sound(sound, repeat = FALSE, wait = FALSE, volume = 25 * L.client.prefs.get_channel_volume(CHANNEL_AMBIENCE), channel = CHANNEL_AMBIENCE))
- L.client.played = TRUE
- addtimer(CALLBACK(L.client, /client/proc/ResetAmbiencePlayed), 600)
-
-/**
- * Reset the played var to false on the client
- */
-/client/proc/ResetAmbiencePlayed()
- played = FALSE
-
/area/proc/gravitychange(var/gravitystate = 0, var/area/A)
A.has_gravity = gravitystate
diff --git a/code/game/area/areas/mining.dm b/code/game/area/areas/mining.dm
index a1de206a0db..59bbcdb35da 100644
--- a/code/game/area/areas/mining.dm
+++ b/code/game/area/areas/mining.dm
@@ -17,6 +17,8 @@
ambientsounds = MINING_SOUNDS
flags = NONE
sound_environment = SOUND_AREA_STANDARD_STATION
+ min_ambience_cooldown = 70 SECONDS
+ max_ambience_cooldown = 220 SECONDS
/area/mine/dangerous/explored/golem
name = "Small Asteroid"
@@ -33,6 +35,8 @@
outdoors = TRUE
ambientsounds = MINING_SOUNDS
flags = NONE
+ min_ambience_cooldown = 70 SECONDS
+ max_ambience_cooldown = 220 SECONDS
/area/mine/lobby
name = "Mining Station"
@@ -103,6 +107,8 @@
power_light = FALSE
requires_power = TRUE
ambientsounds = MINING_SOUNDS
+ min_ambience_cooldown = 70 SECONDS
+ max_ambience_cooldown = 220 SECONDS
/area/lavaland/underground
name = "Lavaland Caves"
@@ -114,6 +120,8 @@
power_equip = FALSE
power_light = FALSE
ambientsounds = MINING_SOUNDS
+ min_ambience_cooldown = 70 SECONDS
+ max_ambience_cooldown = 220 SECONDS
/area/lavaland/surface/outdoors
name = "Lavaland Wastes"
diff --git a/code/game/area/ss13_areas.dm b/code/game/area/ss13_areas.dm
index 2879bedafdc..6e2add03868 100644
--- a/code/game/area/ss13_areas.dm
+++ b/code/game/area/ss13_areas.dm
@@ -480,6 +480,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
ambientsounds = MINING_SOUNDS
sound_environment = SOUND_AREA_ASTEROID
+ min_ambience_cooldown = 70 SECONDS
+ max_ambience_cooldown = 220 SECONDS
/area/asteroid/cave // -- TLE
name = "\improper Asteroid - Underground"
@@ -1239,6 +1241,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/medical
ambientsounds = MEDICAL_SOUNDS
sound_environment = SOUND_AREA_STANDARD_STATION
+ min_ambience_cooldown = 90 SECONDS
+ max_ambience_cooldown = 180 SECONDS
/area/medical/medbay
name = "\improper Medbay"
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index ca30cf25d5a..1950c70556a 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -30,8 +30,8 @@
///////////////
//SOUND STUFF//
///////////////
- var/ambience_playing = 0
- var/played = 0
+
+ var/ambience_playing = FALSE
////////////
//SECURITY//
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 3f3d50ed8d5..9edc012e7ac 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -368,6 +368,8 @@
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
to_chat(src, "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)
@@ -422,6 +424,7 @@
if(movingmob)
movingmob.client_mobs_in_contents -= mob
UNSETEMPTY(movingmob.client_mobs_in_contents)
+ SSambience.ambience_listening_clients -= src
Master.UpdateTickRate()
..() //Even though we're going to be hard deleted there are still some things that want to know the destroy is happening
return QDEL_HINT_HARDDEL_NOW
@@ -1218,6 +1221,13 @@
if(show_warning)
message_admins("[ckey] has just connected and has a history of [cidcount] different CIDs. (WebInfo) (Suppress Warning)")
+/client/proc/update_ambience_pref()
+ if(prefs.sound & 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
#undef LIMITER_SIZE
#undef CURRENT_SECOND
diff --git a/code/modules/client/preference/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm
index 054fd5ccd39..fb6a1482403 100644
--- a/code/modules/client/preference/preferences_toggles.dm
+++ b/code/modules/client/preference/preferences_toggles.dm
@@ -179,6 +179,7 @@
else
to_chat(src, "You will no longer hear ambient sounds.")
usr.stop_sound_channel(CHANNEL_AMBIENCE)
+ update_ambience_pref()
SSblackbox.record_feedback("tally", "toggle_verbs", 1, "Toggle Ambience") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/Toggle_Buzz() //No more headaches because headphones bump up shipambience.ogg to insanity levels.
diff --git a/paradise.dme b/paradise.dme
index 7ad1f61982b..90540ba5b49 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -189,6 +189,7 @@
#include "code\controllers\subsystem\afk.dm"
#include "code\controllers\subsystem\air.dm"
#include "code\controllers\subsystem\alarm.dm"
+#include "code\controllers\subsystem\ambience.dm"
#include "code\controllers\subsystem\assets.dm"
#include "code\controllers\subsystem\atoms.dm"
#include "code\controllers\subsystem\blackbox.dm"