mirror of
https://github.com/KabKebab/GS13.git
synced 2026-07-10 23:47:16 +01:00
48cddaaf51
"Please send help, I don't know how I'm contacting you without captain access, but it would sure be nice about now!" Simply enough made it so anyone who can access the communications console normally can message Central Command.
768 lines
35 KiB
Plaintext
768 lines
35 KiB
Plaintext
// 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/auth_id = "Unknown" //Who is currently logged in?
|
|
var/list/datum/comm_message/messages = list()
|
|
var/datum/comm_message/currmsg
|
|
var/datum/comm_message/aicurrmsg
|
|
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/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(..())
|
|
var/ai_autoupdate = aistate != STATE_STATUSDISPLAY && aistate != STATE_CALLSHUTTLE && aistate != STATE_PURCHASE && aistate != STATE_VIEWMESSAGE
|
|
var/machine_user_autoupdate = state != STATE_STATUSDISPLAY && state != STATE_CALLSHUTTLE && state != STATE_PURCHASE && state != STATE_VIEWMESSAGE
|
|
updateDialog(machine_user_autoupdate,ai_autoupdate)
|
|
|
|
/obj/machinery/computer/communications/Topic(href, href_list)
|
|
if(..())
|
|
return
|
|
if(!usr.canUseTopic(src))
|
|
return
|
|
if(!is_station_level(z) && !is_reserved_level(z)) //Can only use in transit and on SS13
|
|
to_chat(usr, "<span class='boldannounce'>Unable to establish a connection</span>: \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")
|
|
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_idcard(TRUE)
|
|
|
|
if(I && istype(I))
|
|
if(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(obj_flags & EMAGGED)
|
|
authenticated = 2
|
|
auth_id = "Unknown"
|
|
to_chat(M, "<span class='warning'>[src] lets out a quiet alarm as its login is overridden.</span>")
|
|
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/pda))
|
|
var/obj/item/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
|
|
if(tmp_alertlevel > SEC_LEVEL_AMBER)
|
|
tmp_alertlevel = SEC_LEVEL_AMBER //Cannot engage delta with this
|
|
set_security_level(tmp_alertlevel)
|
|
if(GLOB.security_level != old_level)
|
|
to_chat(usr, "<span class='notice'>Authorization confirmed. Modifying security level.</span>")
|
|
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
|
//Only notify people if an actual change happened
|
|
var/security_level = get_security_level()
|
|
log_game("[key_name(usr)] has changed the security level to [security_level] with [src] at [AREACOORD(usr)].")
|
|
message_admins("[ADMIN_LOOKUPFLW(usr)] has changed the security level to [security_level] with [src] at [AREACOORD(usr)].")
|
|
deadchat_broadcast("<span class='deadsay'><span class='name'>[usr.real_name]</span> has changed the security level to [security_level] with [src] at <span class='name'>[get_area_name(usr, TRUE)]</span>.</span>", usr)
|
|
tmp_alertlevel = 0
|
|
else
|
|
to_chat(usr, "<span class='warning'>You are not authorized to do this!</span>")
|
|
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
|
tmp_alertlevel = 0
|
|
state = STATE_DEFAULT
|
|
else
|
|
to_chat(usr, "<span class='warning'>You need to swipe your ID!</span>")
|
|
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
|
|
|
if("announce")
|
|
if(authenticated==2)
|
|
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
|
make_announcement(usr)
|
|
|
|
if("crossserver")
|
|
if(authenticated==2)
|
|
if(!checkCCcooldown())
|
|
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
|
|
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
|
return
|
|
var/input = stripped_multiline_input(usr, "Please choose a message to transmit to allied stations. 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)) || !checkCCcooldown())
|
|
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")
|
|
usr.log_talk(input, LOG_SAY, tag="message to the other server")
|
|
message_admins("[ADMIN_LOOKUPFLW(usr)] has sent a message to the other server.")
|
|
deadchat_broadcast("<span class='deadsay bold'>[usr.real_name] has sent an outgoing message to the other station(s).</span>", usr)
|
|
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
|
|
SSshuttle.points -= S.credit_cost
|
|
minor_announce("[usr.real_name] has purchased [S.name] for [S.credit_cost] credits." , "Shuttle Purchase")
|
|
message_admins("[ADMIN_LOOKUPFLW(usr)] purchased [S.name].")
|
|
SSblackbox.record_feedback("text", "shuttle_purchase", 1, "[S.name]")
|
|
M.unload_preview()
|
|
M.load_template(S)
|
|
M.existing_shuttle = SSshuttle.emergency
|
|
M.action_load(S)
|
|
message_admins("[S.name] loaded, purchased by [usr]")
|
|
else
|
|
to_chat(usr, "Something went wrong! The shuttle exchange system seems to be down.")
|
|
else
|
|
to_chat(usr, "Not enough credits.")
|
|
|
|
if("callshuttle")
|
|
state = STATE_DEFAULT
|
|
if(authenticated)
|
|
state = STATE_CALLSHUTTLE
|
|
if("callshuttle2")
|
|
if(authenticated)
|
|
SSshuttle.requestEvac(usr, href_list["call"])
|
|
if(SSshuttle.emergency.timer)
|
|
post_status("shuttle")
|
|
state = STATE_DEFAULT
|
|
if("cancelshuttle")
|
|
state = STATE_DEFAULT
|
|
if(authenticated)
|
|
state = STATE_CANCELSHUTTLE
|
|
if("cancelshuttle2")
|
|
if(authenticated)
|
|
if((world.realtime - SSshuttle.realtimeofstart) > SSshuttle.auto_call) //Citadel Edit Removing auto_call caused recall.
|
|
say("Warning: Emergency shuttle recalls have been blocked by Central Command due to ongoing crew transfer procedures.")
|
|
else
|
|
SSshuttle.cancelEvac(usr)
|
|
state = STATE_DEFAULT
|
|
if("messagelist")
|
|
currmsg = 0
|
|
state = STATE_MESSAGELIST
|
|
if("viewmessage")
|
|
state = STATE_VIEWMESSAGE
|
|
if (!currmsg)
|
|
if(href_list["message-num"])
|
|
var/msgnum = text2num(href_list["message-num"])
|
|
currmsg = messages[msgnum]
|
|
else
|
|
state = STATE_MESSAGELIST
|
|
if("delmessage")
|
|
state = currmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST
|
|
if("delmessage2")
|
|
if(authenticated)
|
|
if(currmsg)
|
|
if(aicurrmsg == currmsg)
|
|
aicurrmsg = null
|
|
messages -= currmsg
|
|
currmsg = null
|
|
state = STATE_MESSAGELIST
|
|
else
|
|
state = STATE_VIEWMESSAGE
|
|
if("respond")
|
|
var/answer = text2num(href_list["answer"])
|
|
if(!currmsg || !answer || currmsg.possible_answers.len < answer)
|
|
state = STATE_MESSAGELIST
|
|
else
|
|
if(!currmsg.answered)
|
|
currmsg.answered = answer
|
|
log_game("[key_name(usr)] answered [currmsg.title] comm message. Answer : [currmsg.answered]")
|
|
if(currmsg)
|
|
currmsg.answer_callback.InvokeAsync()
|
|
state = STATE_VIEWMESSAGE
|
|
updateDialog()
|
|
if("status")
|
|
state = STATE_STATUSDISPLAY
|
|
if("securitylevel")
|
|
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("[ADMIN_LOOKUPFLW(usr)] enabled emergency maintenance access.")
|
|
deadchat_broadcast("<span class='deadsay'><span class='name'>[usr.real_name]</span> enabled emergency maintenance access at <span class='name'>[get_area_name(usr, TRUE)]</span>.</span>", usr)
|
|
state = STATE_DEFAULT
|
|
if("disableemergency")
|
|
revoke_maint_all_access()
|
|
log_game("[key_name(usr)] disabled emergency maintenance access.")
|
|
message_admins("[ADMIN_LOOKUPFLW(usr)] disabled emergency maintenance access.")
|
|
deadchat_broadcast("<span class='deadsay'><span class='name'>[usr.real_name]</span> disabled emergency maintenance access at <span class='name'>[get_area_name(usr, TRUE)]</span>.</span>", usr)
|
|
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)
|
|
updateDialog()
|
|
if("setmsg2")
|
|
stat_msg2 = reject_bad_text(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40)
|
|
updateDialog()
|
|
|
|
// OMG CENTCOM LETTERHEAD
|
|
if("MessageCentCom")
|
|
if(authenticated)
|
|
if(!checkCCcooldown())
|
|
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
|
|
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, "<span class='notice'>Message transmitted to Central Command.</span>")
|
|
usr.log_talk(input, LOG_SAY, tag="CentCom announcement")
|
|
deadchat_broadcast("<span class='deadsay'><span class='name'>[usr.real_name]</span> has messaged CentCom, \"[input]\" at <span class='name'>[get_area_name(usr, TRUE)]</span>.</span>", usr)
|
|
CM.lastTimeUsed = world.time
|
|
|
|
// OMG SYNDICATE ...LETTERHEAD
|
|
if("MessageSyndicate")
|
|
if((authenticated) && (obj_flags & EMAGGED))
|
|
if(!checkCCcooldown())
|
|
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
|
|
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, "<span class='danger'>SYSERR @l(19833)of(transmit.dm): !@$ MESSAGE TRANSMITTED TO SYNDICATE COMMAND.</span>")
|
|
usr.log_talk(input, LOG_SAY, tag="Syndicate announcement")
|
|
deadchat_broadcast("<span class='deadsay'><span class='name'>[usr.real_name]</span> has messaged the Syndicate, \"[input]\" at <span class='name'>[get_area_name(usr, TRUE)]</span>.</span>", usr)
|
|
CM.lastTimeUsed = world.time
|
|
|
|
if("RestoreBackup")
|
|
to_chat(usr, "<span class='notice'>Backup routing data restored!</span>")
|
|
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
|
obj_flags &= ~EMAGGED
|
|
updateDialog()
|
|
|
|
if("nukerequest") //When there's no other way
|
|
if(authenticated==2)
|
|
if(!checkCCcooldown())
|
|
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
|
|
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, "<span class='notice'>Request sent.</span>")
|
|
usr.log_message("has requested the nuclear codes from CentCom", LOG_SAY)
|
|
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")
|
|
aicurrmsg = null
|
|
aistate = STATE_DEFAULT
|
|
if("ai-callshuttle")
|
|
aistate = STATE_CALLSHUTTLE
|
|
if("ai-callshuttle2")
|
|
SSshuttle.requestEvac(usr, href_list["call"])
|
|
aistate = STATE_DEFAULT
|
|
if("ai-messagelist")
|
|
aicurrmsg = null
|
|
aistate = STATE_MESSAGELIST
|
|
if("ai-viewmessage")
|
|
aistate = STATE_VIEWMESSAGE
|
|
if (!aicurrmsg)
|
|
if(href_list["message-num"])
|
|
var/msgnum = text2num(href_list["message-num"])
|
|
aicurrmsg = messages[msgnum]
|
|
else
|
|
aistate = STATE_MESSAGELIST
|
|
if("ai-delmessage")
|
|
aistate = aicurrmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST
|
|
if("ai-delmessage2")
|
|
if(aicurrmsg)
|
|
if(currmsg == aicurrmsg)
|
|
currmsg = null
|
|
messages -= aicurrmsg
|
|
aicurrmsg = null
|
|
aistate = STATE_MESSAGELIST
|
|
if("ai-respond")
|
|
var/answer = text2num(href_list["answer"])
|
|
if(!aicurrmsg || !answer || aicurrmsg.possible_answers.len < answer)
|
|
aistate = STATE_MESSAGELIST
|
|
else
|
|
if(!aicurrmsg.answered)
|
|
aicurrmsg.answered = answer
|
|
log_game("[key_name(usr)] answered [aicurrmsg.title] comm message. Answer : [aicurrmsg.answered]")
|
|
if(aicurrmsg.answer_callback)
|
|
aicurrmsg.answer_callback.InvokeAsync()
|
|
aistate = STATE_VIEWMESSAGE
|
|
if("ai-status")
|
|
aistate = STATE_STATUSDISPLAY
|
|
if("ai-announce")
|
|
make_announcement(usr, 1)
|
|
if("ai-securitylevel")
|
|
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
|
|
if(tmp_alertlevel > SEC_LEVEL_AMBER)
|
|
tmp_alertlevel = SEC_LEVEL_AMBER //Cannot engage delta with this
|
|
set_security_level(tmp_alertlevel)
|
|
if(GLOB.security_level != old_level)
|
|
//Only notify people if an actual change happened
|
|
var/security_level = get_security_level()
|
|
log_game("[key_name(usr)] has changed the security level to [security_level] from [src] at [AREACOORD(usr)].")
|
|
message_admins("[ADMIN_LOOKUPFLW(usr)] has changed the security level to [security_level] from [src] at [AREACOORD(usr)].")
|
|
deadchat_broadcast("<span class='deadsay'><span class='name'>[usr.real_name]</span> has changed the security level to [security_level] from [src] at [get_area_name(usr, TRUE)].</span>", usr)
|
|
tmp_alertlevel = 0
|
|
aistate = STATE_DEFAULT
|
|
if("ai-changeseclevel")
|
|
aistate = STATE_ALERT_LEVEL
|
|
if("ai-emergencyaccess")
|
|
aistate = STATE_TOGGLE_EMERGENCY
|
|
if("ai-enableemergency")
|
|
make_maint_all_access()
|
|
log_game("[key_name(usr)] enabled emergency maintenance access.")
|
|
message_admins("[ADMIN_LOOKUPFLW(usr)] enabled emergency maintenance access.")
|
|
deadchat_broadcast("<span class='deadsay bold'>[usr.real_name] enabled emergency maintenance access.</span>", usr)
|
|
aistate = STATE_DEFAULT
|
|
if("ai-disableemergency")
|
|
revoke_maint_all_access()
|
|
log_game("[key_name(usr)] disabled emergency maintenance access.")
|
|
message_admins("[ADMIN_LOOKUPFLW(usr)] disabled emergency maintenance access.")
|
|
deadchat_broadcast("<span class='deadsay bold'>[usr.real_name] disabled emergency maintenance access.</span>", usr)
|
|
aistate = STATE_DEFAULT
|
|
|
|
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(obj_flags & EMAGGED)
|
|
return
|
|
obj_flags |= EMAGGED
|
|
SSshuttle.shuttle_purchase_requirements_met |= "emagged"
|
|
if(authenticated == 1)
|
|
authenticated = 2
|
|
to_chat(user, "<span class='danger'>You scramble the communication routing circuits!</span>")
|
|
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
|
|
return TRUE
|
|
|
|
/obj/machinery/computer/communications/ui_interact(mob/user)
|
|
. = ..()
|
|
if (z > 6)
|
|
to_chat(user, "<span class='boldannounce'>Unable to establish a connection</span>: \black You're too far away from the station!")
|
|
return
|
|
|
|
var/dat = ""
|
|
if(SSshuttle.emergency.mode == SHUTTLE_CALL)
|
|
var/timeleft = SSshuttle.emergency.timeLeft()
|
|
dat += "<B>Emergency shuttle</B>\n<BR>\nETA: [timeleft / 60 % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]"
|
|
|
|
|
|
var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
|
|
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
|
|
|
if(issilicon(user))
|
|
var/dat2 = 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(state)
|
|
if(STATE_DEFAULT)
|
|
if (authenticated)
|
|
if(SSshuttle.emergencyCallAmount)
|
|
if(SSshuttle.emergencyLastCallLoc)
|
|
dat += "Most recent shuttle call/recall traced to: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b><BR>"
|
|
else
|
|
dat += "Unable to trace most recent shuttle call/recall signal.<BR>"
|
|
dat += "Logged in as: [auth_id]"
|
|
dat += "<BR>"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=logout'>Log Out</A> \]<BR>"
|
|
dat += "<BR><B>General Functions</B>"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=messagelist'>Message List</A> \]"
|
|
switch(SSshuttle.emergency.mode)
|
|
if(SHUTTLE_IDLE, SHUTTLE_RECALL)
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=callshuttle'>Call Emergency Shuttle</A> \]"
|
|
else
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=cancelshuttle'>Cancel Shuttle Call</A> \]"
|
|
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=status'>Set Status Display</A> \]"
|
|
if(!(obj_flags & EMAGGED))
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=MessageCentCom'>Send Message to CentCom</A> \]"
|
|
else
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=MessageSyndicate'>Send Message to \[UNKNOWN\]</A> \]"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=RestoreBackup'>Restore Backup Routing Data</A> \]"
|
|
if (authenticated==2)
|
|
dat += "<BR><BR><B>Captain Functions</B>"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=announce'>Make a Captain's Announcement</A> \]"
|
|
var/cross_servers_count = length(CONFIG_GET(keyed_list/cross_server))
|
|
if(cross_servers_count)
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=crossserver'>Send a message to [cross_servers_count == 1 ? "an " : ""]allied station[cross_servers_count > 1 ? "s" : ""]</A> \]"
|
|
if(SSmapping.config.allow_custom_shuttles)
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=purchase_menu'>Purchase Shuttle</A> \]"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=changeseclevel'>Change Alert Level</A> \]"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=emergencyaccess'>Emergency Maintenance Access</A> \]"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=nukerequest'>Request Nuclear Authentication Codes</A> \]"
|
|
else
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=login'>Log In</A> \]"
|
|
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 in 1 to messages.len)
|
|
var/datum/comm_message/M = messages[i]
|
|
dat += "<BR><A HREF='?src=[REF(src)];operation=viewmessage;message-num=[i]'>[M.title]</A>"
|
|
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
|
if(STATE_VIEWMESSAGE)
|
|
if (currmsg)
|
|
dat += "<B>[currmsg.title]</B><BR><BR>[currmsg.content]"
|
|
if(!currmsg.answered && currmsg.possible_answers.len)
|
|
for(var/i in 1 to currmsg.possible_answers.len)
|
|
var/answer = currmsg.possible_answers[i]
|
|
dat += "<br>\[ <A HREF='?src=[REF(src)];operation=respond;answer=[i]'>Answer : [answer]</A> \]"
|
|
else if(currmsg.answered)
|
|
var/answered = currmsg.possible_answers[currmsg.answered]
|
|
dat += "<br> Archived Answer : [answered]"
|
|
dat += "<BR><BR>\[ <A HREF='?src=[REF(src)];operation=delmessage'>Delete</A> \]"
|
|
else
|
|
aistate = STATE_MESSAGELIST
|
|
attack_hand(user)
|
|
return
|
|
if(STATE_DELMESSAGE)
|
|
if (currmsg)
|
|
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=[REF(src)];operation=delmessage2'>OK</A> | <A HREF='?src=[REF(src)];operation=viewmessage'>Cancel</A> \]"
|
|
else
|
|
state = STATE_MESSAGELIST
|
|
attack_hand(user)
|
|
return
|
|
if(STATE_STATUSDISPLAY)
|
|
dat += "Set Status Displays<BR>"
|
|
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=blank'>Clear</A> \]<BR>"
|
|
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
|
|
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=message'>Message</A> \]"
|
|
dat += "<ul><li> Line 1: <A HREF='?src=[REF(src)];operation=setmsg1'>[ stat_msg1 ? stat_msg1 : "(none)"]</A>"
|
|
dat += "<li> Line 2: <A HREF='?src=[REF(src)];operation=setmsg2'>[ stat_msg2 ? stat_msg2 : "(none)"]</A></ul><br>"
|
|
dat += "\[ Alert: <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=default'>None</A> |"
|
|
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=redalert'>Red Alert</A> |"
|
|
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=lockdown'>Lockdown</A> |"
|
|
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR><HR>"
|
|
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
|
if(STATE_ALERT_LEVEL)
|
|
dat += "Current alert level: [get_security_level()]<BR>"
|
|
if(GLOB.security_level == SEC_LEVEL_DELTA)
|
|
dat += "<font color='red'><b>The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate.</b></font>"
|
|
else
|
|
dat += "<A HREF='?src=[REF(src)];operation=securitylevel;newalertlevel=[SEC_LEVEL_AMBER]'>Amber</A><BR>"
|
|
dat += "<A HREF='?src=[REF(src)];operation=securitylevel;newalertlevel=[SEC_LEVEL_BLUE]'>Blue</A><BR>"
|
|
dat += "<A HREF='?src=[REF(src)];operation=securitylevel;newalertlevel=[SEC_LEVEL_GREEN]'>Green</A>"
|
|
if(STATE_CONFIRM_LEVEL)
|
|
dat += "Current alert level: [get_security_level()]<BR>"
|
|
dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]<BR>"
|
|
dat += "<A HREF='?src=[REF(src)];operation=swipeidseclevel'>Swipe ID</A> to confirm change.<BR>"
|
|
if(STATE_TOGGLE_EMERGENCY)
|
|
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
|
if(GLOB.emergency_access == 1)
|
|
dat += "<b>Emergency Maintenance Access is currently <font color='red'>ENABLED</font></b>"
|
|
dat += "<BR>Restore maintenance access restrictions? <BR>\[ <A HREF='?src=[REF(src)];operation=disableemergency'>OK</A> | <A HREF='?src=[REF(src)];operation=viewmessage'>Cancel</A> \]"
|
|
else
|
|
dat += "<b>Emergency Maintenance Access is currently <font color='green'>DISABLED</font></b>"
|
|
dat += "<BR>Lift access restrictions on maintenance and external airlocks? <BR>\[ <A HREF='?src=[REF(src)];operation=enableemergency'>OK</A> | <A HREF='?src=[REF(src)];operation=viewmessage'>Cancel</A> \]"
|
|
|
|
if(STATE_PURCHASE)
|
|
dat += "Budget: [SSshuttle.points] Credits.<BR>"
|
|
dat += "<BR>"
|
|
dat += "<b>Caution: Purchasing dangerous shuttles may lead to mutiny and/or death.</b><br>"
|
|
dat += "<BR>"
|
|
for(var/shuttle_id in SSmapping.shuttle_templates)
|
|
var/datum/map_template/shuttle/S = SSmapping.shuttle_templates[shuttle_id]
|
|
if(S.can_be_bought && S.credit_cost < INFINITY)
|
|
dat += "[S.name] | [S.credit_cost] Credits<BR>"
|
|
dat += "[S.description]<BR>"
|
|
if(S.prerequisites)
|
|
dat += "Prerequisites: [S.prerequisites]<BR>"
|
|
dat += "<A href='?src=[REF(src)];operation=buyshuttle;chosen_shuttle=[REF(S)]'>(<font color=red><i>Purchase</i></font>)</A><BR><BR>"
|
|
|
|
dat += "<BR><BR>\[ [(state != STATE_DEFAULT) ? "<A HREF='?src=[REF(src)];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=[REF(user)];mach_close=communications'>Close</A> \]"
|
|
|
|
popup.set_content(dat)
|
|
popup.open()
|
|
popup.set_content(dat)
|
|
popup.open()
|
|
|
|
/obj/machinery/computer/communications/proc/get_javascript_header(form_id)
|
|
var/dat = {"<script type="text/javascript">
|
|
function getLength(){
|
|
var reasonField = document.getElementById('reasonfield');
|
|
if(reasonField.value.length >= [CALL_SHUTTLE_REASON_LENGTH]){
|
|
reasonField.style.backgroundColor = "#DDFFDD";
|
|
}
|
|
else {
|
|
reasonField.style.backgroundColor = "#FFDDDD";
|
|
}
|
|
}
|
|
function submit() {
|
|
document.getElementById('[form_id]').submit();
|
|
}
|
|
</script>"}
|
|
return dat
|
|
|
|
/obj/machinery/computer/communications/proc/get_call_shuttle_form(ai_interface = 0)
|
|
var/form_id = "callshuttle"
|
|
var/dat = get_javascript_header(form_id)
|
|
dat += "<form name='callshuttle' id='[form_id]' action='?src=[REF(src)]' method='get' style='display: inline'>"
|
|
dat += "<input type='hidden' name='src' value='[REF(src)]'>"
|
|
dat += "<input type='hidden' name='operation' value='[ai_interface ? "ai-callshuttle2" : "callshuttle2"]'>"
|
|
dat += "<b>Nature of emergency:</b><BR> <input type='text' id='reasonfield' name='call' style='width:250px; background-color:#FFDDDD; onkeydown='getLength() onkeyup='getLength()' onkeypress='getLength()'>"
|
|
dat += "<BR>Are you sure you want to call the shuttle? \[ <a href='#' onclick='submit()'>Call</a> \]"
|
|
return dat
|
|
|
|
/obj/machinery/computer/communications/proc/get_cancel_shuttle_form()
|
|
var/form_id = "cancelshuttle"
|
|
var/dat = get_javascript_header(form_id)
|
|
dat += "<form name='cancelshuttle' id='[form_id]' action='?src=[REF(src)]' method='get' style='display: inline'>"
|
|
dat += "<input type='hidden' name='src' value='[REF(src)]'>"
|
|
dat += "<input type='hidden' name='operation' value='cancelshuttle2'>"
|
|
|
|
dat += "<BR>Are you sure you want to cancel the shuttle? \[ <a href='#' onclick='submit()'>Cancel</a> \]"
|
|
return dat
|
|
|
|
/obj/machinery/computer/communications/proc/interact_ai(mob/living/silicon/ai/user)
|
|
var/dat = ""
|
|
switch(aistate)
|
|
if(STATE_DEFAULT)
|
|
if(SSshuttle.emergencyCallAmount)
|
|
if(SSshuttle.emergencyLastCallLoc)
|
|
dat += "Latest emergency signal trace attempt successful.<BR>Last signal origin: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b>.<BR>"
|
|
else
|
|
dat += "Latest emergency signal trace attempt failed.<BR>"
|
|
if(authenticated)
|
|
dat += "Current login: [auth_id]"
|
|
else
|
|
dat += "Current login: None"
|
|
dat += "<BR><BR><B>General Functions</B>"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-messagelist'>Message List</A> \]"
|
|
if(SSshuttle.emergency.mode == SHUTTLE_IDLE)
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-callshuttle'>Call Emergency Shuttle</A> \]"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-status'>Set Status Display</A> \]"
|
|
dat += "<BR><BR><B>Special Functions</B>"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-announce'>Make an Announcement</A> \]"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-changeseclevel'>Change Alert Level</A> \]"
|
|
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-emergencyaccess'>Emergency Maintenance Access</A> \]"
|
|
if(STATE_CALLSHUTTLE)
|
|
dat += get_call_shuttle_form(1)
|
|
if(STATE_MESSAGELIST)
|
|
dat += "Messages:"
|
|
for(var/i in 1 to messages.len)
|
|
var/datum/comm_message/M = messages[i]
|
|
dat += "<BR><A HREF='?src=[REF(src)];operation=ai-viewmessage;message-num=[i]'>[M.title]</A>"
|
|
if(STATE_VIEWMESSAGE)
|
|
if (aicurrmsg)
|
|
dat += "<B>[aicurrmsg.title]</B><BR><BR>[aicurrmsg.content]"
|
|
if(!aicurrmsg.answered && aicurrmsg.possible_answers.len)
|
|
for(var/i in 1 to aicurrmsg.possible_answers.len)
|
|
var/answer = aicurrmsg.possible_answers[i]
|
|
dat += "<br>\[ <A HREF='?src=[REF(src)];operation=ai-respond;answer=[i]'>Answer : [answer]</A> \]"
|
|
else if(aicurrmsg.answered)
|
|
var/answered = aicurrmsg.possible_answers[aicurrmsg.answered]
|
|
dat += "<br> Archived Answer : [answered]"
|
|
dat += "<BR><BR>\[ <A HREF='?src=[REF(src)];operation=ai-delmessage'>Delete</A> \]"
|
|
else
|
|
aistate = STATE_MESSAGELIST
|
|
attack_hand(user)
|
|
return null
|
|
if(STATE_DELMESSAGE)
|
|
if(aicurrmsg)
|
|
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=[REF(src)];operation=ai-delmessage2'>OK</A> | <A HREF='?src=[REF(src)];operation=ai-viewmessage'>Cancel</A> \]"
|
|
else
|
|
aistate = STATE_MESSAGELIST
|
|
attack_hand(user)
|
|
return
|
|
|
|
if(STATE_STATUSDISPLAY)
|
|
dat += "Set Status Displays<BR>"
|
|
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=blank'>Clear</A> \]<BR>"
|
|
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
|
|
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=message'>Message</A> \]"
|
|
dat += "<ul><li> Line 1: <A HREF='?src=[REF(src)];operation=setmsg1'>[ stat_msg1 ? stat_msg1 : "(none)"]</A>"
|
|
dat += "<li> Line 2: <A HREF='?src=[REF(src)];operation=setmsg2'>[ stat_msg2 ? stat_msg2 : "(none)"]</A></ul><br>"
|
|
dat += "\[ Alert: <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=default'>None</A> |"
|
|
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=redalert'>Red Alert</A> |"
|
|
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=lockdown'>Lockdown</A> |"
|
|
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR><HR>"
|
|
|
|
if(STATE_ALERT_LEVEL)
|
|
dat += "Current alert level: [get_security_level()]<BR>"
|
|
if(GLOB.security_level == SEC_LEVEL_DELTA)
|
|
dat += "<font color='red'><b>The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate.</b></font>"
|
|
else
|
|
dat += "<A HREF='?src=[REF(src)];operation=ai-securitylevel;newalertlevel=[SEC_LEVEL_AMBER]'>Amber</A><BR>"
|
|
dat += "<A HREF='?src=[REF(src)];operation=ai-securitylevel;newalertlevel=[SEC_LEVEL_BLUE]'>Blue</A><BR>"
|
|
dat += "<A HREF='?src=[REF(src)];operation=ai-securitylevel;newalertlevel=[SEC_LEVEL_GREEN]'>Green</A>"
|
|
|
|
if(STATE_TOGGLE_EMERGENCY)
|
|
if(GLOB.emergency_access == 1)
|
|
dat += "<b>Emergency Maintenance Access is currently <font color='red'>ENABLED</font></b>"
|
|
dat += "<BR>Restore maintenance access restrictions? <BR>\[ <A HREF='?src=[REF(src)];operation=ai-disableemergency'>OK</A> | <A HREF='?src=[REF(src)];operation=ai-viewmessage'>Cancel</A> \]"
|
|
else
|
|
dat += "<b>Emergency Maintenance Access is currently <font color='green'>DISABLED</font></b>"
|
|
dat += "<BR>Lift access restrictions on maintenance and external airlocks? <BR>\[ <A HREF='?src=[REF(src)];operation=ai-enableemergency'>OK</A> | <A HREF='?src=[REF(src)];operation=ai-viewmessage'>Cancel</A> \]"
|
|
|
|
dat += "<BR><BR>\[ [(aistate != STATE_DEFAULT) ? "<A HREF='?src=[REF(src)];operation=ai-main'>Main Menu</A> | " : ""]<A HREF='?src=[REF(user)];mach_close=communications'>Close</A> \]"
|
|
return dat
|
|
|
|
/obj/machinery/computer/communications/proc/make_announcement(mob/living/user, is_silicon)
|
|
if(!SScommunications.can_announce(user, is_silicon))
|
|
to_chat(user, "Intercomms recharging. Please stand by.")
|
|
return
|
|
var/input = stripped_input(user, "Please choose a message to announce to the station crew.", "What?")
|
|
if(!input || !user.canUseTopic(src))
|
|
return
|
|
SScommunications.make_announcement(user, is_silicon, input)
|
|
deadchat_broadcast("<span class='deadsay'><span class='name'>[user.real_name]</span> made an priority announcement from <span class='name'>[get_area_name(usr, TRUE)]</span>.</span>", user)
|
|
|
|
/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 ..()
|
|
|
|
/obj/machinery/computer/communications/proc/overrideCooldown()
|
|
var/obj/item/circuitboard/computer/communications/CM = circuit
|
|
CM.lastTimeUsed = 0
|
|
|
|
/obj/machinery/computer/communications/proc/add_message(datum/comm_message/new_message)
|
|
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
|