Files
Yogstation/code/game/machinery/computer/communications.dm
adamsong cf3be5cb15 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
2024-02-26 20:13:25 -05:00

637 lines
24 KiB
Plaintext
Executable File

#define IMPORTANT_ACTION_COOLDOWN (60 SECONDS)
#define MAX_STATUS_LINE_LENGTH 40
#define STATE_BUYING_SHUTTLE "buying_shuttle"
#define STATE_CHANGING_STATUS "changing_status"
#define STATE_MAIN "main"
#define STATE_MESSAGES "messages"
// The communications computer
/obj/machinery/computer/communications
name = "communications console"
desc = "A console used for high-priority announcements and emergencies."
icon_screen = "comm"
icon_keyboard = "tech_key"
req_access = list(ACCESS_HEADS)
circuit = /obj/item/circuitboard/computer/communications
light_color = LIGHT_COLOR_BLUE
/// Cooldown for important actions, such as messaging CentCom or other sectors
COOLDOWN_DECLARE(static/important_action_cooldown)
/// The current state of the UI
var/state = STATE_MAIN
/// The current state of the UI for AIs
var/cyborg_state = STATE_MAIN
/// The name of the user who logged in
var/authorize_name
/// The access that the card had on login
var/list/authorize_access
/// The messages this console has been sent
var/list/datum/comm_message/messages
/// How many times the alert level has been changed
/// Used to clear the modal to change alert level
var/alert_level_tick = 0
/// The last lines used for changing the status display
var/static/last_status_display
/// Allows use off station z-level
var/unlocked = FALSE
/obj/machinery/computer/communications/unlocked
unlocked = TRUE
/obj/machinery/computer/communications/Initialize(mapload)
. = ..()
GLOB.shuttle_caller_list += src
AddComponent(/datum/component/gps, "Secured Communications Signal")
/// Are we NOT a silicon, AND we're logged in as the captain?
/obj/machinery/computer/communications/proc/authenticated_as_non_silicon_captain(mob/user)
if (issilicon(user))
return FALSE
return ACCESS_CAPTAIN in authorize_access
/// Are we a silicon, OR we're logged in as the captain?
/obj/machinery/computer/communications/proc/authenticated_as_silicon_or_captain(mob/user)
if (issilicon(user))
return TRUE
return ACCESS_CAPTAIN in authorize_access
/// Are we NOT a silicon, AND we're logged in as a head
/obj/machinery/computer/communications/proc/authenticated_as_non_silicon_head(mob/user)
if(issilicon(user))
return FALSE
return ACCESS_HEADS in authorize_access
/// Are we a silicon, OR logged in?
/obj/machinery/computer/communications/proc/authenticated(mob/user)
if (issilicon(user))
return TRUE
return authenticated
/obj/machinery/computer/communications/attackby(obj/I, mob/user, params)
if(istype(I, /obj/item/card/id))
attack_hand(user)
else
return ..()
/obj/machinery/computer/communications/emag_act(mob/user, obj/item/card/emag/emag_card)
if(obj_flags & EMAGGED)
return FALSE
obj_flags |= EMAGGED
if (authenticated)
authorize_access = get_all_accesses()
to_chat(user, span_danger("You scramble the communication routing circuits!"))
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
return TRUE
/obj/machinery/computer/communications/ui_act(action, list/params)
var/static/list/approved_states = list(STATE_BUYING_SHUTTLE, STATE_CHANGING_STATUS, STATE_MAIN, STATE_MESSAGES)
var/static/list/approved_status_pictures = list("biohazard", "blank", "default", "lockdown", "redalert", "shuttle")
. = ..()
if (.)
return
. = TRUE
if(authenticated(usr) && !unlocked && !is_station_level(z) && !IsAdminGhost(usr))
if(issilicon(usr))
visible_message("An error appears on the screen: Unable to contact authentication servers. Please move closer to the station.")
return
action = "toggleAuthentication" // We actually want to log out
visible_message("An error appears on the screen: Unable to communicate with the station. Logging out.")
switch (action)
if ("answerMessage")
if (!authenticated(usr))
return
var/answer_index = params["answer"]
var/message_index = params["message"]
// If either of these aren't numbers, then bad voodoo.
if(!isnum(answer_index) || !isnum(message_index))
message_admins("[ADMIN_LOOKUPFLW(usr)] provided an invalid index type when replying to a message on [src] [ADMIN_JMP(src)]. This should not happen. Please check with a maintainer and/or consult tgui logs.")
CRASH("Non-numeric index provided when answering comms console message.")
if (!answer_index || !message_index || answer_index < 1 || message_index < 1)
return
var/datum/comm_message/message = messages[message_index]
if (message.answered)
return
message.answered = answer_index
message.answer_callback.InvokeAsync()
if ("callShuttle")
if (!authenticated(usr))
return
var/reason = trim(params["reason"], MAX_MESSAGE_LEN)
if (length(reason) < CALL_SHUTTLE_REASON_LENGTH)
return
SSshuttle.requestEvac(usr, reason)
post_status("shuttle")
if ("changeSecurityLevel")
if (!COOLDOWN_FINISHED(src, important_action_cooldown))
to_chat(usr, span_warning("The system is not able to change the security alert level more than once per minute, please wait."))
return
// Check if they have
if (!issilicon(usr))
var/obj/item/held_item = usr.get_active_held_item()
var/obj/item/card/id/id_card = held_item?.GetID()
if (!istype(id_card))
to_chat(usr, span_warning("You need to swipe your ID!"))
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
if (!(ACCESS_HEADS in id_card.access))
to_chat(usr, span_warning("You are not authorized to do this!"))
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
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 (SSsecurity_level.get_current_level_as_number() == new_sec_level)
return
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)
// Only notify people if an actual change happened
log_game("[key_name(usr)] has changed the security level to [params["newSecurityLevel"]] with [src] at [AREACOORD(usr)].")
message_admins("[ADMIN_LOOKUPFLW(usr)] has changed the security level to [params["newSecurityLevel"]] with [src] at [AREACOORD(usr)].")
deadchat_broadcast(" has changed the security level to [params["newSecurityLevel"]] with [src] at [span_name("[get_area_name(usr, TRUE)]")].", span_name("[usr.real_name]"), usr)
alert_level_tick += 1
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
if ("deleteMessage")
if (!authenticated(usr))
return
var/message_index = text2num(params["message"])
if (!message_index)
return
LAZYREMOVE(messages, LAZYACCESS(messages, message_index))
if ("makePriorityAnnouncement")
if (!authenticated_as_silicon_or_captain(usr))
return
make_announcement(usr)
if ("makeVoiceAnnouncement")
if (!authenticated_as_non_silicon_captain(usr))
return
make_voice_announcement(usr)
if ("messageAssociates")
if (!authenticated_as_non_silicon_captain(usr))
return
if (!COOLDOWN_FINISHED(src, important_action_cooldown))
return
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
var/message = trim(html_encode(params["message"]), MAX_MESSAGE_LEN)
var/emagged = obj_flags & EMAGGED
if (emagged)
message_syndicate(message, usr)
to_chat(usr, span_danger("SYSERR @l(19833)of(transmit.dm): !@$ MESSAGE TRANSMITTED TO SYNDICATE COMMAND."))
else
message_centcom(message, usr)
to_chat(usr, span_notice("Message transmitted to Central Command."))
var/associates = emagged ? "the Syndicate": "CentCom"
usr.log_talk(message, LOG_SAY, tag = "message to [associates]")
deadchat_broadcast(" has messaged [associates], \"[message]\" at [span_name("[get_area_name(usr, TRUE)]")].", span_name("[usr.real_name]"), usr)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
if ("purchaseShuttle")
var/can_buy_shuttles_or_fail_reason = can_buy_shuttles(usr)
if (can_buy_shuttles_or_fail_reason != TRUE)
if (can_buy_shuttles_or_fail_reason != FALSE)
to_chat(usr, span_alert("[can_buy_shuttles_or_fail_reason]"))
return
var/list/shuttles = flatten_list(SSmapping.shuttle_templates)
var/datum/map_template/shuttle/shuttle = locate(params["shuttle"]) in shuttles
if (!istype(shuttle))
return
if (!can_purchase_this_shuttle(shuttle))
return
if (!shuttle.prerequisites_met())
to_chat(usr, span_alert("You have not met the requirements for purchasing this shuttle."))
return
var/datum/bank_account/bank_account = SSeconomy.get_dep_account(ACCOUNT_CAR)
if (bank_account.account_balance < shuttle.credit_cost)
return
SSshuttle.shuttle_purchased = SHUTTLEPURCHASE_PURCHASED
if(obj_flags & EMAGGED)
SSshuttle.emag_shuttle_purchased = TRUE
SSshuttle.unload_preview()
SSshuttle.existing_shuttle = SSshuttle.emergency
SSshuttle.emergency.name = shuttle.name
SSshuttle.action_load(shuttle, replace = TRUE)
bank_account.adjust_money(-shuttle.credit_cost)
minor_announce("[authorize_name] has purchased [shuttle.name] for [shuttle.credit_cost] credits.[shuttle.extra_desc ? " [shuttle.extra_desc]" : ""]" , "Shuttle Purchase")
message_admins("[ADMIN_LOOKUPFLW(usr)] purchased [shuttle.name].")
SSblackbox.record_feedback("text", "shuttle_purchase", 1, shuttle.name)
state = STATE_MAIN
if ("recallShuttle")
// AIs cannot recall the shuttle
if (!authenticated(usr) || issilicon(usr))
return
SSshuttle.cancelEvac(usr)
if ("requestNukeCodes")
if (!authenticated_as_non_silicon_captain(usr))
return
if (!COOLDOWN_FINISHED(src, important_action_cooldown))
return
var/reason = trim(html_encode(params["reason"]), MAX_MESSAGE_LEN)
nuke_request(reason, usr)
to_chat(usr, span_notice("Request sent."))
usr.log_message("has requested the nuclear codes from CentCom with reason \"[reason]\"", LOG_SAY)
priority_announce("The codes for the on-station nuclear self-destruct have been requested by [authorize_name]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self-Destruct Codes Requested", SSstation.announcer.get_rand_report_sound())
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
if ("restoreBackupRoutingData")
if (!authenticated_as_non_silicon_captain(usr))
return
if (!(obj_flags & EMAGGED))
return
to_chat(usr, span_notice("Backup routing data restored."))
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
obj_flags &= ~EMAGGED
if ("sendToOtherSector")
if (!authenticated_as_non_silicon_captain(usr))
return
if (!can_send_messages_to_other_sectors(usr))
return
if (!COOLDOWN_FINISHED(src, important_action_cooldown))
return
var/message = trim(html_encode(params["message"]), MAX_MESSAGE_LEN)
if (!message)
return
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
var/destination = params["destination"]
send2otherserver(station_name(), message, "Comms_Console", destination == "all" ? null : list(destination))
minor_announce(message, title = "Outgoing message to allied station")
usr.log_talk(message, LOG_SAY, tag = "message to the other server")
message_admins("[ADMIN_LOOKUPFLW(usr)] has sent a message to the other server\[s].")
deadchat_broadcast(" has sent an outgoing message to the other station(s).</span>", "<span class='bold'>[usr.real_name]", usr)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
if ("setState")
if (!authenticated(usr))
return
if (!(params["state"] in approved_states))
return
if (state == STATE_BUYING_SHUTTLE && can_buy_shuttles(usr) != TRUE)
return
set_state(usr, params["state"])
playsound(src, "terminal_type", 50, FALSE)
if ("setStatusMessage")
if (!authenticated(usr))
return
var/line_one = reject_bad_text(params["lineOne"] || "", MAX_STATUS_LINE_LENGTH)
var/line_two = reject_bad_text(params["lineTwo"] || "", MAX_STATUS_LINE_LENGTH)
post_status("alert", "blank")
post_status("message", line_one, line_two)
last_status_display = list(line_one, line_two)
playsound(src, "terminal_type", 50, FALSE)
if ("setStatusPicture")
if (!authenticated(usr))
return
var/picture = params["picture"]
if (!(picture in approved_status_pictures))
return
post_status("alert", picture)
playsound(src, "terminal_type", 50, FALSE)
if ("toggleAuthentication")
// Log out if we're logged in
if (authorize_name)
authenticated = FALSE
authorize_access = null
authorize_name = null
playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE)
return
if(!unlocked && !is_station_level(z) && !IsAdminGhost(usr))
visible_message("An error appears on the screen: Unable to contact authentication servers. Please move closer to the station.")
return
if (obj_flags & EMAGGED)
authenticated = TRUE
authorize_access = get_all_accesses()
authorize_name = "Unknown"
to_chat(usr, span_warning("[src] lets out a quiet alarm as its login is overridden."))
playsound(src, 'sound/machines/terminal_alert.ogg', 25, FALSE)
else if (IsAdminGhost(usr))
authenticated = TRUE
authorize_access = get_all_accesses()
authorize_name = usr.client.holder.admin_signature
else
var/obj/item/card/id/id_card = usr.get_idcard(hand_first = TRUE)
if (check_access(id_card))
authenticated = TRUE
authorize_access = id_card.access
authorize_name = "[id_card.registered_name] - [id_card.assignment]"
state = STATE_MAIN
playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE)
if ("toggleEmergencyAccess")
if (GLOB.emergency_access)
if (!COOLDOWN_FINISHED(src, important_action_cooldown))
to_chat(usr, span_alert("Maintenance airlock communications relays recharging. Please stand by."))
return
revoke_maint_all_access()
log_game("[key_name(usr)] disabled emergency maintenance access.")
message_admins("[ADMIN_LOOKUPFLW(usr)] disabled emergency maintenance access.")
deadchat_broadcast(" disabled emergency maintenance access at [span_name("[get_area_name(usr, TRUE)]")].", span_name("[usr.real_name]"), usr)
else
make_maint_all_access()
log_game("[key_name(usr)] enabled emergency maintenance access.")
message_admins("[ADMIN_LOOKUPFLW(usr)] enabled emergency maintenance access.")
deadchat_broadcast(" enabled emergency maintenance access at [span_name("[get_area_name(usr, TRUE)]")].", span_name("[usr.real_name]"), usr)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
if ("printSpare")
if (authenticated_as_non_silicon_head(usr))
if (!COOLDOWN_FINISHED(src, important_action_cooldown))
return
playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1)
new /obj/item/card/id/captains_spare/temporary(loc)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
priority_announce("The emergency spare ID has been printed by [authorize_name].", "Emergency Spare ID Warning System", SSstation.announcer.get_rand_report_sound())
if("printAIControlCode")
if(authenticated_as_non_silicon_head(usr))
if(!COOLDOWN_FINISHED(src, important_action_cooldown))
return
playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1)
GLOB.ai_control_code = random_nukecode(6)
new /obj/item/paper/ai_control_code(loc)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
priority_announce("The AI Control Code been printed by [authorize_name]. All previous codes have been invalidated.", "Central Tech Support", SSstation.announcer.get_rand_report_sound())
/obj/machinery/computer/communications/ui_data(mob/user)
var/list/data = list(
"authenticated" = FALSE,
"emagged" = FALSE,
)
var/ui_state = issilicon(user) ? cyborg_state : state
if (authenticated || issilicon(user))
data["authenticated"] = TRUE
data["canLogOut"] = !issilicon(user)
data["page"] = ui_state
if (obj_flags & EMAGGED)
data["emagged"] = TRUE
switch (ui_state)
if (STATE_MAIN)
data["canBuyShuttles"] = can_buy_shuttles(user)
data["canMakeAnnouncement"] = FALSE
data["canMakeVoiceAnnouncement"] = FALSE
data["canMessageAssociates"] = FALSE
data["canRecallShuttles"] = !issilicon(user)
data["canRequestNuke"] = FALSE
data["canSendToSectors"] = FALSE
data["canSetAlertLevel"] = TRUE
data["canToggleEmergencyAccess"] = TRUE
data["importantActionReady"] = COOLDOWN_FINISHED(src, important_action_cooldown)
data["shuttleCalled"] = FALSE
data["shuttleLastCalled"] = FALSE
data["aprilFools"] = check_holidays(APRIL_FOOLS)
data["canPrintIdAndCode"] = FALSE
data["alertLevel"] = SSsecurity_level.get_current_level_as_text()
data["authorizeName"] = authorize_name
data["canLogOut"] = !issilicon(user)
data["shuttleCanEvacOrFailReason"] = SSshuttle.canEvac(user)
if (authenticated_as_non_silicon_captain(user))
data["canMessageAssociates"] = TRUE
data["canRequestNuke"] = TRUE
if (!issilicon(user))
data["canPrintIdAndCode"] = TRUE
if (can_send_messages_to_other_sectors(user))
data["canSendToSectors"] = TRUE
var/list/sectors = list()
var/our_id = CONFIG_GET(string/cross_comms_name)
for (var/server in CONFIG_GET(keyed_list/cross_server))
if (server == our_id)
continue
sectors += server
data["sectors"] = sectors
if (authenticated_as_silicon_or_captain(user))
data["canToggleEmergencyAccess"] = TRUE
data["emergencyAccess"] = GLOB.emergency_access
data["alertLevelTick"] = alert_level_tick
data["canMakeAnnouncement"] = TRUE
data["canMakeVoiceAnnouncement"] = ishuman(user)
data["canSetAlertLevel"] = issilicon(user) ? "NO_SWIPE_NEEDED" : "SWIPE_NEEDED"
if (SSshuttle.emergency.mode != SHUTTLE_IDLE && SSshuttle.emergency.mode != SHUTTLE_RECALL)
data["shuttleCalled"] = TRUE
data["shuttleRecallable"] = SSshuttle.canRecall()
if (SSshuttle.emergencyCallAmount)
data["shuttleCalledPreviously"] = TRUE
if (SSshuttle.emergency_last_call_loc)
data["shuttleLastCalled"] = format_text(SSshuttle.emergency_last_call_loc.name)
if (STATE_MESSAGES)
data["messages"] = list()
if (messages)
for (var/_message in messages)
var/datum/comm_message/message = _message
data["messages"] += list(list(
"answered" = message.answered,
"content" = message.content,
"title" = message.title,
"possibleAnswers" = message.possible_answers,
))
if (STATE_BUYING_SHUTTLE)
var/datum/bank_account/bank_account = SSeconomy.get_dep_account(ACCOUNT_CAR)
var/list/shuttles = list()
for (var/shuttle_id in SSmapping.shuttle_templates)
var/datum/map_template/shuttle/shuttle_template = SSmapping.shuttle_templates[shuttle_id]
if (shuttle_template.credit_cost == INFINITY)
continue
if (!can_purchase_this_shuttle(shuttle_template))
continue
shuttles += list(list(
"name" = shuttle_template.name,
"description" = shuttle_template.description,
"occupancy_limit" = shuttle_template.occupancy_limit,
"creditCost" = shuttle_template.credit_cost,
"initial_cost" = initial(shuttle_template.credit_cost),
"emagOnly" = shuttle_template.emag_only,
"prerequisites" = shuttle_template.prerequisites,
"ref" = REF(shuttle_template),
))
data["budget"] = bank_account.account_balance
data["shuttles"] = shuttles
if (STATE_CHANGING_STATUS)
data["lineOne"] = last_status_display ? last_status_display[1] : ""
data["lineTwo"] = last_status_display ? last_status_display[2] : ""
return data
/obj/machinery/computer/communications/ui_interact(mob/user, datum/tgui/ui)
play_click_sound(user)
ui = SStgui.try_update_ui(user, src, ui)
if (!ui)
ui = new(user, src, "CommunicationsConsole")
ui.open()
/obj/machinery/computer/communications/ui_static_data(mob/user)
return list(
"callShuttleReasonMinLength" = CALL_SHUTTLE_REASON_LENGTH,
"maxStatusLineLength" = MAX_STATUS_LINE_LENGTH,
"maxMessageLength" = MAX_MESSAGE_LEN,
)
/obj/machinery/computer/communications/proc/set_state(mob/user, new_state)
if (issilicon(user))
cyborg_state = new_state
else
state = new_state
/// Returns TRUE if the user can buy shuttles.
/// If they cannot, returns FALSE or a string detailing why.
/obj/machinery/computer/communications/proc/can_buy_shuttles(mob/user)
if (!SSmapping.config.allow_custom_shuttles)
return FALSE
if (issilicon(user))
return FALSE
var/has_access = FALSE
for (var/access in SSshuttle.has_purchase_shuttle_access)
if (access in authorize_access)
has_access = TRUE
break
if (!has_access)
return FALSE
if (SSshuttle.emergency.mode != SHUTTLE_RECALL && SSshuttle.emergency.mode != SHUTTLE_IDLE)
return "The shuttle is already in transit."
if (SSshuttle.shuttle_purchased == SHUTTLEPURCHASE_PURCHASED)
return "A replacement shuttle has already been purchased."
if (SSshuttle.shuttle_purchased == SHUTTLEPURCHASE_FORCED)
return "Due to unforseen circumstances, shuttle purchasing is no longer available."
return TRUE
/// Returns whether we are authorized to buy this specific shuttle.
/// Does not handle prerequisite checks, as those should still *show*.
/obj/machinery/computer/communications/proc/can_purchase_this_shuttle(datum/map_template/shuttle/shuttle_template)
if (isnull(shuttle_template.who_can_purchase))
return FALSE
if (shuttle_template.emag_only)
return !!(obj_flags & EMAGGED)
for (var/access in authorize_access)
if (access in shuttle_template.who_can_purchase)
return TRUE
return FALSE
/obj/machinery/computer/communications/proc/can_send_messages_to_other_sectors(mob/user)
if (!authenticated_as_non_silicon_captain(user))
return
return length(CONFIG_GET(keyed_list/cross_server)) > 0
/obj/machinery/computer/communications/proc/make_announcement(mob/living/user)
var/is_ai = issilicon(user)
if(!SScommunications.can_announce(user, is_ai))
to_chat(user, span_alert("Intercomms recharging. Please stand by."))
return
var/input = stripped_multiline_input(user, "Please choose a message to announce to the station crew.", "What?")
if(!input || !user.canUseTopic(src, !issilicon(usr)))
return
SScommunications.make_announcement(user, is_ai, input)
deadchat_broadcast(" made a priority announcement from [span_name("[get_area_name(usr, TRUE)]")].", span_name("[user.real_name]"), user)
/obj/machinery/computer/communications/proc/make_voice_announcement(mob/living/user)
if(!SScommunications.can_announce(user, FALSE))
to_chat(user, span_alert("Intercomms recharging. Please stand by."))
return
var/datum/voice_announce/command/announce_datum = new(user.client, src)
announce_datum.open()
/obj/machinery/computer/communications/proc/post_status(command, data1, data2)
var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS)
if(!frequency)
return
var/datum/signal/status_signal = new(list("command" = command))
switch(command)
if("message")
status_signal.data["msg1"] = data1
status_signal.data["msg2"] = data2
if("alert")
status_signal.data["picture_state"] = data1
frequency.post_signal(src, status_signal)
/obj/machinery/computer/communications/Destroy()
GLOB.shuttle_caller_list -= src
SSshuttle.autoEvac()
return ..()
/// Override the cooldown for special actions
/// Used in places such as CentCom messaging back so that the crew can answer right away
/obj/machinery/computer/communications/proc/override_cooldown()
COOLDOWN_RESET(src, important_action_cooldown)
/obj/machinery/computer/communications/proc/add_message(datum/comm_message/new_message)
LAZYADD(messages, new_message)
/datum/comm_message
var/title
var/content
var/list/possible_answers = list()
var/answered
var/datum/callback/answer_callback
/datum/comm_message/New(new_title,new_content,new_possible_answers)
..()
if(new_title)
title = new_title
if(new_content)
content = new_content
if(new_possible_answers)
possible_answers = new_possible_answers
#undef MAX_STATUS_LINE_LENGTH
#undef STATE_BUYING_SHUTTLE
#undef STATE_CHANGING_STATUS
#undef STATE_MAIN
#undef STATE_MESSAGES