diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 65194b26f8..9de0dbe7c5 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -44,6 +44,9 @@
/// from SSsun when the sun changes position : (primary_sun, suns)
#define COMSIG_SUN_MOVED "sun_moved"
+///from SSsecurity_level when the security level changes : (new_level)
+#define COMSIG_SECURITY_LEVEL_CHANGED "security_level_changed"
+
/// from SSactivity for things that add threat but aren't "global" (e.g. phylacteries)
#define COMSIG_THREAT_CALC "threat_calculation"
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 560bc2daf3..49bad31a60 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -111,6 +111,7 @@
#define INIT_ORDER_SOUNDS 83
#define INIT_ORDER_INSTRUMENTS 82
#define INIT_ORDER_VIS 80
+#define INIT_ORDER_SECURITY_LEVEL 79 // We need to load before events so that it has a security level to choose from.
#define INIT_ORDER_ACHIEVEMENTS 77
#define INIT_ORDER_RESEARCH 75
#define INIT_ORDER_STATION 74 //This is high priority because it manipulates a lot of the subsystems that will initialize after it.
diff --git a/code/controllers/subsystem/security_level.dm b/code/controllers/subsystem/security_level.dm
new file mode 100644
index 0000000000..94fa822e8b
--- /dev/null
+++ b/code/controllers/subsystem/security_level.dm
@@ -0,0 +1,114 @@
+// NOT THE SAME AS TG! THIS IS BAREMETAL JUST TO MAKE COMSIGS WORK!
+SUBSYSTEM_DEF(security_level)
+ name = "Security Level"
+ can_fire = FALSE // We will control when we fire in this subsystem
+ init_order = INIT_ORDER_SECURITY_LEVEL
+
+/**
+ * Sets a new security level as our current level
+ *
+ * This is how everything should change the security level.
+ *
+ * Arguments:
+ * * new_level - The new security level that will become our current level
+ */
+/datum/controller/subsystem/security_level/proc/set_level(new_level)
+ if(!isnum(new_level))
+ new_level = GLOB.all_security_levels.Find()
+
+ //Will not be announced if you try to set to the same level as it already is
+ if(new_level >= SEC_LEVEL_GREEN && new_level <= SEC_LEVEL_DELTA && new_level != GLOB.security_level)
+ switch(new_level)
+ if(SEC_LEVEL_GREEN)
+ minor_announce(CONFIG_GET(string/alert_green), "Attention! Security level lowered to green:")
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ if(GLOB.security_level >= SEC_LEVEL_RED)
+ SSshuttle.emergency.modTimer(4)
+ else if(GLOB.security_level == SEC_LEVEL_AMBER)
+ SSshuttle.emergency.modTimer(2.5)
+ else
+ SSshuttle.emergency.modTimer(1.66)
+ GLOB.security_level = SEC_LEVEL_GREEN
+ for(var/obj/machinery/firealarm/FA in GLOB.machines)
+ if(is_station_level(FA.z))
+ FA.update_icon()
+ if(SEC_LEVEL_BLUE)
+ if(GLOB.security_level < SEC_LEVEL_BLUE)
+ minor_announce(CONFIG_GET(string/alert_blue_upto), "Attention! Security level elevated to blue:",1)
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ SSshuttle.emergency.modTimer(0.6)
+ else
+ minor_announce(CONFIG_GET(string/alert_blue_downto), "Attention! Security level lowered to blue:")
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ if(GLOB.security_level >= SEC_LEVEL_RED)
+ SSshuttle.emergency.modTimer(2.4)
+ else
+ SSshuttle.emergency.modTimer(1.5)
+ GLOB.security_level = SEC_LEVEL_BLUE
+ sound_to_playing_players('sound/misc/voybluealert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
+ for(var/obj/machinery/firealarm/FA in GLOB.machines)
+ if(is_station_level(FA.z))
+ FA.update_icon()
+ if(SEC_LEVEL_AMBER)
+ if(GLOB.security_level < SEC_LEVEL_AMBER)
+ minor_announce(CONFIG_GET(string/alert_amber_upto), "Attention! Security level elevated to amber:",1)
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ if(GLOB.security_level == SEC_LEVEL_GREEN)
+ SSshuttle.emergency.modTimer(0.4)
+ else
+ SSshuttle.emergency.modTimer(0.66)
+ else
+ minor_announce(CONFIG_GET(string/alert_amber_downto), "Attention! Security level lowered to amber:")
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ SSshuttle.emergency.modTimer(1.6)
+ GLOB.security_level = SEC_LEVEL_AMBER
+ sound_to_playing_players('sound/effects/alert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
+ for(var/obj/machinery/firealarm/FA in GLOB.machines)
+ if(is_station_level(FA.z))
+ FA.update_icon()
+ if(SEC_LEVEL_RED)
+ if(GLOB.security_level < SEC_LEVEL_RED)
+ minor_announce(CONFIG_GET(string/alert_red_upto), "Attention! Code red!",1)
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ if(GLOB.security_level == SEC_LEVEL_GREEN)
+ SSshuttle.emergency.modTimer(0.25)
+ else if(GLOB.security_level == SEC_LEVEL_BLUE)
+ SSshuttle.emergency.modTimer(0.416)
+ else
+ SSshuttle.emergency.modTimer(0.625)
+ else
+ minor_announce(CONFIG_GET(string/alert_red_downto), "Attention! Code red!")
+ GLOB.security_level = SEC_LEVEL_RED
+ sound_to_playing_players('sound/misc/voyalert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
+
+ for(var/obj/machinery/firealarm/FA in GLOB.machines)
+ if(is_station_level(FA.z))
+ FA.update_icon()
+ for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines)
+ pod.admin_controlled = FALSE
+ if(SEC_LEVEL_DELTA)
+ minor_announce(CONFIG_GET(string/alert_delta), "Attention! Delta security level reached!",1)
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ if(GLOB.security_level < SEC_LEVEL_BLUE)
+ SSshuttle.emergency.modTimer(0.25)
+ else if(GLOB.security_level == SEC_LEVEL_BLUE)
+ SSshuttle.emergency.modTimer(0.416)
+ else
+ SSshuttle.emergency.modTimer(0.625)
+ GLOB.security_level = SEC_LEVEL_DELTA
+ sound_to_playing_players('sound/misc/deltakalaxon.ogg') // Citadel change - Makes alerts play a sound
+ for(var/obj/machinery/firealarm/FA in GLOB.machines)
+ if(is_station_level(FA.z))
+ FA.update_icon()
+ for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines)
+ pod.admin_controlled = FALSE
+ if(new_level >= SEC_LEVEL_RED)
+ for(var/obj/machinery/door/D in GLOB.machines)
+ if(D.red_alert_access)
+ D.visible_message("[D] whirrs as it automatically lifts access requirements!")
+ playsound(D, 'sound/machines/boltsup.ogg', 50, TRUE)
+ SEND_SIGNAL(src, COMSIG_SECURITY_LEVEL_CHANGED, new_level)
+ SSblackbox.record_feedback("tally", "security_level_changes", 1, NUM2SECLEVEL(GLOB.security_level))
+ SSnightshift.check_nightshift()
+ else
+ return
diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm
index 99357d802a..4b0208889c 100644
--- a/code/modules/security_levels/security_levels.dm
+++ b/code/modules/security_levels/security_levels.dm
@@ -14,101 +14,4 @@ GLOBAL_LIST_INIT(all_security_levels, list("green", "blue", "amber", "red", "del
//config.alert_desc_blue_downto
/proc/set_security_level(level)
- if(!isnum(level))
- level = GLOB.all_security_levels.Find(level)
-
- //Will not be announced if you try to set to the same level as it already is
- if(level >= SEC_LEVEL_GREEN && level <= SEC_LEVEL_DELTA && level != GLOB.security_level)
- switch(level)
- if(SEC_LEVEL_GREEN)
- minor_announce(CONFIG_GET(string/alert_green), "Attention! Security level lowered to green:")
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- if(GLOB.security_level >= SEC_LEVEL_RED)
- SSshuttle.emergency.modTimer(4)
- else if(GLOB.security_level == SEC_LEVEL_AMBER)
- SSshuttle.emergency.modTimer(2.5)
- else
- SSshuttle.emergency.modTimer(1.66)
- GLOB.security_level = SEC_LEVEL_GREEN
- for(var/obj/machinery/firealarm/FA in GLOB.machines)
- if(is_station_level(FA.z))
- FA.update_icon()
- if(SEC_LEVEL_BLUE)
- if(GLOB.security_level < SEC_LEVEL_BLUE)
- minor_announce(CONFIG_GET(string/alert_blue_upto), "Attention! Security level elevated to blue:",1)
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- SSshuttle.emergency.modTimer(0.6)
- else
- minor_announce(CONFIG_GET(string/alert_blue_downto), "Attention! Security level lowered to blue:")
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- if(GLOB.security_level >= SEC_LEVEL_RED)
- SSshuttle.emergency.modTimer(2.4)
- else
- SSshuttle.emergency.modTimer(1.5)
- GLOB.security_level = SEC_LEVEL_BLUE
- sound_to_playing_players('sound/misc/voybluealert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
- for(var/obj/machinery/firealarm/FA in GLOB.machines)
- if(is_station_level(FA.z))
- FA.update_icon()
- if(SEC_LEVEL_AMBER)
- if(GLOB.security_level < SEC_LEVEL_AMBER)
- minor_announce(CONFIG_GET(string/alert_amber_upto), "Attention! Security level elevated to amber:",1)
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- if(GLOB.security_level == SEC_LEVEL_GREEN)
- SSshuttle.emergency.modTimer(0.4)
- else
- SSshuttle.emergency.modTimer(0.66)
- else
- minor_announce(CONFIG_GET(string/alert_amber_downto), "Attention! Security level lowered to amber:")
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- SSshuttle.emergency.modTimer(1.6)
- GLOB.security_level = SEC_LEVEL_AMBER
- sound_to_playing_players('sound/effects/alert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
- for(var/obj/machinery/firealarm/FA in GLOB.machines)
- if(is_station_level(FA.z))
- FA.update_icon()
- if(SEC_LEVEL_RED)
- if(GLOB.security_level < SEC_LEVEL_RED)
- minor_announce(CONFIG_GET(string/alert_red_upto), "Attention! Code red!",1)
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- if(GLOB.security_level == SEC_LEVEL_GREEN)
- SSshuttle.emergency.modTimer(0.25)
- else if(GLOB.security_level == SEC_LEVEL_BLUE)
- SSshuttle.emergency.modTimer(0.416)
- else
- SSshuttle.emergency.modTimer(0.625)
- else
- minor_announce(CONFIG_GET(string/alert_red_downto), "Attention! Code red!")
- GLOB.security_level = SEC_LEVEL_RED
- sound_to_playing_players('sound/misc/voyalert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
-
- for(var/obj/machinery/firealarm/FA in GLOB.machines)
- if(is_station_level(FA.z))
- FA.update_icon()
- for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines)
- pod.admin_controlled = FALSE
- if(SEC_LEVEL_DELTA)
- minor_announce(CONFIG_GET(string/alert_delta), "Attention! Delta security level reached!",1)
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- if(GLOB.security_level < SEC_LEVEL_BLUE)
- SSshuttle.emergency.modTimer(0.25)
- else if(GLOB.security_level == SEC_LEVEL_BLUE)
- SSshuttle.emergency.modTimer(0.416)
- else
- SSshuttle.emergency.modTimer(0.625)
- GLOB.security_level = SEC_LEVEL_DELTA
- sound_to_playing_players('sound/misc/deltakalaxon.ogg') // Citadel change - Makes alerts play a sound
- for(var/obj/machinery/firealarm/FA in GLOB.machines)
- if(is_station_level(FA.z))
- FA.update_icon()
- for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines)
- pod.admin_controlled = FALSE
- if(level >= SEC_LEVEL_RED)
- for(var/obj/machinery/door/D in GLOB.machines)
- if(D.red_alert_access)
- D.visible_message("[D] whirrs as it automatically lifts access requirements!")
- playsound(D, 'sound/machines/boltsup.ogg', 50, TRUE)
- SSblackbox.record_feedback("tally", "security_level_changes", 1, NUM2SECLEVEL(GLOB.security_level))
- SSnightshift.check_nightshift()
- else
- return
+ SSsecurity_level.set_level(level)
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index d4e6f3e050..d87e34f4a7 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -538,6 +538,10 @@
density = FALSE
clockwork = TRUE //it'd look weird
+/obj/machinery/computer/shuttle/pod/Initialize(mapload)
+ . = ..()
+ RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, .proc/check_lock)
+
/obj/machinery/computer/shuttle/pod/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_blocker)
@@ -555,6 +559,21 @@
if(possible_destinations == initial(possible_destinations) || override)
possible_destinations = "pod_lavaland[idnum]"
+/**
+ * Signal handler for checking if we should lock or unlock escape pods accordingly to a newly set security level
+ *
+ * Arguments:
+ * * source The datum source of the signal
+ * * new_level The new security level that is in effect
+ */
+/obj/machinery/computer/shuttle/pod/proc/check_lock(datum/source, new_level)
+ SIGNAL_HANDLER
+
+ if(obj_flags & EMAGGED)
+ return
+
+ admin_controlled = !(new_level < SEC_LEVEL_RED)
+
/obj/docking_port/stationary/random
name = "escape pod"
id = "pod"
diff --git a/tgstation.dme b/tgstation.dme
index 6878f256e2..67c3f21514 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -401,6 +401,7 @@
#include "code\controllers\subsystem\radio.dm"
#include "code\controllers\subsystem\research.dm"
#include "code\controllers\subsystem\runechat.dm"
+#include "code\controllers\subsystem\security_level.dm"
#include "code\controllers\subsystem\server_maint.dm"
#include "code\controllers\subsystem\shuttle.dm"
#include "code\controllers\subsystem\sound_loops.dm"