// 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
var/authenticated = 0
var/auth_id = "Unknown" //Who is currently logged in?
var/list/messagetitle = list()
var/list/messagetext = list()
var/currmsg = 0
var/aicurrmsg = 0
var/state = STATE_DEFAULT
var/aistate = STATE_DEFAULT
var/message_cooldown = 0
var/ai_message_cooldown = 0
var/tmp_alertlevel = 0
var/const/STATE_DEFAULT = 1
var/const/STATE_CALLSHUTTLE = 2
var/const/STATE_CANCELSHUTTLE = 3
var/const/STATE_MESSAGELIST = 4
var/const/STATE_VIEWMESSAGE = 5
var/const/STATE_DELMESSAGE = 6
var/const/STATE_STATUSDISPLAY = 7
var/const/STATE_ALERT_LEVEL = 8
var/const/STATE_CONFIRM_LEVEL = 9
var/const/STATE_TOGGLE_EMERGENCY = 10
var/const/STATE_PURCHASE = 11
var/status_display_freq = "1435"
var/stat_msg1
var/stat_msg2
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/communications/proc/checkCCcooldown()
var/obj/item/circuitboard/computer/communications/CM = circuit
if(CM.lastTimeUsed + 600 > world.time)
return FALSE
return TRUE
/obj/machinery/computer/communications/Initialize()
. = ..()
GLOB.shuttle_caller_list += src
/obj/machinery/computer/communications/process()
if(..())
if(state != STATE_STATUSDISPLAY)
src.updateDialog()
/obj/machinery/computer/communications/Topic(href, href_list)
if(..())
return
if(!(z in GLOB.station_z_levels) && z != ZLEVEL_CENTCOM) //Can only use on centcom and SS13
to_chat(usr, "Unable to establish a connection: \black You're too far away from the station!")
return
usr.set_machine(src)
if(!href_list["operation"])
return
var/obj/item/circuitboard/computer/communications/CM = circuit
switch(href_list["operation"])
// main interface
if("main")
src.state = STATE_DEFAULT
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
if("login")
var/mob/M = usr
var/obj/item/card/id/I = M.get_active_held_item()
if(!istype(I))
I = M.get_idcard()
if(I && istype(I))
if(src.check_access(I))
authenticated = 1
auth_id = "[I.registered_name] ([I.assignment])"
if((20 in I.access))
authenticated = 2
playsound(src, 'sound/machines/terminal_on.ogg', 50, 0)
if(src.emagged)
authenticated = 2
auth_id = "Unknown"
to_chat(M, "[src] lets out a quiet alarm as its login is overriden.")
playsound(src, 'sound/machines/terminal_on.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_alert.ogg', 25, 0)
if(prob(25))
for(var/mob/living/silicon/ai/AI in active_ais())
SEND_SOUND(AI, sound('sound/machines/terminal_alert.ogg', volume = 10)) //Very quiet for balance reasons
if("logout")
authenticated = 0
playsound(src, 'sound/machines/terminal_off.ogg', 50, 0)
if("swipeidseclevel")
var/mob/M = usr
var/obj/item/card/id/I = M.get_active_held_item()
if (istype(I, /obj/item/device/pda))
var/obj/item/device/pda/pda = I
I = pda.id
if (I && istype(I))
if(ACCESS_CAPTAIN in I.access)
var/old_level = GLOB.security_level
if(!tmp_alertlevel)
tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel < SEC_LEVEL_GREEN)
tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel > SEC_LEVEL_BLUE)
tmp_alertlevel = SEC_LEVEL_BLUE //Cannot engage delta with this
set_security_level(tmp_alertlevel)
if(GLOB.security_level != old_level)
to_chat(usr, "Authorization confirmed. Modifying security level.")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
//Only notify the admins if an actual change happened
log_game("[key_name(usr)] has changed the security level to [get_security_level()].")
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
switch(GLOB.security_level)
if(SEC_LEVEL_GREEN)
SSblackbox.inc("alert_comms_green",1)
if(SEC_LEVEL_BLUE)
SSblackbox.inc("alert_comms_blue",1)
tmp_alertlevel = 0
else
to_chat(usr, "You are not authorized to do this!")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
tmp_alertlevel = 0
state = STATE_DEFAULT
else
to_chat(usr, "You need to swipe your ID!")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
if("announce")
if(src.authenticated==2)
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
make_announcement(usr)
if("crossserver")
if(authenticated==2)
if(CM.lastTimeUsed + 600 > world.time)
to_chat(usr, "Arrays recycling. Please stand by.")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
var/input = stripped_multiline_input(usr, "Please choose a message to transmit to an allied station. Please be aware that this process is very expensive, and abuse will lead to... termination.", "Send a message to an allied station.", "")
if(!input || !(usr in view(1,src)))
return
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
send2otherserver("[station_name()]", input,"Comms_Console")
minor_announce(input, title = "Outgoing message to allied station")
log_talk(usr,"[key_name(usr)] has sent a message to the other server: [input]",LOGSAY)
message_admins("[key_name_admin(usr)] has sent a message to the other server.")
CM.lastTimeUsed = world.time
if("purchase_menu")
state = STATE_PURCHASE
if("buyshuttle")
if(authenticated==2)
var/list/shuttles = flatten_list(SSmapping.shuttle_templates)
var/datum/map_template/shuttle/S = locate(href_list["chosen_shuttle"]) in shuttles
if(S && istype(S))
if(SSshuttle.emergency.mode != SHUTTLE_RECALL && SSshuttle.emergency.mode != SHUTTLE_IDLE)
to_chat(usr, "It's a bit late to buy a new shuttle, don't you think?")
return
if(SSshuttle.shuttle_purchased)
to_chat(usr, "A replacement shuttle has already been purchased.")
else if(!S.prerequisites_met())
to_chat(usr, "You have not met the requirements for purchasing this shuttle.")
else
if(SSshuttle.points >= S.credit_cost)
var/obj/machinery/shuttle_manipulator/M = locate() in GLOB.machines
if(M)
SSshuttle.shuttle_purchased = TRUE
M.unload_preview()
M.load_template(S)
M.existing_shuttle = SSshuttle.emergency
M.action_load(S)
SSshuttle.points -= S.credit_cost
minor_announce("[usr.name] has purchased [S.name] for [S.credit_cost] credits." , "Shuttle Purchase")
message_admins("[key_name_admin(usr)] purchased [S.name].")
SSblackbox.add_details("shuttle_purchase", S.name)
else
to_chat(usr, "Something went wrong! The shuttle exchange system seems to be down.")
else
to_chat(usr, "Not enough credits.")
if("callshuttle")
src.state = STATE_DEFAULT
if(src.authenticated)
src.state = STATE_CALLSHUTTLE
if("callshuttle2")
if(src.authenticated)
SSshuttle.requestEvac(usr, href_list["call"])
if(SSshuttle.emergency.timer)
post_status("shuttle")
src.state = STATE_DEFAULT
if("cancelshuttle")
src.state = STATE_DEFAULT
if(src.authenticated)
src.state = STATE_CANCELSHUTTLE
if("cancelshuttle2")
if(src.authenticated)
SSshuttle.cancelEvac(usr)
src.state = STATE_DEFAULT
if("messagelist")
src.currmsg = 0
src.state = STATE_MESSAGELIST
if("viewmessage")
src.state = STATE_VIEWMESSAGE
if (!src.currmsg)
if(href_list["message-num"])
src.currmsg = text2num(href_list["message-num"])
else
src.state = STATE_MESSAGELIST
if("delmessage")
src.state = (src.currmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
if("delmessage2")
if(src.authenticated)
if(src.currmsg)
var/title = src.messagetitle[src.currmsg]
var/text = src.messagetext[src.currmsg]
src.messagetitle.Remove(title)
src.messagetext.Remove(text)
if(src.currmsg == src.aicurrmsg)
src.aicurrmsg = 0
src.currmsg = 0
src.state = STATE_MESSAGELIST
else
src.state = STATE_VIEWMESSAGE
if("status")
src.state = STATE_STATUSDISPLAY
if("securitylevel")
src.tmp_alertlevel = text2num( href_list["newalertlevel"] )
if(!tmp_alertlevel)
tmp_alertlevel = 0
state = STATE_CONFIRM_LEVEL
if("changeseclevel")
state = STATE_ALERT_LEVEL
if("emergencyaccess")
state = STATE_TOGGLE_EMERGENCY
if("enableemergency")
make_maint_all_access()
log_game("[key_name(usr)] enabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] enabled emergency maintenance access.")
src.state = STATE_DEFAULT
if("disableemergency")
revoke_maint_all_access()
log_game("[key_name(usr)] disabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] disabled emergency maintenance access.")
src.state = STATE_DEFAULT
// Status display stuff
if("setstat")
playsound(src, "terminal_type", 50, 0)
switch(href_list["statdisp"])
if("message")
post_status("message", stat_msg1, stat_msg2)
if("alert")
post_status("alert", href_list["alert"])
else
post_status(href_list["statdisp"])
if("setmsg1")
stat_msg1 = reject_bad_text(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40)
src.updateDialog()
if("setmsg2")
stat_msg2 = reject_bad_text(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40)
src.updateDialog()
// OMG CENTCOM LETTERHEAD
if("MessageCentCom")
if(src.authenticated==2)
if(!checkCCcooldown())
to_chat(usr, "Arrays recycling. Please stand by.")
return
var/input = stripped_input(usr, "Please choose a message to transmit to CentCom via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "Send a message to CentCom.", "")
if(!input || !(usr in view(1,src)) || !checkCCcooldown())
return
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
CentCom_announce(input, usr)
to_chat(usr, "Message transmitted to Central Command.")
log_talk(usr,"[key_name(usr)] has made a CentCom announcement: [input]",LOGSAY)
CM.lastTimeUsed = world.time
// OMG SYNDICATE ...LETTERHEAD
if("MessageSyndicate")
if((src.authenticated==2) && (src.emagged))
if(!checkCCcooldown())
to_chat(usr, "Arrays recycling. Please stand by.")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING COORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "Send a message to /??????/.", "")
if(!input || !(usr in view(1,src)) || !checkCCcooldown())
return
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
Syndicate_announce(input, usr)
to_chat(usr, "SYSERR @l(19833)of(transmit.dm): !@$ MESSAGE TRANSMITTED TO SYNDICATE COMMAND.")
log_talk(usr,"[key_name(usr)] has made a Syndicate announcement: [input]",LOGSAY)
CM.lastTimeUsed = world.time
if("RestoreBackup")
to_chat(usr, "Backup routing data restored!")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
emagged = FALSE
src.updateDialog()
if("nukerequest") //When there's no other way
if(src.authenticated==2)
if(!checkCCcooldown())
to_chat(usr, "Arrays recycling. Please stand by.")
return
var/input = stripped_input(usr, "Please enter the reason for requesting the nuclear self-destruct codes. Misuse of the nuclear request system will not be tolerated under any circumstances. Transmission does not guarantee a response.", "Self Destruct Code Request.","")
if(!input || !(usr in view(1,src)) || !checkCCcooldown())
return
Nuke_request(input, usr)
to_chat(usr, "Request sent.")
log_talk(usr,"[key_name(usr)] has requested the nuclear codes from CentCom",LOGSAY)
priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested",'sound/ai/commandreport.ogg')
CM.lastTimeUsed = world.time
// AI interface
if("ai-main")
src.aicurrmsg = 0
src.aistate = STATE_DEFAULT
if("ai-callshuttle")
src.aistate = STATE_CALLSHUTTLE
if("ai-callshuttle2")
SSshuttle.requestEvac(usr, href_list["call"])
src.aistate = STATE_DEFAULT
if("ai-messagelist")
src.aicurrmsg = 0
src.aistate = STATE_MESSAGELIST
if("ai-viewmessage")
src.aistate = STATE_VIEWMESSAGE
if (!src.aicurrmsg)
if(href_list["message-num"])
src.aicurrmsg = text2num(href_list["message-num"])
else
src.aistate = STATE_MESSAGELIST
if("ai-delmessage")
src.aistate = (src.aicurrmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
if("ai-delmessage2")
if(src.aicurrmsg)
var/title = src.messagetitle[src.aicurrmsg]
var/text = src.messagetext[src.aicurrmsg]
src.messagetitle.Remove(title)
src.messagetext.Remove(text)
if(src.currmsg == src.aicurrmsg)
src.currmsg = 0
src.aicurrmsg = 0
src.aistate = STATE_MESSAGELIST
if("ai-status")
src.aistate = STATE_STATUSDISPLAY
if("ai-announce")
make_announcement(usr, 1)
if("ai-securitylevel")
src.tmp_alertlevel = text2num( href_list["newalertlevel"] )
if(!tmp_alertlevel)
tmp_alertlevel = 0
var/old_level = GLOB.security_level
if(!tmp_alertlevel)
tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel < SEC_LEVEL_GREEN)
tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel > SEC_LEVEL_BLUE)
tmp_alertlevel = SEC_LEVEL_BLUE //Cannot engage delta with this
set_security_level(tmp_alertlevel)
if(GLOB.security_level != old_level)
//Only notify the admins if an actual change happened
log_game("[key_name(usr)] has changed the security level to [get_security_level()].")
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
switch(GLOB.security_level)
if(SEC_LEVEL_GREEN)
SSblackbox.inc("alert_comms_green",1)
if(SEC_LEVEL_BLUE)
SSblackbox.inc("alert_comms_blue",1)
tmp_alertlevel = 0
src.aistate = STATE_DEFAULT
if("ai-changeseclevel")
src.aistate = STATE_ALERT_LEVEL
if("ai-emergencyaccess")
src.aistate = STATE_TOGGLE_EMERGENCY
if("ai-enableemergency")
make_maint_all_access()
log_game("[key_name(usr)] enabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] enabled emergency maintenance access.")
src.aistate = STATE_DEFAULT
if("ai-disableemergency")
revoke_maint_all_access()
log_game("[key_name(usr)] disabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] disabled emergency maintenance access.")
src.aistate = STATE_DEFAULT
src.updateUsrDialog()
/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)
if(emagged)
return
emagged = TRUE
if(authenticated == 1)
authenticated = 2
to_chat(user, "You scramble the communication routing circuits!")
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
/obj/machinery/computer/communications/attack_hand(mob/user)
if(..())
return
if (src.z > 6)
to_chat(user, "Unable to establish a connection: \black You're too far away from the station!")
return
user.set_machine(src)
var/dat = ""
if(SSshuttle.emergency.mode == SHUTTLE_CALL)
var/timeleft = SSshuttle.emergency.timeLeft()
dat += "Emergency shuttle\n
\nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]"
var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
if(issilicon(user))
var/dat2 = src.interact_ai(user) // give the AI a different interact proc to limit its access
if(dat2)
dat += dat2
popup.set_content(dat)
popup.open()
return
switch(src.state)
if(STATE_DEFAULT)
if (src.authenticated)
if(SSshuttle.emergencyCallAmount)
if(SSshuttle.emergencyLastCallLoc)
dat += "Most recent shuttle call/recall traced to: [format_text(SSshuttle.emergencyLastCallLoc.name)]
"
else
dat += "Unable to trace most recent shuttle call/recall signal.
"
dat += "Logged in as: [auth_id]"
dat += "
"
dat += "
\[ Log Out \]
"
dat += "
General Functions"
dat += "
\[ Message List \]"
switch(SSshuttle.emergency.mode)
if(SHUTTLE_IDLE, SHUTTLE_RECALL)
dat += "
\[ Call Emergency Shuttle \]"
else
dat += "
\[ Cancel Shuttle Call \]"
dat += "
\[ Set Status Display \]"
if (src.authenticated==2)
dat += "
Captain Functions"
dat += "
\[ Make a Captain's Announcement \]"
if(config.cross_allowed)
dat += "
\[ Send a message to an allied station \]"
if(SSmapping.config.allow_custom_shuttles == "yes")
dat += "
\[ Purchase Shuttle \]"
dat += "
\[ Change Alert Level \]"
dat += "
\[ Emergency Maintenance Access \]"
dat += "
\[ Request Nuclear Authentication Codes \]"
if(!emagged)
dat += "
\[ Send Message to CentCom \]"
else
dat += "
\[ Send Message to \[UNKNOWN\] \]"
dat += "
\[ Restore Backup Routing Data \]"
else
dat += "
\[ Log In \]"
if(STATE_CALLSHUTTLE)
dat += get_call_shuttle_form()
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
if(STATE_CANCELSHUTTLE)
dat += get_cancel_shuttle_form()
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
if(STATE_MESSAGELIST)
dat += "Messages:"
for(var/i = 1; i<=src.messagetitle.len; i++)
dat += "
[src.messagetitle[i]]"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if(STATE_VIEWMESSAGE)
if (src.currmsg)
dat += "[src.messagetitle[src.currmsg]]
[src.messagetext[src.currmsg]]"
if (src.authenticated)
dat += "
\[ Delete \]"
else
src.state = STATE_MESSAGELIST
src.attack_hand(user)
return
if(STATE_DELMESSAGE)
if (src.currmsg)
dat += "Are you sure you want to delete this message? \[ OK | Cancel \]"
else
src.state = STATE_MESSAGELIST
src.attack_hand(user)
return
if(STATE_STATUSDISPLAY)
dat += "Set Status Displays
"
dat += "\[ Clear \]
"
dat += "\[ Shuttle ETA \]
"
dat += "\[ Message \]"
dat += "