From cf3be5cb15d59ff2bd678e64a6b031858ef7f8c9 Mon Sep 17 00:00:00 2001 From: adamsong Date: Mon, 26 Feb 2024 20:13:25 -0500 Subject: [PATCH] Security level datums (#21051) * Initial conversion * Fixed cryopods * It compiles, yay * Removes cowbot's bad variables * Small fixes * Tweaked epsilon * Fix build * Switches to using defines * Nuke old file, fix typo * Add proper comment to epsilon --- code/__DEFINES/shuttles.dm | 20 +-- code/__DEFINES/subsystems.dm | 1 + code/__HELPERS/priority_announce.dm | 6 +- code/controllers/subsystem/nightshift.dm | 2 +- code/controllers/subsystem/security_level.dm | 94 ++++++++++ code/controllers/subsystem/shuttle.dm | 4 +- code/controllers/subsystem/ticker.dm | 9 - code/datums/world_topic.dm | 2 +- code/game/gamemodes/cult/cult.dm | 2 +- code/game/gamemodes/dynamic/dynamic.dm | 4 +- code/game/gamemodes/game_mode.dm | 4 +- .../game/machinery/computer/communications.dm | 8 +- code/game/machinery/cryopod.dm | 13 +- code/game/machinery/defibrillator_mount.dm | 4 +- code/game/machinery/doors/door.dm | 13 +- code/game/machinery/firealarm.dm | 12 +- code/game/mecha/mech_fabricator.dm | 4 +- code/game/objects/structures/displaycase.dm | 2 +- code/modules/admin/verbs/randomverbs.dm | 2 +- code/modules/antagonists/blob/overmind.dm | 2 +- .../ark_of_the_clockwork_justiciar.dm | 4 +- .../clock_structures/heralds_beacon.dm | 2 +- code/modules/antagonists/cult/cult_items.dm | 2 +- .../eldritch_cult/eldritch_transmutations.dm | 2 +- .../transmutations/cosmo_transmutations.dm | 2 +- .../transmutations/flesh_transmutations.dm | 2 +- .../nukeop/equipment/nuclear_challenge.dm | 2 +- .../nukeop/equipment/nuclearbomb.dm | 12 +- .../traitor/equipment/Malf_Modules.dm | 2 +- code/modules/events/_event.dm | 4 +- code/modules/events/prison_break.dm | 4 +- code/modules/holodeck/computer.dm | 2 +- code/modules/mob/living/silicon/ai/death.dm | 2 +- code/modules/power/singularity/narsie.dm | 4 +- .../security_levels/keycard_authentication.dm | 4 +- .../security_levels/level_interface.dm | 20 ++- .../security_levels/security_level_datums.dm | 96 ++++++---- .../security_levels/security_levels.dm | 167 ------------------ code/modules/shuttle/emergency.dm | 22 ++- code/modules/shuttle/shuttle.dm | 14 ++ yogstation.dme | 2 +- .../gamemodes/battle_royale/battleroyale.dm | 8 +- .../code/game/gamemodes/gangs/dominator.dm | 4 +- yogstation/code/game/world.dm | 2 +- .../antagonists/darkspawn/darkspawn.dm | 2 +- .../code/modules/antagonists/gang/gang.dm | 2 +- .../special_shadowling_abilities.dm | 2 +- 47 files changed, 295 insertions(+), 304 deletions(-) create mode 100644 code/controllers/subsystem/security_level.dm delete mode 100644 code/modules/security_levels/security_levels.dm diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm index 307af49de783..5904f4276f60 100644 --- a/code/__DEFINES/shuttles.dm +++ b/code/__DEFINES/shuttles.dm @@ -63,6 +63,16 @@ #define ENGINE_COEFF_MAX 2 #define ENGINE_DEFAULT_MAXSPEED_ENGINES 5 + +// Alert level related +#define ALERT_COEFF_AUTOEVAC_NORMAL 2.5 +#define ALERT_COEFF_GREEN 2 +#define ALERT_COEFF_BLUE 1 +#define ALERT_COEFF_RED 0.5 +#define ALERT_COEFF_AUTOEVAC_CRITICAL 0.4 +#define ALERT_COEFF_EPSILON 1000 +#define ALERT_COEFF_DELTA 0.25 + //Docking error flags #define DOCKING_SUCCESS 0 #define DOCKING_BLOCKED (1<<0) @@ -115,13 +125,3 @@ ///Check for arena shuttle, if the bubblegum has died this round GLOBAL_VAR_INIT(bubblegum_dead, FALSE) - -// Alert level related for new thing im porting --- cowbot93 -#define ALERT_COEFF_AUTOEVAC_NORMAL 6 -#define ALERT_COEFF_GREEN 5 -#define ALERT_COEFF_BLUE 4 -#define ALERT_COEFF_RED 3 -#define ALERT_COEFF_AUTOEVAC_CRITICAL 2 -#define ALERT_COEFF_DELTA 1 -#define ALERT_COEFF_GAMMA 0 -#define ALERT_COEFF_EPSILON -1 diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 696563feadb6..27e9df227bf4 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -138,6 +138,7 @@ #define INIT_ORDER_SOUNDS 83 #define INIT_ORDER_INSTRUMENTS 82 #define INIT_ORDER_VIS 80 +#define INIT_ORDER_SECURITY_LEVEL 79 #define INIT_ORDER_MATERIALS 76 #define INIT_ORDER_RESEARCH 75 #define INIT_ORDER_STATION 74 diff --git a/code/__HELPERS/priority_announce.dm b/code/__HELPERS/priority_announce.dm index 3661d0c2ed8f..b6fd5669bb81 100644 --- a/code/__HELPERS/priority_announce.dm +++ b/code/__HELPERS/priority_announce.dm @@ -155,11 +155,13 @@ var/title var/message + if(selected_level.custom_title) + title = selected_level.custom_title if(current_level_number > previous_level_number) - title = "Attention! Security level elevated to [current_level_name]:" + title = title || "Attention! Security level elevated to [current_level_name]:" message = selected_level.elevating_to_announcement else - title = "Attention! Security level lowered to [current_level_name]:" + title = title || "Attention! Security level lowered to [current_level_name]:" message = selected_level.lowering_to_announcement var/list/level_announcement_strings = list() diff --git a/code/controllers/subsystem/nightshift.dm b/code/controllers/subsystem/nightshift.dm index 3876b3e36c5a..2229dd345938 100644 --- a/code/controllers/subsystem/nightshift.dm +++ b/code/controllers/subsystem/nightshift.dm @@ -24,7 +24,7 @@ SUBSYSTEM_DEF(nightshift) priority_announce(message, sound='sound/misc/notice2.ogg', sender_override="Automated Lighting System Announcement") /datum/controller/subsystem/nightshift/proc/check_nightshift() - var/emergency = GLOB.security_level >= SEC_LEVEL_RED + var/emergency = SSsecurity_level.current_security_level.disable_night_mode var/announcing = TRUE var/time = station_time() var/night_time = (time < nightshift_end_time) || (time > nightshift_start_time) diff --git a/code/controllers/subsystem/security_level.dm b/code/controllers/subsystem/security_level.dm new file mode 100644 index 000000000000..0ee31c3bd9d0 --- /dev/null +++ b/code/controllers/subsystem/security_level.dm @@ -0,0 +1,94 @@ +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 + /// Currently set security level + var/datum/security_level/current_security_level + /// A list of initialised security level datums. + var/list/available_levels = list() + +/datum/controller/subsystem/security_level/Initialize() + for(var/iterating_security_level_type in subtypesof(/datum/security_level)) + var/datum/security_level/new_security_level = new iterating_security_level_type + available_levels[new_security_level.name] = new_security_level + current_security_level = available_levels[number_level_to_text(SEC_LEVEL_GREEN)] + return SS_INIT_SUCCESS + +/datum/controller/subsystem/security_level/fire(resumed) + if(!current_security_level.looping_sound) // No sound? No play. + can_fire = FALSE + return + sound_to_playing_players(current_security_level.looping_sound) + + +/** + * 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) + new_level = istext(new_level) ? new_level : number_level_to_text(new_level) + if(new_level == current_security_level.name) // If we are already at the desired level, do nothing + return + + var/datum/security_level/selected_level = available_levels[new_level] + + if(!selected_level) + CRASH("set_level was called with an invalid security level([new_level])") + + if(SSnightshift.can_fire && (selected_level.disable_night_mode || current_security_level.disable_night_mode)) + SSnightshift.next_fire = world.time + 7 SECONDS // Fire nightshift after the security level announcement is complete + + level_announce(selected_level, current_security_level.number_level) // We want to announce BEFORE updating to the new level + + selected_level.on_activate(current_security_level) + SSsecurity_level.current_security_level = selected_level + + if(selected_level.looping_sound) + wait = selected_level.looping_sound_interval + can_fire = TRUE + else + can_fire = FALSE + + if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) // By god this is absolutely shit + SSshuttle.emergency.alert_coeff_change(selected_level.shuttle_call_time_mod) + + SEND_SIGNAL(src, COMSIG_SECURITY_LEVEL_CHANGED, selected_level) + SSblackbox.record_feedback("tally", "security_level_changes", 1, selected_level.name) + +/** + * Returns the current security level as a number + */ +/datum/controller/subsystem/security_level/proc/get_current_level_as_number() + return ((!initialized || !current_security_level) ? SEC_LEVEL_GREEN : current_security_level.number_level) //Send the default security level in case the subsystem hasn't finished initializing yet + +/** + * Returns the current security level as text + */ +/datum/controller/subsystem/security_level/proc/get_current_level_as_text() + return ((!initialized || !current_security_level) ? "green" : current_security_level.name) + +/** + * Converts a text security level to a number + * + * Arguments: + * * level - The text security level to convert + */ +/datum/controller/subsystem/security_level/proc/text_level_to_number(text_level) + var/datum/security_level/selected_level = available_levels[text_level] + return selected_level?.number_level + +/** + * Converts a number security level to a text + * + * Arguments: + * * level - The number security level to convert + */ +/datum/controller/subsystem/security_level/proc/number_level_to_text(number_level) + for(var/iterating_level_text in available_levels) + var/datum/security_level/iterating_security_level = available_levels[iterating_level_text] + if(iterating_security_level.number_level == number_level) + return iterating_security_level.name diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 156b929bae0b..9395509e69f9 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -334,7 +334,7 @@ SUBSYSTEM_DEF(shuttle) call_reason = trim(html_encode(call_reason)) - if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH && seclevel2num(get_security_level()) > SEC_LEVEL_GREEN) + if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH && SSsecurity_level.current_security_level.require_call_reason) to_chat(user, "You must provide a reason.") return @@ -396,7 +396,7 @@ SUBSYSTEM_DEF(shuttle) /datum/controller/subsystem/shuttle/proc/canRecall() if(!emergency || emergency.mode != SHUTTLE_CALL || admin_emergency_no_recall || emergency_no_recall) return - var/security_num = seclevel2num(get_security_level()) + var/security_num = SSsecurity_level.get_current_level_as_number() switch(security_num) if(SEC_LEVEL_GREEN) if(emergency.timeLeft(1) < emergency_call_time) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 301f1a683d9d..63fb9a648b5a 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -145,15 +145,6 @@ SUBSYSTEM_DEF(ticker) return SS_INIT_SUCCESS /datum/controller/subsystem/ticker/fire() - if(seclevel2num(get_security_level()) < SEC_LEVEL_GAMMA && !GLOB.cryopods_enabled) - GLOB.cryopods_enabled = TRUE - for(var/obj/machinery/cryopod/pod as anything in GLOB.cryopods) - pod.PowerOn() - else if(seclevel2num(get_security_level()) >= SEC_LEVEL_GAMMA && GLOB.cryopods_enabled) - GLOB.cryopods_enabled = FALSE - for(var/obj/machinery/cryopod/pod as anything in GLOB.cryopods) - pod.PowerOff() - switch(current_state) if(GAME_STATE_STARTUP) if(Master.initializations_finished_with_no_players_logged_in) diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm index 8be8d4b4b4ef..943cc4155e83 100644 --- a/code/datums/world_topic.dm +++ b/code/datums/world_topic.dm @@ -241,7 +241,7 @@ .["real_mode"] = SSticker.mode.name // Key-authed callers may know the truth behind the "secret" - .["security_level"] = get_security_level() + .["security_level"] = SSsecurity_level.get_current_level_as_number() .["round_duration"] = SSticker ? round((world.time-SSticker.round_start_time)/10) : 0 // Amount of world's ticks in seconds, useful for calculating round duration diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 645d1708fd3d..45bd4f1c07d8 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -178,7 +178,7 @@ priority_announce("Figments of an eldritch god are being pulled through the veil anomaly in [bloodstone_areas[1]], [bloodstone_areas[2]], [bloodstone_areas[3]], and [bloodstone_areas[4]]! Destroy any occult structures located in those areas!","Central Command Higher Dimensional Affairs") addtimer(CALLBACK(src, PROC_REF(increase_bloodstone_power)), 30 SECONDS) - set_security_level(SEC_LEVEL_GAMMA) + SSsecurity_level.set_level(SEC_LEVEL_GAMMA) /datum/game_mode/proc/increase_bloodstone_power() if(!bloodstone_list.len) //check if we somehow ran out of bloodstones diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 8acf271cf892..2672ed2d68a1 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -305,8 +305,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if(CONFIG_GET(flag/auto_blue_alert)) print_command_report(., "Central Command Status Summary", announce=FALSE) priority_announce(desc, title, ANNOUNCER_INTERCEPT) - if(GLOB.security_level < SEC_LEVEL_BLUE) - set_security_level(SEC_LEVEL_BLUE) + if(SSsecurity_level.get_current_level_as_number() < SEC_LEVEL_BLUE) + SSsecurity_level.set_level(SEC_LEVEL_BLUE) else print_command_report(., "Central Command Status Summary") diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index f194b119758a..c3ff23b9892a 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -313,8 +313,8 @@ if(CONFIG_GET(flag/auto_blue_alert)) print_command_report(intercepttext, "Central Command Status Summary", announce=FALSE) priority_announce("A summary has been copied and printed to all communications consoles.\n\n[generate_station_trait_announcement()]", "Enemy communication intercepted. Security level elevated.", ANNOUNCER_INTERCEPT) - if(GLOB.security_level < SEC_LEVEL_BLUE) - set_security_level(SEC_LEVEL_BLUE) + if(SSsecurity_level.get_current_level_as_number() < SEC_LEVEL_BLUE) + SSsecurity_level.set_level(SEC_LEVEL_BLUE) else print_command_report(intercepttext, "Central Command Status Summary") diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 967cb02b766c..3f51a3074af0 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -155,13 +155,13 @@ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) return - var/new_sec_level = seclevel2num(params["newSecurityLevel"]) + var/new_sec_level = SSsecurity_level.text_level_to_number(params["newSecurityLevel"]) if (new_sec_level != SEC_LEVEL_GREEN && new_sec_level != SEC_LEVEL_BLUE) return - if (GLOB.security_level == new_sec_level) + if (SSsecurity_level.get_current_level_as_number() == new_sec_level) return - set_security_level(new_sec_level) + SSsecurity_level.set_level(new_sec_level) to_chat(usr, span_notice("Authorization confirmed. Modifying security level.")) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) @@ -410,7 +410,7 @@ data["aprilFools"] = check_holidays(APRIL_FOOLS) data["canPrintIdAndCode"] = FALSE - data["alertLevel"] = get_security_level() + data["alertLevel"] = SSsecurity_level.get_current_level_as_text() data["authorizeName"] = authorize_name data["canLogOut"] = !issilicon(user) data["shuttleCanEvacOrFailReason"] = SSshuttle.canEvac(user) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 996a0decb188..fbf082fbef07 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -134,8 +134,6 @@ GLOBAL_LIST_EMPTY(cryopod_computers) updateUsrDialog() return -GLOBAL_VAR_INIT(cryopods_enabled, FALSE) - //Cryopods themselves. /obj/machinery/cryopod name = "cryogenic freezer" @@ -168,6 +166,7 @@ GLOBAL_VAR_INIT(cryopods_enabled, FALSE) /obj/machinery/cryopod/Initialize(mapload) ..() GLOB.cryopods += src + RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, PROC_REF(update_security_level)) return INITIALIZE_HINT_LATELOAD //Gotta populate the cryopod computer GLOB first /obj/machinery/cryopod/Destroy() @@ -178,6 +177,12 @@ GLOBAL_VAR_INIT(cryopods_enabled, FALSE) update_appearance(UPDATE_ICON) find_control_computer() +/obj/machinery/cryopod/proc/update_security_level(_, datum/security_level/new_level) + if(new_level.allow_cryo) + PowerOn() + else + PowerOff() + /obj/machinery/cryopod/proc/PowerOn() if(!occupant) open_machine() @@ -232,7 +237,7 @@ GLOBAL_VAR_INIT(cryopods_enabled, FALSE) /obj/machinery/cryopod/open_machine() ..() - icon_state = GLOB.cryopods_enabled ? "cryopod-open" : "cryopod-off" + icon_state = SSsecurity_level.current_security_level.allow_cryo ? "cryopod-open" : "cryopod-off" if(open_sound) playsound(src, open_sound, 40) density = TRUE @@ -378,7 +383,7 @@ GLOBAL_VAR_INIT(cryopods_enabled, FALSE) if(!istype(target) || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || !ismob(target) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled) return - if(!GLOB.cryopods_enabled) + if(SSsecurity_level.current_security_level.allow_cryo) to_chat(user, span_boldnotice("Nanotrasen does not allow abandoning your crew during a crisis. Cryo systems disabled until the current crisis is resolved.")) return diff --git a/code/game/machinery/defibrillator_mount.dm b/code/game/machinery/defibrillator_mount.dm index 63a7a47cf142..079a930be5f2 100644 --- a/code/game/machinery/defibrillator_mount.dm +++ b/code/game/machinery/defibrillator_mount.dm @@ -27,7 +27,7 @@ . = ..() if(defib) . += "There is a defib unit hooked up. Alt-click to remove it." - if(GLOB.security_level >= SEC_LEVEL_RED) + if(SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED) . += span_notice("Due to a security situation, its locking clamps can be toggled by swiping any ID.") else . += span_notice("Its locking clamps can be [clamps_locked ? "dis" : ""]engaged by swiping an ID with access.") @@ -83,7 +83,7 @@ return var/obj/item/card/id = I.GetID() if(id) - if(check_access(id) || GLOB.security_level >= SEC_LEVEL_RED) //anyone can toggle the clamps in red alert! + if(check_access(id) || SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED) //anyone can toggle the clamps in red alert! if(!defib) to_chat(user, span_warning("You can't engage the clamps on a defibrillator that isn't there.")) return diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index c1bc607cfe89..2b809496424b 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -63,10 +63,10 @@ /obj/machinery/door/examine(mob/user) . = ..() if(red_alert_access) - if(GLOB.security_level >= SEC_LEVEL_RED) + if(SSsecurity_level.current_security_level.emergency_doors) . += span_notice("Due to a security threat, its access requirements have been lifted!") else - . += span_notice("In the event of a red alert, its access requirements will automatically lift.") + . += span_notice("In the event of an emegerency alert, its access requirements will automatically lift.") if(!poddoor) . += span_notice("Its maintenance panel is screwed in place.") if(!isdead(user)) @@ -76,7 +76,7 @@ . += span_notice("It leads into [areaName].") /obj/machinery/door/check_access_list(list/access_list) - if(red_alert_access && GLOB.security_level >= SEC_LEVEL_RED) + if(red_alert_access && SSsecurity_level.current_security_level.emergency_doors) return TRUE return ..() @@ -97,6 +97,13 @@ COMSIG_ATOM_MAGICALLY_UNLOCKED = PROC_REF(on_magic_unlock), ) AddElement(/datum/element/connect_loc, loc_connections) + if(red_alert_access) + RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, PROC_REF(update_security_level)) + +/obj/machinery/door/proc/update_security_level(_, datum/security_level/new_level) + if(red_alert_access && new_level.emergency_doors) + visible_message(span_notice("[src] whirrs as it automatically lifts access requirements!")) + playsound(src, 'sound/machines/boltsup.ogg', 50, TRUE) /obj/machinery/door/proc/set_init_door_layer() if(density) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index d946d60f8ffc..7104e96300e2 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -66,6 +66,8 @@ radio.recalculateChannels() STOP_PROCESSING(SSmachines, src) // I will do this + RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, PROC_REF(update_security_level)) + /obj/machinery/firealarm/Destroy() myarea.firereset(src, TRUE) QDEL_NULL(radio) @@ -82,15 +84,19 @@ return icon_state = "fire0" +/obj/machinery/firealarm/proc/update_security_level() + if(is_station_level(z)) + update_appearance(UPDATE_OVERLAYS) + /obj/machinery/firealarm/update_overlays() . = ..() if(stat & (NOPOWER|BROKEN)) return if(is_station_level(z)) - var/current_level = GLOB.security_level - . += mutable_appearance(icon, "fire_[GLOB.security_level]") - . += emissive_appearance(icon, "fire_[GLOB.security_level]", src) + var/current_level = SSsecurity_level.get_current_level_as_number() + . += mutable_appearance(icon, "fire_[current_level]") + . += emissive_appearance(icon, "fire_[current_level]", src) switch(current_level) if(SEC_LEVEL_GREEN) set_light(l_color = LIGHT_COLOR_BLUEGREEN) diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 10c16ae29f95..d0b15b6428eb 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -609,7 +609,7 @@ data["isProcessingQueue"] = process_queue data["authorization"] = authorization_override data["user_clearance"] = head_or_silicon(user) - data["alert_level"] = GLOB.security_level + data["alert_level"] = SSsecurity_level.get_current_level_as_number() data["combat_parts_allowed"] = combat_parts_allowed(user) data["emagged"] = (obj_flags & EMAGGED) data["silicon_user"] = issilicon(user) @@ -618,7 +618,7 @@ /// Updates the various authorization checks used to determine if combat parts are available to the current user /obj/machinery/mecha_part_fabricator/proc/combat_parts_allowed(mob/user) - return authorization_override || GLOB.security_level >= SEC_LEVEL_RED || head_or_silicon(user) + return authorization_override || SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED || head_or_silicon(user) /// made as a lazy check to allow silicons full access always /obj/machinery/mecha_part_fabricator/proc/head_or_silicon(mob/user) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 97c4a5f2cb50..0f1be99c0bed 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -238,7 +238,7 @@ /obj/structure/displaycase/captain/attackby(obj/item/W, mob/user, params) // Unless shit has really hit the fan. if(!istype(W, /obj/item/card/id)) return ..() - if(seclevel2num(get_security_level()) >= SEC_LEVEL_GAMMA) // Everything higher than red. + if(SSsecurity_level.get_current_level_as_number()>= SEC_LEVEL_GAMMA) // Everything higher than red. req_access = list(ACCESS_CAPTAIN) else to_chat(user, span_warning("The display case's access locks can only be lifted above red alert!")) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 9dde10f43dd8..ecd8c29535d1 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -888,7 +888,7 @@ Traitors and the like can also be revived with the previous role mostly intact. var/level = input("Select security level to change to","Set Security Level") as null|anything in list("green","blue","red","gamma","epsilon","delta") if(level) - set_security_level(level) + SSsecurity_level.set_level(level) log_admin("[key_name(usr)] changed the security level to [level]") message_admins("[key_name_admin(usr)] changed the security level to [level]") diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index 3c79ce8c687e..983d5f684fdd 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -115,7 +115,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) else if(!victory_in_progress && (blobs_legit.len >= blobwincount)) victory_in_progress = TRUE priority_announce("Biohazard has reached critical mass. Station loss is imminent.", "Biohazard Alert") - set_security_level("delta") + SSsecurity_level.set_level(SEC_LEVEL_DELTA) max_blob_points = INFINITY blob_points = INFINITY blob_core.max_integrity = 999999 diff --git a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justiciar.dm b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justiciar.dm index cca95290a006..e75bf4a8be56 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justiciar.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justiciar.dm @@ -94,7 +94,7 @@ @!$, [text2ratvar("PURGE ALL UNTRUTHS")] <&. the anomalies and destroy their source to prevent further damage to corporate property. This is \ not a drill.[grace_period ? " Estimated time of appearance: [grace_period] seconds. Use this time to prepare for an attack on [station_name()]." : ""]", \ "Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ark_activation.ogg') - set_security_level(SEC_LEVEL_GAMMA) + SSsecurity_level.set_level(SEC_LEVEL_GAMMA) for(var/V in SSticker.mode.servants_of_ratvar) var/datum/mind/M = V if(!M || !M.current) @@ -335,7 +335,7 @@ glow.icon_state = "clockwork_gateway_closing" if(GATEWAY_RATVAR_ARRIVAL to INFINITY) if(!purpose_fulfilled) - set_security_level(SEC_LEVEL_DELTA) + SSsecurity_level.set_level(SEC_LEVEL_DELTA) countdown.stop() resistance_flags |= INDESTRUCTIBLE purpose_fulfilled = TRUE diff --git a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm index aa74ab72091b..23a7dc2db2df 100644 --- a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm +++ b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm @@ -97,7 +97,7 @@ /obj/structure/destructible/clockwork/heralds_beacon/proc/herald_the_justiciar() priority_announce("A powerful group of fanatical zealots following the cause of Ratvar have brazenly sacrificed stealth for power, and dare anyone \ to try and stop them.", title = "The Justiciar Comes", sound = 'sound/magic/clockwork/ark_activation.ogg') - set_security_level(SEC_LEVEL_GAMMA) + SSsecurity_level.set_level(SEC_LEVEL_GAMMA) GLOB.ratvar_approaches = TRUE available = FALSE STOP_PROCESSING(SSprocessing, src) diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 4d5fefa3d622..b7be551685ad 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -534,7 +534,7 @@ GLOBAL_VAR_INIT(curselimit, 0) if(SSshuttle.emergency.mode == SHUTTLE_CALL) var/cursetime = 1800 var/timer = SSshuttle.emergency.timeLeft(1) + cursetime - var/security_num = seclevel2num(get_security_level()) + var/security_num = SSsecurity_level.get_current_level_as_number() var/set_coefficient = 1 switch(security_num) if(SEC_LEVEL_GREEN) diff --git a/code/modules/antagonists/eldritch_cult/eldritch_transmutations.dm b/code/modules/antagonists/eldritch_cult/eldritch_transmutations.dm index 90bbe651339e..4fdfca5b5a59 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_transmutations.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_transmutations.dm @@ -141,7 +141,7 @@ /datum/eldritch_transmutation/final/on_finished_recipe(mob/living/user, list/atoms, loc) var/atom/movable/gravity_lens/shockwave = new(get_turf(user)) - set_security_level(SEC_LEVEL_GAMMA) + SSsecurity_level.set_level(SEC_LEVEL_GAMMA) shockwave.transform = matrix().Scale(0.5) shockwave.pixel_x = -240 diff --git a/code/modules/antagonists/eldritch_cult/transmutations/cosmo_transmutations.dm b/code/modules/antagonists/eldritch_cult/transmutations/cosmo_transmutations.dm index 59fdf9e67798..8fc9e3a599b8 100644 --- a/code/modules/antagonists/eldritch_cult/transmutations/cosmo_transmutations.dm +++ b/code/modules/antagonists/eldritch_cult/transmutations/cosmo_transmutations.dm @@ -52,7 +52,7 @@ qdel(spells) priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Fear the cosmos, for The Creator has ascended! Unmake all of reality! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", ANNOUNCER_SPANOMALIES) var/atom/movable/gravity_lens/shockwave = new(get_turf(user)) - set_security_level(SEC_LEVEL_GAMMA) + SSsecurity_level.set_level(SEC_LEVEL_GAMMA) shockwave.transform = matrix().Scale(0.5) shockwave.pixel_x = -240 diff --git a/code/modules/antagonists/eldritch_cult/transmutations/flesh_transmutations.dm b/code/modules/antagonists/eldritch_cult/transmutations/flesh_transmutations.dm index 404f5c6245a2..3258303ce55c 100644 --- a/code/modules/antagonists/eldritch_cult/transmutations/flesh_transmutations.dm +++ b/code/modules/antagonists/eldritch_cult/transmutations/flesh_transmutations.dm @@ -134,7 +134,7 @@ spells.Remove(user) qdel(spells) priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Fear the dark, for King of Arms has ascended! Our Lord of the Night has come! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", ANNOUNCER_SPANOMALIES) - set_security_level(SEC_LEVEL_GAMMA) + SSsecurity_level.set_level(SEC_LEVEL_GAMMA) var/atom/movable/gravity_lens/shockwave = new(get_turf(user)) shockwave.transform = matrix().Scale(0.5) diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm index fe42d23f5607..3dbe930042bc 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm @@ -51,7 +51,7 @@ GLOBAL_LIST_EMPTY(jam_on_wardec) return priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg', has_important_message = TRUE) - set_security_level(SEC_LEVEL_GAMMA) + SSsecurity_level.set_level(SEC_LEVEL_GAMMA) to_chat(user, "You've attracted the attention of powerful forces within the syndicate. A bonus bundle of telecrystals has been granted to your team. Great things await you if you complete the mission.") diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index 71f316318918..e0d48477184b 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -40,7 +40,7 @@ STOP_PROCESSING(SSobj, core) update_appearance(UPDATE_ICON) GLOB.poi_list |= src - previous_level = get_security_level() + previous_level = SSsecurity_level.get_current_level_as_text() /obj/machinery/nuclearbomb/Destroy() safety = FALSE @@ -387,7 +387,7 @@ safety = !safety if(safety) if(timing) - set_security_level(previous_level) + SSsecurity_level.set_level(previous_level) for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list) S.switch_mode_to(initial(S.mode)) S.alert = FALSE @@ -402,15 +402,15 @@ return timing = !timing if(timing) - previous_level = get_security_level() + previous_level = SSsecurity_level.get_current_level_as_text() detonation_timer = world.time + (timer_set * 10) for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list) S.switch_mode_to(TRACK_INFILTRATOR) countdown.start() - set_security_level("delta") + SSsecurity_level.set_level(SEC_LEVEL_DELTA) else detonation_timer = null - set_security_level(previous_level) + SSsecurity_level.set_level(previous_level) for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list) S.switch_mode_to(initial(S.mode)) S.alert = FALSE @@ -544,7 +544,7 @@ detonation_timer = null exploding = FALSE exploded = TRUE - set_security_level(previous_level) + SSsecurity_level.set_level(previous_level) for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list) S.switch_mode_to(initial(S.mode)) S.alert = FALSE diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm index c820bc437c2a..51830e7e1c1c 100644 --- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm +++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm @@ -232,7 +232,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/AI_Module)) if(owner.stat == DEAD) return priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", ANNOUNCER_AIMALF) - set_security_level("delta") + SSsecurity_level.set_level(SEC_LEVEL_DELTA) var/obj/machinery/doomsday_device/DOOM = new(owner_AI) owner_AI.nuking = TRUE owner_AI.doomsday_device = DOOM diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index a4559db26221..5050212bd8ca 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -68,9 +68,9 @@ return FALSE if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) return FALSE - if(GLOB.security_level > max_alert) + if(SSsecurity_level.get_current_level_as_number() > max_alert) return FALSE - if(GLOB.security_level < min_alert) + if(SSsecurity_level.get_current_level_as_number() < min_alert) return FALSE var/datum/game_mode/dynamic/dynamic = SSticker.mode diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm index 28b1f2d0d176..7fef0dcf9ec2 100644 --- a/code/modules/events/prison_break.dm +++ b/code/modules/events/prison_break.dm @@ -90,8 +90,8 @@ continue if(!GLOB.emergency_access) make_maint_all_access() - else if(GLOB.security_level < SEC_LEVEL_RED) - set_security_level(SEC_LEVEL_RED) + else if(SSsecurity_level.get_current_level_as_number() < SEC_LEVEL_RED) + SSsecurity_level.set_level(SEC_LEVEL_RED) diff --git a/code/modules/holodeck/computer.dm b/code/modules/holodeck/computer.dm index fda9e32c3c5e..35b55d5f883f 100644 --- a/code/modules/holodeck/computer.dm +++ b/code/modules/holodeck/computer.dm @@ -239,7 +239,7 @@ if(!is_operational()) A = offline_program force = TRUE - if(A.minimum_sec_level > GLOB.security_level && !force && !(obj_flags & EMAGGED)) + if(A.minimum_sec_level > SSsecurity_level.get_current_level_as_number() && !force && !(obj_flags & EMAGGED)) say("ERROR. Program currently unavailiable, the security level is not high enough.") return if(program == A) diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index a646a92fb17e..9731948c38d0 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -47,7 +47,7 @@ /mob/living/silicon/ai/proc/ShutOffDoomsdayDevice() if(nuking) - set_security_level("red") + SSsecurity_level.set_level(SEC_LEVEL_RED) nuking = FALSE for(var/obj/item/pinpointer/nuke/P in GLOB.pinpointer_list) P.switch_mode_to(TRACK_NUKE_DISK) //Party's over, back to work, everyone diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index b328d36525a3..5d68f0301b9b 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -94,7 +94,7 @@ return priority_announce("Simulations on acausal dimensional event complete. Deploying solution package now. Deployment ETA: 30 SECONDS.","Central Command Higher Dimensional Affairs") sleep(5 SECONDS) - set_security_level("delta") + SSsecurity_level.set_level(SEC_LEVEL_DELTA) SSshuttle.registerHostileEnvironment(GLOB.cult_narsie) SSshuttle.lockdown = TRUE sleep(25 SECONDS) @@ -102,7 +102,7 @@ priority_announce("Nuclear detonation has been aborted due to termination of event. Please note that further damage to corporate property will not be tolerated.","Central Command Higher Dimensional Affairs", 'sound/misc/notice1.ogg') GLOB.cult_narsie = null sleep(2 SECONDS) - set_security_level("red") + SSsecurity_level.set_level(SEC_LEVEL_RED) SSshuttle.clearHostileEnvironment() SSshuttle.lockdown = FALSE INVOKE_ASYNC(GLOBAL_PROC, PROC_REF(cult_ending_helper), 2) diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index b48a1295fcfb..068add880c5e 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -44,7 +44,7 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) var/list/data = list() data["waiting"] = waiting data["auth_required"] = event_source ? event_source.event : 0 - data["red_alert"] = (seclevel2num(get_security_level()) >= SEC_LEVEL_RED) ? 1 : 0 + data["red_alert"] = (SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED) ? 1 : 0 data["emergency_maint"] = GLOB.emergency_access data["bsa_unlock"] = GLOB.bsa_unlock return data @@ -125,7 +125,7 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) deadchat_broadcast(" confirmed [event] at [span_name("[A2.name]")].", span_name("[confirmer]"), confirmer) switch(event) if(KEYCARD_RED_ALERT) - set_security_level(SEC_LEVEL_RED) + SSsecurity_level.set_level(SEC_LEVEL_RED) if(KEYCARD_EMERGENCY_MAINTENANCE_ACCESS) make_maint_all_access() if(KEYCARD_BSA_UNLOCK) diff --git a/code/modules/security_levels/level_interface.dm b/code/modules/security_levels/level_interface.dm index c840fa4400f0..01d22e0ef5e2 100644 --- a/code/modules/security_levels/level_interface.dm +++ b/code/modules/security_levels/level_interface.dm @@ -27,6 +27,10 @@ radio.listening = FALSE radio.independent = TRUE radio.recalculateChannels() + RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, PROC_REF(update_security_level)) + +/obj/machinery/level_interface/proc/update_security_level() + update_appearance(UPDATE_ICON) /obj/machinery/level_interface/update_icon(updates=ALL) . = ..() @@ -37,7 +41,7 @@ /obj/machinery/level_interface/update_overlays() . = ..() - switch(GLOB.security_level) + switch(SSsecurity_level.get_current_level_as_number()) if(SEC_LEVEL_GREEN) . += "alert-level-green" if(SEC_LEVEL_BLUE) @@ -61,7 +65,7 @@ /obj/machinery/level_interface/ui_data(mob/user) var/list/data = ..() - data["alertLevel"] = GLOB.security_level + data["alertLevel"] = SSsecurity_level.get_current_level_as_number() return data /obj/machinery/level_interface/ui_act(action, list/params, mob/user) @@ -79,7 +83,7 @@ switch(action) if("set_level") - if(GLOB.security_level >= SEC_LEVEL_GAMMA) + if(SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_GAMMA) balloon_alert(usr, "Nanotrasen override in progress!") return TRUE if(!check_access(usr.get_idcard())) @@ -88,9 +92,9 @@ var/alert_level = params["level_number"] if(!isnum(alert_level)) return TRUE - if(!num2seclevel(alert_level)) + if(!SSsecurity_level.number_level_to_text(alert_level)) return TRUE - if(GLOB.security_level == alert_level) + if(SSsecurity_level.get_current_level_as_number() == alert_level) return TRUE for(var/obj/machinery/computer/communications/comms_console in GLOB.machines) if(!COOLDOWN_FINISHED(comms_console, important_action_cooldown)) @@ -99,11 +103,11 @@ return TRUE COOLDOWN_START(comms_console, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN) break - set_security_level(num2seclevel(alert_level)) + SSsecurity_level.set_level(alert_level) var/username = "ERR_UNK" var/obj/item/card/id/id_card = usr.get_idcard() if(istype(id_card) && id_card && id_card.registered_name) username = id_card.registered_name - radio.talk_into(src, "Security level set to [uppertext(num2seclevel(alert_level))] by [username].", sec_freq) - radio.talk_into(src, "Security level set to [uppertext(num2seclevel(alert_level))] by [username].", command_freq) + radio.talk_into(src, "Security level set to [uppertext(SSsecurity_level.number_level_to_text(alert_level))] by [username].", sec_freq) + radio.talk_into(src, "Security level set to [uppertext(SSsecurity_level.number_level_to_text(alert_level))] by [username].", command_freq) return TRUE diff --git a/code/modules/security_levels/security_level_datums.dm b/code/modules/security_levels/security_level_datums.dm index 586e0b049df1..75c327d74249 100644 --- a/code/modules/security_levels/security_level_datums.dm +++ b/code/modules/security_levels/security_level_datums.dm @@ -29,6 +29,20 @@ var/lowering_to_configuration_key /// Our configuration key for elevating to text, if set, will override the default elevating to announcement. var/elevating_to_configuration_key + /// Custom title to use for announcement messages + var/custom_title + /// If the alert level should disable night mode + var/disable_night_mode = FALSE + /// If the emergency lights should be activiated + var/area_alarm = FALSE + /// If pods should be available for player launch + var/pod_access = FALSE + /// If red alert access doors should be unlocked + var/emergency_doors = FALSE + /// Are players allowed to cryo + var/allow_cryo = TRUE + /// Require providing a reason for a shuttle call at this alert level + var/require_call_reason = TRUE /datum/security_level/New() . = ..() @@ -37,6 +51,8 @@ if(elevating_to_configuration_key) elevating_to_announcement = global.config.Get(elevating_to_configuration_key) +/datum/security_level/proc/on_activate(previous_level) + /** * GREEN * @@ -49,6 +65,7 @@ number_level = SEC_LEVEL_GREEN lowering_to_configuration_key = /datum/config_entry/string/alert_green shuttle_call_time_mod = ALERT_COEFF_GREEN + require_call_reason = FALSE /** * BLUE @@ -77,6 +94,49 @@ lowering_to_configuration_key = /datum/config_entry/string/alert_red_downto elevating_to_configuration_key = /datum/config_entry/string/alert_red_upto shuttle_call_time_mod = ALERT_COEFF_RED + disable_night_mode = TRUE + pod_access = TRUE + emergency_doors = TRUE + +/** + * GAMMA + * + * Station is under severe threat, but not threat of immediate destruction + */ +/datum/security_level/gamma + name = "gamma" + announcement_color = "orange" + sound = 'sound/misc/gamma_alert.ogg' + number_level = SEC_LEVEL_GAMMA + elevating_to_configuration_key = /datum/config_entry/string/alert_gamma + lowering_to_configuration_key = /datum/config_entry/string/alert_gamma + shuttle_call_time_mod = ALERT_COEFF_DELTA + disable_night_mode = TRUE + pod_access = TRUE + emergency_doors = TRUE + allow_cryo = FALSE + +/** + * EPSILON + * + * Death squad alert + */ +/datum/security_level/epsilon + name = "epsilon" + announcement_color = "grey" + sound = 'sound/misc/epsilon_alert.ogg' + number_level = SEC_LEVEL_EPSILON + elevating_to_configuration_key = /datum/config_entry/string/alert_epsilon + lowering_to_configuration_key = /datum/config_entry/string/alert_epsilon + custom_title = "Epsilon Protocol Activated" + shuttle_call_time_mod = ALERT_COEFF_EPSILON + disable_night_mode = TRUE + pod_access = TRUE + emergency_doors = TRUE + allow_cryo = FALSE + +/datum/security_level/epsilon/on_activate(previous_level) + send_to_playing_players(span_notice("You get a bad feeling as you hear the Epsilon alert siren.")) /** * DELTA @@ -86,36 +146,12 @@ /datum/security_level/delta name = "delta" announcement_color = "purple" - sound = 'sound/misc/delta_alert.ogg' // Air alarm to signify importance + sound = 'sound/misc/delta_alert.ogg' number_level = SEC_LEVEL_DELTA elevating_to_configuration_key = /datum/config_entry/string/alert_delta shuttle_call_time_mod = ALERT_COEFF_DELTA - - -/** - * GAMMA - * - * Station is not having a very good fun time - */ -/datum/security_level/gamma - name = "gamma" - announcement_color = "orange" - sound = 'sound/misc/gamma_alert.ogg'// Air alarm to signify importance - number_level = SEC_LEVEL_GAMMA - elevating_to_configuration_key = /datum/config_entry/string/alert_gamma - shuttle_call_time_mod = ALERT_COEFF_GAMMA - - - -/** - * EPSILON - * - * Station destruction is here, and you probably caused it, you monster. - */ -/datum/security_level/epsilon - name = "epsilon" - announcement_color = "black" - sound = 'sound/misc/epsilon_alert.ogg'// Air alarm to signify importance - number_level = SEC_LEVEL_EPSILON - elevating_to_configuration_key = /datum/config_entry/string/alert_epsilon - shuttle_call_time_mod = ALERT_COEFF_EPSILON + disable_night_mode = TRUE + area_alarm = TRUE + pod_access = TRUE + emergency_doors = TRUE + allow_cryo = FALSE diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm deleted file mode 100644 index 5b98ecb20220..000000000000 --- a/code/modules/security_levels/security_levels.dm +++ /dev/null @@ -1,167 +0,0 @@ -GLOBAL_VAR_INIT(security_level, SEC_LEVEL_GREEN) -//SEC_LEVEL_GREEN = code green -//SEC_LEVEL_BLUE = code blue -//SEC_LEVEL_RED = code red -//SEC_LEVEL_GAMMA = code gamma -//SEC_LEVEL_EPSILON = code epsilon -//SEC_LEVEL_DELTA = code delta - -//config.alert_desc_blue_downto - -//set all area lights on station level to red if true, do otherwise if false -/proc/change_areas_lights_alarm(red=TRUE) - if(red) - for(var/area/A in GLOB.delta_areas) - A.set_fire_alarm_effect(TRUE) - else - for(var/area/A in GLOB.delta_areas) - A.unset_fire_alarm_effects(TRUE) - -/proc/set_security_level(level) - switch(level) - if("green") - level = SEC_LEVEL_GREEN - if("blue") - level = SEC_LEVEL_BLUE - if("red") - level = SEC_LEVEL_RED - if("gamma") - level = SEC_LEVEL_GAMMA - if("epsilon") - level = SEC_LEVEL_EPSILON - if("delta") - level = SEC_LEVEL_DELTA - - //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) - var/modTimer - switch(level) - if(SEC_LEVEL_GREEN) - minor_announce(CONFIG_GET(string/alert_green), "Attention! Security level lowered to green:") - sound_to_playing_players('sound/misc/notice2.ogg') - if(GLOB.security_level >= SEC_LEVEL_RED) - modTimer = 4 - else - modTimer = 2 - - 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:", TRUE) - sound_to_playing_players('sound/misc/notice1.ogg') - modTimer = 0.5 - else - minor_announce(CONFIG_GET(string/alert_blue_downto), "Attention! Security level lowered to blue:") - modTimer = 2 - - if(SEC_LEVEL_RED) - if(GLOB.security_level < SEC_LEVEL_RED) - minor_announce(CONFIG_GET(string/alert_red_upto), "Attention! Code red!", TRUE) - sound_to_playing_players('sound/misc/notice4.ogg') - if(GLOB.security_level == SEC_LEVEL_GREEN) - modTimer = 0.25 - else - modTimer = 0.5 - else - minor_announce(CONFIG_GET(string/alert_red_downto), "Attention! Code red!") - if(GLOB.security_level == SEC_LEVEL_GAMMA) - modTimer = 2 - - if(SEC_LEVEL_GAMMA) - minor_announce(CONFIG_GET(string/alert_gamma), "Attention! Gamma security level activated!", TRUE) - sound_to_playing_players('sound/misc/gamma_alert.ogg') - if(GLOB.security_level == SEC_LEVEL_GREEN) - modTimer = 0.25 - else if(GLOB.security_level == SEC_LEVEL_BLUE) - modTimer = 0.50 - else if(GLOB.security_level == SEC_LEVEL_RED) - modTimer = 0.75 - - if(SEC_LEVEL_EPSILON) - minor_announce(CONFIG_GET(string/alert_epsilon), "Attention! Epsilon security level reached!", TRUE) - sound_to_playing_players('sound/misc/epsilon_alert.ogg') - send_to_playing_players(span_notice("You get a bad feeling as you hear the Epsilon alert siren.")) - if(GLOB.security_level < SEC_LEVEL_EPSILON) - modTimer = 1 - - if(SEC_LEVEL_DELTA) - minor_announce(CONFIG_GET(string/alert_delta), "Attention! Delta security level reached!", TRUE) - sound_to_playing_players('sound/misc/delta_alert.ogg') - if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) - if(GLOB.security_level == SEC_LEVEL_GREEN) - modTimer = 0.25 - else if(GLOB.security_level == SEC_LEVEL_BLUE) - modTimer = 0.5 - - GLOB.security_level = level - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_level(FA.z)) - FA.update_appearance(UPDATE_ICON) - - for(var/obj/machinery/level_interface/LI in GLOB.machines) - LI.update_appearance(UPDATE_ICON) - - if(level >= SEC_LEVEL_RED) - for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines) - pod.admin_controlled = FALSE - for(var/obj/machinery/door/D in GLOB.machines) - if(D.red_alert_access) - D.visible_message(span_notice("[D] whirrs as it automatically lifts access requirements!")) - playsound(D, 'sound/machines/boltsup.ogg', 50, TRUE) - - if(level == SEC_LEVEL_DELTA) - change_areas_lights_alarm() - else - change_areas_lights_alarm(FALSE) - - if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) - SSshuttle.emergency.modTimer(modTimer) - - SSblackbox.record_feedback("tally", "security_level_changes", 1, get_security_level()) - SSnightshift.check_nightshift() - else - return - -/proc/get_security_level() - switch(GLOB.security_level) - if(SEC_LEVEL_GREEN) - return "green" - if(SEC_LEVEL_BLUE) - return "blue" - if(SEC_LEVEL_RED) - return "red" - if(SEC_LEVEL_GAMMA) - return "gamma" - if(SEC_LEVEL_EPSILON) - return "epsilon" - if(SEC_LEVEL_DELTA) - return "delta" - -/proc/num2seclevel(num) - switch(num) - if(SEC_LEVEL_GREEN) - return "green" - if(SEC_LEVEL_BLUE) - return "blue" - if(SEC_LEVEL_RED) - return "red" - if(SEC_LEVEL_GAMMA) - return "gamma" - if(SEC_LEVEL_EPSILON) - return "epsilon" - if(SEC_LEVEL_DELTA) - return "delta" - -/proc/seclevel2num(seclevel) - switch( lowertext(seclevel) ) - if("green") - return SEC_LEVEL_GREEN - if("blue") - return SEC_LEVEL_BLUE - if("red") - return SEC_LEVEL_RED - if("gamma") - return SEC_LEVEL_GAMMA - if("epsilon") - return SEC_LEVEL_EPSILON - if("delta") - return SEC_LEVEL_DELTA diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index fb1d3d34c1ed..ea0583694272 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -227,14 +227,9 @@ /obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, area/signalOrigin, reason, set_coefficient=null) if(!isnum(set_coefficient)) - var/security_num = seclevel2num(get_security_level()) - switch(security_num) - if(SEC_LEVEL_GREEN) - set_coefficient = 2 - if(SEC_LEVEL_BLUE) - set_coefficient = 1 - else - set_coefficient = 0.5 + set_coefficient = SSsecurity_level.current_security_level.shuttle_call_time_mod + alert_coeff = set_coefficient + var/call_time = SSshuttle.emergency_call_time * set_coefficient * engine_coeff switch(mode) // The shuttle can not normally be called while "recalling", so @@ -253,7 +248,7 @@ SSshuttle.emergency_last_call_loc = null var/emergency_reason = "\nNature of emergency:\n\n[reason]" - priority_announce("The emergency shuttle has been called. [GLOB.security_level >= SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[html_decode(emergency_reason)][SSshuttle.emergency_last_call_loc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, ANNOUNCER_SHUTTLECALLED, "Priority") + priority_announce("The emergency shuttle has been called. [SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[html_decode(emergency_reason)][SSshuttle.emergency_last_call_loc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, ANNOUNCER_SHUTTLECALLED, "Priority") /obj/docking_port/mobile/emergency/cancel(area/signalOrigin) if(mode != SHUTTLE_CALL) @@ -479,7 +474,7 @@ var/obj/machinery/computer/shuttle/C = get_control_console() if(!istype(C, /obj/machinery/computer/shuttle/pod)) return ..() - if(GLOB.security_level >= SEC_LEVEL_RED || (C && (C.obj_flags & EMAGGED))) + if(SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED || (C && (C.obj_flags & EMAGGED))) if(launch_status == UNLAUNCHED) launch_status = EARLY_LAUNCHED return ..() @@ -492,7 +487,7 @@ /obj/machinery/computer/shuttle/pod name = "pod control computer" - admin_controlled = 1 + admin_controlled = TRUE possible_destinations = "pod_asteroid" icon = 'icons/obj/terminals.dmi' icon_state = "dorm_available" @@ -504,6 +499,9 @@ AddElement(/datum/element/update_icon_blocker) return ..() +/obj/machinery/computer/shuttle/pod/proc/update_security_level(_, datum/security_level/new_level) + admin_controlled = !new_level.pod_access + /obj/machinery/computer/shuttle/pod/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) return FALSE @@ -628,7 +626,7 @@ /obj/item/storage/pod/can_interact(mob/user) if(!..()) return FALSE - if(GLOB.security_level >= SEC_LEVEL_RED || unlocked) + if(SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED || unlocked) return TRUE to_chat(user, "The storage unit will only unlock during a Red or Delta security alert.") diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index bdd487ee37a0..3449b6f3b6df 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -928,6 +928,20 @@ last_timer_length *= multiple setTimer(time_remaining) +/obj/docking_port/mobile/proc/alert_coeff_change(new_coeff) + if(isnull(new_coeff)) + return + + var/time_multiplier = new_coeff / alert_coeff + var/time_remaining = timer - world.time + if(time_remaining < 0 || !last_timer_length) + return + + time_remaining *= time_multiplier + last_timer_length *= time_multiplier + alert_coeff = new_coeff + setTimer(time_remaining) + /obj/docking_port/mobile/proc/invertTimer() if(!last_timer_length) return diff --git a/yogstation.dme b/yogstation.dme index b25df7431b73..16415a5552a0 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -448,6 +448,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\sounds.dm" @@ -3629,7 +3630,6 @@ #include "code\modules\security_levels\keycard_authentication.dm" #include "code\modules\security_levels\level_interface.dm" #include "code\modules\security_levels\security_level_datums.dm" -#include "code\modules\security_levels\security_levels.dm" #include "code\modules\shuttle\ai_ship.dm" #include "code\modules\shuttle\arrivals.dm" #include "code\modules\shuttle\assault_pod.dm" diff --git a/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm b/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm index 1810591c78ae..be5e3d95852c 100644 --- a/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm +++ b/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm @@ -152,13 +152,13 @@ GLOBAL_VAR(final_zone) /datum/game_mode/fortnite/proc/shrinkborders() switch(borderstage)//to keep it seperate and not fuck with weather selection if(1) - set_security_level("blue") + SSsecurity_level.set_level(SEC_LEVEL_BLUE) if(4) - set_security_level("red") + SSsecurity_level.set_level(SEC_LEVEL_RED) if(7) - set_security_level("gamma") + SSsecurity_level.set_level(SEC_LEVEL_GAMMA) if(9) - set_security_level("epsilon") + SSsecurity_level.set_level(SEC_LEVEL_EPSILON) var/datum/weather/royale/W switch(borderstage) diff --git a/yogstation/code/game/gamemodes/gangs/dominator.dm b/yogstation/code/game/gamemodes/gangs/dominator.dm index 6faa286dc4c5..bbfac90e9f6a 100644 --- a/yogstation/code/game/gamemodes/gangs/dominator.dm +++ b/yogstation/code/game/gamemodes/gangs/dominator.dm @@ -242,8 +242,8 @@ if(!was_stranded) priority_announce("All hostile activity within station systems has ceased.","Network Alert") - if(get_security_level() == "delta") - set_security_level("red") + if(SSsecurity_level.get_current_level_as_text() == SEC_LEVEL_DELTA) + SSsecurity_level.set_level(SEC_LEVEL_RED) gang.message_gangtools("Hostile takeover cancelled: Dominator is no longer operational.[gang.dom_attempts ? " You have [gang.dom_attempts] attempt remaining." : " The station network will have likely blocked any more attempts by us."]",1,1) diff --git a/yogstation/code/game/world.dm b/yogstation/code/game/world.dm index 19f4643c9869..97b75fd50d0a 100644 --- a/yogstation/code/game/world.dm +++ b/yogstation/code/game/world.dm @@ -42,7 +42,7 @@ GLOBAL_LIST_EMPTY(donators) if (server_name) s += "[server_name]\] — Dive in Now: Perfect for Beginners!" s += "
99% Lag-Free MRP Experience! Join the Adventure!" - s += "
Time: [gameTimestamp("hh:mm")] | Map: [SSmapping?.config?.map_name || "Unknown"] | Alert: [capitalize(get_security_level())]" + s += "
Time: [gameTimestamp("hh:mm")] | Map: [SSmapping?.config?.map_name || "Unknown"] | Alert: [capitalize(SSsecurity_level.get_current_level_as_text())]" s += "
\[Website" // link to our website so they can join forums + discord from here //As of October 27th, 2023 taglines.txt is no longer used in the status because we never had the characters to spare it, so it would put 2-3 random characters at the end and look bad. diff --git a/yogstation/code/modules/antagonists/darkspawn/darkspawn.dm b/yogstation/code/modules/antagonists/darkspawn/darkspawn.dm index cabb30efe47c..71929e7a87f6 100644 --- a/yogstation/code/modules/antagonists/darkspawn/darkspawn.dm +++ b/yogstation/code/modules/antagonists/darkspawn/darkspawn.dm @@ -354,7 +354,7 @@ /datum/antagonist/darkspawn/proc/sacrament() var/mob/living/carbon/human/user = owner.current if(!SSticker.mode.sacrament_done) - set_security_level(SEC_LEVEL_GAMMA) + SSsecurity_level.set_level(SEC_LEVEL_GAMMA) addtimer(CALLBACK(src, PROC_REF(sacrament_shuttle_call)), 50) for(var/V in abilities) remove_ability(abilities[V], TRUE) diff --git a/yogstation/code/modules/antagonists/gang/gang.dm b/yogstation/code/modules/antagonists/gang/gang.dm index 7aba5234418a..d125285519a8 100644 --- a/yogstation/code/modules/antagonists/gang/gang.dm +++ b/yogstation/code/modules/antagonists/gang/gang.dm @@ -514,7 +514,7 @@ /datum/team/gang/proc/domination() domination_time = world.time + determine_domination_time()*10 - set_security_level("delta") + SSsecurity_level.set_level(SEC_LEVEL_DELTA) /datum/team/gang/proc/determine_domination_time() // calculates the value in seconds (this is the initial domination time!) var/total_territories = total_claimable_territories() diff --git a/yogstation/code/modules/antagonists/shadowling/special_shadowling_abilities.dm b/yogstation/code/modules/antagonists/shadowling/special_shadowling_abilities.dm index e76c1369df92..191d4c687865 100644 --- a/yogstation/code/modules/antagonists/shadowling/special_shadowling_abilities.dm +++ b/yogstation/code/modules/antagonists/shadowling/special_shadowling_abilities.dm @@ -205,7 +205,7 @@ H.invisibility = 60 //This is pretty bad, but is also necessary for the shuttle call to function properly H.forceMove(A) if(!SSticker.mode.shadowling_ascended) - set_security_level(SEC_LEVEL_GAMMA) + SSsecurity_level.set_level(SEC_LEVEL_GAMMA) SSshuttle.emergency_call_time = 1800 SSshuttle.emergency.request(null, 0.3) SSshuttle.emergency_no_recall = TRUE