Skip to content

Commit

Permalink
Ports datumized security levels & converts to Subsytem (#11186)
Browse files Browse the repository at this point in the history
* security subystem

* security level datums

* fix sounds

* night lighting

* gupdate

* 515
  • Loading branch information
Tsar-Salat authored Aug 4, 2024
1 parent a6a7351 commit c132696
Show file tree
Hide file tree
Showing 35 changed files with 384 additions and 204 deletions.
3 changes: 2 additions & 1 deletion beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,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.dm"
Expand Down Expand Up @@ -3834,7 +3835,7 @@
#include "code\modules\security\prison_scanner.dm"
#include "code\modules\security\workshop.dm"
#include "code\modules\security_levels\keycard_authentication.dm"
#include "code\modules\security_levels\security_levels.dm"
#include "code\modules\security_levels\security_level_datums.dm"
#include "code\modules\shuttle\arrivals.dm"
#include "code\modules\shuttle\assault_pod.dm"
#include "code\modules\shuttle\custom_shuttle.dm"
Expand Down
3 changes: 3 additions & 0 deletions code/__DEFINES/dcs/signals/signals_datum/signals_datum.dm
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@
///From base of datum/controller/subsystem/Initialize
#define COMSIG_SUBSYSTEM_POST_INITIALIZE "subsystem_post_initialize"

///from SSsecurity_level when the security level changes : (new_level)
#define COMSIG_SECURITY_LEVEL_CHANGED "security_level_changed"

/// a weather event of some kind occured
#define COMSIG_WEATHER_TELEGRAPH(event_type) "!weather_telegraph [event_type]"
#define COMSIG_WEATHER_START(event_type) "!weather_start [event_type]"
Expand Down
1 change: 0 additions & 1 deletion code/__DEFINES/dcs/signals/signals_global.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#define COMSIG_GLOB_MOB_DEATH "!mob_death" //! mob died somewhere : (mob , gibbed)
#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //! global living say plug - use sparingly: (mob/speaker , message)
#define COMSIG_GLOB_CARBON_THROW_THING "!throw_thing" //! a person somewhere has thrown something : (mob/living/carbon/carbon_thrower, target)
#define COMSIG_GLOB_SECURITY_ALERT_CHANGE "!alert_change" //! security level was changed : (new_alert)
#define COMSIG_GLOB_SOUND_PLAYED "!sound_played" //! a sound was played : (sound_player, sound_file)
/// called by datum/cinematic/play() : (datum/cinematic/new_cinematic)
#define COMSIG_GLOB_PLAY_CINEMATIC "!play_cinematic"
Expand Down
8 changes: 8 additions & 0 deletions code/__DEFINES/shuttles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@
#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_DELTA 0.25

//Docking error flags
#define DOCKING_SUCCESS 0
#define DOCKING_BLOCKED (1<<0)
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
#define INIT_ORDER_INSTRUMENTS 82
#define INIT_ORDER_GREYSCALE 81
#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_ORBITS 74 //Other things use the orbital map, so it needs to be made early on.
Expand Down
42 changes: 30 additions & 12 deletions code/__HELPERS/priority_announce.dm
Original file line number Diff line number Diff line change
Expand Up @@ -75,24 +75,42 @@

SScommunications.send_message(M)

/proc/minor_announce(message, title = "Attention:", alert, from, html_encode = TRUE)
/**
* Sends a minor annoucement to players.
* Minor announcements are large text, with the title in red and message in white.
* Only mobs that can hear can see the announcements.
*
* message - the message contents of the announcement.
* title - the title of the announcement, which is often "who sent it".
* alert - whether this announcement is an alert, or just a notice. Only changes the sound that is played by default.
* from - who sent the announcement, in the case of communications consoles or the like.
* html_encode - if TRUE, we will html encode our title and message before sending it, to prevent player input abuse.
* players - optional, a list mobs to send the announcement to. If unset, sends to all players.
* sound_override - optional, use the passed sound file instead of the default notice sounds.
*/
/proc/minor_announce(message, title = "Attention:", alert, from, html_encode = TRUE, list/players, sound_override)
if(!message)
return

if (html_encode)
title = html_encode(title)
message = html_encode(message)

for(var/mob/M in GLOB.player_list)
if(!isnewplayer(M) && M.can_hear())
var/complete_msg = "<meta charset='UTF-8'><span class='big bold'><font color = red>[title]</font color><BR>[message]</span><BR>"
if(from)
complete_msg += "<span class='alert'>-[from]</span>"
to_chat(M, complete_msg)
if(M.client.prefs.read_player_preference(/datum/preference/toggle/sound_announcements))
if(alert)
SEND_SOUND(M, sound('sound/misc/notice1.ogg'))
else
SEND_SOUND(M, sound('sound/misc/notice2.ogg'))
if(!players)
players = GLOB.player_list

for(var/mob/target in players)
if(isnewplayer(target))
continue
if(!target.can_hear())
continue

var/complete_msg = "<meta charset='UTF-8'><span class='big bold'><font color = red>[title]</font color><BR>[message]</span><BR>"
if(from)
complete_msg += "<span class='alert'>-[from]</span>"
to_chat(target, complete_msg)
if(target.client.prefs.read_player_preference(/datum/preference/toggle/sound_announcements))
var/sound_to_play = sound_override || (alert ? 'sound/misc/notice1.ogg' : 'sound/misc/notice2.ogg')
SEND_SOUND(target, sound(sound_to_play))

#undef DEFAULT_ALERT
2 changes: 1 addition & 1 deletion code/controllers/subsystem/nightshift.dm
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,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.get_current_level_as_number() >= SEC_LEVEL_RED
var/announcing = TRUE
var/time = station_time()
var/night_time = (time < nightshift_end_time) || (time > nightshift_start_time)
Expand Down
105 changes: 105 additions & 0 deletions code/controllers/subsystem/security_level.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
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.number_level >= SEC_LEVEL_RED || current_security_level.number_level >= SEC_LEVEL_RED))
SSnightshift.next_fire = world.time + 7 SECONDS // Fire nightshift after the security level announcement is complete

announce_security_level(selected_level) // We want to announce BEFORE updating to the new 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.number_level)
SSblackbox.record_feedback("tally", "security_level_changes", 1, selected_level.name)

/**
* Handles announcements of the newly set security level
*
* Arguments:
* * selected_level - The new security level that has been set
*/
/datum/controller/subsystem/security_level/proc/announce_security_level(datum/security_level/selected_level)
if(selected_level.number_level > current_security_level.number_level) // We are elevating to this level.
minor_announce(selected_level.elevating_to_announcemnt, "Attention! Security level elevated to [selected_level.name]:", sound_override = selected_level.sound)
else // Going down
minor_announce(selected_level.lowering_to_announcement, "Attention! Security level lowered to [selected_level.name]:", sound_override = selected_level.sound)

/**
* 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
12 changes: 6 additions & 6 deletions code/controllers/subsystem/shuttle.dm
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ SUBSYSTEM_DEF(shuttle)
log_game("[msg] Alive: [alive], Roundstart: [total], Threshold: [threshold]")
emergencyNoRecall = TRUE
priority_announce("Catastrophic casualties detected: crisis shuttle protocols activated - jamming recall signals across all frequencies.", sound = SSstation.announcer.get_rand_alert_sound())
if(emergency.timeLeft(1) > emergencyCallTime * 0.4)
emergency.request(null, set_coefficient = 0.4)
if(emergency.timeLeft(1) > emergencyCallTime * ALERT_COEFF_AUTOEVAC_CRITICAL)
emergency.request(null, set_coefficient = ALERT_COEFF_AUTOEVAC_CRITICAL)

/datum/controller/subsystem/shuttle/proc/block_recall(lockout_timer)
emergencyNoRecall = TRUE
Expand Down Expand Up @@ -207,13 +207,13 @@ 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.get_current_level_as_number() > SEC_LEVEL_GREEN)
to_chat(user, "<span class='alert'>You must provide a reason.</span>")
return

var/area/signal_origin = get_area(user)
var/emergency_reason = "\nNature of emergency:\n\n[call_reason]"
var/security_num = seclevel2num(get_security_level())
var/security_num = SSsecurity_level.get_current_level_as_number()
switch(security_num)
if(SEC_LEVEL_RED,SEC_LEVEL_DELTA)
emergency.request(null, signal_origin, html_decode(emergency_reason), 1) //There is a serious threat we gotta move no time to give them five minutes.
Expand Down Expand Up @@ -275,7 +275,7 @@ SUBSYSTEM_DEF(shuttle)
/datum/controller/subsystem/shuttle/proc/canRecall()
if(!emergency || emergency.mode != SHUTTLE_CALL || emergencyNoRecall || SSticker.mode.name == "meteor")
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) < emergencyCallTime)
Expand Down Expand Up @@ -313,7 +313,7 @@ SUBSYSTEM_DEF(shuttle)

if(callShuttle)
if(EMERGENCY_IDLE_OR_RECALLED)
emergency.request(null, set_coefficient = 2.5)
emergency.request(null, set_coefficient = ALERT_COEFF_AUTOEVAC_NORMAL)
log_game("There is no means of calling the shuttle anymore. Shuttle automatically called.")
message_admins("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.")

Expand Down
2 changes: 1 addition & 1 deletion code/datums/world_topic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@

data["map_name"] = SSmapping.config?.map_name || "Loading..."

data["security_level"] = get_security_level()
data["security_level"] = SSsecurity_level.get_current_level_as_text()
data["round_duration"] = SSticker?.round_start_timeofday ? round((world.timeofday - SSticker.round_start_timeofday)/10) : 0
// Amount of world's ticks in seconds, useful for calculating round duration

Expand Down
4 changes: 2 additions & 2 deletions code/game/gamemodes/dynamic/dynamic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)

print_command_report(., "Central Command Status Summary", announce=FALSE)
priority_announce("A summary has been copied and printed to all communications consoles.", "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)

// Yes, this is copy pasted from game_mode
/datum/game_mode/dynamic/check_finished(force_ending)
Expand Down
4 changes: 2 additions & 2 deletions code/game/gamemodes/game_mode.dm
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,8 @@

print_command_report(intercepttext, "Central Command Status Summary", announce=FALSE)
priority_announce("A summary has been copied and printed to all communications consoles.", "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)


/*
Expand Down
2 changes: 1 addition & 1 deletion code/game/gamemodes/gangs/dominator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@
priority_announce("All hostile activity within station systems has ceased.","Network Alert", SSstation.announcer.get_rand_alert_sound())

if(get_security_level() == "delta")
set_security_level("red")
SSsecurity_level.set_level(SEC_LEVEL_RED)

SSshuttle.clearHostileEnvironment(src)
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)
Expand Down
12 changes: 6 additions & 6 deletions code/game/machinery/computer/communications.dm
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,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 class='notice'>Authorization confirmed. Modifying security level.</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
Expand All @@ -156,7 +156,7 @@
make_announcement(usr)
. = TRUE
if ("messageAssociates")
if (!authenticated(usr) || issilicon(usr) || (GLOB.security_level < SEC_LEVEL_RED && !authenticated_as_non_silicon_captain(usr)))
if (!authenticated(usr) || issilicon(usr) || (SSsecurity_level.get_current_level_as_number() < SEC_LEVEL_RED && !authenticated_as_non_silicon_captain(usr)))
return
if (!COOLDOWN_FINISHED(src, important_action_cooldown))
return
Expand Down Expand Up @@ -351,7 +351,7 @@
//Main section is always visible when authenticated
data["canBuyShuttles"] = can_buy_shuttles(user)
data["canMakeAnnouncement"] = FALSE
data["canMessageAssociates"] = !issilicon(user) && GLOB.security_level >= SEC_LEVEL_RED
data["canMessageAssociates"] = !issilicon(user) && SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED
data["canRecallShuttles"] = !issilicon(user)
data["canRequestNuke"] = FALSE
data["canSendToSectors"] = FALSE
Expand All @@ -361,7 +361,7 @@
data["shuttleCalled"] = FALSE
data["shuttleLastCalled"] = 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)
Expand Down
4 changes: 2 additions & 2 deletions code/game/machinery/defibrillator_mount.dm
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount/loaded, 28)
. = ..()
if(defib)
. += "<span class='notice'>There is a defib unit hooked up. Alt-click to remove it.</span>"
if(GLOB.security_level >= SEC_LEVEL_RED)
if(SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED)
. += "<span class='notice'>Due to a security situation, its locking clamps can be toggled by swiping any ID.</span>"
else
. += "<span class='notice'>Its locking clamps can be [clamps_locked ? "dis" : ""]engaged by swiping an ID with access.</span>"
Expand Down Expand Up @@ -103,7 +103,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount/loaded, 28)
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 class='warning'>You can't engage the clamps on a defibrillator that isn't there.</span>")
return
Expand Down
Loading

0 comments on commit c132696

Please sign in to comment.